fix(core): hide Bedrock bare IDs that require inference profiles (#48078)

This commit is contained in:
Aiden Cline
2026-09-09 00:06:05 -05:00
committed by GitHub
Unverified
parent 1fe06bb4ed
commit fcafe82cdc
2 changed files with 75 additions and 1 deletions
@@ -18,6 +18,32 @@ const isBedrock = (item: { readonly package: string }) => {
return name.startsWith("@ai-sdk/amazon-bedrock") || name.startsWith("@opencode/ai/providers/amazon-bedrock")
}
// Bare Bedrock model IDs that AWS rejects unless sent as an inference-profile
// ID (`us.`/`eu.`/`global.`/...). Verified via on-demand foundation-model
// listings across six regions plus live Converse probes, all returning "with
// on-demand throughput isn't supported. Retry ... with an inference profile".
// V1 rewrites these to profiles at request time so they must stay in
// models.dev; V2 sends IDs verbatim, so listing them only produces errors.
// Interim until per-entry source-region metadata lands; region-aware
// filtering will subsume this list then.
export const PROFILE_ONLY_BARE_IDS = [
"amazon.nova-2-lite-v1:0",
"anthropic.claude-fable-5",
"anthropic.claude-fable-5-1",
"anthropic.claude-haiku-4-5-20251001-v1:0",
"anthropic.claude-opus-4-1-20250805-v1:0",
"anthropic.claude-opus-4-5-20251101-v1:0",
"anthropic.claude-opus-4-6-v1",
"anthropic.claude-opus-4-7",
"anthropic.claude-opus-4-8",
"anthropic.claude-opus-5",
"anthropic.claude-sonnet-4-5-20250929-v1:0",
"anthropic.claude-sonnet-4-6",
"anthropic.claude-sonnet-5",
"deepseek.r1-v1:0",
"mistral.pixtral-large-2502-v1:0",
]
export const AmazonBedrockPlugin = define({
id: "opencode.provider.amazon.bedrock",
effect: Effect.fn(function* (ctx) {
@@ -53,6 +79,12 @@ export const AmazonBedrockPlugin = define({
}
delete provider.settings.endpoint
})
for (const modelID of PROFILE_ONLY_BARE_IDS) {
if (!evt.model.get(item.provider.id, modelID)) continue
evt.model.update(item.provider.id, modelID, (model) => {
model.enabled = false
})
}
}
})
}),
@@ -4,7 +4,8 @@ import { Catalog } from "@opencode/core/catalog"
import { Integration } from "@opencode/core/integration"
import { Plugin } from "@opencode/core/plugin"
import { PluginHost } from "@opencode/core/plugin/host"
import { AmazonBedrockPlugin } from "@opencode/core/plugin/provider/amazon-bedrock"
import { AmazonBedrockPlugin, PROFILE_ONLY_BARE_IDS } from "@opencode/core/plugin/provider/amazon-bedrock"
import { Model } from "@opencode/core/model"
import { Provider } from "@opencode/core/provider"
import { testEffect } from "../lib/effect"
import { PluginTestLayer } from "./fixture"
@@ -222,4 +223,45 @@ describe("AmazonBedrockPlugin", () => {
}),
),
)
it.effect("disables profile-only bare IDs while keeping working IDs", () =>
withEnv(noAmbientAWS, () =>
Effect.gen(function* () {
const catalog = yield* seedBedrock()
const controls = [
"us.anthropic.claude-sonnet-4-5-20250929-v1:0",
"amazon.nova-micro-v1:0",
"openai.gpt-6-astra",
]
yield* catalog.transform((catalog) => {
for (const id of [...PROFILE_ONLY_BARE_IDS, ...controls]) {
catalog.model.update(Provider.ID.amazonBedrock, Model.ID.make(id), () => {})
}
})
yield* addPlugin()
for (const id of PROFILE_ONLY_BARE_IDS) {
expect(required(yield* catalog.model.get(Provider.ID.amazonBedrock, Model.ID.make(id))).enabled).toBe(
false,
)
}
for (const id of controls) {
expect(required(yield* catalog.model.get(Provider.ID.amazonBedrock, Model.ID.make(id))).enabled).toBe(
true,
)
}
}),
),
)
it.effect("does not create catalog entries for absent profile-only IDs", () =>
withEnv(noAmbientAWS, () =>
Effect.gen(function* () {
const catalog = yield* seedBedrock()
yield* addPlugin()
for (const id of PROFILE_ONLY_BARE_IDS) {
expect(yield* catalog.model.get(Provider.ID.amazonBedrock, Model.ID.make(id))).toBeUndefined()
}
}),
),
)
})