Bug Description
The in-session /model picker (and switch_model path) for the Bedrock provider offers bare foundation-model IDs alongside their inference-profile counterparts. On on-demand accounts the bare IDs are not invokable — selecting one persists it to config.yaml (model.default), and every subsequent call in every future session fails with:
HTTP 400: Invocation of model ID anthropic.claude-fable-5 with on-demand throughput
isn't supported. Retry your request with the ID or ARN of an inference profile that
contains this model.
The confusing part: the setup wizard already solves this. hermes_cli/model_setup_flows.py (~line 2224) deduplicates the discovery output, preferring us.*/global.* inference profiles and hiding bare IDs that are covered by a profile. But the /model picker path — list_authenticated_providers() → cached_provider_model_ids("bedrock") → bedrock_model_ids_or_none() (agent/bedrock_adapter.py:387) — returns the raw discovery list with no such dedup, so the picker shows both forms of the same model:
global.anthropic.claude-fable-5 ← works
...
anthropic.claude-fable-5 ← same model; 400s on invoke, but picker offers it
discover_bedrock_models() even tags which entries are profiles ("provider": "inference-profile"), so the information needed to dedup is already there — it's just dropped when the list is flattened to bare ID strings.
Not a duplicate of #10774: that one was closed as a missing bedrock:ListInferenceProfiles IAM permission (profiles absent from the list). Here discovery is fully working and profiles ARE listed — the bug is that the un-invokable bare IDs are listed too, as separate picker entries.
Steps to Reproduce
- Configure
model.provider: bedrock with a working AWS_BEARER_TOKEN_BEDROCK (on-demand account, no provisioned throughput), bedrock.discovery.enabled: true.
- Start an interactive session, run
/model, pick Bedrock, scroll past the global.* entries and select anthropic.claude-fable-5 (listed as a normal entry).
- The switch persists to config (
model.default: anthropic.claude-fable-5).
- Next message → HTTP 400 above. Every new session also fails until the config is hand-edited back to the
global.-prefixed ID.
Expected Behavior
The picker should apply the same profile-preferring dedup the setup wizard uses: when a bare foundation-model ID is covered by a discovered ACTIVE inference profile, list only the profile ID. (Alternatively/additionally: validate_requested_model's bedrock branch could warn when persisting a bare anthropic.* ID that has a profile sibling in the discovery output.)
Suggested Fix
Apply the dedup inside bedrock_model_ids_or_none() in agent/bedrock_adapter.py — that helper is the shared source for provider_model_ids and list_authenticated_providers sections 2 and 3, so fixing it there covers the CLI picker, gateway picker, and validation suggestions in one place:
_PROFILE_PREFIXES = ("us.", "global.", "eu.", "ap.", "jp.")
ids = [m["id"] for m in discovered]
profile_bases = {
mid.split(".", 1)[1] for mid in ids if mid.startswith(_PROFILE_PREFIXES)
}
return [
mid for mid in ids
if mid.startswith(_PROFILE_PREFIXES) or mid not in profile_bases
]
Tested locally against live us-east-1 discovery: picker drops the covered bare IDs (anthropic.claude-*) while keeping profiles and uncovered bare models (e.g. amazon.titan-*); end-to-end /model selection of global.anthropic.claude-fable-5 then works. Happy to send this as a PR if the approach looks right.
Environment
- hermes-agent 0.18.0 (wheel install), commit 19d4174
- Python 3.14.6, Linux x86_64
- Provider: bedrock via
AWS_BEARER_TOKEN_BEDROCK (bearer auth), region us-east-1
- anthropic SDK 0.116.0
Bug Description
The in-session
/modelpicker (andswitch_modelpath) for the Bedrock provider offers bare foundation-model IDs alongside their inference-profile counterparts. On on-demand accounts the bare IDs are not invokable — selecting one persists it toconfig.yaml(model.default), and every subsequent call in every future session fails with:The confusing part: the setup wizard already solves this.
hermes_cli/model_setup_flows.py(~line 2224) deduplicates the discovery output, preferringus.*/global.*inference profiles and hiding bare IDs that are covered by a profile. But the/modelpicker path —list_authenticated_providers()→cached_provider_model_ids("bedrock")→bedrock_model_ids_or_none()(agent/bedrock_adapter.py:387) — returns the raw discovery list with no such dedup, so the picker shows both forms of the same model:discover_bedrock_models()even tags which entries are profiles ("provider": "inference-profile"), so the information needed to dedup is already there — it's just dropped when the list is flattened to bare ID strings.Not a duplicate of #10774: that one was closed as a missing
bedrock:ListInferenceProfilesIAM permission (profiles absent from the list). Here discovery is fully working and profiles ARE listed — the bug is that the un-invokable bare IDs are listed too, as separate picker entries.Steps to Reproduce
model.provider: bedrockwith a workingAWS_BEARER_TOKEN_BEDROCK(on-demand account, no provisioned throughput),bedrock.discovery.enabled: true./model, pick Bedrock, scroll past theglobal.*entries and selectanthropic.claude-fable-5(listed as a normal entry).model.default: anthropic.claude-fable-5).global.-prefixed ID.Expected Behavior
The picker should apply the same profile-preferring dedup the setup wizard uses: when a bare foundation-model ID is covered by a discovered ACTIVE inference profile, list only the profile ID. (Alternatively/additionally:
validate_requested_model's bedrock branch could warn when persisting a bareanthropic.*ID that has a profile sibling in the discovery output.)Suggested Fix
Apply the dedup inside
bedrock_model_ids_or_none()inagent/bedrock_adapter.py— that helper is the shared source forprovider_model_idsandlist_authenticated_providerssections 2 and 3, so fixing it there covers the CLI picker, gateway picker, and validation suggestions in one place:Tested locally against live us-east-1 discovery: picker drops the covered bare IDs (
anthropic.claude-*) while keeping profiles and uncovered bare models (e.g.amazon.titan-*); end-to-end/modelselection ofglobal.anthropic.claude-fable-5then works. Happy to send this as a PR if the approach looks right.Environment
AWS_BEARER_TOKEN_BEDROCK(bearer auth), region us-east-1