A persistent Neovim AI assistant with multi-conversation support, built on OpenAI's Agents SDK.
- Persistent Conversations: Conversations survive Neovim restarts via SQLite storage
- Multi-Layout Support: Toggle between replace, pane, and tab layouts
- Streaming Output: Real-time LLM responses with animated text rendering
- Prompt History: Cycle through previous prompts with
<C-p>and<C-n> - Context Awareness: Automatic inclusion of selected code and
@filereferences - Conversation Browser: Browse and load previous conversations with
:Anya history - Intelligent Code Tools: File editing, searching, and execution with confirmation flow
- OpenRouter & Custom Providers: Drop-in support for any OpenAI-compatible API
- MCP Tools: Optional external tool access via Model Context Protocol
- Neovim 0.10+
- Python 3.11+
- An OpenAI API key (or compatible provider key)
These are not required, but enhance the experience:
| Plugin | Purpose |
|---|---|
| blink.cmp | Autocompletion for @file references and /commands in the prompt buffer |
| snacks.nvim | Powers the :Anya history conversation picker |
| img-clip.nvim | Enables image-aware paste in the prompt buffer via <C-v> and <localleader>v |
{
"igorgue/anya",
config = function()
require("anya").setup({
start_in_insert = true, -- Enter insert mode when opening the prompt
})
end,
}Plug 'igorgue/anya'Then install Python dependencies manually:
cd ~/.local/share/nvim/plugged/anya # or wherever vim-plug installs itAfter installing, register the remote plugin once:
:UpdateRemotePlugins
Then restart Neovim.
Set these before launching Neovim (e.g. in your shell profile):
| Variable | Default | Purpose |
|---|---|---|
ANYA_MODEL |
gpt-4.1 |
Model to use |
ANYA_API_KEY |
— | Override API key (e.g. for OpenRouter) |
ANYA_API_BASE |
— | Custom API base URL |
ANYA_API_TYPE |
responses |
API type: responses or chat_completions or anthropic |
ANYA_THINKING_BUDGET |
— | Reasoning effort hint for supported models |
ANYA_DISABLE_MCP |
0 |
Set to 1 to disable MCP tools |
export ANYA_API_TYPE=chat_completions
export ANYA_API_KEY="sk-or-..."
export ANYA_MODEL="anthropic/claude-opus-4-6"Any model name containing / or : is automatically routed through
https://openrouter.ai/api/v1. You can also point ANYA_API_BASE at any
other OpenAI-compatible endpoint.
require("anya").setup({
start_in_insert = true, -- Auto-enter insert mode when prompt opens (default: false)
image_clip = {
default = {
dir_path = "images",
prompt_for_file_name = false,
},
},
})Anya's daemon always runs under its own bundled Python venv (<plugin-root>/.venv),
regardless of what the shell environment looks like. This means it works correctly even
when you open Neovim from a project directory with a virtualenv activated (mise, pyenv,
conda, plain source .venv/bin/activate, etc.).
However, Neovim's rplugin host (the process that loads plugin.py) is controlled
separately by python3_host_prog. If you don't pin this, Neovim may pick up the active
project Python at startup, which won't have pynvim or the anya package installed, causing
a load failure.
Recommended fix: pin python3_host_prog to Anya's venv Python in your Neovim config:
-- in init.lua (set this before any plugin manager setup)
vim.g.python3_host_prog = vim.fn.expand("~/Code/anya/.venv/bin/python")
-- adjust the path to wherever you cloned/installed anyaWith lazy.nvim you can also set it per-plugin installation path:
vim.g.python3_host_prog = vim.fn.stdpath("data") .. "/lazy/anya/.venv/bin/python"If the daemon still fails to start, Anya will print the Python path it tried to use in the error message so you can diagnose the mismatch quickly.
For quick access from the terminal, add this alias to your ~/.zshrc or ~/.bashrc:
alias anya="nvim +Anya"alias anya="nvim -u ~~/.local/share/nvim/lazy/anya/standalone/init.lua +Anya"Then reload your shell:
source ~/.zshrc # or source ~/.bashrcNow you can open Anya directly by typing anya in your terminal.
| Command | Description |
|---|---|
:Anya |
Toggle Anya UI (reopens last layout) |
:Anya open |
Open Anya UI |
:Anya close |
Close Anya UI |
:Anya tab |
Open in a new tab |
:Anya pane [right|left] |
Open as a side pane |
:Anya send <text> |
Send a message without opening the UI |
:Anya cancel |
Cancel the current in-progress response |
:Anya history |
Open the conversation history picker |
:Anya daemon start |
Start the background daemon manually |
:Anya daemon stop |
Stop the background daemon |
:Anya daemon status |
Show daemon status |
:Anya help |
Show help text |
:Anya do "instruction |
Run an arbitrary command (e.g. :Anya do "write a commit for me") |
The daemon starts automatically when Neovim loads the plugin — you normally don't need to manage it manually.
- Run
:Anyato open the chat interface - Type your message in the prompt window at the bottom
- Press
<CR>to send
| Key | Mode | Action |
|---|---|---|
<CR> |
Normal / Insert | Send message |
<C-p> |
Normal / Insert | Previous prompt in history |
<C-n> |
Normal / Insert | Next prompt in history |
<C-j> |
Normal / Insert | Insert blank line |
<C-k> |
Normal / Insert | Focus chat window |
<Tab> |
Normal / Insert | Toggle focus to chat window |
<C-Up> / <C-Down> |
Normal / Insert | Increase / decrease prompt height |
<C-Left> / <C-Right> |
Normal / Insert | Resize side pane (pane layout) |
<C-a> / <C-e> |
Normal / Insert | Jump to start / end of line |
<C-u> |
Normal / Insert | Delete whole line |
<C-v> |
Normal / Insert | Smart paste: paste image via img-clip.nvim when the clipboard holds an image, otherwise do a normal paste |
<localleader>v |
Normal / Insert | Force image paste via img-clip.nvim |
| Key | Mode | Action |
|---|---|---|
<CR> |
Normal | Open code block / tool output, or toggle fold |
<Space> |
Normal | Open code block or tool output |
<Tab> |
Normal / Insert | Toggle focus to prompt window |
<C-c> |
Normal | Cancel current response |
]] / [[ |
Normal | Jump to next / previous message header |
<localleader>h |
Normal | Open conversation history |
<C-j> |
Normal | Focus prompt window |
In either buffer you can use:
@path/to/file— include a file's contents in your message/command— run a built-in slash command (e.g./review,/plan)
Both are highlighted automatically.
Conversations are saved to ~/.local/share/anya/conversations.db.
Use :Anya history to browse and reload previous conversations.
This requires snacks.nvim.
Daemon not starting?
# Start manually in the foreground to see errors
python -m anya.server.main --foregroundPlugin not loading after install?
Make sure you ran :UpdateRemotePlugins and restarted Neovim.
Streaming issues or errors?
Check the log:
tail -f ~/.local/share/anya/daemon.logCommands not found?
Confirm the Python dependencies are installed in the same environment Neovim
uses. Run :checkhealth provider to verify.
See AGENTS.md for a full technical reference covering the agent system, daemon design, IPC protocol, marker format, and tool extensibility.
TBD
If you install img-clip.nvim, Anya's prompt buffer can paste clipboard images directly into the prompt. <C-v> is image-aware and falls back to normal clipboard paste when there is no image in the clipboard. <localleader>v always tries an image paste. Anya explicitly disables img-clip.nvim drag-and-drop paste interception so terminal paste paths like <C-S-v> keep their normal behavior. The standalone config vendors img-clip.nvim the same way as the other bundled plugins.