Bug: tool calls lose their name/id when streamed through OpenAI-compatible gateways (empty-string deltas overwrite assembly) #3090
Replies: 3 comments
Additional data point: the
|
|
Thanks for isolating this. I independently reproduced the user-visible I prepared a minimal, tested implementation that covers both continuation placeholder variants in one regression case: { index: 0, id: 'call_00_x', function: { name: 'get_weather', arguments: '' } }
{ index: 0, function: { name: null, arguments: '{"city"' } }
{ index: 0, function: { name: '', arguments: ': "Paris"}' } }The current assignment fails the test because the emitted delta names become const name = call.function?.name
if (typeof name === 'string' && name.length > 0) block.name = nameIt also models the observed wire shape as Tested commit (one commit directly on the referenced master revision):
Verification completed:
This commit deliberately scopes itself to |
|
A measured A/B for exactly the delta shapes you isolated, from the other accumulator in this ecosystem. We fault-injected the real pi-ai 0.84.1 openai-completions client/parser/accumulator (only the wire bytes are synthetic) with the gateway shapes from your report: continuation deltas carrying empty-string Live confirmation on a real upstream: through pi2dsh (stock Scope honesty: this is a parallel-path datapoint, not a fix for |
Uh oh!
There was an error while loading. Please reload this page.
Symptom
Running
dsh-llm-deepseek@0.1.0-rc.7against an OpenAI-compatible gateway (a New-API deployment,DEEPSEEK_BASE_URLpointed at it) breaks every tool-using turn: the assembled tool call ends withname: '', dispatch fails on the unknown empty name, and the turn dies after its first call — with a well-formed wire stream and no adapter error.Root cause
The official DeepSeek API sends a tool call's
id/function.nameonly on the opening chunk and omits both fields from argument-delta chunks. Gateways instead pad them with empty strings on every delta (captured 2026-08-18 againstdeepseek-v4-flash-0731):{"delta":{"tool_calls":[{"index":0,"id":"call_x","type":"function","function":{"name":"bash","arguments":""}}]}} {"delta":{"tool_calls":[{"index":0,"id":"","type":"function","function":{"name":"","arguments":"{\"command\""}}]}}translate.tstreats any present field as authoritative:so each argument delta overwrites the assembled identity with
''.Fix
An empty-string identity never names a call — both guards should ignore
''exactly like an absent field. Since PRs are disabled on this repository, the complete fix (two-line guard + regression test pinning the gateway capture shape + Agent Note with zh pair, all repo gates passing) is on this branch:master...fengcunhan:deepseek-harness:fix/llm-deepseek-gateway-empty-tool-identity
Verified end to end against the real gateway with the guard patched into
0.1.0-rc.7viapnpm patch:bash/readcalls assemble and dispatch correctly; unpatched, the same turn fails as described. Happy to adjust anything if a maintainer wants to pull it in.All reactions