Skip to content

Commit 89489b0

Browse files
committed
fix: replace _noop stub with read-shaped tool for LiteLLM/Bedrock compaction
During compaction, an empty tools map is passed to the LLM processor. For LiteLLM proxying Bedrock/Anthropic models, the _noop stub was injected to satisfy LiteLLM's requirement for a non-empty tools array when message history contains tool calls. However, the _noop stub had an empty inputSchema which Bedrock rejects, causing compaction to fail silently — the model would call _noop instead of summarising, producing post-compaction amnesia. Replacing the stub with a read-shaped tool (with a real inputSchema) satisfies Bedrock validation while keeping execution harmless via the compaction agent's deny-all permission ruleset.
1 parent d5337b4 commit 89489b0

File tree

1 file changed

+14
-4
lines changed
  • packages/opencode/src/session

1 file changed

+14
-4
lines changed

packages/opencode/src/session/llm.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,20 @@ export namespace LLM {
177177
input.model.api.id.toLowerCase().includes("litellm")
178178

179179
if (isLiteLLMProxy && Object.keys(tools).length === 0 && hasToolCalls(input.messages)) {
180-
tools["_noop"] = tool({
181-
description:
182-
"Placeholder for LiteLLM/Anthropic proxy compatibility - required when message history contains tool calls but no active tools are needed",
183-
inputSchema: jsonSchema({ type: "object", properties: {} }),
180+
// Inject a read tool stub so LiteLLM/Bedrock gets a non-empty tools array.
181+
// Bedrock rejects requests with tool history but no tools param, and also
182+
// rejects tool_choice=none, so a real-shaped tool is required. The execute
183+
// is a no-op; the compaction agent's deny-all permission ruleset prevents
184+
// any actual execution.
185+
tools["read"] = tool({
186+
description: "Read a file at the given path",
187+
inputSchema: jsonSchema({
188+
type: "object",
189+
properties: {
190+
filePath: { type: "string", description: "Absolute path to the file to read" },
191+
},
192+
required: ["filePath"],
193+
}),
184194
execute: async () => ({ output: "", title: "", metadata: {} }),
185195
})
186196
}

0 commit comments

Comments
 (0)