Skip to content

fix(bedrock): honor api_mode=bedrock_converse so bearer-token auth works for Claude - #64857

Open
taoxee wants to merge 1 commit into
NousResearch:mainfrom
taoxee:fix/bedrock-bearer-token-converse-routing
Open

fix(bedrock): honor api_mode=bedrock_converse so bearer-token auth works for Claude#64857
taoxee wants to merge 1 commit into
NousResearch:mainfrom
taoxee:fix/bedrock-bearer-token-converse-routing

Conversation

@taoxee

@taoxee taoxee commented Jul 15, 2026

Copy link
Copy Markdown

Problem

Claude models on Bedrock are hardcoded to api_mode=anthropic_messages in resolve_runtime_provider() (hermes_cli/runtime_provider.py), which routes them through the AnthropicBedrock SDK. That SDK signs requests with SigV4 and resolves credentials via boto3's session.get_credentials() — it never reads AWS_BEARER_TOKEN_BEDROCK.

For users authenticated with a Bedrock bearer token only (no IAM access key, no ~/.aws), every Claude call fails:

RuntimeError: could not resolve credentials from session
API call failed after 3 retries: could not resolve credentials from session

The retries can't recover a missing credential, so it always exhausts them. Non-Claude Bedrock models already use the Converse API, which does honor the bearer token.

Fix

  • resolve_runtime_provider(): honor an explicit model.api_mode: bedrock_converse in config so Claude-on-Bedrock can route through the Converse API too. Default behavior is unchanged — without that config, Claude still uses the AnthropicBedrock path.
  • build_converse_kwargs(): inject the 1M-context beta via additionalModelRequestFields so the Converse path keeps the 1M context window (the AnthropicBedrock client attaches it as a client-level anthropic-beta header). Bedrock ignores the beta for models that don't support it, so it's safe to send unconditionally — matching build_anthropic_bedrock_client().

Testing

Verified on us-east-1 with a bearer-token-only setup (no IAM):

  • resolve_runtime_provider() returns bedrock_converse when configured.
  • Real Converse calls to claude-sonnet-5 and claude-opus-4-8 succeed (end_turn, real content) using only AWS_BEARER_TOKEN_BEDROCK.
  • The 1M beta is accepted by Bedrock (HTTP 200) and is a harmless no-op on models that don't support it.

@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard provider/bedrock AWS Bedrock (boto3, IAM) area/auth Authentication, OAuth, credential pools P2 Medium — degraded but workaround exists labels Jul 15, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the focused Bedrock fix. Current main already addresses the bearer-token-only failure by routing AWS_BEARER_TOKEN_BEDROCK users to Converse in hermes_cli/runtime_provider.py:1979-2008 (commit 5e6a0d9ee). The remaining explicit override and Converse 1M-context behavior are still worth evaluating.

Problems

  • The routing hunk conflicts with current behavior: the current Claude condition is is_anthropic_bedrock_model(...) and not _has_bearer_token at hermes_cli/runtime_provider.py:1985-1986. Integrate the explicit bedrock_converse override with that condition so bearer-token routing remains intact.
  • The PR adds no tests. Main's bearer routing is covered in tests/agent/test_bedrock_adapter.py:1756-1796; add coverage for the explicit override and for the additionalModelRequestFields generated by build_converse_kwargs().

Suggested changes

  • Preserve main's automatic bearer-token route and add the explicit-config route as an additional Converse selector.
  • Add focused resolver and request-shaping tests for the two new paths.

Automated hermes-sweeper review.

Comment thread hermes_cli/runtime_provider.py Outdated
# with SigV4 and ignores AWS_BEARER_TOKEN_BEDROCK — so bearer-token-only
# setups (no IAM key, no ~/.aws) must route Claude through the Converse
# API, which DOES honor the bearer token. The Converse path injects the
# 1M-context beta via additionalModelRequestFields (see

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Current main now selects Converse for AWS_BEARER_TOKEN_BEDROCK at runtime_provider.py:1979-2008. Please integrate this override with that bearer-token condition rather than replacing the current routing logic, so both selectors retain the Converse path.

@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 16, 2026
…e for Claude

main already routes bearer-token Claude users through the Converse API
(5e6a0d9), but that path does NOT set the 1M-context beta — so those
users silently lose the 1M window that the AnthropicBedrock SDK path gets
via its client-level anthropic-beta header. This adds the beta to the
Converse path and layers an explicit config override on top.

- resolve_runtime_provider(): honor an explicit model.api_mode:
  bedrock_converse as an additional Converse selector, integrated with
  main's bearer-token condition (either signal routes Claude to Converse).
  Default behavior is unchanged: no override + no bearer token → Claude
  keeps the AnthropicBedrock SDK path.
- build_converse_kwargs(): inject the 1M-context beta via
  additionalModelRequestFields, gated on is_anthropic_bedrock_model().
  anthropic_beta is an Anthropic-only field, so non-Claude Converse models
  (Nova, Llama, DeepSeek) must not receive it or Bedrock 400s.

Tests: resolver coverage for the explicit override (SigV4 + bearer, and
the unchanged default), and request-shaping coverage asserting the 1M beta
is present for Claude and absent for non-Claude models.
@taoxee
taoxee force-pushed the fix/bedrock-bearer-token-converse-routing branch from 34875a6 to 5895796 Compare July 16, 2026 11:04
@taoxee

taoxee commented Jul 16, 2026

Copy link
Copy Markdown
Author

Rebased onto current main and addressed the review:

  • Integrated with main's bearer-token routing (not clobbered): the Claude→AnthropicBedrock branch is now gated on not _forces_converse, where _forces_converse = _has_bearer_token or api_mode == bedrock_converse. Either signal routes Claude to Converse; the default (no bearer token, no override) still uses the AnthropicBedrock SDK path.
  • The remaining value beyond main: main routes bearer-token Claude users through Converse but does not set the 1M-context beta, so those users silently lose the 1M window. build_converse_kwargs() now injects it via additionalModelRequestFields, gated on is_anthropic_bedrock_model()anthropic_beta is Anthropic-only, so non-Claude Converse models (Nova/Llama/DeepSeek) must not receive it (would 400).
  • Tests added: resolver coverage for the explicit override under SigV4 and bearer, plus the unchanged default; and request-shaping coverage asserting the 1M beta is present for Claude and absent for non-Claude models.

tests/agent/test_bedrock_adapter.py passes (141 tests).

@GottZ

GottZ commented Aug 3, 2026

Copy link
Copy Markdown

This was generated by AI during triage.

Summary

Nine PRs address or reference the Bedrock complex: #24507, #26531, #34742, and merged #64628 change bearer-token routing; #28085, #33536, #34742, and #64628 decode image payloads; #64628 also fixes region-scoped discovery, while #54431/#63650 update the Anthropic SDK and #64857 adds an explicit Converse override plus 1M-context request shaping. The merged #64628 is the recorded best fix for both #28156 and #33317, but the visible diffs leave separable auxiliary, strict-validation, SDK-version, context-metadata, and explicit-override work in some open PRs.

Related pull requests

Duplicates

#24507, #26531, and the bearer-routing portion of #34742 overlap the routing now merged in #64628; #33536 and the image-decoding portions of #28085/#34742 duplicate #64628's raw-bytes fix. #54431 and #63650 overlap on the Anthropic SDK bump, while #64857's original bearer fix overlaps #64628 but its explicit override and Converse 1M request shaping do not.

Suggested consolidation

Keep #64857 open with a salvage path limited to the explicit Converse override and tested Claude-only 1M request shaping, and keep #28085 open only for auxiliary bearer routing plus strict malformed-image/deprecated-parameter hardening. Close #24507 and #33536 as duplicates of merged #64628; leave closed #26531/#34742 closed as superseded or salvaged references. For #54431 and #63650, require author action to rebase and either select one clean SDK-pin update or split #63650's tested context metadata from the competing version bump; do not disturb merged #64628, the recorded best fix for both issues.

Cross-PR triage: Reviewed 9 pull requests and 2 issues in this complex. Each diff was read against this issue; Assessment working set: 86 kB of PR diffs, 36 kB of issue/PR text, 41 kB of discussion (50 comments), 11 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch.

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

Labels

area/auth Authentication, OAuth, credential pools comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists provider/bedrock AWS Bedrock (boto3, IAM) sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants