Replies: 2 comments
|
This is the same bug already reported on #1713 (BehindTheCartan, SGLang) — your one-line fix is exactly right, and I verified it line-by-line against master (47f9438) when that thread was open. Worth converging the two threads so the fix lands once. Confirmation (current master):
The fix (both threads agree): if (call.id != null) block.callId = call.id
if (call.function?.name != null) block.name = call.function.nameplus One thing both reports missed: the regression-test gap in Details (reachable surface, scope, lint) are in my #1713 reply: #1713 (comment). If you have the wire capture handy, adding it to #1713 would give the maintainers a single thread with both provider samples. |
|
Shipped with the regression that closes the test gap @argszero flagged.
Agree this converges with #1713 — same two lines, now with the regression test in place. If the maintainers want one PR, the test belongs here regardless of which thread carries the patch. |
Uh oh!
There was an error while loading. Please reload this page.
Streaming tool calls lose
function.namewhen continuation chunks sendname: nullPackage:
@deepseek-ai/dsh-llm-deepseek(also affects@deepseek-ai/dsh) · Version: 0.1.0-rc.6Repo path:
packages/llm/llm-deepseek/.../index.jsSummary
Every tool call made by the model is rejected at dispatch with
unknown tool ""when theLLM is reached over an OpenAI-compatible streaming chat-completions endpoint whose
continuation chunks include
function.name: null(a valid, common variant of the OpenAIstreaming tool-call protocol — the name is sent once in the first chunk, then
nullwhilethe arguments stream).
Root cause
In the SSE tool-call accumulator:
The guard
call.function?.name !== void 0only skipsundefined. When the provider streamsfunction.name: nullin continuation chunks (after the first chunk carried the real name),null !== undefinedistrue, soblock.nameis overwritten withnull. Atfinalization
name: block.name ?? ""collapses to"", and the runtime then rejects thecall as
unknown tool "".Observed stream (first chunk has the name, rest send
name: null):Non-streaming responses from the same endpoint return the complete
function.name, so thedefect is specific to the streaming accumulator.
Fix (one line)
Guard against
nullas well asundefined:(
!= nullmatches bothnullandundefined.) The same care should be applied to thetool-call-deltaemit that follows, so a laternullnever blanks a previously known name.Impact
Tool use is completely broken for any OpenAI-compatible provider that emits
name: nulloncontinuation chunks — the agent can never call
write/bash/fs/etc. Confirmed fixrestores tool use (verified end-to-end: model created a file via its file tool).
All reactions