Skip to content

Conversation

@shanevcantwell
Copy link

@shanevcantwell shanevcantwell commented Dec 25, 2025

Summary

Adds the ability to customize tool prompts via .continuerc.json at the workspace level, plus fixes two bugs that were preventing this feature from working.

Motivation

Local models (via LM Studio, Ollama, etc.) often struggle with Continue's default tool prompts, which include legacy syntax examples that confuse models into outputting raw [TOOL_CALLS]BEGIN_ARG... text instead of using proper tool calling.

This feature allows per-repo customization of tool prompts to work better with specific models.

Before (broken tool syntax output):

[TOOL_CALLS]ls BEGIN_ARG: dirPath ./docs END_ARG BEGIN_ARG: recursive false END_ARG

After (clean tool usage with custom prompts):

  • Model lists available tools properly
  • Tools are called via native function calling
  • No broken syntax in output

Example .continuerc.json

{
  "mergeBehavior": "merge",
  "tools": [
    {
      "name": "view_diff",
      "disabled": true
    },
    {
      "name": "read_file",
      "description": "Read file contents. Use relative paths from workspace root.",
      "systemMessageDescription": {
        "prefix": "To read a file, use read_file with a relative path:"
      }
    }
  ]
}

Bug Fixes Included

Fix #9312: .continuerc.json files fail to load

rcFiles.map(ide.readFile) lost this binding, causing silent failures. Fixed by using rcFiles.map((uri) => ide.readFile(uri)).

Fix #9313: YAML config path ignores .continuerc.json

loadContinueConfigFromYaml never called getWorkspaceRcConfigs. Added conditional loading in doLoadConfig.ts so tool overrides work regardless of config format.

Test plan

  • Verified .continuerc.json loads with JSON config
  • Verified .continuerc.json loads with YAML config
  • Verified disabled: true removes tool from list
  • Verified custom descriptions appear in tool prompts
  • Tested with devstral via LM Studio - clean tool usage

Fixes #9312, Fixes #9313

🤖 Generated with Claude Code


Summary by cubic

Add workspace-level tool prompt overrides via .continuerc.json and fix config loading so these overrides work with both JSON and YAML configs.

  • New Features

    • Support a tools array in .continuerc.json to override per-tool description, displayTitle, action phrases, systemMessageDescription, or disable tools.
    • Merge tools by name during config load and apply overrides at runtime with applyToolOverrides.
    • Typed ToolOverride added to config and public types; unit tests included.
  • Bug Fixes

Written for commit 3f26b0d. Summary will update automatically on new commits.

shanevcantwell and others added 2 commits December 24, 2025 21:21
Adds a `tools` array to config that allows users to override tool
descriptions at the repo level, following the existing pattern for
models, contextProviders, and slashCommands.

This enables teams to customize tool prompts (e.g., standardizing
path format instructions) without forking the codebase.

Example .continuerc.json:
```json
{
  "tools": [
    {
      "name": "read_file",
      "description": "Custom description here"
    }
  ]
}
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Fixes continuedev#9312, Fixes continuedev#9313

Two bugs were preventing workspace .continuerc.json files from working:

1. loadRcConfigs.ts: `rcFiles.map(ide.readFile)` lost `this` binding,
   causing silent failures when reading .continuerc.json files.
   Fixed by using `rcFiles.map((uri) => ide.readFile(uri))`.

2. doLoadConfig.ts: YAML config path never loaded workspace configs.
   Added conditional loading of workspace .continuerc.json files
   for tool overrides when using config.yaml.

Debugging notes:
- Added file-based tracing to /tmp/continue_debug.txt in installed
  extension to trace config loading path
- Discovered JSON path was taken but getWorkspaceRcConfigs returned []
- Found listDir found the file but readFile failed silently
- Wrapping readFile in try-catch revealed the this binding issue

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@shanevcantwell shanevcantwell requested a review from a team as a code owner December 25, 2025 06:25
@shanevcantwell shanevcantwell requested review from sestinj and removed request for a team December 25, 2025 06:25
@continue
Copy link
Contributor

continue bot commented Dec 25, 2025

All Green - Keep your PRs mergeable

Learn more

All Green is an AI agent that automatically:

✅ Addresses code review comments

✅ Fixes failing CI checks

✅ Resolves merge conflicts


Unsubscribe from All Green comments

@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Dec 25, 2025
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 7 files

@continue
Copy link
Contributor

continue bot commented Dec 25, 2025

📚 Documentation PR created: #9315

I've created a documentation PR that adds usage examples and explains the new tool prompt override feature. The docs include accordion components showing how to:

  • Override tool descriptions
  • Disable specific tools
  • Customize system message prompts
  • Override display titles and action phrases

The documentation follows the existing structure in .continuerc.json section and uses Mintlify components for better discoverability.

shanevcantwell and others added 4 commits December 25, 2025 02:52
Add defensive .catch(() => []) to ide.listDir() call to gracefully
handle non-existent directories (e.g., in test environments).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Replace hardcoded 100ms timeout with waitForCondition polling
for the edit selector close test. Windows CI runners are slower
and need polling instead of fixed timeouts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
macOS CI runners are slower and need longer timeouts for UI
polling in the file search test.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
The test was writing to stdin immediately before the component
was ready to receive input. Add 100ms delay to match other tests.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@shanevcantwell
Copy link
Author

shanevcantwell commented Dec 25, 2025

@sestinj Just to personalize this a bit... I've been trying to love Continue with my local models for like 6mo now, but tool usage never worked. I finally discovered that there were multiple conflicting messages being prompted to the models. With this in place, and the following tool definitions, tools now "just work", with dozens of mixin tool calls strung together, and no broken tool call text in the stream.

Every model is a little different, so making the tool prompts completely override-able is to me just a necessity. I tried to stick to your established patterns and touch as little as possible, and I think there is minimal drift.

I hope you'll consider this a nice xmas gift!
Cheers

{
"mergeBehavior": "merge",
"tools": [
{
"name": "view_diff",
"disabled": true
},
{
"name": "read_file",
"description": "Read the contents of an existing file. Use relative paths from workspace root (e.g., 'src/index.ts').",
"systemMessageDescription": {
"prefix": "To read a file, use the read_file tool with a relative path from workspace root. Example:"
}
},
{
"name": "create_new_file",
"description": "Create a new file with the specified content. Use relative paths from workspace root.",
"systemMessageDescription": {
"prefix": "To create a new file, use the create_new_file tool with a relative path. Example:"
}
},
{
"name": "run_terminal_command",
"description": "Run a shell command in the workspace directory. Stateless between calls. Use Edit tools for file modifications.",
"systemMessageDescription": {
"prefix": "To run a terminal command, use the run_terminal_command tool. Shell is stateless. Use Edit tools instead of sed/awk. Example:"
}
},
{
"name": "grep_search",
"description": "Search file contents using regex patterns. Returns matching lines with context.",
"systemMessageDescription": {
"prefix": "To search file contents, use grep_search with a regex pattern. Example:"
}
},
{
"name": "glob_search",
"description": "Find files by name pattern (e.g., '**/*.ts'). Use for locating files.",
"systemMessageDescription": {
"prefix": "To find files by name pattern, use glob_search. Example:"
}
},
{
"name": "multi_edit",
"description": "Make multiple edits to files. Each edit: filepath, old_string (exact match), new_string.",
"systemMessageDescription": {
"prefix": "To edit files, use multi_edit with filepath, old_string, and new_string. Use relative paths. Example:"
}
}
],
"chatOptions": {
"baseSystemMessage": "You are an AI coding assistant. Focus on completing tasks efficiently. Use relative paths from workspace root for all file operations. Be concise."
}
}

@shanevcantwell
Copy link
Author

shanevcantwell commented Dec 26, 2025

Before & after for reference (with PR #9325 fix) (gpt-oss-20b)

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

Bug: YAML config path does not load workspace .continuerc.json files Bug: .continuerc.json files fail to load due to 'this' binding issue

1 participant