feat(llm): add compatible and vertex provider entrypoints (#36900)
This commit is contained in:
parent
22334b94c8
commit
4f1298063b
22 changed files with 860 additions and 53 deletions
|
|
@ -191,11 +191,7 @@ export const fromCatalogModel = (
|
|||
const packageName = ProviderV2.packageName(resolved.package)
|
||||
const key = apiKey(resolved, credential)
|
||||
|
||||
if (
|
||||
OpenAICodex.isChatGPT(credential) &&
|
||||
!ProviderV2.isAISDK(resolved.package) &&
|
||||
isNativeOpenAI(resolved.package)
|
||||
) {
|
||||
if (OpenAICodex.isChatGPT(credential) && !ProviderV2.isAISDK(resolved.package) && isNativeOpenAI(resolved.package)) {
|
||||
return Effect.succeed(codexModel(resolved, credential, key))
|
||||
}
|
||||
|
||||
|
|
@ -243,11 +239,10 @@ export const fromCatalogModel = (
|
|||
const module = yield* (dependencies.loadPackage ?? ProviderV2.loadPackage)(specifier).pipe(
|
||||
Effect.mapError(() => unsupported(resolved)),
|
||||
)
|
||||
const configured = { ...resolved.settings, ...credential?.metadata }
|
||||
const settings = {
|
||||
...resolved.settings,
|
||||
...(credential?.type === "key" ? { apiKey: credential.key } : {}),
|
||||
...(credential?.type === "oauth" ? { apiKey: credential.access } : {}),
|
||||
...credential?.metadata,
|
||||
...(credential ? withoutNativeAuthSettings(configured) : configured),
|
||||
...nativeCredentialSettings(specifier, credential),
|
||||
headers: resolved.headers,
|
||||
body: resolved.body,
|
||||
limits: { context: resolved.limit.context, output: resolved.limit.output },
|
||||
|
|
@ -264,6 +259,27 @@ const isNativeOpenAI = (packageName: string | undefined) =>
|
|||
packageName === "@opencode-ai/llm/providers/openai" ||
|
||||
packageName?.startsWith("@opencode-ai/llm/providers/openai/") === true
|
||||
|
||||
const nativeCredentialSettings = (specifier: string, credential: Credential.Value | undefined) => {
|
||||
if (!credential) return {}
|
||||
if (credential.type === "key") return { apiKey: credential.key }
|
||||
if (
|
||||
specifier === "@opencode-ai/llm/providers/anthropic" ||
|
||||
specifier === "@opencode-ai/llm/providers/anthropic-compatible"
|
||||
)
|
||||
return { authToken: credential.access }
|
||||
if (
|
||||
specifier === "@opencode-ai/llm/providers/google-vertex" ||
|
||||
specifier.startsWith("@opencode-ai/llm/providers/google-vertex/")
|
||||
)
|
||||
return { accessToken: credential.access }
|
||||
return { apiKey: credential.access }
|
||||
}
|
||||
|
||||
const withoutNativeAuthSettings = (settings: Record<string, unknown>) => {
|
||||
const { accessToken: _accessToken, apiKey: _apiKey, authToken: _authToken, ...rest } = settings
|
||||
return rest
|
||||
}
|
||||
|
||||
const codexModel = (
|
||||
model: ModelV2.Info,
|
||||
credential: Credential.Value | undefined,
|
||||
|
|
|
|||
|
|
@ -540,6 +540,42 @@ describe("SessionRunnerModel", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("maps OAuth credentials to native provider auth settings", () =>
|
||||
Effect.gen(function* () {
|
||||
const native = yield* SessionRunnerModel.fromCatalogModel(
|
||||
model(ProviderV2.aisdk("@ai-sdk/openai"), {
|
||||
settings: { baseURL: "https://openai.example/v1" },
|
||||
}),
|
||||
)
|
||||
const credential = Credential.OAuth.make({
|
||||
type: "oauth",
|
||||
methodID: Integration.MethodID.make("device"),
|
||||
access: "oauth-token",
|
||||
refresh: "refresh",
|
||||
expires: Date.now() + 60_000,
|
||||
})
|
||||
const packages = [
|
||||
["@opencode-ai/llm/providers/google-vertex", "accessToken"],
|
||||
["@opencode-ai/llm/providers/google-vertex/anthropic", "accessToken"],
|
||||
["@opencode-ai/llm/providers/anthropic", "authToken"],
|
||||
["@opencode-ai/llm/providers/anthropic-compatible", "authToken"],
|
||||
] as const
|
||||
|
||||
yield* Effect.forEach(packages, ([specifier, key]) =>
|
||||
SessionRunnerModel.fromCatalogModel(model(specifier, { settings: { apiKey: "configured-key" } }), credential, {
|
||||
loadPackage: () =>
|
||||
Effect.succeed({
|
||||
model: (modelID, settings) => {
|
||||
expect(settings).toMatchObject({ [key]: "oauth-token" })
|
||||
expect(settings).not.toHaveProperty("apiKey")
|
||||
return Model.make({ id: modelID, provider: "package-provider", route: native.route })
|
||||
},
|
||||
}),
|
||||
}),
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("loads arbitrary AISDK packages through the injected AISDK loader", () =>
|
||||
Effect.gen(function* () {
|
||||
const native = yield* SessionRunnerModel.fromCatalogModel(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue