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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Axon Code delivers frontier models performance for coding and support all the ma
</p>

### Agentic Tools Supported

- `fileEdit`: A new advanced Diff-Patch apply tool
- `web_search`: Search the web
- `web_fetch`: Fetch specific link data from the web
Expand All @@ -73,9 +74,8 @@ Axon Code delivers frontier models performance for coding and support all the ma
- `writeToFile`: Write to a file

### Support Models

- `axon-mini`: Mini Axon Code model for everyday low-effort tasks
- `axon-code`: High intelligence Axon Code model for all-day coding tasks
- `axon-code-pro`: Heavily powerful Axon Code model for high-effort coding tasks

You can read more about the models here: https://docs.matterai.so/axon-overview

5 changes: 4 additions & 1 deletion packages/types/src/mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,10 @@ for i in range(10):

<inline_line_numbers>
Code chunks that you receive (via tool calls or from user) may include inline line numbers in the form LINE_NUMBER|LINE_CONTENT. Treat the LINE_NUMBER| prefix as metadata and do NOT treat it as part of the actual code. LINE_NUMBER is right-aligned number padded with spaces to 6 characters.
</inline_line_numbers>`,
</inline_line_numbers>

CRITICAL: For any task, small or big, you will always and always use the update_todo_list tool to create the TODO list, always keep is upto date with updates to the status and updating/editing the list as needed.
`,
whenToUse:
"Use this mode when you need to write, modify, or refactor code. Ideal for implementing features, fixing bugs, creating new files, or making code improvements across any programming language or framework.",
description: "Write, modify, and refactor code",
Expand Down
2 changes: 1 addition & 1 deletion src/core/assistant-message/presentAssistantMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ export async function presentAssistantMessage(cline: Task) {
await searchAndReplaceTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "file_edit":
await fileEditTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await fileEditTool(cline, block, handleError, pushToolResult, removeClosingTag)
break
// kilocode_change start: Morph fast apply
case "edit_file":
Expand Down
151 changes: 45 additions & 106 deletions src/core/prompts/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,116 +33,27 @@ export function getPromptComponent(
}

const applyDiffToolDescription = `
## apply_diff Tool Usage
Common tool calls and explanations

The \`apply_diff\` tool allows you to make precise, surgical edits to one or more files simultaneously.
## file_edit

### CRITICAL: Single Content Field with Complete Structure
**Description**: Perform targeted text replacements within a single file without constructing manual diff blocks.

**Each diff has ONLY TWO fields:**
- \`content\`: A single string containing the complete SEARCH/REPLACE block
- \`start_line\`: The line number where SEARCH begins
**When to use**:
- You know the exact text that should be replaced and its updated form.
- You want a deterministic edit without invoking Fast Apply models.
- You need to delete or rewrite a block of code but don't want to craft search/replace diff markers manually.

**DO NOT create separate fields like \`search\`, \`replace\`, \`old\`, \`new\`, etc.**
**Parameters**:
1. \`target_file\` — Relative path to the file you want to modify.
2. \`old_string\` — The current text you expect to replace. Provide enough context for a unique match; this can be empty to replace the entire file.
3. \`new_string\` — The text that should replace the match. Use an empty string to delete the matched content.
4. \`replace_all\` (optional, default false) — Set to true to replace every occurrence of the matched text. Leave false to replace only a single uniquely identified match.

### REQUIRED Content Format

The \`content\` field MUST contain this COMPLETE structure as a SINGLE STRING:
\`\`\`
<<<<<<< SEARCH
[exact lines from original file]
=======
[new lines to replace with]
>>>>>>> REPLACE
\`\`\`

**All three markers must be present IN THE CONTENT STRING.**

### Correct Example
\`\`\`json
{
"files": [
{
"path": "src/services/llmPricing.js",
"diffs": [
{
"content": "<<<<<<< SEARCH\n \"accounts/fireworks/models/glm-4p5\": {\n input: 0.55,\n output: 2.19,\n },\n \"gpt-oss-120b\": {\n input: 0.25,\n output: 0.69,\n },\n=======\n \"accounts/fireworks/models/glm-4p5\": {\n input: 0.55,\n output: 2.19,\n },\n \"accounts/fireworks/models/glm-4.6\": {\n input: 0.6,\n output: 2.2,\n },\n \"gpt-oss-120b\": {\n input: 0.25,\n output: 0.69,\n },\n>>>>>>> REPLACE",
"start_line": 30
}
]
}
]
}
\`\`\`

### ❌ INCORRECT Examples
\`\`\`json
// WRONG - Incomplete content (missing ======= and >>>>>>> REPLACE)
{
"content": "<<<<<<< SEARCH\n old code\n",
"start_line": 30
}

// WRONG - Creating separate fields
{
"content": "<<<<<<< SEARCH\n old code\n",
"replace": "new code\n>>>>>>> REPLACE",
"start_line": 30
}

// WRONG - Using search/replace fields
{
"search": "old code",
"replace": "new code",
"start_line": 30
}
\`\`\`

### Step-by-Step Process

When creating a diff:

1. **Identify the exact lines** to change from the original file
2. **Write the SEARCH block**: Include 2-3 lines of context before and after
3. **Add the separator**: \`=======\` on its own line
4. **Write the REPLACE block**: The new content (can include the context lines)
5. **Close with marker**: \`>>>>>>> REPLACE\` on its own line
6. **Combine into single string**: Put all of this into the \`content\` field
7. **Add start_line**: The line number where your SEARCH block begins

### JSON Schema Reminder
\`\`\`typescript
{
path: string, // File path
diffs: [
{
content: string, // COMPLETE "<<<<<<< SEARCH\n...\n=======\n...\n>>>>>>> REPLACE" block
start_line: number // Line where SEARCH begins
}
]
}
\`\`\`

**Only these two fields exist in each diff object. Do not invent additional fields.**

### Common Errors to Avoid

- ❌ **Stopping the content string before \`=======\` and \`>>>>>>> REPLACE\`** (most common)
- ❌ Creating \`replace\`, \`search\`, \`old\`, or \`new\` fields
- ❌ Missing the \`=======\` separator line
- ❌ Missing the \`>>>>>>> REPLACE\` closing marker
- ❌ Not including enough context in SEARCH block
- ❌ Whitespace mismatches between SEARCH and original file

### Verification Checklist

Before submitting, verify each diff has:
- ✅ Single \`content\` field (not multiple fields)
- ✅ Starts with \`<<<<<<< SEARCH\n\`
- ✅ Contains \`=======\n\` in the middle
- ✅ Ends with \`>>>>>>> REPLACE\`
- ✅ SEARCH block matches original file exactly
- ✅ Correct \`start_line\` number
**Guidance**:
- Prefer multi-line snippets for \`old_string\` to help the tool locate the correct section.
- If multiple matches exist, either refine \`old_string\` or set \`replace_all\` to true when you intend to change every occurrence.
- The tool shows a diff before applying changes so you can confirm the result.

# execute_command

Expand Down Expand Up @@ -323,7 +234,6 @@ Before submitting, verify:
- \`poetry\` - Python Package Manager
- \`virtualenv\` - Python Virtual Environment


CRITICAL:
1. A command never starts with \`:\`
2. A command never uses <|tool_call_argument_begin|> OR any <> TAG
Expand All @@ -333,6 +243,35 @@ CRITICAL:
6. Commands are always valid for the user's shell
7. Commands are always valid with executable permissions
8. Commands are always valid with the user's current working directory


## update_todo_list

**Description:**
Replace the entire TODO list with an updated checklist reflecting the current state. Always provide the full list; the system will overwrite the previous one. This tool is designed for step-by-step task tracking, allowing you to confirm completion of each step before updating, update multiple task statuses at once (e.g., mark one as completed and start the next), and dynamically add new todos discovered during long or complex tasks.

**Checklist Format:**
- Use a single-level markdown checklist (no nesting or subtasks).
- List todos in the intended execution order.
- Status options:
- [ ] Task description (pending)
- [x] Task description (completed)
- [-] Task description (in progress)

**Status Rules:**
- [ ] = pending (not started)
- [x] = completed (fully finished, no unresolved issues)
- [-] = in_progress (currently being worked on)

**Core Principles:**
- Before updating, always confirm which todos have been completed since the last update.
- You may update multiple statuses in a single update (e.g., mark the previous as completed and the next as in progress).
- When a new actionable item is discovered during a long or complex task, add it to the todo list immediately.
- Do not remove any unfinished todos unless explicitly instructed.
- Always retain all unfinished tasks, updating their status as needed.
- Only mark a task as completed when it is fully accomplished (no partials, no unresolved dependencies).
- If a task is blocked, keep it as in_progress and add a new todo describing what needs to be resolved.
- Remove tasks only if they are no longer relevant or if the user requests deletion.
`

async function generatePrompt(
Expand Down
13 changes: 3 additions & 10 deletions src/core/prompts/tools/native-tools/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { OpenAI } from "openai/client"
import askFollowupQuestion from "./ask_followup_question"
import attemptCompletion from "./attempt_completion"
import browserAction from "./browser_action"
import codebaseSearch from "./codebase_search"
import executeCommand from "./execute_command"
import fetchInstructions from "./fetch_instructions"
import generateImage from "./generate_image"
import insertContent from "./insert_content"
import listCodeDefinitionNames from "./list_code_definition_names"
import listFiles from "./list_files"
import newTask from "./new_task"
Expand All @@ -15,11 +11,8 @@ import runSlashCommand from "./run_slash_command"
// import searchAndReplace from "./search_and_replace"
import searchFiles from "./search_files"
// import switchMode from "./switch_mode"
import updateTodoList from "./update_todo_list"
import writeToFile from "./write_to_file"
import { apply_diff_single_file, apply_diff_multi_file } from "./apply_diff"
import editFile from "./edit_file"
import fileEdit from "./file_edit"
import updateTodoList from "./update_todo_list"

export const nativeTools = [
// apply_diff_single_file,
Expand All @@ -33,7 +26,7 @@ export const nativeTools = [
executeCommand,
fetchInstructions,
// generateImage,
insertContent,
// insertContent,
listCodeDefinitionNames,
listFiles,
newTask,
Expand All @@ -42,5 +35,5 @@ export const nativeTools = [
// searchAndReplace,
searchFiles,
updateTodoList,
writeToFile,
// writeToFile,
] satisfies OpenAI.Chat.ChatCompletionTool[]
6 changes: 3 additions & 3 deletions src/core/prompts/tools/native-tools/read_file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const read_file_multi = {
function: {
name: "read_file",
description:
"Read one or more files and return their contents with line numbers for diffing or discussion. Use line ranges when available to keep reads efficient and combine related files when possible.",
"Read one or more files and return their contents with line numbers for diffing or discussion. Use line ranges always to keep reads efficient and combine related files when possible. You will always read less thatn 100 lines at a time",
strict: true,
parameters: {
type: "object",
Expand All @@ -21,9 +21,9 @@ export const read_file_multi = {
description: "Path to the file to read, relative to the workspace",
},
line_ranges: {
type: ["array", "null"],
type: ["array"],
description:
"Optional 1-based inclusive ranges to read (format: start-end). Use multiple ranges for non-contiguous sections and keep ranges tight to the needed context.",
"Always required line ranges to read (format: start-end). If you are unsure about about the what line numbers to query, you can perform a search on the file to determine line numbers. You will never read more than 100 lines at a time!",
items: {
type: "string",
pattern: "^\\d+-\\d+$",
Expand Down
4 changes: 2 additions & 2 deletions src/core/prompts/tools/native-tools/search_files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export default {
description: "Rust-compatible regular expression pattern to match",
},
file_pattern: {
type: ["string", "null"],
description: "Optional string glob to limit which files are searched (e.g., '*.ts')",
type: ["string"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Type Safety

Issue: The file_pattern parameter type was changed to an array ["string"], but the description and usage pattern indicate it should be a single string. This is a breaking change that could cause runtime errors.

Fix: Revert the type back to "string" to match the description and expected usage.

Impact: Prevents API compatibility issues and maintains consistent tool behavior.

Suggested change
type: ["string"],
type: "string",

Fix in Cursor

description: "String glob to limit which files are searched (e.g., '*.ts')",
},
Comment on lines 20 to 23
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Type Safety

Issue: The file_pattern parameter type was changed from string to array, but the description still suggests it accepts a single string pattern like '*.ts'.

Fix: Either revert to string type or update the description and validation to handle array of patterns.

Impact: Prevents runtime errors when tools pass string patterns instead of arrays.

Suggested change
file_pattern: {
type: ["string", "null"],
description: "Optional string glob to limit which files are searched (e.g., '*.ts')",
type: ["string"],
description: "String glob to limit which files are searched (e.g., '*.ts')",
},
file_pattern: {
type: "string",
description: "String glob to limit which files are searched (e.g., '*.ts')",
},

Fix in Cursor

},
required: ["path", "regex", "file_pattern"],
Expand Down
9 changes: 9 additions & 0 deletions src/core/task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import { RepoPerTaskCheckpointService } from "../../services/checkpoints"

// integrations
import { DiffViewProvider } from "../../integrations/editor/DiffViewProvider"
import { FileEditReviewController } from "../../integrations/editor/FileEditReviewController"
import { findToolName, formatContentBlockToMarkdown } from "../../integrations/misc/export-markdown"
import { RooTerminalProcess } from "../../integrations/terminal/types"
import { TerminalRegistry } from "../../integrations/terminal/TerminalRegistry"
Expand Down Expand Up @@ -263,6 +264,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
diffEnabled: boolean = false
fuzzyMatchThreshold: number
didEditFile: boolean = false
fileEditReviewController: FileEditReviewController

// LLM Messages & Chat Messages
apiConversationHistory: ApiMessage[] = []
Expand Down Expand Up @@ -386,6 +388,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
this.providerRef = new WeakRef(provider)
this.globalStoragePath = provider.context.globalStorageUri.fsPath
this.diffViewProvider = new DiffViewProvider(this.cwd, this)
this.fileEditReviewController = new FileEditReviewController(this.cwd)
this.enableCheckpoints = enableCheckpoints
this.enableBridge = enableBridge

Expand Down Expand Up @@ -1781,6 +1784,12 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
console.error("Error disposing file context tracker:", error)
}

try {
this.fileEditReviewController.dispose()
} catch (error) {
console.error("Error disposing file edit review controller:", error)
}

try {
// If we're not streaming then `abortStream` won't be called.
if (this.isStreaming && this.diffViewProvider.isEditing) {
Expand Down
Loading
Loading