add possibility to define a project based instruction file

This commit is contained in:
samuelm00
2025-08-18 22:54:28 +02:00
committed by yetone
parent fed6902c9a
commit 0a603efad1
4 changed files with 148 additions and 6 deletions

View File

@@ -61,6 +61,7 @@ If you like this project, please consider supporting me on Patreon, as it helps
- **AI-Powered Code Assistance**: Interact with AI to ask questions about your current code file and receive intelligent suggestions for improvement or modification.
- **One-Click Application**: Quickly apply the AI's suggested changes to your source code with a single command, streamlining the editing process and saving time.
- **Project-Specific Instruction Files**: Customize AI behavior by adding a markdown file (`avante.md` by default) in the project root. This file is automatically referenced during workspace changes. You can also configure a custom file name for tailored project instructions.
## Installation
@@ -84,6 +85,8 @@ For building binary if you wish to build from source, then `cargo` is required.
---@type avante.Config
opts = {
-- add any opts here
-- this file can containe specific instructions for your project
instructions_file = "avante.md"
-- for example
provider = "claude",
providers = {
@@ -656,6 +659,7 @@ For other users just add a custom provider
Avante.nvim provides several completion sources that can be integrated with blink.cmp:
#### Mentions (`@` trigger)
Mentions allow you to quickly reference specific features or add files to the chat context:
- `@codebase` - Enable project context and repository mapping
@@ -665,6 +669,7 @@ Mentions allow you to quickly reference specific features or add files to the ch
- `@buffers` - Add open buffers to chat context
#### Slash Commands (`/` trigger)
Built-in slash commands for common operations:
- `/help` - Show help message with available commands
@@ -676,6 +681,7 @@ Built-in slash commands for common operations:
- `/commit` - Generate commit message for changes
#### Shortcuts (`#` trigger)
Shortcuts provide quick access to predefined prompt templates. You can customize these in your config:
```lua
@@ -983,6 +989,7 @@ Fast Apply is a feature that enables instant code edits with high accuracy by le
Fast Apply addresses the common pain point of slow code application in AI-assisted development. Instead of waiting for a full language model to process and apply changes, Fast Apply uses a specialized "apply model" that can quickly and accurately merge code edits with 96-98% accuracy at speeds of 2500-4500+ tokens per second.
Key benefits:
- **Instant application**: Code changes are applied immediately without noticeable delays
- **High accuracy**: Specialized models achieve 96-98% accuracy for code edits
- **Seamless workflow**: Maintains the natural flow of development without interruptions
@@ -993,6 +1000,7 @@ Key benefits:
To enable Fast Apply, you need to:
1. **Enable Fast Apply in your configuration**:
```lua
behaviour = {
enable_fastapply = true, -- Enable Fast Apply feature
@@ -1004,6 +1012,7 @@ To enable Fast Apply, you need to:
Go to [morphllm.com](https://morphllm.com/api-keys) and create an account and get the API key.
3. **Set your Morph API key**:
```bash
export MORPH_API_KEY="your-api-key"
```
@@ -1021,11 +1030,11 @@ To enable Fast Apply, you need to:
Morph provides different models optimized for different use cases:
| Model | Speed | Accuracy | Context Limit |
|-------|-------|----------|---------------|
| `morph-v3-fast` | 4500+ tok/sec | 96% | 16k tokens |
| `morph-v3-large` | 2500+ tok/sec | 98% | 16k tokens |
| `auto` | 2500-4500 tok/sec | 98% | 16k tokens |
| Model | Speed | Accuracy | Context Limit |
| ---------------- | ----------------- | -------- | ------------- |
| `morph-v3-fast` | 4500+ tok/sec | 96% | 16k tokens |
| `morph-v3-large` | 2500+ tok/sec | 98% | 16k tokens |
| `auto` | 2500-4500 tok/sec | 98% | 16k tokens |
### How It Works
@@ -1037,6 +1046,7 @@ When Fast Apply is enabled and a Morph provider is configured, avante.nvim will:
4. Apply the changes directly to your files with high accuracy
The process uses a specialized prompt format that includes:
- `<instructions>`: Clear description of what changes to make
- `<code>`: The original code content
- `<update>`: The specific changes using truncation markers (`// ... existing code ...`)
@@ -1387,6 +1397,7 @@ Avante.nvim can be extended to work with other plugins by using its extension mo
### How to disable agentic mode?
Avante.nvim provides two interaction modes:
- **`agentic`** (default): Uses AI tools to automatically generate and apply code changes
- **`legacy`**: Uses the traditional planning method without automatic tool execution
@@ -1400,10 +1411,12 @@ To disable agentic mode and switch to legacy mode, update your configuration:
```
**What's the difference?**
- **Agentic mode**: AI can automatically execute tools like file operations, bash commands, web searches, etc. to complete complex tasks
- **Legacy mode**: AI provides suggestions and plans but requires manual approval for all actions
**When should you use legacy mode?**
- If you prefer more control over what actions the AI takes
- If you're concerned about security with automatic tool execution
- If you want to manually review each step before applying changes

View File

@@ -17,6 +17,9 @@ local Utils = require("avante.utils")
---@class avante.CoreConfig: avante.Config
local M = {}
--- Default configuration for project-specific instruction file
M.instructions_file = "avante.md"
---@class avante.Config
M._defaults = {
debug = false,

View File

@@ -8,6 +8,7 @@ local Utils = require("avante.utils")
local Prompts = require("avante.utils.prompts")
local Config = require("avante.config")
local Path = require("avante.path")
local PPath = require("plenary.path")
local Providers = require("avante.providers")
local LLMToolHelpers = require("avante.llm_tools.helpers")
local LLMTools = require("avante.llm_tools")
@@ -255,6 +256,17 @@ end
---@param opts AvanteGeneratePromptsOptions
---@return AvantePromptOptions
function M.generate_prompts(opts)
local project_instruction_file = Config.instructions_file or "avante.md"
local project_root = Utils.root.get()
local instruction_file_path = PPath:new(project_root, project_instruction_file)
if instruction_file_path:exists() then
local lines = Utils.read_file_from_buf_or_disk(instruction_file_path:absolute())
local instruction_content = lines and table.concat(lines, "\n") or ""
if instruction_content then opts.instructions = (opts.instructions or "") .. "\n" .. instruction_content end
end
local provider = opts.provider or Providers[Config.provider]
local mode = opts.mode or Config.mode
@@ -264,7 +276,6 @@ function M.generate_prompts(opts)
image_paths = vim.list_extend(image_paths, opts.prompt_opts.image_paths)
end
local project_root = Utils.root.get()
Path.prompts.initialize(Path.prompts.get_templates_dir(project_root), project_root)
local system_info = Utils.get_system_info()

115
tests/llm_spec.lua Normal file
View File

@@ -0,0 +1,115 @@
local utils = require("avante.utils")
local PPath = require("plenary.path")
local llm = require("avante.llm")
describe("generate_prompts", function()
local project_root = "/tmp/project_root"
before_each(function()
local mock_dir = PPath:new("tests", project_root)
mock_dir:mkdir({ parents = true })
local mock_file = PPath:new("tests", project_root, "avante.md")
mock_file:write("# Mock Instructions\nThis is a mock instruction file.", "w")
-- Mock the project root
utils.root = {}
utils.root.get = function() return mock_dir end
-- Mock Config.providers
local Config = require("avante.config")
Config.instructions_file = "avante.md"
Config.provider = "openai"
Config.providers = {
openai = {
endpoint = "https://api.mock.com/v1",
model = "gpt-mock",
timeout = 10000,
context_window = 1000,
extra_request_body = {
temperature = 0.5,
max_tokens = 1000,
},
},
}
-- Mock Config.history to prevent nil access error in Path.setup()
Config.history = {
max_tokens = 4096,
carried_entry_count = nil,
storage_path = "/tmp/test_avante_history",
paste = {
extension = "png",
filename = "pasted-%Y-%m-%d-%H-%M-%S",
},
}
-- Mock Config.behaviour
Config.behaviour = {
auto_focus_sidebar = true,
auto_suggestions = false, -- Experimental stage
auto_suggestions_respect_ignore = false,
auto_set_highlight_group = true,
auto_set_keymaps = true,
auto_apply_diff_after_generation = false,
jump_result_buffer_on_finish = false,
support_paste_from_clipboard = false,
minimize_diff = true,
enable_token_counting = true,
use_cwd_as_project_root = false,
auto_focus_on_diff_view = false,
auto_approve_tool_permissions = false, -- Default: show permission prompts for all tools
auto_check_diagnostics = true,
enable_fastapply = false,
}
-- Mock Config.rules to prevent nil access error in get_templates_dir()
Config.rules = {
project_dir = nil,
global_dir = nil,
}
-- Mock P.available to always return true
local Path = require("avante.path")
Path.available = function() return true end
-- Mock the Prompt functions directly since _templates_lib is a local variable
-- that we can't easily access from outside the module
Path.prompts.initialize = function(cache_directory, project_directory)
-- Mock initialization - no-op for tests
end
Path.prompts.render_file = function(path, opts)
-- Mock render - return empty string for tests
return ""
end
Path.prompts.render_mode = function(mode, opts)
-- Mock render_mode - return empty string for tests
return ""
end
Path.setup() -- Initialize necessary paths like cache_path
end)
after_each(function()
-- Clean up created test files and directories
local mock_dir = PPath:new("tests", project_root)
if mock_dir:exists() then mock_dir:rmdir() end
end)
it("should include instruction file content when the file exists", function()
local opts = {}
llm.generate_prompts(opts)
assert.are.same("\n# Mock Instructions\nThis is a mock instruction file.", opts.instructions)
end)
it("should not modify instructions if the file does not exist", function()
local mock_file = PPath:new("tests", project_root, "avante.md")
if mock_file:exists() then mock_file:rm() end
local opts = {}
llm.generate_prompts(opts)
assert.are.same(opts.instructions, nil)
end)
end)