fix(rust): make ChatCompletionChunk a transparent Value passthrough#65
Conversation
Streaming tool_call deltas from LLMs (e.g. GLM-5 via vLLM) send null for id, type, and function.name fields in subsequent chunks after the first. The previous typed structs required these as non-Optional Strings, causing deserialization failures on multi-tool streaming responses. Replace ChatCompletionChunk, ChatChoiceDelta, and ChatMessageDelta with a single transparent serde_json::Value wrapper. This makes the streaming path a full JSON passthrough, avoiding failures on null/absent fields and future-proofing against new fields from the backend. Also fixes kimi-k2-thinking -> kimi-k2-5 model name in tests and adds a new test_streaming_multi_tool_calls integration test. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 📝 WalkthroughWalkthroughThe pull request replaces three fixed streaming delta types (ChatCompletionChunk, ChatChoiceDelta, ChatMessageDelta) with a single transparent wrapper ChatCompletionChunk that encapsulates a generic Value. This enables passthrough of raw backend JSON without deserialization constraints. Tests are updated to access chunk data via JSON navigation rather than structured field access, and a new streaming test for multiple tool calls is added. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
Deploying opensecret-sdk with
|
| Latest commit: |
9354c31
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://fd6a5007.opensecret-sdk.pages.dev |
| Branch Preview URL: | https://fix-streaming-tool-call-pass.opensecret-sdk.pages.dev |
Problem
Streaming chat completions with multiple tool calls fail with:
The OpenAI streaming spec sends
nullforid,type, andfunction.namein subsequent tool_call delta chunks after the first. The SDK'sToolCallstruct had these as requiredStringfields, causing deserialization failures.Fix
Replace the typed streaming structs (
ChatCompletionChunk,ChatChoiceDelta,ChatMessageDelta) with a single transparentserde_json::Valuewrapper:This makes the streaming path a full JSON passthrough -- any valid JSON from the backend flows through without the SDK ever failing on null, absent, or new fields.
Also
kimi-k2-thinking->kimi-k2-5model name in tests (old model no longer available)test_streaming_multi_tool_callsintegration test that verifies parallel tool call streaming works end-to-endTesting
Verified against the dev instance (
enclave.secretgpt.ai) withglm-5model via maple-proxy:Summary by CodeRabbit
New Features
Refactor