Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 0 additions & 75 deletions ACP.md

This file was deleted.

85 changes: 0 additions & 85 deletions NEW-ARCHITECTURE.md

This file was deleted.

19 changes: 19 additions & 0 deletions PROXY-API-TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Proxy API TODO

Future work for Vimini's proxy/API backend support.

## Anthropic API support

- Add a native Anthropic backend in addition to the current OpenAI-compatible proxy backend.
- Map Vimini's generic chat, streaming, tools, and tool-response abstractions to Anthropic's Messages API.
- Handle Anthropic-specific streaming events and content block formats.
- Add global config support for `api: "anthropic"`, including model defaults and API key file loading.
- Add tests for model listing behavior, streaming responses, tool calls, and error handling.

## OpenAI Files API for context files

- Add support for OpenAI-compatible Files API uploads so proxy/openai backends can handle Vimini context files similarly to the Gemini backend.
- Track uploaded file IDs and metadata per backend/session where needed.
- Decide how context files should be attached to requests for supported providers and models.
- Add cleanup/list/delete support for uploaded files through `:ViminiFiles` where the provider supports it.
- Add graceful fallback behavior for providers that expose OpenAI-compatible chat APIs but do not support files.
90 changes: 83 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ customizations.
YOUR_API_KEY_HERE
```

2. **Default Model (`g:vimini_model`)**:
Specify the default Gemini model you want to use. The default is
`gemini-2.5-flash`. You can list available models using `:ViminiListModels`.
```vim
let g:vimini_model = 'gemini-2.5-flash' " Or 'gemini-2.5-pro', etc.
```
2. **Default Model (`~/.var/vimini/config.json`)**:
The default model is configured per backend in the global Vimini configuration
file under each backend's `default_model` field. Setting `g:vimini_model` in
your Vim config is deprecated and no longer controls startup model selection.
Use `:ViminiGlobalConfig` or press `D` on a model in `:ViminiListModels` to
save it as the active backend's default model.

3. **Thinking Display (`g:vimini_thinking`)**:
Control whether the AI's "thinking" process is displayed in a
Expand Down Expand Up @@ -156,14 +156,90 @@ customizations.
}
```

11. **Global & Backend Configuration (`~/.var/vimini/config.json`)**:
Vimini manages global settings and model provider backends in `~/.var/vimini/config.json`. If this file does not exist, Vimini automatically generates a default configuration on startup:
```json
{
"active_backend": "Gemini",
"backends": {
"Gemini": {
"api": "genai",
"api_key_file": "~/.config/gemini.token",
"default_model": "gemini-3.8-flash"
}
}
}
```
Configure per-project settings such as whether compilation is needed, shell commands for compiling/building code and running tests when invoked by chat tools (`build_code` and `test_code`), and the directory path where temporary git worktrees can be created. Project configuration is stored in `~/.var/vimini/projects/<project_name>`:
```json
{
"version": "0.1",
"configuration": {
"build-command": "make -j$(nproc)",
"test-command": "pytest",
"compilation-needed": false,
"worktree": "~/.var/vimini/worktree"
},
"files": []
}
```

You can configure multiple backends (Google Gemini via `"api": "genai"`, or OpenAI-compatible proxies and endpoints via `"api": "openai"`).

Backends that require credentials specify an `api_key_file`; Gemini requires
one, while OpenAI-compatible local/proxy endpoints may omit it unless
`requires_api_key` is set. The background agent always reads API keys from
this global configuration file and never receives API key paths through
runtime setup messages. You can also edit this file interactively from Vim with `:ViminiGlobalConfig`.

### `:ViminiGlobalConfig`

Opens an interactive configuration editor in a new split window to configure global Vimini settings and model provider backends stored in `~/.var/vimini/config.json`.

**How to use the global configuration manager:**
* Move the cursor to any configuration option or backend line.
* **`<Enter>` or `e`**: Edits the selected value. On `active_backend`, enter one of the configured backend names. On a backend header, rename the backend.
* **`a`**: Adds a new backend and prompts for API type, default model, API key file, and base URL for OpenAI-compatible backends.
* **`d`**: Clears the selected backend field or deletes the selected backend after confirmation. The last backend cannot be deleted.
* **`r`**: Resets all global configuration options to their last saved state.
* **`q`**: Closes the configuration window. If modifications were made, a confirmation prompt asks whether to save changes permanently to `~/.var/vimini/config.json`.

```vim
:ViminiGlobalConfig
```

12. **Active Backend (`g:vimini_backend`)**:
Specifies the active backend name matching a key in `~/.var/vimini/config.json`. The default is `'Gemini'`.
You can switch backends at runtime using the `:ViminiBackend` command.
```vim
let g:vimini_backend = 'Gemini'
```

## Usage

### `:ViminiBackend [backend_name]`

Displays or switches the active model provider backend at runtime without restarting Vim:
* **Without arguments**: Echoes the active backend and lists other available backends in parentheses (e.g. `Gemini (available: Custom 1, Custom 2)`).
* **With argument**: Validates and switches to the specified backend, updating `g:vimini_backend` and `g:vimini_model` to that backend's default model, and sends an updated setup message to the background agent. Supports tab completion.

```vim
" Check current backend
:ViminiBackend

" Switch to an alternative backend
:ViminiBackend Custom 1
```

Vimini exposes several commands for interacting with the Gemini API:

### `:ViminiListModels`

Lists all available Gemini models in a new split window. This is
useful for knowing which models you can set for `g:vimini_model`.
useful for viewing models available to the active backend.
Press `<Enter>` on a supported model to switch to it for the current session.
Press `D` on a supported model to save it as the active backend's default model
in `~/.var/vimini/config.json` and switch to it immediately.

```vim
:ViminiListModels
Expand Down
46 changes: 42 additions & 4 deletions plugin/vimini.vim
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ let g:loaded_vimini = 1
" Configuration: API Key file path
let s:api_key_file = expand('~/.config/gemini.token')

" Configuration: Model name
let g:vimini_model = get(g:, 'vimini_model', 'gemini-3.6-flash')
" Configuration: Active Backend name
let g:vimini_backend = get(g:, 'vimini_backend', '')

" Configuration: How to split new windows ('vertical' or 'horizontal').
let g:vimini_split_method = get(g:, 'vimini_split_method', 'vertical')
Expand Down Expand Up @@ -60,9 +60,13 @@ try:

from vimini import main
api_key_file = vim.eval('s:api_key_file')
model = vim.eval('g:vimini_model')
backend = vim.eval('g:vimini_backend')
log_file = vim.eval('g:vimini_log_file') if vim.eval('g:vimini_logging') == 'on' else None
main.initialize(api_key_file=api_key_file, model=model, logfile=log_file)
main.initialize(api_key_file=api_key_file, logfile=log_file, backend=backend if backend else None)
from vimini import util
if util._BACKEND:
vim.command(f"let g:vimini_backend = '{util._BACKEND}'")
vim.command(f"let g:vimini_model = '{util._MODEL}'")
socket_path = main.start_agent()
if socket_path:
vim.command(f"let s:socket_path = '{socket_path}'")
Expand Down Expand Up @@ -102,6 +106,26 @@ endfunction

command! ViminiListModels call ViminiListModels()

" Expose a function to switch or display backend
function! ViminiBackend(...)
let l:backend = get(a:, 1, '')
py3 << EOF
try:
from vimini import main
backend_arg = vim.eval('l:backend')
main.backend_command(backend_arg if backend_arg else None)
except Exception as e:
error_message = str(e).replace("\n", " ").replace("\r", " ").replace("'", "''")
vim.command(f"echoerr '[Vimini] Error: {error_message}'")
EOF
endfunction

function! ViminiBackendComplete(ArgLead, CmdLine, CursorPos)
return py3eval("main.get_available_backends(vim.eval('a:ArgLead'))")
endfunction

command! -nargs=* -complete=customlist,ViminiBackendComplete ViminiBackend call ViminiBackend(<q-args>)

" Expose a function to Chat with Gemini
function! ViminiChat()
py3 << EOF
Expand Down Expand Up @@ -463,6 +487,20 @@ endfunction

command! -nargs=0 ViminiConfig call ViminiConfig()

" Expose a function to manage global/backend configuration
function! ViminiGlobalConfig()
py3 << EOF
try:
from vimini import main
main.global_config_command()
except Exception as e:
error_message = str(e).replace("\n", " ").replace("\r", " ").replace("'", "''")
vim.command(f"echoerr '[Vimini] Error: {error_message}'")
EOF
endfunction

command! -nargs=0 ViminiGlobalConfig call ViminiGlobalConfig()

" Expose a function for autocompletion.
" This calls the non-blocking python function that handles the async request.
function! ViminiAutocomplete()
Expand Down
Loading
Loading