Skip to content

fix(bedrock): forward stop and max_completion_tokens as sent on Claude InvokeModel - #1344

Merged
jarvis9443 merged 3 commits into
mainfrom
fix/f32-invoke-stop-forward
Oct 22, 2026
Merged

jarvis9443 merged 3 commits into
mainfrom
fix/f32-invoke-stop-forward

Conversation

@jarvis9443

@jarvis9443 jarvis9443 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Non-streamed chat to Claude on Amazon Bedrock now forwards stop and max_completion_tokens the same way the Anthropic route does, instead of silently dropping or filtering values it can't map.

The InvokeModel path builds its body with the shared Anthropic request builder, but shape_invoke_body then re-derived stop_sequences from stop using the Converse helper (which drops empty strings and ignores non-string values) and removed stop and max_completion_tokens unconditionally. The result was that stop: 5 and a non-integer max_completion_tokens vanished from the request and stop: "" / ["", "gamma"] lost their empty entries, so these requests got a 200 that ignored what the caller asked for. On the Anthropic route the same requests reach the upstream as sent and are rejected with a 400.

The fix removes that re-derivation and the two removals, so the InvokeModel body carries exactly what the shared builder produced. Unchanged: a native stop_sequences still wins over stop, a string stop becomes a one-element array, and null or [] sets nothing. A side effect is that a provider-key body override of stop_sequences is no longer overwritten on this route.

Behavior change after upgrading: a non-streamed chat request to a Bedrock Claude model carrying an invalid stop (a number, an empty string, an array with an empty string) or a non-integer max_completion_tokens now gets the upstream's 400 (e.g. stop_sequences: each stop sequence must be non-empty, stop: Extra inputs are not permitted) instead of a 200 that ignored the value. Valid values behave as before. Streamed Bedrock chat and non-Claude Bedrock models use Converse, which builds a typed request, and are not changed here.

Tests: the InvokeModel mock test chat_anthropic_maps_max_completion_tokens_and_stop now pins forwarding of empty stop strings, null/[], an unmappable stop and a non-integer max_completion_tokens, and a new case in bedrock-converse-and-chat-completions-e2e checks the body a non-streamed Claude request puts on /invoke for the same inputs. Both fail against the previous main.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved Claude request handling for Amazon Bedrock’s InvokeModel endpoint.
    • Stop sequences and completion token limits are now forwarded more consistently, including empty strings, arrays, numeric values, and nonnumeric limits.
    • Empty or null stop values continue to be omitted where appropriate.
  • Tests

    • Added end-to-end coverage confirming non-streaming Claude requests preserve these parameters when sent to Bedrock.

…e InvokeModel

Non-streamed chat to Claude on Bedrock goes through InvokeModel, which
builds its body with the shared Anthropic request builder and then
re-derived `stop_sequences` from `stop` with the Converse helper. That
helper drops empty strings and ignores anything that is not a string or
an array, and the shaping step then removed `stop` and
`max_completion_tokens` unconditionally. So `stop: 5`, `stop: ""`,
`stop: ["", "x"]` and a non-integer `max_completion_tokens` were silently
dropped or filtered on this route, while the Anthropic route forwards
them and lets the upstream reject them.

The re-derivation and both removals are gone: the body keeps what the
shared builder produced, so InvokeModel now matches the Anthropic route
for every input. A native `stop_sequences` still wins over `stop`, a
string `stop` is still a one-element array, and `null` or `[]` still
sets nothing.
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: c369188d-2eec-4761-9127-692224ea521e
📥 Commits

Reviewing files that changed from the base of the PR and between ac911e1 and df875ec.

📒 Files selected for processing: 2
  • crates/aisix-provider-bedrock/src/bridge.rs
  • tests/e2e/src/cases/bedrock-converse-and-chat-completions-e2e.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 5 included reviews per hour; 1 remain after this review.

📝 Walkthrough

The Bedrock InvokeModel body shaper no longer removes or remaps stop and max_completion_tokens based on the upstream model ID. Unit and end-to-end tests cover stop-value handling and forwarding these fields to the InvokeModel endpoint.

Changes: InvokeModel Body Shaping

Layer / File(s) Summary
Update body shaping and expectations
crates/aisix-provider-bedrock/src/bridge.rs, tests/e2e/src/cases/bedrock-converse-and-chat-completions-e2e.test.ts
The body shaper no longer receives the upstream model ID or removes and remaps stop and max_completion_tokens. Unit tests cover stop-sequence precedence and preservation of specified values. End-to-end tests verify forwarding to InvokeModel.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: moonming

Merge Risk: ⚪ Minimal · up to df875

No issue requiring a change before merge is established by the supplied evidence.

Pre-merge checks: Passed 6
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: forwarding stop and max_completion_tokens unchanged for Bedrock Claude InvokeModel requests.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
E2e Test Quality Review Passed PASS. The PR adds a real E2E path through the spawned gateway to a captured Bedrock /invoke endpoint. The test covers empty stop values, mixed empty/non-empty arrays, numeric stop values, and nonnum…
Security Check Passed No security vulnerability is introduced by the reviewed diff. The change only preserves stop, stop_sequences, and max_completion_tokens in the Bedrock InvokeModel request body. The code does not…
Full details: E2e Test Quality Review

Explanation

PASS. The PR adds a real E2E path through the spawned gateway to a captured Bedrock /invoke endpoint. The test covers empty stop values, mixed empty/non-empty arrays, numeric stop values, and nonnumeric max_completion_tokens. Rust tests additionally cover null and empty-array omission, native stop_sequences precedence, and combined valid mappings. Assertions are readable, test cases are independent, and the implementation changes only the relevant InvokeModel shaping logic. No blocking error-handling, mocking, scope, or concurrency issue is evident.

Full details: Security Check

Explanation

No security vulnerability is introduced by the reviewed diff. The change only preserves stop, stop_sequences, and max_completion_tokens in the Bedrock InvokeModel request body. The code does not log or return these values, persist data, change authorization, access ownership, resource deletion, TLS settings, or secret-reference resolution. Category 1: No issues found. Category 2: No issues found. Category 3: No issues found. Category 4: No issues found. Category 5: No issues found. Category 6: No issues found. Category 7: No issues found. The changed request remains sent through the existing SigV4 Bedrock client, and the added tests only capture request bodies in test code.

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@jarvis9443
jarvis9443 merged commit baae9d1 into main Oct 22, 2026
20 checks passed
@jarvis9443
jarvis9443 deleted the fix/f32-invoke-stop-forward branch October 22, 2026 01:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant