opencode-crs-bedrock 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +77 -11
  2. package/index.ts +61 -11
  3. package/package.json +6 -2
  4. package/bun.lock +0 -28
package/README.md CHANGED
@@ -45,7 +45,11 @@ npm install -g opencode-crs-bedrock
45
45
 
46
46
  ## Configuration
47
47
 
48
- ### 1. Set Environment Variables
48
+ > **Note**: Both `apiKey` and `baseURL` are optional. You can configure them via environment variables, use `opencode auth login crs` for interactive setup, or configure them directly in the config file.
49
+
50
+ ### Option 1: Using Environment Variables (Recommended)
51
+
52
+ Set environment variables for automatic configuration:
49
53
 
50
54
  ```bash
51
55
  export ANTHROPIC_BASE_URL=https://your-crs-endpoint.com/api
@@ -54,9 +58,7 @@ export ANTHROPIC_AUTH_TOKEN=cr_your_api_key_here
54
58
 
55
59
  Add to your shell profile (`~/.bashrc`, `~/.zshrc`) to persist.
56
60
 
57
- ### 2. Create OpenCode Config
58
-
59
- Create `opencode.json` in your project or `~/.config/opencode/opencode.json` globally:
61
+ Then create `opencode.json` in your project or `~/.config/opencode/opencode.json`:
60
62
 
61
63
  ```json
62
64
  {
@@ -95,7 +97,58 @@ Create `opencode.json` in your project or `~/.config/opencode/opencode.json` glo
95
97
  }
96
98
  ```
97
99
 
98
- ### 3. Use the Model
100
+ ### Option 2: Using OpenCode Auth (Interactive)
101
+
102
+ The plugin supports interactive authentication. First, create the config **without** `baseURL` or `apiKey`:
103
+
104
+ ```json
105
+ {
106
+ "$schema": "https://opencode.ai/config.json",
107
+ "plugin": [
108
+ "opencode-crs-bedrock"
109
+ ],
110
+ "provider": {
111
+ "crs": {
112
+ "npm": "@ai-sdk/anthropic",
113
+ "models": {
114
+ "claude-sonnet-4-5": {
115
+ "name": "Sonnet 4.5 [CRS]",
116
+ "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+ ```
123
+
124
+ Then run the auth login command to store your credentials:
125
+
126
+ ```bash
127
+ opencode auth login crs
128
+ ```
129
+
130
+ OpenCode will prompt you to enter your CRS API key, which will be securely stored. The plugin's auth loader will then be triggered automatically to configure the custom fetch handler for CRS/Bedrock compatibility.
131
+
132
+ ### Option 3: Direct Configuration (No Environment Variables)
133
+
134
+ You can also hardcode credentials directly in the config (not recommended for shared configs):
135
+
136
+ ```json
137
+ {
138
+ "provider": {
139
+ "crs": {
140
+ "npm": "@ai-sdk/anthropic",
141
+ "options": {
142
+ "baseURL": "https://your-crs-endpoint.com/api",
143
+ "apiKey": "cr_your_api_key_here"
144
+ },
145
+ "models": { /* ... */ }
146
+ }
147
+ }
148
+ }
149
+ ```
150
+
151
+ ### Using the Model
99
152
 
100
153
  ```bash
101
154
  # Interactive mode
@@ -185,13 +238,16 @@ CRS API keys start with `cr_`. The plugin uses the `x-api-key` header instead of
185
238
 
186
239
  ### Connection Issues
187
240
 
188
- 1. Verify environment variables:
189
- ```bash
190
- echo $ANTHROPIC_BASE_URL
191
- echo $ANTHROPIC_AUTH_TOKEN
192
- ```
241
+ 1. Check your authentication method:
242
+ - **Environment variables**: Verify they're set:
243
+ ```bash
244
+ echo $ANTHROPIC_BASE_URL
245
+ echo $ANTHROPIC_AUTH_TOKEN
246
+ ```
247
+ - **OpenCode auth**: Run `opencode auth list` to see stored credentials
248
+ - **Direct config**: Check your `opencode.json` has correct values
193
249
 
194
- 2. Test the endpoint:
250
+ 2. Test the endpoint (if using environment variables):
195
251
  ```bash
196
252
  curl -H "x-api-key: $ANTHROPIC_AUTH_TOKEN" "$ANTHROPIC_BASE_URL/v1/messages"
197
253
  ```
@@ -201,6 +257,16 @@ CRS API keys start with `cr_`. The plugin uses the `x-api-key` header instead of
201
257
  CRS_DEBUG_SSE=true opencode run -m crs/claude-sonnet-4-5 "test"
202
258
  ```
203
259
 
260
+ ### Missing API Key or Base URL
261
+
262
+ Both `apiKey` and `baseURL` are **optional** in the plugin:
263
+
264
+ - If **not provided via environment variables or config**, use `opencode auth login crs` to store credentials interactively
265
+ - The plugin defaults to `https://crs.tonob.net/api` if no `baseURL` is specified
266
+ - You can mix and match: set `baseURL` in config and use `opencode auth login` for the `apiKey`, or vice versa
267
+
268
+ **Important**: The plugin's custom fetch handler (which fixes CRS/Bedrock compatibility issues) is only activated when using `opencode auth login` or environment variables. If you hardcode credentials directly in the config, the auth loader may not be triggered.
269
+
204
270
  ## License
205
271
 
206
272
  MIT
package/index.ts CHANGED
@@ -12,8 +12,31 @@
12
12
  * - Bedrock model ID mapping to standard Anthropic format
13
13
  */
14
14
 
15
- import type { Plugin } from "@opencode-ai/plugin";
16
- import type { Auth, Provider } from "@opencode-ai/sdk";
15
+ import type { Plugin, PluginInput } from "@opencode-ai/plugin";
16
+ import type { Provider } from "@opencode-ai/sdk";
17
+
18
+ // ============================================================================
19
+ // Type Definitions for Plugin
20
+ // ============================================================================
21
+
22
+ interface AuthDetails {
23
+ type?: string;
24
+ [key: string]: unknown;
25
+ }
26
+
27
+ type GetAuth = () => Promise<AuthDetails>;
28
+
29
+ interface LoaderResult {
30
+ apiKey?: string;
31
+ baseURL?: string;
32
+ fetch: typeof fetch;
33
+ }
34
+
35
+ type PluginClient = PluginInput["client"];
36
+
37
+ interface PluginContext {
38
+ client: PluginClient;
39
+ }
17
40
 
18
41
  // ============================================================================
19
42
  // Type Definitions
@@ -1004,26 +1027,53 @@ function createCRSFetch(
1004
1027
  /**
1005
1028
  * CRS Auth Plugin for OpenCode
1006
1029
  */
1007
- export const CRSAuthPlugin: Plugin = async () => {
1030
+ export const CRSAuthPlugin: Plugin = async ({ client }: PluginContext) => {
1031
+ debugLog("CRS Bedrock plugin initializing...");
1032
+
1008
1033
  return {
1009
1034
  auth: {
1010
1035
  provider: PROVIDER_ID,
1011
1036
 
1012
- methods: [],
1037
+ loader: async (
1038
+ getAuth: GetAuth,
1039
+ _provider: Provider
1040
+ ): Promise<LoaderResult | Record<string, unknown>> => {
1041
+ debugLog("CRS auth loader called");
1042
+
1043
+ const auth = await getAuth();
1044
+ const apiKey = auth.apiKey as string | undefined;
1045
+ const baseURL = (auth.baseURL as string | undefined) || process.env.ANTHROPIC_BASE_URL || "https://crs.tonob.net/api";
1046
+
1047
+ debugLog("Auth details:", { hasApiKey: !!apiKey, baseURL });
1048
+
1049
+ if (!apiKey) {
1050
+ debugLog("No API key found, returning baseURL only");
1051
+ return { baseURL };
1052
+ }
1013
1053
 
1014
- async loader(
1015
- _getAuth: () => Promise<Auth>,
1016
- provider: Provider
1017
- ) {
1018
- const baseURL = provider?.options?.baseURL as string | undefined;
1019
- const apiKey = provider?.options?.apiKey as string | undefined;
1054
+ debugLog("Returning full config with custom fetch");
1020
1055
 
1021
1056
  return {
1022
1057
  apiKey,
1023
1058
  baseURL,
1024
- fetch: createCRSFetch(apiKey!),
1059
+ fetch: createCRSFetch(apiKey),
1025
1060
  };
1026
1061
  },
1062
+
1063
+ methods: [
1064
+ {
1065
+ label: "Enter CRS API Key",
1066
+ type: "api",
1067
+ prompts: [
1068
+ {
1069
+ type: "text",
1070
+ message: "Enter your CRS API Key",
1071
+ key: "apiKey",
1072
+ },
1073
+ ],
1074
+ },
1075
+ ],
1027
1076
  },
1028
1077
  };
1029
1078
  };
1079
+
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "opencode-crs-bedrock",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "OpenCode plugin for FeedMob CRS proxy to AWS Bedrock Anthropic models",
5
5
  "type": "module",
6
6
  "module": "index.ts",
7
+ "files": [
8
+ "index.ts"
9
+ ],
7
10
  "keywords": [
8
11
  "opencode",
9
12
  "plugin",
@@ -13,7 +16,8 @@
13
16
  "anthropic"
14
17
  ],
15
18
  "dependencies": {
16
- "@opencode-ai/plugin": "^0.4.45"
19
+ "@opencode-ai/sdk": "^1.1.23 ",
20
+ "@opencode-ai/plugin": "^1.1.23"
17
21
  },
18
22
  "devDependencies": {
19
23
  "@types/bun": "latest"
package/bun.lock DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "configVersion": 1,
4
- "workspaces": {
5
- "": {
6
- "name": "opencode-crs-bedrock",
7
- "dependencies": {
8
- "@opencode-ai/plugin": "^0.4.45",
9
- },
10
- "devDependencies": {
11
- "@types/bun": "latest",
12
- },
13
- },
14
- },
15
- "packages": {
16
- "@opencode-ai/plugin": ["@opencode-ai/plugin@0.4.45", "", { "dependencies": { "@opencode-ai/sdk": "0.4.19" } }, "sha512-TuD+FNmA6vN+/B82qayCvOyTXRuAtfvU0U95UKSZoNrYgIBhpD/sW/oS65iUv5QwQqzO8BxI4DYWjmLIqCz8uw=="],
17
-
18
- "@opencode-ai/sdk": ["@opencode-ai/sdk@0.4.19", "", {}, "sha512-7V+wDR1+m+TQZAraAh/bOSObiA/uysG1YIXZVe6gl1sQAXDtkG2FYCzs0gTZ/ORdkUKEnr3vyQIk895Mu0CC/w=="],
19
-
20
- "@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="],
21
-
22
- "@types/node": ["@types/node@22.19.7", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw=="],
23
-
24
- "bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
25
-
26
- "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
27
- }
28
- }