From d9a7c781383d319b51ee2f9deabb98444eb9bf81 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 15 Feb 2026 11:35:03 +0000 Subject: [PATCH] Update implementation plan: add OpenCode Bedrock support Co-Authored-By: Claude Opus 4.6 --- .../2026-02-15-aws-bedrock-implementation.md | 245 +++++++++++++++++- 1 file changed, 233 insertions(+), 12 deletions(-) diff --git a/docs/plans/2026-02-15-aws-bedrock-implementation.md b/docs/plans/2026-02-15-aws-bedrock-implementation.md index f0aaa9435..792073a0f 100644 --- a/docs/plans/2026-02-15-aws-bedrock-implementation.md +++ b/docs/plans/2026-02-15-aws-bedrock-implementation.md @@ -2,9 +2,9 @@ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. -**Goal:** Add AWS Bedrock as a provider in cc-switch with AKSK and API Key authentication support. +**Goal:** Add AWS Bedrock as a provider in cc-switch for both Claude Code and OpenCode, with AKSK and API Key authentication support. -**Architecture:** Preset-Only integration — add two provider presets (AKSK and API Key) to the existing Claude provider presets array. Add a new "cloud_provider" category to the ProviderCategory type. No Rust backend changes. +**Architecture:** Preset-Only integration — add provider presets to Claude and OpenCode preset arrays, add `@ai-sdk/amazon-bedrock` to OpenCode npm packages, and add a new "cloud_provider" category to ProviderCategory. No Rust backend changes. **Tech Stack:** TypeScript, Vitest, React (existing cc-switch stack) @@ -44,10 +44,11 @@ git commit -m "feat: add cloud_provider category to ProviderCategory type" --- -### Task 2: Add AWS Bedrock (AKSK) preset +### Task 2: Add AWS Bedrock (AKSK) Claude Code preset **Files:** -- Modify: `src/config/claudeProviderPresets.ts:53-536` (add to `providerPresets` array) +- Create: `tests/config/claudeProviderPresets.test.ts` +- Modify: `src/config/claudeProviderPresets.ts` (add to `providerPresets` array) **Step 1: Write the failing test** @@ -162,12 +163,12 @@ Expected: PASS — all 6 tests pass ```bash git add src/config/claudeProviderPresets.ts tests/config/claudeProviderPresets.test.ts -git commit -m "feat: add AWS Bedrock (AKSK) provider preset with tests" +git commit -m "feat: add AWS Bedrock (AKSK) Claude Code provider preset with tests" ``` --- -### Task 3: Add AWS Bedrock (API Key) preset +### Task 3: Add AWS Bedrock (API Key) Claude Code preset **Files:** - Modify: `src/config/claudeProviderPresets.ts` (add to `providerPresets` array) @@ -269,12 +270,232 @@ Expected: PASS — all 11 tests pass ```bash git add src/config/claudeProviderPresets.ts tests/config/claudeProviderPresets.test.ts -git commit -m "feat: add AWS Bedrock (API Key) provider preset with tests" +git commit -m "feat: add AWS Bedrock (API Key) Claude Code provider preset with tests" ``` --- -### Task 4: Run full test suite and verify +### Task 4: Add AWS Bedrock OpenCode preset with @ai-sdk/amazon-bedrock + +**Files:** +- Modify: `src/config/opencodeProviderPresets.ts` (add npm package + model variants + preset) +- Create: `tests/config/opencodeProviderPresets.test.ts` + +**Step 1: Write the failing test** + +Create file `tests/config/opencodeProviderPresets.test.ts`: + +```typescript +import { describe, expect, it } from "vitest"; +import { + opencodeProviderPresets, + opencodeNpmPackages, + OPENCODE_PRESET_MODEL_VARIANTS, +} from "@/config/opencodeProviderPresets"; + +describe("AWS Bedrock OpenCode Provider Presets", () => { + it("should include @ai-sdk/amazon-bedrock in npm packages", () => { + const bedrockPkg = opencodeNpmPackages.find( + (p) => p.value === "@ai-sdk/amazon-bedrock", + ); + expect(bedrockPkg).toBeDefined(); + expect(bedrockPkg!.label).toBe("Amazon Bedrock"); + }); + + it("should include Bedrock model variants", () => { + const variants = OPENCODE_PRESET_MODEL_VARIANTS["@ai-sdk/amazon-bedrock"]; + expect(variants).toBeDefined(); + expect(variants.length).toBeGreaterThan(0); + + const opusModel = variants.find((v) => + v.id.includes("anthropic.claude-opus-4-6"), + ); + expect(opusModel).toBeDefined(); + }); + + const bedrockPreset = opencodeProviderPresets.find( + (p) => p.name === "AWS Bedrock", + ); + + it("should include AWS Bedrock preset", () => { + expect(bedrockPreset).toBeDefined(); + }); + + it("Bedrock preset should use @ai-sdk/amazon-bedrock npm package", () => { + expect(bedrockPreset!.settingsConfig.npm).toBe( + "@ai-sdk/amazon-bedrock", + ); + }); + + it("Bedrock preset should have region in options", () => { + expect(bedrockPreset!.settingsConfig.options).toHaveProperty("region"); + }); + + it("Bedrock preset should have cloud_provider category", () => { + expect(bedrockPreset!.category).toBe("cloud_provider"); + }); + + it("Bedrock preset should have template values for AWS credentials", () => { + expect(bedrockPreset!.templateValues).toBeDefined(); + expect(bedrockPreset!.templateValues!.region).toBeDefined(); + expect(bedrockPreset!.templateValues!.region.editorValue).toBe( + "us-west-2", + ); + expect(bedrockPreset!.templateValues!.accessKeyId).toBeDefined(); + expect(bedrockPreset!.templateValues!.secretAccessKey).toBeDefined(); + }); + + it("Bedrock preset should include Claude models", () => { + const models = bedrockPreset!.settingsConfig.models; + expect(models).toBeDefined(); + const modelIds = Object.keys(models!); + expect( + modelIds.some((id) => id.includes("anthropic.claude")), + ).toBe(true); + }); +}); +``` + +**Step 2: Run test to verify it fails** + +Run: `cd /root/keith-space/github-search/cc-switch && pnpm test:unit -- tests/config/opencodeProviderPresets.test.ts` +Expected: FAIL — @ai-sdk/amazon-bedrock not found + +**Step 3: Add @ai-sdk/amazon-bedrock to npm packages list** + +In `src/config/opencodeProviderPresets.ts`, update `opencodeNpmPackages`: + +```typescript +export const opencodeNpmPackages = [ + { value: "@ai-sdk/openai", label: "OpenAI" }, + { value: "@ai-sdk/openai-compatible", label: "OpenAI Compatible" }, + { value: "@ai-sdk/anthropic", label: "Anthropic" }, + { value: "@ai-sdk/amazon-bedrock", label: "Amazon Bedrock" }, + { value: "@ai-sdk/google", label: "Google (Gemini)" }, +] as const; +``` + +**Step 4: Add Bedrock model variants** + +In `src/config/opencodeProviderPresets.ts`, add the following entry to `OPENCODE_PRESET_MODEL_VARIANTS`: + +```typescript + "@ai-sdk/amazon-bedrock": [ + { + id: "global.anthropic.claude-opus-4-6-v1", + name: "Claude Opus 4.6", + contextLimit: 1000000, + outputLimit: 128000, + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + }, + { + id: "global.anthropic.claude-sonnet-4-5-20250929-v1:0", + name: "Claude Sonnet 4.5", + contextLimit: 200000, + outputLimit: 64000, + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + }, + { + id: "global.anthropic.claude-haiku-4-5-20251001-v1:0", + name: "Claude Haiku 4.5", + contextLimit: 200000, + outputLimit: 64000, + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + }, + { + id: "us.amazon.nova-pro-v1:0", + name: "Amazon Nova Pro", + contextLimit: 300000, + outputLimit: 5000, + modalities: { input: ["text", "image"], output: ["text"] }, + }, + { + id: "us.meta.llama4-maverick-17b-instruct-v1:0", + name: "Meta Llama 4 Maverick", + contextLimit: 131072, + outputLimit: 131072, + modalities: { input: ["text"], output: ["text"] }, + }, + { + id: "us.deepseek.r1-v1:0", + name: "DeepSeek R1", + contextLimit: 131072, + outputLimit: 131072, + modalities: { input: ["text"], output: ["text"] }, + }, + ], +``` + +**Step 5: Add the Bedrock preset** + +In `src/config/opencodeProviderPresets.ts`, add the following entry to `opencodeProviderPresets` array (before the "OpenAI Compatible" custom template entry): + +```typescript + { + name: "AWS Bedrock", + websiteUrl: "https://aws.amazon.com/bedrock/", + settingsConfig: { + npm: "@ai-sdk/amazon-bedrock", + name: "AWS Bedrock", + options: { + region: "${region}", + accessKeyId: "${accessKeyId}", + secretAccessKey: "${secretAccessKey}", + }, + models: { + "global.anthropic.claude-opus-4-6-v1": { name: "Claude Opus 4.6" }, + "global.anthropic.claude-sonnet-4-5-20250929-v1:0": { + name: "Claude Sonnet 4.5", + }, + "global.anthropic.claude-haiku-4-5-20251001-v1:0": { + name: "Claude Haiku 4.5", + }, + "us.amazon.nova-pro-v1:0": { name: "Amazon Nova Pro" }, + "us.meta.llama4-maverick-17b-instruct-v1:0": { + name: "Meta Llama 4 Maverick", + }, + "us.deepseek.r1-v1:0": { name: "DeepSeek R1" }, + }, + }, + category: "cloud_provider", + icon: "aws", + iconColor: "#FF9900", + templateValues: { + region: { + label: "AWS Region", + placeholder: "us-west-2", + defaultValue: "us-west-2", + editorValue: "us-west-2", + }, + accessKeyId: { + label: "Access Key ID", + placeholder: "AKIA...", + editorValue: "", + }, + secretAccessKey: { + label: "Secret Access Key", + placeholder: "your-secret-key", + editorValue: "", + }, + }, + }, +``` + +**Step 6: Run test to verify all pass** + +Run: `cd /root/keith-space/github-search/cc-switch && pnpm test:unit -- tests/config/opencodeProviderPresets.test.ts` +Expected: PASS — all 8 tests pass + +**Step 7: Commit** + +```bash +git add src/config/opencodeProviderPresets.ts tests/config/opencodeProviderPresets.test.ts +git commit -m "feat: add AWS Bedrock OpenCode provider preset with @ai-sdk/amazon-bedrock" +``` + +--- + +### Task 5: Run full test suite and verify **Files:** - None (verification only) @@ -292,7 +513,7 @@ Expected: PASS (or fix with `pnpm format` then re-check) **Step 3: Run full unit test suite** Run: `cd /root/keith-space/github-search/cc-switch && pnpm test:unit` -Expected: PASS — all existing tests pass, plus 11 new Bedrock tests +Expected: PASS — all existing tests pass, plus 19 new Bedrock tests **Step 4: Fix any issues and commit** @@ -305,7 +526,7 @@ git commit -m "style: format code" --- -### Task 5: Final verification commit +### Task 6: Final verification **Files:** - None @@ -317,8 +538,8 @@ Expected: Clean working directory **Step 2: Review all changes** -Run: `cd /root/keith-space/github-search/cc-switch && git log --oneline -5` -Expected: See the 3-4 commits from this implementation +Run: `cd /root/keith-space/github-search/cc-switch && git log --oneline -6` +Expected: See the 4-5 commits from this implementation **Step 3: Run full test suite one final time**