fix(ai): strip partialJson from responses tool calls

Mutate persisted tool-call blocks in place on function_call completion,
remove partialJson, and emit the same reference on toolcall_end.
Add regression coverage for persisted block cleanup and event identity.

fixes #3078
This commit is contained in:
Armin Ronacher
2026-04-14 18:37:06 +02:00
parent 64a0a74d37
commit e2b40dfc81
9 changed files with 155 additions and 11 deletions

View File

@@ -452,12 +452,22 @@ export async function processResponsesStream<TApi extends Api>(
currentBlock?.type === "toolCall" && currentBlock.partialJson
? parseStreamingJson(currentBlock.partialJson)
: parseStreamingJson(item.arguments || "{}");
const toolCall: ToolCall = {
type: "toolCall",
id: `${item.call_id}|${item.id}`,
name: item.name,
arguments: args,
};
let toolCall: ToolCall;
if (currentBlock?.type === "toolCall") {
// Finalize in-place and strip the scratch buffer so replay only
// carries parsed arguments.
currentBlock.arguments = args;
delete (currentBlock as { partialJson?: string }).partialJson;
toolCall = currentBlock;
} else {
toolCall = {
type: "toolCall",
id: `${item.call_id}|${item.id}`,
name: item.name,
arguments: args,
};
}
currentBlock = null;
stream.push({ type: "toolcall_end", contentIndex: blockIndex(), toolCall, partial: output });