mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-13 19:46:16 +03:00
refactor(core): remove dead AISDK hooks (#48523)
This commit is contained in:
committed by
GitHub
Unverified
parent
923bda07a2
commit
6e8ff0c2b7
@@ -1,6 +1,5 @@
|
||||
import { AlibabaPlugin } from "./provider/alibaba.js"
|
||||
import { AmazonBedrockPlugin } from "./provider/amazon-bedrock.js"
|
||||
import { AnthropicPlugin } from "./provider/anthropic.js"
|
||||
import { AzurePlugin } from "./provider/azure.js"
|
||||
import { CerebrasPlugin } from "./provider/cerebras.js"
|
||||
import { CloudflareAIGatewayPlugin } from "./provider/cloudflare-ai-gateway.js"
|
||||
@@ -15,7 +14,6 @@ import { GoogleVertexPlugin } from "./provider/google-vertex.js"
|
||||
import { KiloPlugin } from "./provider/kilo.js"
|
||||
import { LLMGatewayPlugin } from "./provider/llmgateway.js"
|
||||
import { LMStudioPlugin } from "./provider/lmstudio.js"
|
||||
import { MistralPlugin } from "./provider/mistral.js"
|
||||
import { ModalPlugin } from "./provider/modal.js"
|
||||
import { NvidiaPlugin } from "./provider/nvidia.js"
|
||||
import { OllamaPlugin } from "./provider/ollama.js"
|
||||
@@ -37,7 +35,6 @@ import type { PluginInternal } from "./internal.js"
|
||||
export const ProviderPlugins: PluginInternal.InternalPlugin[] = [
|
||||
AlibabaPlugin,
|
||||
AmazonBedrockPlugin,
|
||||
AnthropicPlugin,
|
||||
AzurePlugin,
|
||||
CerebrasPlugin,
|
||||
CloudflareAIGatewayPlugin,
|
||||
@@ -51,7 +48,6 @@ export const ProviderPlugins: PluginInternal.InternalPlugin[] = [
|
||||
KiloPlugin,
|
||||
LLMGatewayPlugin,
|
||||
LMStudioPlugin,
|
||||
MistralPlugin,
|
||||
ModalPlugin,
|
||||
NvidiaPlugin,
|
||||
OllamaPlugin,
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { Effect } from "effect"
|
||||
import { define } from "@opencode/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider.js"
|
||||
|
||||
export const AnthropicPlugin = define({
|
||||
id: "opencode.provider.anthropic",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/anthropic") continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
provider.headers = {
|
||||
...provider.headers,
|
||||
"anthropic-beta": "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14",
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
yield* ctx.aisdk.hook(
|
||||
"sdk",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.package !== "@ai-sdk/anthropic") return
|
||||
const mod = yield* Effect.promise(() => import("@ai-sdk/anthropic"))
|
||||
evt.sdk = mod.createAnthropic(evt.options)
|
||||
}),
|
||||
)
|
||||
}),
|
||||
})
|
||||
@@ -24,14 +24,6 @@ const decodeToken = Schema.decodeUnknownEffect(
|
||||
expiresOn: Schema.optional(Schema.NonEmptyString),
|
||||
}),
|
||||
)
|
||||
function selectLanguage(sdk: any, modelID: string, useChat: boolean) {
|
||||
if (useChat && sdk.chat) return sdk.chat(modelID)
|
||||
if (sdk.responses) return sdk.responses(modelID)
|
||||
if (sdk.messages) return sdk.messages(modelID)
|
||||
if (sdk.chat) return sdk.chat(modelID)
|
||||
return sdk.languageModel(modelID)
|
||||
}
|
||||
|
||||
export const AzurePlugin = define({
|
||||
id: "opencode.provider.azure",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
@@ -201,35 +193,6 @@ export const AzurePlugin = define({
|
||||
}),
|
||||
{ providerID: Provider.ID.azure },
|
||||
)
|
||||
|
||||
yield* ctx.aisdk.hook(
|
||||
"sdk",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.package !== "@ai-sdk/azure") return
|
||||
if (evt.model.providerID === Provider.ID.azure) {
|
||||
if (
|
||||
!evt.options.resourceName &&
|
||||
!evt.options.baseURL &&
|
||||
(!Provider.isAISDK(evt.model.package) || typeof evt.model.settings?.baseURL !== "string")
|
||||
) {
|
||||
throw new Error("Azure resource name is missing; set AZURE_RESOURCE_NAME or configure resourceName/baseURL")
|
||||
}
|
||||
}
|
||||
const mod = yield* Effect.promise(() => import("@ai-sdk/azure"))
|
||||
evt.sdk = mod.createAzure(evt.options)
|
||||
}),
|
||||
)
|
||||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== Provider.ID.azure) return
|
||||
evt.language = selectLanguage(
|
||||
evt.sdk,
|
||||
evt.model.modelID ?? evt.model.id,
|
||||
Boolean(evt.options.useCompletionUrls),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}),
|
||||
})
|
||||
|
||||
|
||||
@@ -92,33 +92,6 @@ export const GoogleVertexPlugin = define({
|
||||
evt.options.fetch = authFetch(evt.options.fetch)
|
||||
return
|
||||
}
|
||||
if (evt.package === "@ai-sdk/google-vertex/anthropic") {
|
||||
const mod = yield* Effect.promise(() => import("@ai-sdk/google-vertex/anthropic"))
|
||||
const project = resolveProject(evt.options)
|
||||
const location = String(resolveLocation(evt.options))
|
||||
const regionalBaseURL =
|
||||
(location === "eu" || location === "us") && project && !evt.options.baseURL
|
||||
? `https://aiplatform.${location}.rep.googleapis.com/v1/projects/${project}/locations/${location}/publishers/anthropic/models`
|
||||
: undefined
|
||||
evt.sdk = mod.createVertexAnthropic({
|
||||
...evt.options,
|
||||
project,
|
||||
location,
|
||||
...(regionalBaseURL ? { baseURL: regionalBaseURL } : {}),
|
||||
})
|
||||
return
|
||||
}
|
||||
if (evt.package !== "@ai-sdk/google-vertex") return
|
||||
const mod = yield* Effect.promise(() => import("@ai-sdk/google-vertex"))
|
||||
const project = resolveProject(evt.options)
|
||||
const location = resolveLocation(evt.options)
|
||||
const options = { ...evt.options }
|
||||
delete options.fetch
|
||||
evt.sdk = mod.createVertex({
|
||||
...options,
|
||||
project,
|
||||
location,
|
||||
})
|
||||
}),
|
||||
)
|
||||
yield* ctx.aisdk.hook(
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { createProviderPlugin } from "./factory.js"
|
||||
|
||||
export const MistralPlugin = createProviderPlugin({
|
||||
id: "opencode.provider.mistral",
|
||||
package: "@ai-sdk/mistral",
|
||||
load: async (options) => {
|
||||
const { createMistral } = await import("@ai-sdk/mistral")
|
||||
return createMistral(options)
|
||||
},
|
||||
})
|
||||
@@ -1,86 +0,0 @@
|
||||
import { AISDK } from "@opencode/core/aisdk"
|
||||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Catalog } from "@opencode/core/catalog"
|
||||
import { Model } from "@opencode/core/model"
|
||||
import { Plugin } from "@opencode/core/plugin"
|
||||
import { PluginHost } from "@opencode/core/plugin/host"
|
||||
import { AnthropicPlugin } from "@opencode/core/plugin/provider/anthropic"
|
||||
import { Provider } from "@opencode/core/provider"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import { PluginTestLayer } from "./fixture"
|
||||
|
||||
const it = testEffect(PluginTestLayer)
|
||||
|
||||
const addPlugin = Effect.fn(function* () {
|
||||
const plugin = yield* Plugin.Service
|
||||
const host = yield* PluginHost.make(plugin)
|
||||
yield* AnthropicPlugin.effect(host)
|
||||
})
|
||||
|
||||
function required<T>(value: T | undefined): T {
|
||||
if (value === undefined) throw new Error("Expected value")
|
||||
return value
|
||||
}
|
||||
|
||||
describe("AnthropicPlugin", () => {
|
||||
it.effect("applies legacy beta headers", () =>
|
||||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => {
|
||||
catalog.provider.update(Provider.ID.anthropic, (draft) => {
|
||||
draft.package = Provider.aisdk("@ai-sdk/anthropic")
|
||||
draft.headers = { Existing: "1" }
|
||||
})
|
||||
})
|
||||
yield* addPlugin()
|
||||
expect(required(yield* catalog.provider.get(Provider.ID.anthropic)).headers?.["anthropic-beta"]).toBe(
|
||||
"interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14",
|
||||
)
|
||||
expect(required(yield* catalog.provider.get(Provider.ID.anthropic)).headers?.Existing).toBe("1")
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("ignores non-Anthropic providers", () =>
|
||||
Effect.gen(function* () {
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) => catalog.provider.update(Provider.ID.openai, () => {}))
|
||||
yield* addPlugin()
|
||||
expect(required(yield* catalog.provider.get(Provider.ID.openai)).headers?.["anthropic-beta"]).toBeUndefined()
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("creates Anthropic SDKs with the model provider ID as the SDK name", () =>
|
||||
Effect.gen(function* () {
|
||||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.make("custom-anthropic"), Model.ID.make("claude-sonnet-4-5")),
|
||||
modelID: Model.ID.make("claude-sonnet-4-5"),
|
||||
package: Provider.aisdk("@ai-sdk/anthropic"),
|
||||
}),
|
||||
package: "@ai-sdk/anthropic",
|
||||
options: { name: "custom-anthropic", apiKey: "test" },
|
||||
})
|
||||
expect(result.sdk.languageModel("claude-sonnet-4-5").provider).toBe("custom-anthropic")
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("uses the Anthropic provider ID as the SDK name for the bundled Anthropic provider", () =>
|
||||
Effect.gen(function* () {
|
||||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.anthropic, Model.ID.make("claude-sonnet-4-5")),
|
||||
modelID: Model.ID.make("claude-sonnet-4-5"),
|
||||
package: Provider.aisdk("@ai-sdk/anthropic"),
|
||||
}),
|
||||
package: "@ai-sdk/anthropic",
|
||||
options: { name: "anthropic", apiKey: "test" },
|
||||
})
|
||||
expect(result.sdk.languageModel("claude-sonnet-4-5").provider).toBe("anthropic")
|
||||
}),
|
||||
)
|
||||
})
|
||||
@@ -1,6 +1,5 @@
|
||||
import { chmod } from "node:fs/promises"
|
||||
import { Agent } from "@opencode/core/agent"
|
||||
import { AISDK } from "@opencode/core/aisdk"
|
||||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Schedule } from "effect"
|
||||
import { Catalog } from "@opencode/core/catalog"
|
||||
@@ -15,7 +14,6 @@ import { Integration } from "@opencode/core/integration"
|
||||
import { Location } from "@opencode/core/location"
|
||||
import { Session } from "@opencode/core/session"
|
||||
import { AppProcess } from "@opencode/util/process"
|
||||
import { fakeSelectorSdk } from "../fixture/selector"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import { PluginTestLayer } from "./fixture"
|
||||
|
||||
@@ -422,36 +420,6 @@ describe("AzurePlugin", () => {
|
||||
),
|
||||
)
|
||||
|
||||
it.effect("allows configured baseURL without resourceName", () =>
|
||||
withEnv({ AZURE_RESOURCE_NAME: undefined }, () =>
|
||||
Effect.gen(function* () {
|
||||
const aisdk = yield* AISDK.Service
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) =>
|
||||
catalog.provider.update(Provider.ID.azure, (provider) => {
|
||||
provider.settings = { ...provider.settings, baseURL: "https://proxy.example.com/openai" }
|
||||
}),
|
||||
)
|
||||
yield* addPlugin()
|
||||
const integrations = yield* Integration.Service
|
||||
expect((yield* integrations.get(Integration.ID.make("azure")))?.methods).toContainEqual({
|
||||
type: "key",
|
||||
label: "API key",
|
||||
})
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.azure, Model.ID.make("deployment")),
|
||||
modelID: Model.ID.make("deployment"),
|
||||
package: Provider.aisdk("test-provider"),
|
||||
}),
|
||||
package: "@ai-sdk/azure",
|
||||
options: { name: "azure", baseURL: "https://proxy.example.com/openai" },
|
||||
})
|
||||
expect(result.sdk).toBeDefined()
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
it.effect("marks only Azure v1 Responses deployments as WebSocket capable", () =>
|
||||
withEnv({ AZURE_RESOURCE_NAME: undefined, AZURE_COGNITIVE_SERVICES_RESOURCE_NAME: undefined }, () =>
|
||||
Effect.gen(function* () {
|
||||
@@ -500,138 +468,4 @@ describe("AzurePlugin", () => {
|
||||
),
|
||||
)
|
||||
|
||||
it.effect("rejects missing resourceName when baseURL is not configured", () =>
|
||||
withEnv({ AZURE_RESOURCE_NAME: undefined }, () =>
|
||||
Effect.gen(function* () {
|
||||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const exit = yield* aisdk
|
||||
.runSDK({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.azure, Model.ID.make("deployment")),
|
||||
modelID: Model.ID.make("deployment"),
|
||||
package: Provider.aisdk("test-provider"),
|
||||
}),
|
||||
package: "@ai-sdk/azure",
|
||||
options: { name: "azure" },
|
||||
})
|
||||
.pipe(Effect.exit)
|
||||
expect(exit._tag).toBe("Failure")
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
it.effect("selects chat only for completion URLs", () =>
|
||||
Effect.gen(function* () {
|
||||
const aisdk = yield* AISDK.Service
|
||||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.azure, Model.ID.make("deployment")),
|
||||
modelID: Model.ID.make("deployment"),
|
||||
package: Provider.aisdk("test-provider"),
|
||||
}),
|
||||
sdk: fakeSelectorSdk(calls),
|
||||
options: { useCompletionUrls: true },
|
||||
})
|
||||
expect(calls).toEqual(["chat:deployment"])
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("selects chat from per-call useCompletionUrls", () =>
|
||||
Effect.gen(function* () {
|
||||
const aisdk = yield* AISDK.Service
|
||||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.azure, Model.ID.make("deployment")),
|
||||
modelID: Model.ID.make("deployment"),
|
||||
package: Provider.aisdk("test-provider"),
|
||||
}),
|
||||
sdk: fakeSelectorSdk(calls),
|
||||
options: { useCompletionUrls: true },
|
||||
})
|
||||
expect(calls).toEqual(["chat:deployment"])
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("ignores model useCompletionUrls when per-call option is unset", () =>
|
||||
Effect.gen(function* () {
|
||||
const aisdk = yield* AISDK.Service
|
||||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.azure, Model.ID.make("deployment")),
|
||||
modelID: Model.ID.make("deployment"),
|
||||
package: Provider.aisdk("test-provider"),
|
||||
body: { useCompletionUrls: true },
|
||||
}),
|
||||
sdk: fakeSelectorSdk(calls),
|
||||
options: {},
|
||||
})
|
||||
expect(calls).toEqual(["responses:deployment"])
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("uses the legacy Azure selector order and provider guard", () =>
|
||||
Effect.gen(function* () {
|
||||
const aisdk = yield* AISDK.Service
|
||||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.azure, Model.ID.make("deployment")),
|
||||
modelID: Model.ID.make("deployment"),
|
||||
package: Provider.aisdk("test-provider"),
|
||||
}),
|
||||
sdk: fakeSelectorSdk(calls),
|
||||
options: {},
|
||||
})
|
||||
const ignored = yield* aisdk.runLanguage({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.openai, Model.ID.make("deployment")),
|
||||
modelID: Model.ID.make("deployment"),
|
||||
package: Provider.aisdk("test-provider"),
|
||||
}),
|
||||
sdk: fakeSelectorSdk(calls),
|
||||
options: {},
|
||||
})
|
||||
expect(calls).toEqual(["responses:deployment"])
|
||||
expect(ignored.language).toBeUndefined()
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("falls back through the legacy Azure selector order", () =>
|
||||
Effect.gen(function* () {
|
||||
const aisdk = yield* AISDK.Service
|
||||
const calls: string[] = []
|
||||
const make = (method: string) => (id: string) => {
|
||||
calls.push(`${method}:${id}`)
|
||||
return { modelId: id, provider: method, specificationVersion: "v3" }
|
||||
}
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.azure, Model.ID.make("messages-deployment")),
|
||||
modelID: Model.ID.make("messages-deployment"),
|
||||
package: Provider.aisdk("test-provider"),
|
||||
}),
|
||||
sdk: { messages: make("messages"), chat: make("chat"), languageModel: make("languageModel") },
|
||||
options: {},
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.azure, Model.ID.make("language-deployment")),
|
||||
modelID: Model.ID.make("language-deployment"),
|
||||
package: Provider.aisdk("test-provider"),
|
||||
}),
|
||||
sdk: { languageModel: make("languageModel") },
|
||||
options: {},
|
||||
})
|
||||
expect(calls).toEqual(["messages:messages-deployment", "languageModel:language-deployment"])
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -7,7 +7,6 @@ import { PluginHost } from "@opencode/core/plugin/host"
|
||||
import { AlibabaPlugin } from "@opencode/core/plugin/provider/alibaba"
|
||||
import { CoherePlugin } from "@opencode/core/plugin/provider/cohere"
|
||||
import { GatewayPlugin } from "@opencode/core/plugin/provider/gateway"
|
||||
import { MistralPlugin } from "@opencode/core/plugin/provider/mistral"
|
||||
import { PerplexityPlugin } from "@opencode/core/plugin/provider/perplexity"
|
||||
import { VenicePlugin } from "@opencode/core/plugin/provider/venice"
|
||||
import { Provider } from "@opencode/core/provider"
|
||||
@@ -20,7 +19,6 @@ const providers = [
|
||||
{ id: "alibaba", plugin: AlibabaPlugin, package: "@ai-sdk/alibaba", provider: "alibaba.chat" },
|
||||
{ id: "cohere", plugin: CoherePlugin, package: "@ai-sdk/cohere", provider: "cohere.chat" },
|
||||
{ id: "gateway", plugin: GatewayPlugin, package: "@ai-sdk/gateway", provider: "gateway" },
|
||||
{ id: "mistral", plugin: MistralPlugin, package: "@ai-sdk/mistral", provider: "mistral.chat" },
|
||||
{ id: "perplexity", plugin: PerplexityPlugin, package: "@ai-sdk/perplexity", provider: "perplexity" },
|
||||
{ id: "venice", plugin: VenicePlugin, package: "venice-ai-sdk-provider", provider: "custom-provider.chat" },
|
||||
] as const
|
||||
|
||||
@@ -11,7 +11,6 @@ import { fakeSelectorSdk } from "../fixture/selector"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import { PluginTestLayer } from "./fixture"
|
||||
|
||||
const vertexOptions: Record<string, any>[] = []
|
||||
const googleAuthOptions: Record<string, any>[] = []
|
||||
const it = testEffect(PluginTestLayer)
|
||||
|
||||
@@ -48,15 +47,6 @@ function withEnv<A, E, R>(vars: Record<string, string | undefined>, effect: () =
|
||||
)
|
||||
}
|
||||
|
||||
void mock.module("@ai-sdk/google-vertex", () => ({
|
||||
createVertex: (options: Record<string, any>) => {
|
||||
vertexOptions.push(options)
|
||||
return {
|
||||
languageModel: (modelID: string) => ({ modelID, provider: "google-vertex", specificationVersion: "v3" }),
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
||||
void mock.module("google-auth-library", () => ({
|
||||
GoogleAuth: class {
|
||||
constructor(options: Record<string, any>) {
|
||||
@@ -187,9 +177,6 @@ describe("GoogleVertexPlugin", () => {
|
||||
},
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
vertexOptions.length = 0
|
||||
const plugin = yield* Plugin.Service
|
||||
const aisdk = yield* AISDK.Service
|
||||
const catalog = yield* Catalog.Service
|
||||
yield* catalog.transform((catalog) =>
|
||||
catalog.provider.update(Provider.ID.make("google-vertex"), (provider) => {
|
||||
@@ -203,15 +190,6 @@ describe("GoogleVertexPlugin", () => {
|
||||
)
|
||||
yield* addPlugin()
|
||||
const provider = required(yield* catalog.provider.get(Provider.ID.make("google-vertex")))
|
||||
yield* aisdk.runSDK({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.make("google-vertex"), Model.ID.make("gemini")),
|
||||
modelID: Model.ID.make("gemini"),
|
||||
package: "aisdk:@ai-sdk/google-vertex",
|
||||
}),
|
||||
package: "@ai-sdk/google-vertex",
|
||||
options: { name: "google-vertex" },
|
||||
})
|
||||
|
||||
expect(provider.settings?.project).toBe("vertex-project")
|
||||
expect(provider).toMatchObject({
|
||||
@@ -221,8 +199,6 @@ describe("GoogleVertexPlugin", () => {
|
||||
"https://europe-west4-aiplatform.googleapis.com/v1/projects/vertex-project/locations/europe-west4",
|
||||
},
|
||||
})
|
||||
expect(vertexOptions[0].project).toBe("vertex-project")
|
||||
expect(vertexOptions[0].location).toBe("europe-west4")
|
||||
}),
|
||||
),
|
||||
)
|
||||
@@ -316,56 +292,6 @@ describe("GoogleVertexPlugin", () => {
|
||||
),
|
||||
)
|
||||
|
||||
it.effect("does not pass Google auth fetch to the native Vertex SDK", () =>
|
||||
withEnv(
|
||||
{
|
||||
GOOGLE_CLOUD_PROJECT: "env-project",
|
||||
GOOGLE_VERTEX_LOCATION: "env-location",
|
||||
},
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
vertexOptions.length = 0
|
||||
const plugin = yield* Plugin.Service
|
||||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runSDK({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.make("google-vertex"), Model.ID.make("gemini")),
|
||||
modelID: Model.ID.make("gemini"),
|
||||
package: "aisdk:@ai-sdk/google-vertex",
|
||||
}),
|
||||
package: "@ai-sdk/google-vertex",
|
||||
options: { name: "google-vertex" },
|
||||
})
|
||||
expect(vertexOptions).toHaveLength(1)
|
||||
expect(vertexOptions[0].project).toBe("env-project")
|
||||
expect(vertexOptions[0].location).toBe("env-location")
|
||||
expect(vertexOptions[0].fetch).toBeUndefined()
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
it.effect("creates Anthropic SDKs for canonical Google Vertex models", () =>
|
||||
Effect.gen(function* () {
|
||||
const plugin = yield* Plugin.Service
|
||||
const aisdk = yield* AISDK.Service
|
||||
yield* addPlugin()
|
||||
const result = yield* aisdk.runSDK({
|
||||
model: Model.Info.make({
|
||||
...Model.Info.default(Provider.ID.googleVertex, Model.ID.make("claude-sonnet-4-6@default")),
|
||||
modelID: Model.ID.make("claude-sonnet-4-6@default"),
|
||||
package: "aisdk:@ai-sdk/google-vertex/anthropic",
|
||||
}),
|
||||
package: "@ai-sdk/google-vertex/anthropic",
|
||||
options: { name: "google-vertex", project: "project", location: "eu" },
|
||||
})
|
||||
|
||||
expect(result.sdk.languageModel("claude-sonnet-4-6@default").config.baseURL).toBe(
|
||||
"https://aiplatform.eu.rep.googleapis.com/v1/projects/project/locations/eu/publishers/anthropic/models",
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("wraps an injected transport with Google auth for OpenAI-compatible Vertex endpoints", () =>
|
||||
Effect.gen(function* () {
|
||||
googleAuthOptions.length = 0
|
||||
|
||||
Reference in New Issue
Block a user