Repository navigation
fix: DeepSeek usage counts must be numbers - #309
Merged
Merged
Conversation
tokenUsageSchema (deepseek-chat-api-types.ts:95-113) keeps usage as a loose object but requires its known counts to be numbers or null, so a response with "prompt_tokens": "100" is rejected. aimux kept usage as a raw Value and read such a count as 0. The response and chunk types now validate the seven counts when they deserialize; the generate path reads usage from the parsed response. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
This was referenced Oct 20, 2026
cunninghamcard-bit
pushed a commit
that referenced
this pull request
Oct 20, 2026
The test branch now stacks on fix PR #309, which adds two aimux-own tests at the end of tests/deepseek_chat_test.rs. That file is already merged into src/deepseek/tests/chat/, so the two tests land at the end of chat_language_model.rs with the other aimux-own cases. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW
7 of 13 tasks
15 of 31 tasks
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
cunninghamcard-bit
marked this pull request as ready for review
October 24, 2026 10:13
eric8810
approved these changes
Oct 25, 2026
eric8810
left a comment
Contributor
There was a problem hiding this comment.
DeepSeek usage counts 接受 number-or-null 并保留对象,符合 pinned schema。Approve。
…counts-must-be-numbers # Conflicts: # CHANGELOG.md
…counts-must-be-numbers # Conflicts: # CHANGELOG.md
…counts-must-be-numbers # Conflicts: # CHANGELOG.md
…counts-must-be-numbers # Conflicts: # CHANGELOG.md
…counts-must-be-numbers # Conflicts: # CHANGELOG.md
…counts-must-be-numbers # Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Before: DeepSeek kept
usageas a raw JSON value and read each count with a JSON pointer, so a response with"prompt_tokens": "100"(or any other non-number count) was accepted and the count read as 0. Generate and stream both.After: the response and chunk types check usage when they deserialize, as
@ai-sdk/deepseek3.0.56 does withtokenUsageSchema: usage stays a loose object kept whole asusage.raw, but the seven known counts must be numbers or null, and the two*_detailsfields objects or null. A bad count fails the generate call; in a stream it becomes an error part and the finish reasonerror, like any other chunk that fails validation.Found while porting the upstream DeepSeek tests (#299, case
deepseek raw usage › continues validating known usage fields). Part of the #276 list.How it works today
What this PR changes
Tests (
tests/deepseek_chat_test.rs):generate_rejects_a_usage_count_that_is_not_a_numberandstream_rejects_a_usage_count_that_is_not_a_number; both fail on master. The upstream case is ported in #299.Docs: CHANGELOG
Fixed.Type of change
Checklist
cargo +1.99 fmt -p aimux-providers -- --checkpassescargo +1.99 clippy -p aimux-providers --lib --tests -- -D warningspassescargo +1.99 test -p aimux-providers --test deepseek_chat_test --test deepseek_testpasses (95 + 4)scripts/check_provider_boundaries.shpassesNotes for reviewers
The usage object itself is still kept as
Value, because upstream keeps it loose (.loose()) and returns it whole asusage.raw; only the validation is added.Generated by Claude Code