mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-03-28 22:33:05 +08:00
chore: remove internal planning documents
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,547 +0,0 @@
|
||||
# AWS Bedrock Provider Implementation Plan
|
||||
|
||||
> **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 for both Claude Code and OpenCode, with AKSK and API Key authentication support.
|
||||
|
||||
**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)
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Add "cloud_provider" category to ProviderCategory type
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/types.ts:1-7`
|
||||
|
||||
**Step 1: Add the new category**
|
||||
|
||||
In `src/types.ts`, add `"cloud_provider"` to the `ProviderCategory` union type:
|
||||
|
||||
```typescript
|
||||
export type ProviderCategory =
|
||||
| "official" // 官方
|
||||
| "cn_official" // 开源官方(原"国产官方")
|
||||
| "cloud_provider" // 云服务商(AWS Bedrock 等)
|
||||
| "aggregator" // 聚合网站
|
||||
| "third_party" // 第三方供应商
|
||||
| "custom" // 自定义
|
||||
| "omo"; // Oh My OpenCode
|
||||
```
|
||||
|
||||
**Step 2: Run typecheck to verify**
|
||||
|
||||
Run: `cd /root/keith-space/github-search/cc-switch && pnpm typecheck`
|
||||
Expected: PASS (no errors)
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add src/types.ts
|
||||
git commit -m "feat: add cloud_provider category to ProviderCategory type"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Add AWS Bedrock (AKSK) Claude Code preset
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/config/claudeProviderPresets.test.ts`
|
||||
- Modify: `src/config/claudeProviderPresets.ts` (add to `providerPresets` array)
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
Create file `tests/config/claudeProviderPresets.test.ts`:
|
||||
|
||||
```typescript
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { providerPresets } from "@/config/claudeProviderPresets";
|
||||
|
||||
describe("AWS Bedrock Provider Presets", () => {
|
||||
const bedrockAksk = providerPresets.find(
|
||||
(p) => p.name === "AWS Bedrock (AKSK)",
|
||||
);
|
||||
|
||||
it("should include AWS Bedrock (AKSK) preset", () => {
|
||||
expect(bedrockAksk).toBeDefined();
|
||||
});
|
||||
|
||||
it("AKSK preset should have required AWS env variables", () => {
|
||||
const env = (bedrockAksk!.settingsConfig as any).env;
|
||||
expect(env).toHaveProperty("AWS_ACCESS_KEY_ID");
|
||||
expect(env).toHaveProperty("AWS_SECRET_ACCESS_KEY");
|
||||
expect(env).toHaveProperty("AWS_REGION");
|
||||
expect(env).toHaveProperty("CLAUDE_CODE_USE_BEDROCK", "1");
|
||||
});
|
||||
|
||||
it("AKSK preset should have template values for AWS credentials", () => {
|
||||
expect(bedrockAksk!.templateValues).toBeDefined();
|
||||
expect(bedrockAksk!.templateValues!.AWS_ACCESS_KEY_ID).toBeDefined();
|
||||
expect(bedrockAksk!.templateValues!.AWS_SECRET_ACCESS_KEY).toBeDefined();
|
||||
expect(bedrockAksk!.templateValues!.AWS_REGION).toBeDefined();
|
||||
expect(bedrockAksk!.templateValues!.AWS_REGION.editorValue).toBe(
|
||||
"us-west-2",
|
||||
);
|
||||
});
|
||||
|
||||
it("AKSK preset should have correct base URL template", () => {
|
||||
const env = (bedrockAksk!.settingsConfig as any).env;
|
||||
expect(env.ANTHROPIC_BASE_URL).toContain("bedrock-runtime");
|
||||
expect(env.ANTHROPIC_BASE_URL).toContain("${AWS_REGION}");
|
||||
});
|
||||
|
||||
it("AKSK preset should have cloud_provider category", () => {
|
||||
expect(bedrockAksk!.category).toBe("cloud_provider");
|
||||
});
|
||||
|
||||
it("AKSK preset should have Bedrock model as default", () => {
|
||||
const env = (bedrockAksk!.settingsConfig as any).env;
|
||||
expect(env.ANTHROPIC_MODEL).toContain("anthropic.claude");
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `cd /root/keith-space/github-search/cc-switch && pnpm test:unit -- tests/config/claudeProviderPresets.test.ts`
|
||||
Expected: FAIL — "AWS Bedrock (AKSK)" preset not found
|
||||
|
||||
**Step 3: Add the AKSK preset to the presets array**
|
||||
|
||||
In `src/config/claudeProviderPresets.ts`, add the following entry after the last preset (before the closing `];` of the `providerPresets` array):
|
||||
|
||||
```typescript
|
||||
{
|
||||
name: "AWS Bedrock (AKSK)",
|
||||
websiteUrl: "https://aws.amazon.com/bedrock/",
|
||||
settingsConfig: {
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL:
|
||||
"https://bedrock-runtime.${AWS_REGION}.amazonaws.com",
|
||||
AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}",
|
||||
AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}",
|
||||
AWS_REGION: "${AWS_REGION}",
|
||||
ANTHROPIC_MODEL: "global.anthropic.claude-opus-4-6-v1",
|
||||
ANTHROPIC_DEFAULT_HAIKU_MODEL:
|
||||
"global.anthropic.claude-haiku-4-5-20251001-v1:0",
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL:
|
||||
"global.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||
ANTHROPIC_DEFAULT_OPUS_MODEL: "global.anthropic.claude-opus-4-6-v1",
|
||||
CLAUDE_CODE_USE_BEDROCK: "1",
|
||||
},
|
||||
},
|
||||
category: "cloud_provider",
|
||||
templateValues: {
|
||||
AWS_REGION: {
|
||||
label: "AWS Region",
|
||||
placeholder: "us-west-2",
|
||||
editorValue: "us-west-2",
|
||||
},
|
||||
AWS_ACCESS_KEY_ID: {
|
||||
label: "Access Key ID",
|
||||
placeholder: "AKIA...",
|
||||
editorValue: "",
|
||||
},
|
||||
AWS_SECRET_ACCESS_KEY: {
|
||||
label: "Secret Access Key",
|
||||
placeholder: "your-secret-key",
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
icon: "aws",
|
||||
iconColor: "#FF9900",
|
||||
},
|
||||
```
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `cd /root/keith-space/github-search/cc-switch && pnpm test:unit -- tests/config/claudeProviderPresets.test.ts`
|
||||
Expected: PASS — all 6 tests pass
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add src/config/claudeProviderPresets.ts tests/config/claudeProviderPresets.test.ts
|
||||
git commit -m "feat: add AWS Bedrock (AKSK) Claude Code provider preset with tests"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Add AWS Bedrock (API Key) Claude Code preset
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/config/claudeProviderPresets.ts` (add to `providerPresets` array)
|
||||
- Modify: `tests/config/claudeProviderPresets.test.ts` (add API Key tests)
|
||||
|
||||
**Step 1: Add tests for the API Key preset**
|
||||
|
||||
Append the following test block to `tests/config/claudeProviderPresets.test.ts`, inside the existing `describe` block:
|
||||
|
||||
```typescript
|
||||
const bedrockApiKey = providerPresets.find(
|
||||
(p) => p.name === "AWS Bedrock (API Key)",
|
||||
);
|
||||
|
||||
it("should include AWS Bedrock (API Key) preset", () => {
|
||||
expect(bedrockApiKey).toBeDefined();
|
||||
});
|
||||
|
||||
it("API Key preset should have apiKey template and AWS env variables", () => {
|
||||
const config = bedrockApiKey!.settingsConfig as any;
|
||||
expect(config).toHaveProperty("apiKey", "${BEDROCK_API_KEY}");
|
||||
expect(config.env).toHaveProperty("AWS_REGION");
|
||||
expect(config.env).toHaveProperty("CLAUDE_CODE_USE_BEDROCK", "1");
|
||||
});
|
||||
|
||||
it("API Key preset should NOT have AKSK env variables", () => {
|
||||
const env = (bedrockApiKey!.settingsConfig as any).env;
|
||||
expect(env).not.toHaveProperty("AWS_ACCESS_KEY_ID");
|
||||
expect(env).not.toHaveProperty("AWS_SECRET_ACCESS_KEY");
|
||||
});
|
||||
|
||||
it("API Key preset should have template values for API key and region", () => {
|
||||
expect(bedrockApiKey!.templateValues).toBeDefined();
|
||||
expect(bedrockApiKey!.templateValues!.BEDROCK_API_KEY).toBeDefined();
|
||||
expect(bedrockApiKey!.templateValues!.AWS_REGION).toBeDefined();
|
||||
expect(bedrockApiKey!.templateValues!.AWS_REGION.editorValue).toBe(
|
||||
"us-west-2",
|
||||
);
|
||||
});
|
||||
|
||||
it("API Key preset should have cloud_provider category", () => {
|
||||
expect(bedrockApiKey!.category).toBe("cloud_provider");
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify new tests fail**
|
||||
|
||||
Run: `cd /root/keith-space/github-search/cc-switch && pnpm test:unit -- tests/config/claudeProviderPresets.test.ts`
|
||||
Expected: FAIL — "AWS Bedrock (API Key)" preset not found
|
||||
|
||||
**Step 3: Add the API Key preset**
|
||||
|
||||
In `src/config/claudeProviderPresets.ts`, add the following entry right after the AKSK preset:
|
||||
|
||||
```typescript
|
||||
{
|
||||
name: "AWS Bedrock (API Key)",
|
||||
websiteUrl: "https://aws.amazon.com/bedrock/",
|
||||
apiKeyField: "ANTHROPIC_API_KEY",
|
||||
settingsConfig: {
|
||||
apiKey: "${BEDROCK_API_KEY}",
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL:
|
||||
"https://bedrock-runtime.${AWS_REGION}.amazonaws.com",
|
||||
AWS_REGION: "${AWS_REGION}",
|
||||
ANTHROPIC_MODEL: "global.anthropic.claude-opus-4-6-v1",
|
||||
ANTHROPIC_DEFAULT_HAIKU_MODEL:
|
||||
"global.anthropic.claude-haiku-4-5-20251001-v1:0",
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL:
|
||||
"global.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||
ANTHROPIC_DEFAULT_OPUS_MODEL: "global.anthropic.claude-opus-4-6-v1",
|
||||
CLAUDE_CODE_USE_BEDROCK: "1",
|
||||
},
|
||||
},
|
||||
category: "cloud_provider",
|
||||
templateValues: {
|
||||
AWS_REGION: {
|
||||
label: "AWS Region",
|
||||
placeholder: "us-west-2",
|
||||
editorValue: "us-west-2",
|
||||
},
|
||||
BEDROCK_API_KEY: {
|
||||
label: "Bedrock API Key",
|
||||
placeholder: "your-bedrock-api-key",
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
icon: "aws",
|
||||
iconColor: "#FF9900",
|
||||
},
|
||||
```
|
||||
|
||||
**Step 4: Run test to verify all pass**
|
||||
|
||||
Run: `cd /root/keith-space/github-search/cc-switch && pnpm test:unit -- tests/config/claudeProviderPresets.test.ts`
|
||||
Expected: PASS — all 11 tests pass
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add src/config/claudeProviderPresets.ts tests/config/claudeProviderPresets.test.ts
|
||||
git commit -m "feat: add AWS Bedrock (API Key) Claude Code provider preset with tests"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 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)
|
||||
|
||||
**Step 1: Run TypeScript type checking**
|
||||
|
||||
Run: `cd /root/keith-space/github-search/cc-switch && pnpm typecheck`
|
||||
Expected: PASS (no type errors)
|
||||
|
||||
**Step 2: Run code format check**
|
||||
|
||||
Run: `cd /root/keith-space/github-search/cc-switch && pnpm format:check`
|
||||
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 19 new Bedrock tests
|
||||
|
||||
**Step 4: Fix any issues and commit**
|
||||
|
||||
If format check fails:
|
||||
```bash
|
||||
cd /root/keith-space/github-search/cc-switch && pnpm format
|
||||
git add -A
|
||||
git commit -m "style: format code"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Final verification
|
||||
|
||||
**Files:**
|
||||
- None
|
||||
|
||||
**Step 1: Verify git status is clean**
|
||||
|
||||
Run: `cd /root/keith-space/github-search/cc-switch && git status`
|
||||
Expected: Clean working directory
|
||||
|
||||
**Step 2: Review all changes**
|
||||
|
||||
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**
|
||||
|
||||
Run: `cd /root/keith-space/github-search/cc-switch && pnpm test:unit`
|
||||
Expected: All tests PASS
|
||||
@@ -1,154 +0,0 @@
|
||||
# AWS Bedrock Provider Integration Design
|
||||
|
||||
**Date**: 2026-02-15
|
||||
**Author**: Keith (AWS AI Expert)
|
||||
**Status**: Approved
|
||||
|
||||
## Overview
|
||||
|
||||
Add AWS Bedrock as a provider in cc-switch, supporting both AKSK (Access Key / Secret Key) and Bedrock API Key authentication methods. This is a Preset-Only integration (方案 A) that leverages Claude Code's native Bedrock support without modifying the Rust backend.
|
||||
|
||||
## Requirements
|
||||
|
||||
1. Support AWS Bedrock as a provider in cc-switch
|
||||
2. Two authentication methods: AKSK and Bedrock API Key (equal priority)
|
||||
3. Default region: `us-west-2`, user-configurable
|
||||
4. Support cross-region inference model IDs (`global.*`, `us.*`, `eu.*`, `apac.*`)
|
||||
5. All existing tests must pass after changes
|
||||
|
||||
## Approach: Preset-Only Integration
|
||||
|
||||
Add two provider presets to `src/config/claudeProviderPresets.ts`. No Rust backend changes required. Claude Code handles Bedrock SigV4 signing natively when `CLAUDE_CODE_USE_BEDROCK=1` is set.
|
||||
|
||||
### Why Preset-Only
|
||||
|
||||
- Minimal code changes, low risk
|
||||
- Consistent with existing provider architecture
|
||||
- Claude Code already supports Bedrock natively
|
||||
- Tests remain simple and focused
|
||||
|
||||
## Provider Presets
|
||||
|
||||
### Preset 1: AWS Bedrock (AKSK)
|
||||
|
||||
Authentication via AWS Access Key ID and Secret Access Key.
|
||||
|
||||
```typescript
|
||||
{
|
||||
name: "AWS Bedrock (AKSK)",
|
||||
icon: "aws",
|
||||
iconColor: "#FF9900",
|
||||
websiteUrl: "https://aws.amazon.com/bedrock/",
|
||||
settingsConfig: {
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL: "https://bedrock-runtime.${AWS_REGION}.amazonaws.com",
|
||||
AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}",
|
||||
AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}",
|
||||
AWS_REGION: "${AWS_REGION}",
|
||||
ANTHROPIC_MODEL: "global.anthropic.claude-opus-4-6-v1",
|
||||
CLAUDE_CODE_USE_BEDROCK: "1"
|
||||
}
|
||||
},
|
||||
templateValues: {
|
||||
AWS_REGION: { label: "AWS Region", placeholder: "us-west-2", editorValue: "us-west-2" },
|
||||
AWS_ACCESS_KEY_ID: { label: "Access Key ID", placeholder: "AKIA...", editorValue: "" },
|
||||
AWS_SECRET_ACCESS_KEY: { label: "Secret Access Key", placeholder: "your-secret-key", editorValue: "", secret: true }
|
||||
},
|
||||
models: {
|
||||
model: "global.anthropic.claude-opus-4-6-v1",
|
||||
haikuModel: "global.anthropic.claude-haiku-4-5-20251001-v1:0",
|
||||
sonnetModel: "global.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||
opusModel: "global.anthropic.claude-opus-4-6-v1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Preset 2: AWS Bedrock (API Key)
|
||||
|
||||
Authentication via Bedrock API Key.
|
||||
|
||||
```typescript
|
||||
{
|
||||
name: "AWS Bedrock (API Key)",
|
||||
icon: "aws",
|
||||
iconColor: "#FF9900",
|
||||
websiteUrl: "https://aws.amazon.com/bedrock/",
|
||||
settingsConfig: {
|
||||
apiKey: "${BEDROCK_API_KEY}",
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL: "https://bedrock-runtime.${AWS_REGION}.amazonaws.com",
|
||||
AWS_REGION: "${AWS_REGION}",
|
||||
ANTHROPIC_MODEL: "global.anthropic.claude-opus-4-6-v1",
|
||||
CLAUDE_CODE_USE_BEDROCK: "1"
|
||||
}
|
||||
},
|
||||
templateValues: {
|
||||
AWS_REGION: { label: "AWS Region", placeholder: "us-west-2", editorValue: "us-west-2" },
|
||||
BEDROCK_API_KEY: { label: "Bedrock API Key", placeholder: "your-bedrock-api-key", editorValue: "", secret: true }
|
||||
},
|
||||
models: {
|
||||
model: "global.anthropic.claude-opus-4-6-v1",
|
||||
haikuModel: "global.anthropic.claude-haiku-4-5-20251001-v1:0",
|
||||
sonnetModel: "global.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||
opusModel: "global.anthropic.claude-opus-4-6-v1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Model Catalog
|
||||
|
||||
Default models available in presets:
|
||||
|
||||
| Model | Model ID |
|
||||
|-------|----------|
|
||||
| Claude Opus 4.6 | `global.anthropic.claude-opus-4-6-v1` |
|
||||
| Claude Opus 4.6 (1M context) | `global.anthropic.claude-opus-4-6-v1[1m]` |
|
||||
| Claude Sonnet 4.5 | `global.anthropic.claude-sonnet-4-5-20250929-v1:0` |
|
||||
| Claude Haiku 4.5 | `global.anthropic.claude-haiku-4-5-20251001-v1:0` |
|
||||
| Qwen3 Coder 480B | `qwen.qwen3-coder-480b-a35b-v1:0` |
|
||||
| MiniMax M2.1 | `minimax.minimax-m2.1` |
|
||||
| DeepSeek R1 | `us.deepseek.r1-v1:0` |
|
||||
| Amazon Nova Pro | `us.amazon.nova-pro-v1:0` |
|
||||
| Amazon Nova Lite | `us.amazon.nova-lite-v1:0` |
|
||||
| Meta Llama 4 Maverick | `us.meta.llama4-maverick-17b-instruct-v1:0` |
|
||||
|
||||
Users can manually enter any Bedrock model ID, including cross-region inference profiles.
|
||||
|
||||
## Region Handling
|
||||
|
||||
- Default region: `us-west-2`
|
||||
- User-configurable via template variable `${AWS_REGION}`
|
||||
- Region injected into `ANTHROPIC_BASE_URL` and `AWS_REGION` env var
|
||||
- Cross-region inference: use `global.*`, `us.*`, `eu.*`, `apac.*` prefixed model IDs
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Must Pass
|
||||
|
||||
- `pnpm test:unit` — all existing unit tests
|
||||
- `pnpm typecheck` — TypeScript type checking
|
||||
- `pnpm format:check` — code formatting
|
||||
|
||||
### New Tests
|
||||
|
||||
- Validate Bedrock AKSK preset contains required template variables
|
||||
- Validate Bedrock API Key preset contains required template variables
|
||||
- Validate template variable substitution in URL
|
||||
- Validate default model ID format
|
||||
|
||||
### Out of Scope
|
||||
|
||||
- E2E integration tests (requires live Bedrock environment)
|
||||
- Rust backend tests (no backend changes)
|
||||
|
||||
## Files to Modify
|
||||
|
||||
1. `src/config/claudeProviderPresets.ts` — add two Bedrock presets
|
||||
2. Existing test files for preset validation (if applicable)
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No Rust backend changes
|
||||
- No new `BedrockAdapter` in proxy layer
|
||||
- No SigV4 signing implementation (handled by Claude Code natively)
|
||||
- No changes to MCP, Skills, or other cc-switch subsystems
|
||||
@@ -1,86 +0,0 @@
|
||||
# feat: Add AWS Bedrock Provider Support
|
||||
|
||||
## Summary
|
||||
|
||||
Add AWS Bedrock as a first-class cloud provider in cc-switch, supporting both Claude Code and OpenCode with two authentication methods (AKSK and API Key). Includes cross-region inference model support.
|
||||
|
||||
## Motivation
|
||||
|
||||
AWS Bedrock is a major cloud AI platform that provides access to Claude, Nova, Llama, DeepSeek, and other models through a unified API. Many enterprise users access AI models through Bedrock rather than direct API endpoints. Adding Bedrock support enables cc-switch users to manage their Bedrock-based AI CLI configurations alongside other providers.
|
||||
|
||||
## Changes
|
||||
|
||||
### New Provider Category
|
||||
|
||||
Added `cloud_provider` to `ProviderCategory` type to properly categorize cloud platform providers (distinct from `official`, `aggregator`, or `third_party`).
|
||||
|
||||
### Claude Code Presets (2 new presets)
|
||||
|
||||
**AWS Bedrock (AKSK)**
|
||||
- Authentication via AWS Access Key ID + Secret Access Key
|
||||
- Sets `CLAUDE_CODE_USE_BEDROCK=1` to enable Claude Code's native Bedrock support
|
||||
- `ANTHROPIC_BASE_URL` templated with `${AWS_REGION}` for region flexibility
|
||||
- Default region: `us-west-2` (user-configurable)
|
||||
|
||||
**AWS Bedrock (API Key)**
|
||||
- Authentication via Bedrock API Key
|
||||
- Same Bedrock URL templating and model defaults
|
||||
- Simpler setup for users with Bedrock API Key access
|
||||
|
||||
### OpenCode Preset (1 new preset)
|
||||
|
||||
**AWS Bedrock**
|
||||
- Added `@ai-sdk/amazon-bedrock` to `opencodeNpmPackages` list
|
||||
- Added 6 model variants to `OPENCODE_PRESET_MODEL_VARIANTS`
|
||||
- Uses `region`, `accessKeyId`, `secretAccessKey` options (matching `@ai-sdk/amazon-bedrock` API)
|
||||
|
||||
### Default Models
|
||||
|
||||
All presets include cross-region inference model IDs:
|
||||
|
||||
| Model | ID |
|
||||
|-------|----|
|
||||
| Claude Opus 4.6 | `global.anthropic.claude-opus-4-6-v1` |
|
||||
| Claude Sonnet 4.5 | `global.anthropic.claude-sonnet-4-5-20250929-v1:0` |
|
||||
| Claude Haiku 4.5 | `global.anthropic.claude-haiku-4-5-20251001-v1:0` |
|
||||
| Amazon Nova Pro | `us.amazon.nova-pro-v1:0` |
|
||||
| Meta Llama 4 Maverick | `us.meta.llama4-maverick-17b-instruct-v1:0` |
|
||||
| DeepSeek R1 | `us.deepseek.r1-v1:0` |
|
||||
|
||||
Users can manually enter any Bedrock model ID, including `global.*`, `us.*`, `eu.*`, `apac.*` cross-region profiles.
|
||||
|
||||
## Files Changed
|
||||
|
||||
```
|
||||
src/types.ts | +1 (add cloud_provider category)
|
||||
src/config/claudeProviderPresets.ts | +75 (2 Bedrock presets)
|
||||
src/config/opencodeProviderPresets.ts | +93 (npm pkg + model variants + preset)
|
||||
tests/config/claudeProviderPresets.test.ts | +79 (11 tests)
|
||||
tests/config/opencodeProviderPresets.test.ts | +68 (8 tests)
|
||||
```
|
||||
|
||||
**Total: 5 files, +316 lines, 0 deletions**
|
||||
|
||||
## Testing
|
||||
|
||||
- 19 new unit tests (11 Claude + 8 OpenCode)
|
||||
- All 159/159 existing tests pass
|
||||
- TypeScript typecheck passes
|
||||
- No Rust backend changes required
|
||||
|
||||
## Commits
|
||||
|
||||
```
|
||||
a1b518f feat: add cloud_provider category to ProviderCategory type
|
||||
6381e2f feat: add AWS Bedrock (AKSK) Claude Code provider preset with tests
|
||||
5e18fb8 feat: add AWS Bedrock (API Key) Claude Code provider preset with tests
|
||||
9ff2939 feat: add AWS Bedrock OpenCode provider preset with @ai-sdk/amazon-bedrock
|
||||
```
|
||||
|
||||
## Architecture Decision
|
||||
|
||||
**Preset-Only integration** (no Rust backend changes):
|
||||
- Claude Code natively handles Bedrock SigV4 signing when `CLAUDE_CODE_USE_BEDROCK=1` is set
|
||||
- OpenCode uses `@ai-sdk/amazon-bedrock` which handles AWS authentication natively
|
||||
- Minimal risk, consistent with existing provider architecture
|
||||
- Future: Codex and Gemini CLI support would require proxy-layer changes (out of scope)
|
||||
Reference in New Issue
Block a user