diff --git a/packages/opencode/src/cli/cmd/providers.ts b/packages/opencode/src/cli/cmd/providers.ts index 3775123d83bd..e030b7e77683 100644 --- a/packages/opencode/src/cli/cmd/providers.ts +++ b/packages/opencode/src/cli/cmd/providers.ts @@ -458,7 +458,7 @@ export const ProvidersLoginCommand = effectCmd({ "Amazon Bedrock authentication priority:\n" + " 1. Bearer token (AWS_BEARER_TOKEN_BEDROCK or /connect)\n" + " 2. AWS credential chain (profile, access keys, IAM roles, EKS IRSA)\n\n" + - "Configure via opencode.json options (profile, region, endpoint) or\n" + + "Configure via opencode.json options (profile, region, endpoint), the /connect region prompt, or\n" + "AWS environment variables (AWS_PROFILE, AWS_REGION, AWS_ACCESS_KEY_ID, AWS_WEB_IDENTITY_TOKEN_FILE).", ) } diff --git a/packages/opencode/src/plugin/amazon-bedrock.ts b/packages/opencode/src/plugin/amazon-bedrock.ts new file mode 100644 index 000000000000..d75b61421e96 --- /dev/null +++ b/packages/opencode/src/plugin/amazon-bedrock.ts @@ -0,0 +1,28 @@ +import type { Hooks, PluginInput } from "@opencode-ai/plugin" + +export async function AmazonBedrockAuthPlugin(_input: PluginInput): Promise { + const prompts = !process.env.AWS_REGION + ? [ + { + type: "text" as const, + key: "region", + message: "Enter your AWS region for Bedrock", + placeholder: "e.g. us-east-1", + validate: (value: string) => (value.length > 0 ? undefined : "Required"), + }, + ] + : [] + + return { + auth: { + provider: "amazon-bedrock", + methods: [ + { + type: "api", + label: "Bedrock API key", + prompts, + }, + ], + }, + } +} diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts index 1558c707c3f7..4dd9ce9577d3 100644 --- a/packages/opencode/src/plugin/index.ts +++ b/packages/opencode/src/plugin/index.ts @@ -16,6 +16,7 @@ import { CopilotAuthPlugin } from "./github-copilot/copilot" import { gitlabAuthPlugin as GitlabAuthPlugin } from "opencode-gitlab-auth" import { PoeAuthPlugin } from "opencode-poe-auth" import { CloudflareAIGatewayAuthPlugin, CloudflareWorkersAuthPlugin } from "./cloudflare" +import { AmazonBedrockAuthPlugin } from "./amazon-bedrock" import { AzureAuthPlugin } from "./azure" import { DigitalOceanAuthPlugin } from "./digitalocean" import { XaiAuthPlugin } from "./xai" @@ -72,6 +73,7 @@ function internalPlugins(flags: RuntimeFlags.Info): PluginInstance[] { CopilotAuthPlugin, GitlabAuthPlugin, PoeAuthPlugin, + AmazonBedrockAuthPlugin, CloudflareWorkersAuthPlugin, CloudflareAIGatewayAuthPlugin, AzureAuthPlugin, diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index c979fc44659c..685a99482800 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -287,10 +287,11 @@ function custom(dep: CustomDep): Record { const auth = yield* dep.auth("amazon-bedrock") const env = yield* dep.env() - // Region precedence: 1) config file, 2) env var, 3) default + // Region precedence: 1) config file, 2) env var, 3) /connect metadata, 4) default const configRegion = providerConfig?.options?.region const envRegion = env["AWS_REGION"] - const defaultRegion = configRegion ?? envRegion ?? "us-east-1" + const authRegion = auth?.type === "api" ? auth.metadata?.region : undefined + const defaultRegion = configRegion ?? envRegion ?? authRegion ?? "us-east-1" // Profile: config file takes precedence over env var const configProfile = providerConfig?.options?.profile diff --git a/packages/opencode/test/provider/amazon-bedrock.test.ts b/packages/opencode/test/provider/amazon-bedrock.test.ts index 6e677631c40b..280dbdb0191f 100644 --- a/packages/opencode/test/provider/amazon-bedrock.test.ts +++ b/packages/opencode/test/provider/amazon-bedrock.test.ts @@ -90,6 +90,17 @@ it.instance("Bedrock: falls back to AWS_REGION env var when no config region", ( }), ) +it.instance("Bedrock: falls back to region stored by connect prompt", () => + Effect.gen(function* () { + yield* withAuthJson( + JSON.stringify({ "amazon-bedrock": { type: "api", key: "test-bearer-token", metadata: { region: "eu-west-1" } } }), + ) + const providers = yield* list + expect(providers[ProviderV2.ID.amazonBedrock]).toBeDefined() + expect(providers[ProviderV2.ID.amazonBedrock].options?.region).toBe("eu-west-1") + }), +) + it.instance( "Bedrock: loads when bearer token from auth.json is present", () => diff --git a/packages/web/src/content/docs/providers.mdx b/packages/web/src/content/docs/providers.mdx index d3c541311ffe..e9a3f4b07964 100644 --- a/packages/web/src/content/docs/providers.mdx +++ b/packages/web/src/content/docs/providers.mdx @@ -207,17 +207,19 @@ To use Amazon Bedrock with OpenCode: #### Environment Variables (Quick Start) - Set one of these environment variables while running opencode: + If you use `/connect` or `opencode auth login amazon-bedrock`, OpenCode + prompts for your Bedrock API key and region. You can also set credentials + with environment variables. Bedrock needs a region, set with `AWS_REGION`: ```bash # Option 1: Using AWS access keys - AWS_ACCESS_KEY_ID=XXX AWS_SECRET_ACCESS_KEY=YYY opencode + AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=XXX AWS_SECRET_ACCESS_KEY=YYY opencode # Option 2: Using named AWS profile - AWS_PROFILE=my-profile opencode + AWS_REGION=us-east-1 AWS_PROFILE=my-profile opencode # Option 3: Using Bedrock bearer token - AWS_BEARER_TOKEN_BEDROCK=XXX opencode + AWS_REGION=us-east-1 AWS_BEARER_TOKEN_BEDROCK=XXX opencode ``` Or add them to your bash profile: