fix(agents): skip extracting tool calls from errored assistant turns
When an assistant turn has stopReason: "error", the tool calls within it were never completed (often contain partialJson). Inserting synthetic tool_results for these caused Anthropic's API to reject requests with "unexpected tool_use_id" errors, permanently breaking the session. Now we skip extracting tool calls from assistant messages with stopReason: "error", preventing the broken synthetic results. Fixes #1826 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
c8063bdcd8
commit
6747541040
@ -109,4 +109,34 @@ describe("sanitizeToolUseResultPairing", () => {
|
||||
expect(out.some((m) => m.role === "toolResult")).toBe(false);
|
||||
expect(out.map((m) => m.role)).toEqual(["user", "assistant"]);
|
||||
});
|
||||
|
||||
it("does not insert synthetic tool results for errored/terminated assistant turns", () => {
|
||||
// When an assistant turn has stopReason: "error", the tool calls within it were
|
||||
// never completed. Inserting synthetic tool_results would cause Anthropic's API
|
||||
// to reject requests with "unexpected tool_use_id".
|
||||
// See: https://github.com/clawdbot/clawdbot/issues/1826
|
||||
const input = [
|
||||
{ role: "user", content: "schedule a reminder" },
|
||||
{
|
||||
role: "assistant",
|
||||
content: [
|
||||
{
|
||||
type: "toolCall",
|
||||
id: "toolu_terminated",
|
||||
name: "cron",
|
||||
arguments: { action: "add" },
|
||||
partialJson: '{"action": "add", "job": {"name": "test',
|
||||
},
|
||||
],
|
||||
stopReason: "error",
|
||||
errorMessage: "terminated",
|
||||
},
|
||||
{ role: "user", content: "what happened?" },
|
||||
] satisfies AgentMessage[];
|
||||
|
||||
const out = sanitizeToolUseResultPairing(input);
|
||||
// Should NOT have any tool results - the errored turn's tool calls are ignored
|
||||
expect(out.some((m) => m.role === "toolResult")).toBe(false);
|
||||
expect(out.map((m) => m.role)).toEqual(["user", "assistant", "user"]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -8,6 +8,14 @@ type ToolCallLike = {
|
||||
function extractToolCallsFromAssistant(
|
||||
msg: Extract<AgentMessage, { role: "assistant" }>,
|
||||
): ToolCallLike[] {
|
||||
// Skip extracting tool calls if the assistant turn errored/terminated.
|
||||
// Errored turns contain incomplete tool calls (often with partialJson) that
|
||||
// were never executed. Inserting synthetic tool_results for these would cause
|
||||
// Anthropic's API to reject subsequent requests with "unexpected tool_use_id".
|
||||
// See: https://github.com/clawdbot/clawdbot/issues/1826
|
||||
const stopReason = (msg as { stopReason?: unknown }).stopReason;
|
||||
if (stopReason === "error") return [];
|
||||
|
||||
const content = msg.content;
|
||||
if (!Array.isArray(content)) return [];
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user