Skip to content

Commit 91c4da5

Browse files
Dizzzmasthdxr
andauthored
fix(anomalyco#243): claude on aws bedrock (anomalyco#241)
Co-authored-by: Dax Raad <d@ironbay.co>
1 parent 2fd0e7d commit 91c4da5

File tree

3 files changed

+103
-25
lines changed

3 files changed

+103
-25
lines changed

bun.lock

Lines changed: 47 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/opencode/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
"./*": "./src/*.ts"
1313
},
1414
"devDependencies": {
15+
"@ai-sdk/amazon-bedrock": "2.2.10",
16+
"@ai-sdk/anthropic": "1.2.12",
1517
"@tsconfig/bun": "1.0.7",
1618
"@types/bun": "latest",
1719
"@types/turndown": "5.0.5",
1820
"@types/yargs": "17.0.33",
1921
"typescript": "catalog:",
20-
"zod-to-json-schema": "3.24.5",
21-
"@ai-sdk/anthropic": "1.2.12"
22+
"zod-to-json-schema": "3.24.5"
2223
},
2324
"dependencies": {
2425
"@clack/prompts": "0.11.0",

packages/opencode/src/provider/provider.ts

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@ import { TaskTool } from "../tool/task"
2727
export namespace Provider {
2828
const log = Log.create({ service: "provider" })
2929

30-
type CustomLoader = (
31-
provider: ModelsDev.Provider,
32-
) => Promise<Record<string, any> | false>
30+
type CustomLoader = (provider: ModelsDev.Provider) => Promise<
31+
| {
32+
getModel?: (sdk: any, modelID: string) => Promise<any>
33+
options: Record<string, any>
34+
}
35+
| false
36+
>
3337

3438
type Source = "env" | "config" | "custom" | "api"
3539

@@ -44,30 +48,52 @@ export namespace Provider {
4448
}
4549
}
4650
return {
47-
apiKey: "",
48-
async fetch(input: any, init: any) {
49-
const access = await AuthAnthropic.access()
50-
const headers = {
51-
...init.headers,
52-
authorization: `Bearer ${access}`,
53-
"anthropic-beta": "oauth-2025-04-20",
54-
}
55-
delete headers["x-api-key"]
56-
return fetch(input, {
57-
...init,
58-
headers,
59-
})
51+
options: {
52+
apiKey: "",
53+
async fetch(input: any, init: any) {
54+
const access = await AuthAnthropic.access()
55+
const headers = {
56+
...init.headers,
57+
authorization: `Bearer ${access}`,
58+
"anthropic-beta": "oauth-2025-04-20",
59+
}
60+
delete headers["x-api-key"]
61+
return fetch(input, {
62+
...init,
63+
headers,
64+
})
65+
},
6066
},
6167
}
6268
},
69+
openai: async () => {
70+
return {
71+
async getModel(sdk: any, modelID: string) {
72+
return sdk.responses(modelID)
73+
},
74+
options: {},
75+
}
76+
},
6377
"amazon-bedrock": async () => {
64-
if (!process.env["AWS_PROFILE"]) return false
78+
if (!process.env["AWS_PROFILE"]) false
79+
80+
const region = process.env["AWS_REGION"] ?? "us-east-1"
81+
6582
const { fromNodeProviderChain } = await import(
6683
await BunProc.install("@aws-sdk/credential-providers")
6784
)
6885
return {
69-
region: process.env["AWS_REGION"] ?? "us-east-1",
70-
credentialProvider: fromNodeProviderChain(),
86+
options: {
87+
region,
88+
credentialProvider: fromNodeProviderChain(),
89+
},
90+
async getModel(sdk: any, modelID: string) {
91+
if (modelID.includes("claude")) {
92+
const prefix = region.split("-")[0]
93+
modelID = `${prefix}.${modelID}`
94+
}
95+
return sdk.languageModel(modelID)
96+
},
7197
}
7298
},
7399
}
@@ -80,6 +106,7 @@ export namespace Provider {
80106
[providerID: string]: {
81107
source: Source
82108
info: ModelsDev.Provider
109+
getModel?: (sdk: any, modelID: string) => Promise<any>
83110
options: Record<string, any>
84111
}
85112
} = {}
@@ -95,6 +122,7 @@ export namespace Provider {
95122
id: string,
96123
options: Record<string, any>,
97124
source: Source,
125+
getModel?: (sdk: any, modelID: string) => Promise<any>,
98126
) {
99127
const provider = providers[id]
100128
if (!provider) {
@@ -110,6 +138,7 @@ export namespace Provider {
110138
}
111139
provider.options = mergeDeep(provider.options, options)
112140
provider.source = source
141+
provider.getModel = getModel ?? provider.getModel
113142
}
114143

115144
const configProviders = Object.entries(config.provider ?? {})
@@ -173,7 +202,8 @@ export namespace Provider {
173202
for (const [providerID, fn] of Object.entries(CUSTOM_LOADERS)) {
174203
if (disabled.has(providerID)) continue
175204
const result = await fn(database[providerID])
176-
if (result) mergeProvider(providerID, result, "custom")
205+
if (result)
206+
mergeProvider(providerID, result.options, "custom", result.getModel)
177207
}
178208

179209
// load config
@@ -236,9 +266,9 @@ export namespace Provider {
236266
const sdk = await getSDK(provider.info)
237267

238268
try {
239-
const language =
240-
// @ts-expect-error
241-
"responses" in sdk ? sdk.responses(modelID) : sdk.languageModel(modelID)
269+
const language = provider.getModel
270+
? await provider.getModel(sdk, modelID)
271+
: sdk.languageModel(modelID)
242272
log.info("found", { providerID, modelID })
243273
s.models.set(key, {
244274
info,

0 commit comments

Comments
 (0)