From 0dfa4479dab3cb13d3691b215a72caf99d59d48e Mon Sep 17 00:00:00 2001 From: Knut Zuidema Date: Sat, 21 Mar 2026 21:42:01 +0100 Subject: [PATCH] fix: discourage _noop tool call during LiteLLM compaction When compaction runs with no active tools, LiteLLM/Bedrock rejects the request if the message history contains tool calls but the tools param is absent. The existing fix injected a _noop stub with an empty inputSchema, but Bedrock also rejected that schema and the model would call the stub instead of generating a summary. This updates the stub to have a valid inputSchema (so Bedrock accepts it) and a description that explicitly tells the model not to call it. The compaction prompt also now instructs the model to respond with text only and not call any tools. --- packages/opencode/src/session/compaction.ts | 1 + packages/opencode/src/session/llm.ts | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/session/compaction.ts b/packages/opencode/src/session/compaction.ts index 072ea1d574e8..ca70df89652e 100644 --- a/packages/opencode/src/session/compaction.ts +++ b/packages/opencode/src/session/compaction.ts @@ -174,6 +174,7 @@ export namespace SessionCompaction { const defaultPrompt = `Provide a detailed prompt for continuing our conversation above. Focus on information that would be helpful for continuing the conversation, including what we did, what we're doing, which files we're working on, and what we're going to do next. The summary that you construct will be used so that another agent can read it and continue the work. +Do not call any tools. Respond only with the summary text. When constructing the summary, try to stick to this template: --- diff --git a/packages/opencode/src/session/llm.ts b/packages/opencode/src/session/llm.ts index a8009c49d494..e30d25177bbd 100644 --- a/packages/opencode/src/session/llm.ts +++ b/packages/opencode/src/session/llm.ts @@ -176,11 +176,19 @@ export namespace LLM { input.model.providerID.toLowerCase().includes("litellm") || input.model.api.id.toLowerCase().includes("litellm") + // LiteLLM/Bedrock rejects requests where the message history contains tool + // calls but no tools param is present. When there are no active tools (e.g. + // during compaction), inject a stub tool to satisfy the validation requirement. + // The stub description explicitly tells the model not to call it. if (isLiteLLMProxy && Object.keys(tools).length === 0 && hasToolCalls(input.messages)) { tools["_noop"] = tool({ - description: - "Placeholder for LiteLLM/Anthropic proxy compatibility - required when message history contains tool calls but no active tools are needed", - inputSchema: jsonSchema({ type: "object", properties: {} }), + description: "Do not call this tool. It exists only for API compatibility and must never be invoked.", + inputSchema: jsonSchema({ + type: "object", + properties: { + reason: { type: "string", description: "Unused" }, + }, + }), execute: async () => ({ output: "", title: "", metadata: {} }), }) }