Skip to content
Open
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
2 changes: 1 addition & 1 deletion core/llm/defaultSystemMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const DEFAULT_AGENT_SYSTEM_MESSAGE = `\
<important_rules>
You are in agent mode.

If you need to use multiple tools, you can call multiple read-only tools simultaneously.
Call tools one at a time. Wait for each tool result before deciding whether to call another tool.

${CODEBLOCK_FORMATTING_INSTRUCTIONS}

Expand Down
15 changes: 15 additions & 0 deletions core/llm/llms/OpenRouter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ChatCompletionCreateParams } from "openai/resources/index";

import { OPENROUTER_HEADERS } from "@continuedev/openai-adapters";

import { LLMOptions } from "../../index.js";
import { osModelsEditPrompt } from "../templates/edit.js";

Expand All @@ -18,6 +20,19 @@ class OpenRouter extends OpenAI {
useLegacyCompletionsEndpoint: false,
};

constructor(options: LLMOptions) {
super({
...options,
requestOptions: {
...options.requestOptions,
headers: {
...OPENROUTER_HEADERS,
...options.requestOptions?.headers,
},
},
});
}

private isAnthropicModel(model?: string): boolean {
if (!model) return false;
const modelLower = model.toLowerCase();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,30 @@ describe("generateToolsSystemMessage", () => {
expect(hasExampleDefinition).toBe(true);
expect(hasExampleCall).toBe(true);
});

it("instructs models to call tools serially", () => {
const tools: Tool[] = [
{
function: {
name: "test_tool",
description: "Test description",
parameters: {
type: "object",
properties: {},
required: [],
},
},
...SHARED_TOOL_FIELDS,
},
];

const result = generateToolsSystemMessage(tools, framework);

expect(result).includes(
"Call ONE tool at a time and wait for its result before calling another tool.",
);
expect(result).not.includes("simultaneously");
});
});

describe("addSystemMessageToolsToSystemMessage", () => {
Expand Down
2 changes: 1 addition & 1 deletion core/tools/systemMessageTools/toolCodeblocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ CRITICAL: Follow the exact syntax. Do not use XML tags, JSON objects, or any oth
systemMessageSuffix = `RULES FOR TOOL USE:
1. To call a tool, output a tool code block using EXACTLY the format shown above.
2. Always start the code block on a new line.
3. You can only call ONE tool at a time.
3. Call ONE tool at a time and wait for its result before calling another tool.
4. The tool code block MUST be the last thing in your response. Stop immediately after the closing fence.
5. Do NOT wrap tool calls in XML tags like <tool_call> or <function=...>.
6. Do NOT use JSON format for tool calls.
Expand Down
7 changes: 7 additions & 0 deletions gui/src/redux/util/getBaseSystemMessage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,10 @@ test("getBaseSystemMessage should append no-tools warning for agent/plan modes w
"Custom Plan System Message" + NO_TOOL_WARNING,
);
});

test("default agent system message should instruct serial tool calling", () => {
expect(DEFAULT_AGENT_SYSTEM_MESSAGE).toContain(
"Call tools one at a time. Wait for each tool result before deciding whether to call another tool.",
);
expect(DEFAULT_AGENT_SYSTEM_MESSAGE).not.toContain("simultaneously");
});
5 changes: 3 additions & 2 deletions packages/openai-adapters/src/apis/OpenRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ export interface OpenRouterConfig extends OpenAIConfig {

// TODO: Extract detailed error info from OpenRouter's error.metadata.raw to surface better messages

const OPENROUTER_HEADERS: Record<string, string> = {
export const OPENROUTER_HEADERS: Record<string, string> = {
"HTTP-Referer": "https://www.continue.dev/",
"X-Title": "Continue",
"X-OpenRouter-Title": "Continue",
"X-OpenRouter-Categories": "ide-extension",
};

export class OpenRouterApi extends OpenAIApi {
Expand Down
1 change: 1 addition & 0 deletions packages/openai-adapters/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,5 @@ export {
} from "./apis/AnthropicUtils.js";

export { isResponsesModel } from "./apis/openaiResponses.js";
export { OPENROUTER_HEADERS } from "./apis/OpenRouter.js";
export { extractBase64FromDataUrl, parseDataUrl } from "./util/url.js";
Loading