From b9206221107d5023392431fd7664da80393e253e Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Wed, 15 Apr 2026 20:52:52 +0200 Subject: [PATCH] refactor(ai): extract synthetic tool result helper --- .../ai/src/providers/transform-messages.ts | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/packages/ai/src/providers/transform-messages.ts b/packages/ai/src/providers/transform-messages.ts index f61f0803..709a605d 100644 --- a/packages/ai/src/providers/transform-messages.ts +++ b/packages/ai/src/providers/transform-messages.ts @@ -100,28 +100,31 @@ export function transformMessages( const result: Message[] = []; let pendingToolCalls: ToolCall[] = []; let existingToolResultIds = new Set(); + const insertSyntheticToolResults = () => { + if (pendingToolCalls.length > 0) { + for (const tc of pendingToolCalls) { + if (!existingToolResultIds.has(tc.id)) { + result.push({ + role: "toolResult", + toolCallId: tc.id, + toolName: tc.name, + content: [{ type: "text", text: "No result provided" }], + isError: true, + timestamp: Date.now(), + } as ToolResultMessage); + } + } + pendingToolCalls = []; + existingToolResultIds = new Set(); + } + }; for (let i = 0; i < transformed.length; i++) { const msg = transformed[i]; if (msg.role === "assistant") { // If we have pending orphaned tool calls from a previous assistant, insert synthetic results now - if (pendingToolCalls.length > 0) { - for (const tc of pendingToolCalls) { - if (!existingToolResultIds.has(tc.id)) { - result.push({ - role: "toolResult", - toolCallId: tc.id, - toolName: tc.name, - content: [{ type: "text", text: "No result provided" }], - isError: true, - timestamp: Date.now(), - } as ToolResultMessage); - } - } - pendingToolCalls = []; - existingToolResultIds = new Set(); - } + insertSyntheticToolResults(); // Skip errored/aborted assistant messages entirely. // These are incomplete turns that shouldn't be replayed: @@ -146,22 +149,7 @@ export function transformMessages( result.push(msg); } else if (msg.role === "user") { // User message interrupts tool flow - insert synthetic results for orphaned calls - if (pendingToolCalls.length > 0) { - for (const tc of pendingToolCalls) { - if (!existingToolResultIds.has(tc.id)) { - result.push({ - role: "toolResult", - toolCallId: tc.id, - toolName: tc.name, - content: [{ type: "text", text: "No result provided" }], - isError: true, - timestamp: Date.now(), - } as ToolResultMessage); - } - } - pendingToolCalls = []; - existingToolResultIds = new Set(); - } + insertSyntheticToolResults(); result.push(msg); } else { result.push(msg);