A lightweight, extensible chat plugin for Neovim with AI integration. Chat with AI assistants directly in your editor using a clean, floating window interface.

@read_file, @find_files, @search_text), version control (@git_diff), memory management (@extract_memory, @recall_memory), web operations (@fetch_web, @web_search), and prompt management (@set_prompt):Chat new), navigating (:Chat prev/next), clearing (:Chat clear), deleting (:Chat delete) sessions, and changing working directory (:Chat cd)picker-chat), switching providers (chat_provider), and selecting models (chat_model)Ctrl-C) and retry mechanism (r)System Dependencies (optional but recommended for full functionality):
ripgrep (rg): Required for the @search_text tool
curl: Required for the @fetch_web tool
git: Required for the @git_diff tool
Install with your package manager:
# Ubuntu/Debian
sudo apt install ripgrep curl git
# macOS
brew install ripgrep curl git
# Arch Linux
sudo pacman -S ripgrep curl git
Neovim Plugin Dependencies:
job.nvim: Required dependency for asynchronous operationspicker.nvim: Recommended for enhanced session and provider managementrequire('plug').add({
{
'wsdjeg/chat.nvim',
depends = {
{
'wsdjeg/job.nvim', -- Required
'wsdjeg/picker.nvim', -- Optional but recommended
},
},
},
})
{
'wsdjeg/chat.nvim',
dependencies = {
'wsdjeg/job.nvim', -- Required
'wsdjeg/picker.nvim', -- Optional but recommended
},
}
use({
'wsdjeg/chat.nvim',
requires = {
'wsdjeg/job.nvim', -- Required
'wsdjeg/picker.nvim', -- Optional but recommended
},
})
If you're not using a package manager:
Clone the repositories:
git clone https://github.com/wsdjeg/chat.nvim ~/.local/share/nvim/site/pack/chat/start/chat.nvim
git clone https://github.com/wsdjeg/job.nvim ~/.local/share/nvim/site/pack/chat/start/job.nvim
Add to your Neovim configuration (~/.config/nvim/init.lua or ~/.config/nvim/init.vim):
vim.cmd[[packadd job.nvim]]
vim.cmd[[packadd chat.nvim]]
require('chat').setup({
-- Your configuration here
})
api_key tableallowed_path to control which directories tools can accessAfter installation, you can immediately start using chat.nvim:
:Chat " Open chat window
:Chat new " Start a new session
:Chat prev " Switch to previous session
:Chat next " Switch to next session
For detailed usage instructions, see the Usage section.
chat.nvim provides flexible configuration options through the require('chat').setup() function. All configurations have sensible defaults.
| Option | Type | Default | Description |
|---|---|---|---|
width |
number | 0.8 |
Chat window width (percentage of screen width, 0.0-1.0) |
height |
number | 0.8 |
Chat window height (percentage of screen height, 0.0-1.0) |
auto_scroll |
boolean | true |
Controls automatic scrolling behavior of the result window |
border |
string | 'rounded' |
Window border style, supports all Neovim border options |
provider |
string | 'deepseek' |
Default AI provider |
model |
string | 'deepseek-chat' |
Default AI model |
strftime |
string | '%m-%d %H:%M:%S' |
Time display format |
system_prompt |
string | '' |
Default system prompt |
Configure API keys for the AI providers you plan to use:
api_key = {
deepseek = 'sk-xxxxxxxxxxxx', -- DeepSeek AI
github = 'github_pat_xxxxxxxx', -- GitHub AI
moonshot = 'sk-xxxxxxxxxxxx', -- Moonshot AI
openrouter = 'sk-or-xxxxxxxx', -- OpenRouter
qwen = 'qwen-xxxxxxxx', -- Alibaba Qwen
siliconflow = 'xxxxxxxx-xxxx-xxxx', -- SiliconFlow
tencent = 'xxxxxxxx-xxxx-xxxx', -- Tencent Hunyuan
bigmodel = 'xxxxxxxx-xxxx-xxxx', -- BigModel AI
volcengine = 'xxxxxxxx-xxxx-xxxx', -- Volcengine AI
openai = 'sk-xxxxxxxxxxxx', -- OpenAI
longcat = 'lc-xxxxxxxxxxxx', -- LongCat AI
}
Only configure keys for providers you plan to use; others can be omitted.
Control which file paths tools can access for security:
-- Option 1: Disable all file access (default)
allowed_path = ''
-- Option 2: Allow a single directory
allowed_path = '/home/user/projects'
-- Option 3: Allow multiple directories
allowed_path = {
vim.fn.getcwd(), -- Current working directory
vim.fn.expand('~/.config/nvim'), -- Neovim config directory
'/etc', -- System configuration files
}
Configure the behavior of the long-term memory system:
memory = {
enable = true, -- Whether to enable the memory system
max_memories = 500, -- Maximum number of memories to store
retrieval_limit = 3, -- Maximum memories to retrieve per query
similarity_threshold = 0.3, -- Text similarity threshold (0-1)
storage_dir = vim.fn.stdpath('cache') .. '/chat.nvim/memory/',
}
require('chat').setup({
-- Window settings
width = 0.8,
height = 0.8,
auto_scroll = true, -- Enable smart auto-scrolling (default)
border = 'rounded',
-- AI provider settings
provider = 'deepseek',
model = 'deepseek-chat',
api_key = {
deepseek = 'sk-xxxxxxxxxxxx',
github = 'github_pat_xxxxxxxx',
},
-- File access control
allowed_path = {
vim.fn.getcwd(), -- Current working directory
vim.fn.expand('~/.config/nvim'), -- Neovim config directory
},
-- Other settings
strftime = '%Y-%m-%d %H:%M',
system_prompt = 'You are a helpful programming assistant.',
-- Memory system
memory = {
enable = true,
max_memories = 1000,
retrieval_limit = 5,
similarity_threshold = 0.25,
},
})
allowed_path restricts which file paths tools can access. Empty string disables all file access. Recommended to set to your current project directory for security.memory.enable = false.auto_scroll option controls whether the result window automatically scrolls to show new content. When enabled (default), it only scrolls if the cursor was already at the bottom, preventing interruptions when reviewing history.chat.nvim provides several commands to manage your AI conversations.
The main command is :Chat, which opens the chat window.
You can also navigate between sessions using the following commands.
| Command | Description |
|---|---|
:Chat |
Open the chat window with the current session |
:Chat new |
Start a new chat session |
:Chat prev |
Switch to the previous chat session |
:Chat next |
Switch to the next chat session |
:Chat delete |
Delete current session and create new empty session |
:Chat clear |
Clear all messages in current session |
:Chat cd <dir> |
Change current session cwd, open chat window |
chat.nvim supports running multiple chat sessions simultaneously, with each session operating independently:
:Chat prev and :Chat next to navigate between active sessionsWorkflow Example:
:Chat new (then select DeepSeek model):Chat new (select GitHub model):Chat prev / :Chat nextStart a new conversation:
:Chat new
This creates a fresh session and opens the chat window.
Resume a previous conversation:
:Chat prev
Cycles backward through your saved sessions.
Switch to the next conversation:
:Chat next
Cycles forward through your saved sessions.
Open or forced to the chat window:
:Chat
This command will not change current sessions.
Delete current session:
:Chat delete
Cycles to next session or create a new session if current session is latest one.
Change the working directory of current session:
:Chat cd ../picker.nvim/
If the current session is in progress, the working directory will not be changed, and a warning message will be printed.
Clear messages in current session:
:Chat clear
If the current session is in progress, a warning message will be printed, and current session will not be cleared. This command also will forced to chat window.
Work with multiple parallel sessions:
" Start first session with DeepSeek
:Chat new
" Select DeepSeek as provider and choose a model
" Start second session with GitHub AI
:Chat new
" Select GitHub as provider and choose a model
" Switch between sessions
:Chat prev " Go to first session
:Chat next " Go to second session
This enables simultaneous conversations with different AI assistants for different tasks.
All sessions are automatically saved and can be resumed later. For more advanced session management, see the Picker Integration section below.
Note: The plugin is currently in active development phase. Key bindings may change and may reflect the author's personal preferences. Configuration options for customizing key bindings are planned for future releases.
The following key bindings are available in the Input window:
| Mode | Key Binding | Description |
|---|---|---|
Normal |
<Enter> |
Send message |
Normal |
q |
Close chat window |
Normal |
<Tab> |
Switch between input and result windows |
Normal |
Ctrl-C |
Cancel current request |
Normal |
Ctrl-N |
Open new session |
Normal |
r |
Retry last cancelled request |
Normal |
alt-h |
previous chat session |
Normal |
alt-l |
next chat session |
Normal |
<Leaer>fr |
run :Picker chat |
Normal |
<Leaer>fp |
run :Picker chat_provider |
Normal |
<Leader>fm |
run :Picker chat_model |
The following key bindings are available in the Result window:
| Mode | Key Binding | Description |
|---|---|---|
Normal |
q |
Close chat window |
Normal |
<Tab> |
Switch between input and result windows |
deepseek - DeepSeek AIgithub - GitHub AImoonshot - Moonshot AIopenrouter - OpenRouterqwen - Alibaba Cloud Qwensiliconflow - SiliconFlowtencent - Tencent Hunyuanbigmodel - BigModel AIvolcengine - Volcengine AIopenai - OpenAIlongcat - LongCat AIcherryin - CherryIN AIchat.nvim also supports custom provider, just create lua/chat/providers/<provider_name>.lua, this lua module
should provides two functions request and available_models,
here is an example for using free_chatgpt_api
file: ~/.config/nvim/lua/chat/provides/free_chatgpt_api.lua
local M = {}
local job = require('job')
local sessions = require('chat.sessions')
local config = require('chat.config')
function M.available_models()
return {
'gpt-4o-mini',
}
end
function M.request(requestObj)
local cmd = {
'curl',
'-s',
'https://free.v36.cm/v1/chat/completions',
'-H',
'Content-Type: application/json',
'-H',
'Authorization: Bearer ' .. config.config.api_key.free_chatgpt,
'-X',
'POST',
'@-',
}
local body = vim.json.encode({
model = sessions.get_session_model(opt.session),
messages = opt.messages,
thinking = {
type = 'enabled',
},
stream = true,
stream_options = { include_usage = true },
tools = require('chat.tools').available_tools(),
})
local jobid = job.start(cmd, {
on_stdout = opt.on_stdout,
on_stderr = opt.on_stderr,
on_exit = opt.on_exit,
})
job.send(jobid, body)
job.send(jobid, nil)
sessions.set_session_jobid(opt.session, jobid)
return jobid
end
return M
chat.nvim supports tool call functionality, allowing the AI assistant to interact with your filesystem, manage memories, and perform other operations during conversations. Tools are invoked using the @tool_name syntax directly in your messages.
read_fileReads the content of a file and makes it available to the AI assistant.
Usage:
@read_file <filepath>
Examples:
@read_file ./src/main.lua - Read a Lua file in the current directory@read_file /etc/hosts - Read a system file using absolute path@read_file ../config.json - Read a file from a parent directoryAdvanced Usage with Line Ranges:
@read_file ./src/main.lua line_start=10 line_to=20
Notes:
line_start and line_to parametersline_start is not specified, defaults to line 1line_to is not specified, defaults to last linefind_filesFinds files in the current working directory that match a given pattern.
Usage:
@find_files <pattern>
Examples:
@find_files *.lua - Find all Lua files in the current directory@find_files **/*.md - Recursively find all Markdown files@find_files src/**/*.js - Find JavaScript files in the src directory and its subdirectories@find_files README* - Find files starting with "README"Notes:
globpath syntaxallowed_path configuration settingsearch_textAdvanced text search tool using ripgrep (rg) to search text content in directories with regex support, file type filtering, exclusion patterns, and other advanced features.
Usage:
@search_text <pattern> [options]
Basic Examples:
@search_text "function.*test" - Search for regex pattern in current directory@search_text "TODO:" --file-types "*.lua" - Search TODO comments in Lua files@search_text "error" --context-lines 2 - Search for "error" with 2 lines of contextAdvanced Usage with JSON Parameters:
For more complex searches, you can provide a JSON object with multiple parameters:
@search_text {"pattern": "function.*test", "directory": "./src", "file_types": ["*.lua", "*.vim"], "ignore_case": true, "max_results": 50}
Parameters:
| Parameter | Type | Description |
|---|---|---|
pattern |
string | Required. Text pattern to search for (supports regex) |
directory |
string | Directory path to search in (default: current working directory) |
ignore_case |
boolean | Whether to ignore case (default: false) |
regex |
boolean | Whether to use regex (default: true) |
max_results |
integer | Maximum number of results (default: 100) |
context_lines |
integer | Number of context lines to show around matches (default: 0) |
whole_word |
boolean | Whether to match whole words only (default: false) |
file_types |
array | File type filter, e.g., ["*.py", "*.md", "*.txt"] |
exclude_patterns |
array | Exclude file patterns, e.g., ["*.log", "tmp/*"] |
More Examples:
Case-insensitive search:
@search_text {"pattern": "config", "ignore_case": true}
Search with file type filtering:
@search_text {"pattern": "function", "file_types": ["*.lua", "*.vim"]}
Search with context and exclusions:
@search_text {"pattern": "FIXME", "context_lines": 3, "exclude_patterns": ["*.log", "node_modules/*"]}
Whole word matching:
@search_text {"pattern": "test", "whole_word": true}
Notes:
allowed_path configuration settingextract_memoryExtract long-term memories from conversation text, focusing ONLY on factual information and habitual patterns. Filters out subjective feelings, temporary states, and irrelevant chatter.
Usage:
@extract_memory <parameters>
Examples:
@extract_memory text="Python的GIL是全局解释器锁,我习惯用Vim写代码" category="fact"@extract_memory text="我每天早晨6点起床锻炼,通常下午3点喝咖啡" category="preference"Parameters:
| Parameter | Type | Description |
|---|---|---|
text |
string | Text to analyze for memory extraction |
memories |
array | Pre-extracted memories array (alternative to text parameter) |
category |
string | Suggested category: "fact", "preference", "skill", or "event" |
Category Definitions:
Notes:
recall_memoryRetrieve relevant information from long-term memory and add to current conversation. Automatically extracts keywords if no query is provided.
Usage:
@recall_memory <parameters>
Examples:
@recall_memory query="vim configuration"@recall_memory query="programming tips" limit=8@recall_memory (automatically extracts keywords from current conversation)Parameters:
| Parameter | Type | Description |
|---|---|---|
query |
string | Search query (optional, auto-extracted if not provided) |
limit |
integer | Number of results (default: 5, maximum: 10) |
all_sessions |
boolean | Search all sessions instead of just current (default: false) |
Notes:
set_promptRead a prompt file and set it as the current session's system prompt.
Usage:
@set_prompt <filepath>
Examples:
@set_prompt ./AGENTS.md@set_prompt ./prompts/code_review.txt@set_prompt ~/.config/chat.nvim/default_prompt.mdParameters:
| Parameter | Type | Description |
|---|---|---|
filepath |
string | Path to prompt file |
Notes:
allowed_path configured in chat.nvimfetch_webFetch content from web URLs using curl with comprehensive HTTP support.
Usage:
@fetch_web <parameters>
Basic Examples:
@fetch_web url="https://example.com" - Fetch content from a URL@fetch_web url="https://api.github.com/repos/neovim/neovim" timeout=60 user_agent="MyApp/1.0" - Fetch with custom timeout and user agent@fetch_web url="https://api.github.com/user" headers=["Authorization: Bearer token123"] - Fetch with custom headers@fetch_web url="https://api.example.com/data" method="POST" data='{"key":"value"}' headers=["Content-Type: application/json"] - POST request with JSON data@fetch_web url="https://self-signed.example.com" insecure=true - Disable SSL verification (testing only)@fetch_web url="https://example.com/redirect" max_redirects=2 - Limit redirectsAdvanced Usage with JSON Parameters:
For complex requests, you can provide a JSON object:
@fetch_web {"url": "https://example.com", "method": "POST", "data": "{\"key\":\"value\"}", "headers": ["Content-Type: application/json"], "timeout": 30}
Parameters:
| Parameter | Type | Description |
|---|---|---|
url |
string | Required. URL to fetch (must start with http:// or https://) |
method |
string | HTTP method (default: "GET", options: GET, POST, PUT, DELETE, PATCH, HEAD) |
headers |
array | Additional HTTP headers as strings (e.g., ["Authorization: Bearer token", "Accept: application/json"]) |
data |
string | Request body data for POST/PUT requests |
timeout |
integer | Timeout in seconds (default: 30, minimum: 1, maximum: 300) |
user_agent |
string | Custom User-Agent header string (default: "Mozilla/5.0 (compatible; chat.nvim)") |
insecure |
boolean | Disable SSL certificate verification (use with caution, for testing only) |
max_redirects |
integer | Maximum number of redirects to follow (default: 5, set to 0 to disable) |
output |
string | Save response to file instead of displaying (e.g., "./response.html") |
More Examples:
Basic GET request:
@fetch_web url="https://jsonplaceholder.typicode.com/posts/1"
POST request with JSON data:
@fetch_web url="https://api.example.com/users" method="POST" data='{"name": "John", "age": 30}' headers=["Content-Type: application/json"]
With authentication header:
@fetch_web url="https://api.github.com/user/repos" headers=["Authorization: Bearer YOUR_TOKEN", "Accept: application/vnd.github.v3+json"]
Save response to file:
@fetch_web url="https://example.com" output="./downloaded_page.html"
Configure timeout and SSL verification:
@fetch_web url="https://slow-api.example.com" timeout=60 insecure=true
Notes:
insecure=true for testing)output parameter to save to a fileweb_searchSearch the web using Firecrawl, Google Custom Search API, or SerpAPI.
Usage:
@web_search <parameters>
Supported Engines:
Configuration:
API keys must be set in chat.nvim configuration:
require('chat').setup({
api_key = {
firecrawl = 'fc-YOUR_API_KEY',
google = 'YOUR_GOOGLE_API_KEY',
google_cx = 'YOUR_SEARCH_ENGINE_ID',
serpapi = 'YOUR_SERPAPI_KEY'
}
})
Alternatively, provide API keys directly as parameters.
Examples:
Basic Firecrawl search:
@web_search query="firecrawl web scraping"
Firecrawl with result limit:
@web_search query="neovim plugins" limit=10
Google search:
@web_search query="latest news" engine="google"
Google search with custom API key and cx:
@web_search query="test" engine="google" api_key="GOOGLE_API_KEY" cx="SEARCH_ENGINE_ID"
SerpAPI with Google (default):
@web_search query="neovim plugins" engine="serpapi"
SerpAPI with Bing:
@web_search query="latest news" engine="serpapi" serpapi_engine="bing"
SerpAPI with DuckDuckGo:
@web_search query="privacy tools" engine="serpapi" serpapi_engine="duckduckgo"
Custom timeout:
@web_search query="slow site" timeout=60
Firecrawl with scrape options:
@web_search query="news" scrape_options={"formats":["markdown"]}
Parameters:
| Parameter | Type | Description |
|---|---|---|
query |
string | Required. Search query string |
engine |
string | Search engine to use: "firecrawl", "google", or "serpapi" (default: "firecrawl") |
limit |
integer | Number of results to return (default: 5 for firecrawl, 10 for google/serpapi) |
scrape_options |
object | Options for scraping result pages (Firecrawl only, see Firecrawl docs) |
api_key |
string | API key (optional if configured in config) |
cx |
string | Google Custom Search engine ID (required for Google engine if not in config) |
timeout |
integer | Timeout in seconds (default: 30, minimum: 1, maximum: 300) |
serpapi_engine |
string | SerpAPI search engine: "google", "bing", "duckduckgo", "yahoo", "baidu", etc. (optional) |
SerpAPI Search Engines:
When using SerpAPI, you can specify different search engines via the serpapi_engine parameter:
| Engine | Description |
|---|---|
google |
Google Search |
bing |
Microsoft Bing |
duckduckgo |
DuckDuckGo |
yahoo |
Yahoo Search |
baidu |
Baidu |
yandex |
Yandex |
ebay |
eBay Search |
| ...and more | See SerpAPI docs |
Notes:
serpapi_engine parametergit_diffRun git diff to compare changes between working directory, index, or different branches.
Usage:
@git_diff <parameters>
Basic Examples:
@git_diff - Show all unstaged changes in the repository@git_diff cached=true - Show staged changes (--cached)@git_diff branch="main" - Compare working directory with main branch@git_diff path="./src" - Show changes for specific file or directory@git_diff branch="master" cached=true - Compare staged changes with master branchAdvanced Usage with JSON Parameters:
For more complex comparisons, you can provide a JSON object:
@git_diff {"path": "./lua/chat", "branch": "develop", "cached": true}
Parameters:
| Parameter | Type | Description |
|---|---|---|
path |
string | File or directory path to show diff for (optional) |
cached |
boolean | Show staged changes (git diff --cached) (optional) |
branch |
string | Branch to compare against (e.g., "master", "origin/main") (optional) |
More Examples:
View all unstaged changes:
@git_diff
View staged changes only:
@git_diff cached=true
Compare with another branch:
@git_diff branch="main"
Check changes in specific file:
@git_diff path="./lua/chat/tools/git_diff.lua"
Compare staged changes with master branch:
@git_diff branch="master" cached=true
Combined usage:
@git_diff {"path": "./lua/chat/tools", "branch": "develop", "cached": false}
Notes:
cached flag shows changes that are staged (git diff --cached)branch parameter allows comparing with another branch (git diff )path parameter restricts diff output to specific file or directoryzettelkasten_createCreate new zettelkasten notes, provided by zettelkasten.nvim.
Usage:
@zettelkasten_create <parameters>
Parameters:
| Parameter | Type | Description |
|---|---|---|
title |
string | The title of zettelkasten note |
content |
string | The note body of zettelkasten |
tags |
array | Optional tags for the note (max 3) |
Notes:
zettelkasten_getRetrieve zettelkasten notes by tags, provided by zettelkasten.nvim.
Usage:
@zettelkasten_get <tags>
Parameters:
| Parameter | Type | Description |
|---|---|---|
tags |
array | Tags to search for (e.g., ["programming", "vim"]) |
Notes:
file_name and title fieldsDirect invocation: Include the tool call directly in your message:
Can you review this code? @read_file ./my_script.lua
Multiple tools: Combine multiple tools in a single message:
Compare these two configs: @read_file ./config1.json @read_file ./config2.json
Natural integration: The tool calls can be embedded naturally within your questions:
What's wrong with this function? @read_file ./utils.lua
Memory management: Use memory tools for context-aware conversations:
Based on what we discussed earlier about Vim: @recall_memory query="vim"
The AI assistant will process the tool calls, execute the specified operations, and incorporate their results into its response. This enables more context-aware assistance without needing to manually copy-paste file contents or repeat previous information.
chat.nvim also supports custom tools. Users can create lua/chat/tools/<tool_name>.lua file in their Neovim runtime path.
This module should provide at least two functions: scheme() and <tool_name> function. The scheme() function returns a table describing the tool's schema (name, description, parameters). The <tool_name> function is the actual implementation that will be called when the tool is invoked.
The tools.lua module automatically discovers all tools in the lua/chat/tools/ directory and provides an available_tools() function to list them, and a call(func, arguments) function to invoke a specific tool.
Here is an example for a get_weather tool:
local M = {}
---@param action { city: string, unit?: string }
function M.get_weather(action)
if not action.city or action.city == '' then
return {
error = 'City name is required for weather information.',
}
end
local unit = action.unit or 'celsius'
local valid_units = { 'celsius', 'fahrenheit' }
if not vim.tbl_contains(valid_units, unit) then
return {
error = 'Unit must be either "celsius" or "fahrenheit".',
}
end
-- Simulate fetching weather data (in a real implementation, you would call an API here)
local temperature = math.random(15, 35) -- Random temperature between 15°C and 35°C
local conditions = { 'Sunny', 'Cloudy', 'Rainy', 'Partly Cloudy', 'Windy' }
local condition = conditions[math.random(1, #conditions)]
-- Convert temperature if needed
if unit == 'fahrenheit' then
temperature = math.floor((temperature * 9/5) + 32)
end
return {
content = string.format(
'Weather in %s:\n- Temperature: %d°%s\n- Condition: %s\n- Humidity: %d%%\n- Wind Speed: %d km/h',
action.city,
temperature,
unit == 'celsius' and 'C' or 'F',
condition,
math.random(40, 90),
math.random(5, 25)
),
}
end
function M.scheme()
return {
type = 'function',
['function'] = {
name = 'get_weather',
description = 'Get weather information for a specific city. Use @get_weather {city: "City Name"} to get weather details.',
parameters = {
type = 'object',
properties = {
city = {
type = 'string',
description = 'City name for weather information',
},
unit = {
type = 'string',
description = 'Temperature unit: "celsius" or "fahrenheit"',
enum = { 'celsius', 'fahrenheit' },
},
},
required = { 'city' },
},
},
}
end
return M
chat.nvim provides built-in picker sources for seamless integration with picker.nvim. These sources allow you to quickly access and manage your chat sessions, providers, and models.
Note: The chat picker source displays all your active sessions, allowing quick switching between parallel conversations with different models.
Available Sources:
chat - Search through your chat history sessions

chat_provider - Switch between different AI providers

chat_model - Select available models for the current provider

Like this plugin? Star the repository on GitHub.
Love this plugin? Follow me on GitHub.
If you encounter any bugs or have suggestions, please file an issue in the issue tracker.
This project is licensed under the GPL-3.0 License.