Skip to content

Commit 544bbf3

Browse files
committed
fix(providers): thread the tool-call id through the streaming loops too
The previous commit only reached call sites written as a single-line three-argument call. The streaming loops are formatted across lines, so openai-compat (Groq, DeepSeek and everything else routing through it), Anthropic and Bedrock still omitted the id and kept falling back to a fresh token. Both Gemini paths now pass `part.functionCall?.id` — the RAW model id, not the `ensureToolCallId` value used for stream events. That helper allocates an execution-local id when Gemini supplies none, and it is freshly allocated per attempt: passing it would complete the keyed context, silencing the "could not derive" warning, while leaving the token just as unstable. Gemini frequently omits the id, in which case this is `undefined` and the loud fallback stands. All 27 call sites are now covered.
1 parent b849c72 commit 544bbf3

5 files changed

Lines changed: 29 additions & 11 deletions

File tree

apps/sim/providers/anthropic/streaming-tool-loop.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,8 @@ export function createAnthropicStreamingToolLoopStream(
367367
const { toolParams, executionParams } = prepareToolExecution(
368368
tool,
369369
toolArgs,
370-
request
370+
request,
371+
toolUse.id
371372
)
372373
const { rawResponse, modelResponse } = await executeProviderTool(
373374
toolName,

apps/sim/providers/bedrock/streaming-tool-loop.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,8 @@ export function createBedrockStreamingToolLoopStream(
413413
const { toolParams, executionParams } = prepareToolExecution(
414414
tool,
415415
toolArgs,
416-
request
416+
request,
417+
toolUse.toolUseId
417418
)
418419
const { rawResponse, modelResponse } = await executeProviderTool(
419420
toolName,

apps/sim/providers/gemini/core.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,18 @@ async function executeToolCallsBatch(
133133
}
134134

135135
/*
136-
* No tool-call id is passed: Gemini's function-call parts carry no
137-
* model-supplied identifier, and the streaming loop has to synthesize a
138-
* local one. A positional index would not survive the model re-emitting
139-
* the call, so a `keyed` tool invoked through a Gemini agent falls back to
140-
* a fresh token and logs the missing identity rather than deriving one
141-
* that only looks stable.
136+
* The RAW model id, not a synthesized one. Gemini often omits an id on a
137+
* function-call part, in which case this is `undefined` and the keyed
138+
* helper falls back loudly rather than deriving a token from something —
139+
* a positional index, an execution-local id — that would look stable and
140+
* not be.
142141
*/
143-
const { toolParams, executionParams } = prepareToolExecution(tool, args, request)
142+
const { toolParams, executionParams } = prepareToolExecution(
143+
tool,
144+
args,
145+
request,
146+
part.functionCall?.id
147+
)
144148
const { rawResponse, modelResponse } = await executeProviderTool(toolName, executionParams, {
145149
signal: request.abortSignal,
146150
})

apps/sim/providers/gemini/streaming-tool-loop.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,10 +460,21 @@ export function createGeminiStreamingToolLoopStream(
460460
return value
461461
}
462462

463+
/*
464+
* The RAW model id, not the `ensureToolCallId` value used for
465+
* stream events: that helper falls back to an
466+
* execution-local id when Gemini supplies none, which is
467+
* freshly allocated per attempt. Passing it would complete the
468+
* keyed context — silencing the "could not derive" warning —
469+
* while leaving the token unstable, which is worse than the
470+
* loud fallback. Gemini often omits the id entirely, in which
471+
* case this is `undefined` and the fallback stands.
472+
*/
463473
const { toolParams, executionParams } = prepareToolExecution(
464474
tool,
465475
toolArgs,
466-
request
476+
request,
477+
part.functionCall?.id
467478
)
468479
const { rawResponse, modelResponse } = await executeProviderTool(
469480
toolName,

apps/sim/providers/openai-compat/streaming-tool-loop.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,8 @@ export function createOpenAICompatStreamingToolLoopStream(
426426
const { toolParams, executionParams } = prepareToolExecution(
427427
tool,
428428
toolArgs,
429-
request
429+
request,
430+
tc.id
430431
)
431432
const { rawResponse, modelResponse } = await executeProviderTool(
432433
toolName,

0 commit comments

Comments
 (0)