Skip to content

fix(grpc): preserve oversized integer tool-call arguments digit-exact - #2115

Draft
pallasathena92 wants to merge 1 commit into
mainfrom
fix/tool-arg-numeric-fidelity
Draft

fix(grpc): preserve oversized integer tool-call arguments digit-exact#2115
pallasathena92 wants to merge 1 commit into
mainfrom
fix/tool-arg-numeric-fidelity

Conversation

@pallasathena92

Copy link
Copy Markdown
Collaborator

Description

Problem

process_tool_call_arguments parses each assistant tool call's arguments string into a JSON value before chat-template rendering. serde_json represents integers outside the i64/u64 range as f64, so an argument like {"id": 123456789012345678901234567890} silently re-renders as 1.2345678901234568e29. The model sees the corrupted spelling in its rendered history and echoes a wrong id back to the tool on the next call.

Solution

Pre-scan the arguments string with a minimal string-state lexer and wrap only the integer literals neither i64 nor u64 can hold in quotes, so they survive the parse digit-exact as JSON strings. The guard is deliberately narrow:

  • in-range integers (up to u64::MAX / down to i64::MIN) stay native numbers — zero behavior change;
  • float-shaped tokens (fraction or exponent) pass through untouched — f64 semantics are JSON-standard for those;
  • digits inside string values are never touched (the lexer tracks in-string/escape state);
  • non-canonical tokens (leading zeros, stray operators) are left alone so malformed input still fails in the parser, citing the original text.

Rendering such an argument quoted rather than bare is the accepted trade-off: values at that magnitude are invariably identifiers that must round-trip verbatim, and exact-but-quoted beats bare-but-corrupted.

Changes

  • model_gateway/src/routers/grpc/utils/chat_utils.rs: add quote_unrepresentable_integers (Cow-returning pre-scan; borrows when no rewrite is needed) and is_canonical_json_integer; apply the guard in process_tool_call_arguments.

Test Plan

Six new unit tests in chat_utils:

  • >u64::MAX positive and <i64::MIN negative integers survive digit-exact (top level and nested containers);
  • u64::MAX, i64::MIN, ordinary ints, and floats stay native numbers;
  • digit runs inside string values (including next to escaped quotes) are untouched;
  • malformed arguments ({bad, [1-2], leading-zero integers) still error, citing the original text;
  • untouched inputs take the Cow::Borrowed path.

cargo clippy -p smg --all-targets clean; cargo test -p smg --lib chat_utils 30/30.

Checklist
  • Format your code: make fmt
  • Run lint checks: targeted cargo clippy -p smg --all-targets -- -D warnings
  • Add unit tests for new functionality
  • Update documentation if needed (n/a — internal fix)

History normalization parses each assistant tool call's arguments string
into a JSON value before template rendering. Integers outside the
i64/u64 range fall back to f64 during that parse, so a large id like
123456789012345678901234567890 silently re-renders with different
digits and the model echoes a corrupted value back to the tool.

Guard the parse with a minimal string-state pre-scan that wraps only
canonical integer literals neither i64 nor u64 can hold in quotes,
preserving every digit as a JSON string. In-range integers and floats
stay native numbers, digits inside string values are untouched, and
malformed input still fails in the parser with the original text in
the error. Rendering such an argument quoted rather than bare is the
accepted trade: values at that magnitude are invariably identifiers
that must round-trip verbatim.

Signed-off-by: yifeng liu <31553858+pallasathena92@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 08e73287-a554-4baa-b49e-aa1f28b0eaca

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added grpc gRPC client and router changes model-gateway Model gateway crate changes labels Aug 12, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, well-tested fix. The lexer correctly handles string escaping, float-shaped tokens, canonical-form validation, and the zero-copy borrowed path. Test coverage is thorough across boundaries (u64::MAX, i64::MIN), nested containers, escaped-quote edge cases, and malformed input fallthrough. No issues found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

grpc gRPC client and router changes model-gateway Model gateway crate changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant