opencode-crs-bedrock 1.0.2 → 1.0.4
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.
- package/README.md +77 -11
- package/index.ts +55 -11
- package/package.json +6 -2
- 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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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.
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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 {
|
|
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,47 @@ 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
|
-
|
|
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
|
-
|
|
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
|
+
},
|
|
1068
|
+
],
|
|
1027
1069
|
},
|
|
1028
1070
|
};
|
|
1029
1071
|
};
|
|
1072
|
+
|
|
1073
|
+
export default CRSAuthPlugin;
|
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-crs-bedrock",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
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/
|
|
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
|
-
}
|