Skip to content

fix(bedrock): recognise au./apac. inference profiles to enable prompt caching - #46297

Closed
jaketracey wants to merge 1 commit into
NousResearch:mainfrom
jaketracey:fix/bedrock-au-apac-inference-profiles
Closed

fix(bedrock): recognise au./apac. inference profiles to enable prompt caching#46297
jaketracey wants to merge 1 commit into
NousResearch:mainfrom
jaketracey:fix/bedrock-au-apac-inference-profiles

Conversation

@jaketracey

Copy link
Copy Markdown
Contributor

Problem

Claude models invoked on Amazon Bedrock through the Australia (au.) or Asia-Pacific (apac.) cross-region inference profiles — e.g. au.anthropic.claude-haiku-4-5-20251001-v1:0, apac.anthropic.claude-sonnet-4-6 — run without prompt caching, making multi-turn / agentic sessions far more expensive than they should be.

Root cause

is_anthropic_bedrock_model() decides the routing fork: Claude models go through the AnthropicBedrock SDK path (full feature parity — prompt caching, thinking budgets, adaptive thinking), everything else through the Converse API path (no cache_control support). It detects Claude by stripping a regional prefix and checking for anthropic.claude:

for prefix in ("us.", "global.", "eu.", "ap.", "jp."):

This list is missing au. entirely, and ap. does not match apac. ("apac.anthropic…".startswith("ap.") is False). So au.* and apac.* Claude profiles fall through to the Converse path and silently lose prompt caching.

Fix

Add "apac." and "au." to the prefix list (apac. before ap. for clarity; they don't overlap functionally):

for prefix in ("us.", "global.", "eu.", "apac.", "ap.", "au.", "jp."):

Impact

Validated live on a real agentic session (SEO audit, au.anthropic.claude-*) before vs after:

cache_read_tokens
Before (Converse path) 0
After (AnthropicBedrock path) 80,000+

i.e. the static system+tools prefix was being re-billed at full input price every turn instead of the ~10×-cheaper cache-read rate — a large, silent cost regression for AU/APAC Bedrock users.

Tests

Adds test_au_inference_profile and test_apac_inference_profile to TestIsAnthropicBedrockModel, matching the existing test_eu_claude style. No behaviour change for non-Anthropic models (Nova / DeepSeek / Llama / Mistral) or the existing us. / global. / eu. profiles.

Notes

Discovered while deploying Hermes on Bedrock in ap-southeast-2 (Australia) for an AU-data-residency deployment. AWS added the au. (Sydney + Melbourne) inference profiles relatively recently; this just brings the detector in line. Worth auditing other prefix lists for the same au./apac. gap.

🤖 Generated with Claude Code

… caching

is_anthropic_bedrock_model() strips a regional prefix before checking for
"anthropic.claude" to route Claude through the AnthropicBedrock SDK path
(prompt caching, thinking budgets) instead of the Converse path. The prefix
list was missing "au." and "ap." does not match "apac.", so AU/APAC Claude
inference profiles silently lost prompt caching. Add "apac." and "au.".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/bedrock AWS Bedrock (boto3, IAM) provider/anthropic Anthropic native Messages API labels Jun 14, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for identifying a real Bedrock routing gap. Current main confirms that agent/bedrock_adapter.py:451 omits both au. and apac., while hermes_cli/runtime_provider.py:1979-2000 uses that result to choose the AnthropicBedrock caching path.

Problems

  • The new routing is incomplete for auxiliary Bedrock calls. Once this detector accepts AU/APAC, agent/auxiliary_client.py:5085-5095 selects AnthropicAuxiliaryClient; its request adapter calls build_anthropic_kwargs() without preserve_dots (agent/auxiliary_client.py:1278-1286). _is_bedrock_model_id() still omits these prefixes (agent/anthropic_adapter.py:1571-1575), so normalize_model_name() converts their structural dots into hyphens (agent/anthropic_adapter.py:1597-1604).
  • The mirrored Bedrock pricing prefix list also omits AU/APAC (agent/usage_pricing.py:680-697), although the Bedrock pricing lookup calls it at agent/usage_pricing.py:730-737.

Suggested changes

  • Share or consistently extend the regional-prefix list in the detector, _is_bedrock_model_id(), and _normalize_bedrock_model_name().
  • Add routing, outgoing-model-preservation, and pricing-normalization tests for both prefixes.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) 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 14, 2026
@teknium1 teknium1 added the area/profiles Multi-profile isolation, HERMES_HOME scoping label Jul 19, 2026
teknium1 pushed a commit that referenced this pull request Jul 20, 2026
…nknown

_normalize_bedrock_model_name stripped ("us.", "global.", "eu.", "ap.",
"jp.") before the pricing lookup, but AWS Bedrock's Asia-Pacific
cross-region inference profiles are prefixed "apac." (and Australia
"au."), not "ap.". A bare "ap." never matches an "apac.*" id
(str.startswith stops at the 'a' where "ap." expects '.'), so
"apac.anthropic.claude-*" and "au.anthropic.claude-*" fell through with
the prefix intact, missed the bare "anthropic.claude-*" pricing key, and
every Asia-Pacific / Australia Bedrock session priced as "unknown" — no
cost estimate or tracking for two whole geographies, while us./eu./global.
worked.

Add "apac." and "au." to the strip list (mirrors the same fix landing in
bedrock_adapter.is_anthropic_bedrock_model via #46297, which covers the
prompt-caching capability gate but not this duplicated cost-lookup copy).

Extends the existing cross-region pricing test to cover apac./au.; without
the fix it fails with scoped == None for "apac.".
teknium1 added a commit that referenced this pull request Jul 20, 2026
The au./apac. additions from #46297 and #65973 covered
is_anthropic_bedrock_model and _normalize_bedrock_model_name; the same
prefix lists exist at two more sibling sites that would still miss
au./ca./sa./me./af. profiles:
- anthropic_adapter._looks_like_bedrock_model_id
- chat_completion_helpers (reasoning stale-timeout floor resolution)

All four sites now share the same 11-prefix set (global/us/eu/apac/ap/
au/jp/ca/sa/me/af, longest-first so apac. wins over ap.). The Bedrock
picker's BEDROCK_GEO_PREFIXES is deliberately untouched: au. absent
there fails open (profile shown), and adding it requires a region-to-geo
remap to avoid hiding Sydney profiles.
teknium1 pushed a commit that referenced this pull request Jul 20, 2026
…nknown

_normalize_bedrock_model_name stripped ("us.", "global.", "eu.", "ap.",
"jp.") before the pricing lookup, but AWS Bedrock's Asia-Pacific
cross-region inference profiles are prefixed "apac." (and Australia
"au."), not "ap.". A bare "ap." never matches an "apac.*" id
(str.startswith stops at the 'a' where "ap." expects '.'), so
"apac.anthropic.claude-*" and "au.anthropic.claude-*" fell through with
the prefix intact, missed the bare "anthropic.claude-*" pricing key, and
every Asia-Pacific / Australia Bedrock session priced as "unknown" — no
cost estimate or tracking for two whole geographies, while us./eu./global.
worked.

Add "apac." and "au." to the strip list (mirrors the same fix landing in
bedrock_adapter.is_anthropic_bedrock_model via #46297, which covers the
prompt-caching capability gate but not this duplicated cost-lookup copy).

Extends the existing cross-region pricing test to cover apac./au.; without
the fix it fails with scoped == None for "apac.".
teknium1 added a commit that referenced this pull request Jul 20, 2026
The au./apac. additions from #46297 and #65973 covered
is_anthropic_bedrock_model and _normalize_bedrock_model_name; the same
prefix lists exist at two more sibling sites that would still miss
au./ca./sa./me./af. profiles:
- anthropic_adapter._looks_like_bedrock_model_id
- chat_completion_helpers (reasoning stale-timeout floor resolution)

All four sites now share the same 11-prefix set (global/us/eu/apac/ap/
au/jp/ca/sa/me/af, longest-first so apac. wins over ap.). The Bedrock
picker's BEDROCK_GEO_PREFIXES is deliberately untouched: au. absent
there fails open (profile shown), and adding it requires a region-to-geo
remap to avoid hiding Sydney profiles.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #68005 — your commit was cherry-picked onto current main with your authorship preserved (rebase merge). You were the earliest submission for the au./apac. gap (June 14), and during salvage we found two more sibling sites with the same stale prefix list (the Bedrock-ID detector in anthropic_adapter and the reasoning-timeout resolver) — all four now share one roster. Thanks for the fix, prompt caching now works down under!

#68005

randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…nknown

_normalize_bedrock_model_name stripped ("us.", "global.", "eu.", "ap.",
"jp.") before the pricing lookup, but AWS Bedrock's Asia-Pacific
cross-region inference profiles are prefixed "apac." (and Australia
"au."), not "ap.". A bare "ap." never matches an "apac.*" id
(str.startswith stops at the 'a' where "ap." expects '.'), so
"apac.anthropic.claude-*" and "au.anthropic.claude-*" fell through with
the prefix intact, missed the bare "anthropic.claude-*" pricing key, and
every Asia-Pacific / Australia Bedrock session priced as "unknown" — no
cost estimate or tracking for two whole geographies, while us./eu./global.
worked.

Add "apac." and "au." to the strip list (mirrors the same fix landing in
bedrock_adapter.is_anthropic_bedrock_model via NousResearch#46297, which covers the
prompt-caching capability gate but not this duplicated cost-lookup copy).

Extends the existing cross-region pricing test to cover apac./au.; without
the fix it fails with scoped == None for "apac.".
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
The au./apac. additions from NousResearch#46297 and NousResearch#65973 covered
is_anthropic_bedrock_model and _normalize_bedrock_model_name; the same
prefix lists exist at two more sibling sites that would still miss
au./ca./sa./me./af. profiles:
- anthropic_adapter._looks_like_bedrock_model_id
- chat_completion_helpers (reasoning stale-timeout floor resolution)

All four sites now share the same 11-prefix set (global/us/eu/apac/ap/
au/jp/ca/sa/me/af, longest-first so apac. wins over ap.). The Bedrock
picker's BEDROCK_GEO_PREFIXES is deliberately untouched: au. absent
there fails open (profile shown), and adding it requires a region-to-geo
remap to avoid hiding Sydney profiles.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists provider/anthropic Anthropic native Messages API provider/bedrock AWS Bedrock (boto3, IAM) sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants