diff --git a/packages/core/src/aisdk.ts b/packages/core/src/aisdk.ts index 3aaf5484ee..9eb47006f0 100644 --- a/packages/core/src/aisdk.ts +++ b/packages/core/src/aisdk.ts @@ -198,23 +198,23 @@ export const locationLayer = Layer.effect( const key = `${model.providerID}/${model.id}/${model.modelID ?? model.id}/${JSON.stringify(model.settings)}` const existing = languages.get(key) if (existing) return existing - if (!model.aisdk) + if (!ProviderV2.isAISDK(model.package)) return yield* new InitError({ providerID: model.providerID, cause: new Error(`Unsupported package ${model.package}`), }) - const options = prepareOptions(model, model.package ?? "") + const packageName = ProviderV2.packageName(model.package) ?? "" + const options = prepareOptions(model, packageName) const sdkKey = JSON.stringify({ providerID: model.providerID, - package: model.package, + package: packageName, settings: model.settings, options, }) const sdk = sdks.get(sdkKey) ?? - (yield* service.runSDK({ model, package: model.package ?? "", options }).pipe(initError(model.providerID))) - .sdk + (yield* service.runSDK({ model, package: packageName, options }).pipe(initError(model.providerID))).sdk if (!sdk) return yield* new InitError({ providerID: model.providerID, diff --git a/packages/core/src/catalog.ts b/packages/core/src/catalog.ts index 51b33cea74..96610b71cc 100644 --- a/packages/core/src/catalog.ts +++ b/packages/core/src/catalog.ts @@ -7,6 +7,7 @@ import { EventV2 } from "./event" import { Policy } from "./policy" import { State } from "./state" import { Integration } from "./integration" +import { ProviderOverlay } from "./provider-overlay" export type ProviderRecord = { provider: ProviderV2.MutableInfo @@ -79,10 +80,9 @@ export const layer = Layer.effect( return ModelV2.Info.make({ ...model, package: model.package ?? provider.package, - aisdk: model.package === undefined ? (model.aisdk ?? provider.aisdk) : model.aisdk, - settings: merge(provider.settings, model.settings), - headers: headers(provider.headers, model.headers), - body: merge(provider.body, model.body), + settings: ProviderOverlay.merge(provider.settings, model.settings), + headers: ProviderOverlay.headers(provider.headers, model.headers), + body: ProviderOverlay.merge(provider.body, model.body), }) } @@ -270,43 +270,6 @@ export const layer = Layer.effect( const SMALL_MODEL_RE = /\b(nano|flash|lite|mini|haiku|small|fast)\b/ -function merge( - base: Readonly> | undefined, - overlay: Readonly> | undefined, -): Record | undefined { - if (base === undefined) return overlay && { ...overlay } - if (overlay === undefined) return { ...base } - return Object.fromEntries( - new Set([...Object.keys(base), ...Object.keys(overlay)]).values().map((key) => { - const left = base[key] - const right = overlay[key] - if (right === undefined) return [key, left] - if (plain(left) && plain(right)) return [key, merge(left, right)] - return [key, right] - }), - ) -} - -function plain(input: unknown): input is Readonly> { - if (typeof input !== "object" || input === null || Array.isArray(input)) return false - const prototype = Object.getPrototypeOf(input) - return prototype === Object.prototype || prototype === null -} - -function headers( - base: Readonly> | undefined, - overlay: Readonly> | undefined, -) { - return Object.fromEntries( - [...Object.entries(base ?? {}), ...Object.entries(overlay ?? {})] - .reduce((result, entry) => { - result.set(entry[0].toLowerCase(), entry) - return result - }, new Map()) - .values(), - ) -} - export const locationLayer = layer.pipe( Layer.provideMerge(Integration.locationLayer), Layer.provideMerge(Policy.locationLayer), diff --git a/packages/core/src/config/plugin/provider.ts b/packages/core/src/config/plugin/provider.ts index 3129240639..4dd4e064f2 100644 --- a/packages/core/src/config/plugin/provider.ts +++ b/packages/core/src/config/plugin/provider.ts @@ -4,6 +4,7 @@ import { define } from "../../plugin/internal" import { Effect } from "effect" import { Config } from "../../config" import { ModelV2 } from "../../model" +import { ProviderOverlay } from "../../provider-overlay" import { ProviderV2 } from "../../provider" export const Plugin = define({ @@ -53,10 +54,10 @@ export const Plugin = define({ catalog.provider.update(providerID, (provider) => { if (item.name !== undefined) provider.name = item.name if (item.package !== undefined) provider.package = item.package - if (item.aisdk !== undefined) provider.aisdk = item.aisdk - if (item.settings !== undefined) provider.settings = { ...provider.settings, ...item.settings } - if (item.headers !== undefined) provider.headers = { ...provider.headers, ...item.headers } - if (item.body !== undefined) provider.body = { ...provider.body, ...item.body } + if (item.settings !== undefined) + provider.settings = ProviderOverlay.merge(provider.settings, item.settings) + if (item.headers !== undefined) provider.headers = ProviderOverlay.headers(provider.headers, item.headers) + if (item.body !== undefined) provider.body = ProviderOverlay.merge(provider.body, item.body) }) for (const [id, config] of Object.entries(item.models ?? {})) { catalog.model.update(providerID, id, (model) => { @@ -64,10 +65,10 @@ export const Plugin = define({ if (config.name !== undefined) model.name = config.name if (config.modelID !== undefined) model.modelID = config.modelID if (config.package !== undefined) model.package = config.package - if (config.aisdk !== undefined) model.aisdk = config.aisdk - if (config.settings !== undefined) model.settings = { ...model.settings, ...config.settings } - if (config.headers !== undefined) model.headers = { ...model.headers, ...config.headers } - if (config.body !== undefined) model.body = { ...model.body, ...config.body } + if (config.settings !== undefined) + model.settings = ProviderOverlay.merge(model.settings, config.settings) + if (config.headers !== undefined) model.headers = ProviderOverlay.headers(model.headers, config.headers) + if (config.body !== undefined) model.body = ProviderOverlay.merge(model.body, config.body) if (config.capabilities !== undefined) { model.capabilities = { tools: config.capabilities.tools, @@ -86,9 +87,10 @@ export const Plugin = define({ model.variants.push(existing) } if (variant.settings !== undefined) - existing.settings = { ...existing.settings, ...variant.settings } - if (variant.headers !== undefined) existing.headers = { ...existing.headers, ...variant.headers } - if (variant.body !== undefined) existing.body = { ...existing.body, ...variant.body } + existing.settings = ProviderOverlay.merge(existing.settings, variant.settings) + if (variant.headers !== undefined) + existing.headers = ProviderOverlay.headers(existing.headers, variant.headers) + if (variant.body !== undefined) existing.body = ProviderOverlay.merge(existing.body, variant.body) } } if (config.cost !== undefined) { diff --git a/packages/core/src/config/provider.ts b/packages/core/src/config/provider.ts index 153ab7fcef..990207d9cb 100644 --- a/packages/core/src/config/provider.ts +++ b/packages/core/src/config/provider.ts @@ -40,7 +40,6 @@ class Model extends Schema.Class("ConfigV2.Model")({ family: ModelV2.Family.pipe(Schema.optional), name: Schema.String.pipe(Schema.optional), package: Schema.String.pipe(Schema.optional), - aisdk: Schema.Literal(true).pipe(Schema.optional), ...Overlays, capabilities: ModelV2.Capabilities.pipe(Schema.optional), variants: Schema.Struct({ @@ -56,7 +55,6 @@ export class Info extends Schema.Class("ConfigV2.Provider")({ name: Schema.String.pipe(Schema.optional), env: Schema.String.pipe(Schema.Array, Schema.optional), package: Schema.String.pipe(Schema.optional), - aisdk: Schema.Literal(true).pipe(Schema.optional), ...Overlays, models: Schema.Record(Schema.String, Model).pipe(Schema.optional), }) {} diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index 2d7c597a44..3f264ecd9f 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -1,6 +1,6 @@ -import { Types } from "effect" import { Model } from "@opencode-ai/schema/model" import { ProviderV2 } from "./provider" +import type { DeepMutable } from "./schema" export const ID = Model.ID export type ID = typeof ID.Type @@ -23,7 +23,7 @@ export type Ref = typeof Ref.Type export const Info = Model.Info export type Info = Model.Info -export type MutableInfo = Types.DeepMutable +export type MutableInfo = DeepMutable export function parse(input: string): { providerID: ProviderV2.ID; modelID: ID } { const [providerID, ...modelID] = input.split("/") diff --git a/packages/core/src/plugin/models-dev.ts b/packages/core/src/plugin/models-dev.ts index ba6e4a869a..ae6a828487 100644 --- a/packages/core/src/plugin/models-dev.ts +++ b/packages/core/src/plugin/models-dev.ts @@ -75,8 +75,7 @@ export const ModelsDevPlugin = define({ const providerID = ProviderV2.ID.make(item.id) catalog.provider.update(providerID, (provider) => { provider.name = item.name - provider.package = item.npm ?? "" - provider.aisdk = item.npm ? true : undefined + provider.package = item.npm ? ProviderV2.aisdk(item.npm) : "" provider.settings = item.api ? { ...provider.settings, baseURL: item.api } : provider.settings }) @@ -85,8 +84,7 @@ export const ModelsDevPlugin = define({ catalog.model.update(providerID, modelID, (draft) => { draft.name = model.name draft.family = model.family ? ModelV2.Family.make(model.family) : undefined - draft.package = model.provider?.npm - draft.aisdk = model.provider?.npm ? true : undefined + draft.package = model.provider?.npm ? ProviderV2.aisdk(model.provider.npm) : undefined draft.settings = model.provider?.api ? { ...draft.settings, baseURL: model.provider.api } : draft.settings draft.capabilities = { tools: model.tool_call, diff --git a/packages/core/src/plugin/provider/amazon-bedrock.ts b/packages/core/src/plugin/provider/amazon-bedrock.ts index 00dc73edb0..f538cc1601 100644 --- a/packages/core/src/plugin/provider/amazon-bedrock.ts +++ b/packages/core/src/plugin/provider/amazon-bedrock.ts @@ -65,8 +65,8 @@ export const AmazonBedrockPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/amazon-bedrock") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/amazon-bedrock") continue evt.provider.update(item.provider.id, (provider) => { if (typeof provider.settings?.endpoint !== "string") return // The AI SDK expects a base URL, but users configure Bedrock private/VPC @@ -113,7 +113,10 @@ export const AmazonBedrockPlugin = define({ yield* ctx.aisdk.language( Effect.fn(function* (evt) { if (evt.model.providerID !== ProviderV2.ID.amazonBedrock) return - if (evt.model.aisdk && evt.model.package === "@ai-sdk/amazon-bedrock/mantle") { + if ( + ProviderV2.isAISDK(evt.model.package) && + ProviderV2.packageName(evt.model.package) === "@ai-sdk/amazon-bedrock/mantle" + ) { evt.language = selectMantleModel(evt.sdk, evt.model.modelID ?? evt.model.id) return } diff --git a/packages/core/src/plugin/provider/anthropic.ts b/packages/core/src/plugin/provider/anthropic.ts index c13fbbfdad..13b4d0c78b 100644 --- a/packages/core/src/plugin/provider/anthropic.ts +++ b/packages/core/src/plugin/provider/anthropic.ts @@ -1,5 +1,6 @@ import { Effect } from "effect" import { define } from "../internal" +import { ProviderV2 } from "../../provider" export const AnthropicPlugin = define({ id: "anthropic", @@ -7,8 +8,8 @@ export const AnthropicPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/anthropic") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/anthropic") continue evt.provider.update(item.provider.id, (provider) => { provider.headers = { ...provider.headers, diff --git a/packages/core/src/plugin/provider/azure.ts b/packages/core/src/plugin/provider/azure.ts index b1e5754606..a97713d59d 100644 --- a/packages/core/src/plugin/provider/azure.ts +++ b/packages/core/src/plugin/provider/azure.ts @@ -16,8 +16,8 @@ export const AzurePlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/azure") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/azure") continue const configured = item.provider.settings?.resourceName const resourceName = typeof configured === "string" && configured.trim() !== "" ? configured : process.env.AZURE_RESOURCE_NAME @@ -35,7 +35,7 @@ export const AzurePlugin = define({ if ( !evt.options.resourceName && !evt.options.baseURL && - (!evt.model.aisdk || typeof evt.model.settings?.baseURL !== "string") + (!ProviderV2.isAISDK(evt.model.package) || typeof evt.model.settings?.baseURL !== "string") ) { throw new Error( "AZURE_RESOURCE_NAME is missing, set it using env var or reconnecting the azure provider and setting it", @@ -67,8 +67,8 @@ export const AzureCognitiveServicesPlugin = define({ const resourceName = process.env.AZURE_COGNITIVE_SERVICES_RESOURCE_NAME if (!resourceName) return for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/openai-compatible") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue if (!item.provider.id.includes("azure-cognitive-services")) continue evt.provider.update(item.provider.id, (provider) => { provider.settings = { diff --git a/packages/core/src/plugin/provider/cerebras.ts b/packages/core/src/plugin/provider/cerebras.ts index cb15cb9312..c0829c1c66 100644 --- a/packages/core/src/plugin/provider/cerebras.ts +++ b/packages/core/src/plugin/provider/cerebras.ts @@ -1,5 +1,6 @@ import { Effect } from "effect" import { define } from "../internal" +import { ProviderV2 } from "../../provider" export const CerebrasPlugin = define({ id: "cerebras", @@ -7,8 +8,8 @@ export const CerebrasPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/cerebras") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/cerebras") continue evt.provider.update(item.provider.id, (provider) => { provider.headers = { ...provider.headers, "X-Cerebras-3rd-Party-Integration": "opencode" } }) diff --git a/packages/core/src/plugin/provider/cloudflare-workers-ai.ts b/packages/core/src/plugin/provider/cloudflare-workers-ai.ts index 0ed7b0dffa..08a988b198 100644 --- a/packages/core/src/plugin/provider/cloudflare-workers-ai.ts +++ b/packages/core/src/plugin/provider/cloudflare-workers-ai.ts @@ -14,7 +14,7 @@ export const CloudflareWorkersAIPlugin = define({ const item = evt.provider.get(providerID) if (!item) return evt.provider.update(item.provider.id, (provider) => { - if (!provider.aisdk) return + if (!ProviderV2.isAISDK(provider.package)) return if (typeof provider.settings?.baseURL === "string") return const accountId = resolveAccountId(provider.settings ?? {}) if (accountId) provider.settings = { ...provider.settings, baseURL: workersEndpoint(accountId) } @@ -54,8 +54,11 @@ function workersEndpoint(accountId: string) { return `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1` } -function hasWorkersEndpoint(model: { readonly aisdk?: true; readonly settings?: Readonly> }) { - return model.aisdk && typeof model.settings?.baseURL === "string" +function hasWorkersEndpoint(model: { + readonly package?: string + readonly settings?: Readonly> +}) { + return ProviderV2.isAISDK(model.package) && typeof model.settings?.baseURL === "string" } function sdkOptions(options: Record) { diff --git a/packages/core/src/plugin/provider/google-vertex.ts b/packages/core/src/plugin/provider/google-vertex.ts index fa7afc98bf..202c9ead20 100644 --- a/packages/core/src/plugin/provider/google-vertex.ts +++ b/packages/core/src/plugin/provider/google-vertex.ts @@ -60,12 +60,12 @@ export const GoogleVertexPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue + if (!ProviderV2.isAISDK(item.provider.package)) continue if ( - item.provider.package !== "@ai-sdk/google-vertex" && + ProviderV2.packageName(item.provider.package) !== "@ai-sdk/google-vertex" && !( item.provider.id === ProviderV2.ID.googleVertex && - item.provider.package.includes("@ai-sdk/openai-compatible") + ProviderV2.packageName(item.provider.package)?.includes("@ai-sdk/openai-compatible") ) ) continue @@ -79,7 +79,7 @@ export const GoogleVertexPlugin = define({ ...(typeof provider.settings?.baseURL === "string" ? { baseURL: replaceVertexVars(provider.settings.baseURL, project, location) } : {}), - ...(provider.package.includes("@ai-sdk/openai-compatible") + ...(ProviderV2.packageName(provider.package)?.includes("@ai-sdk/openai-compatible") ? { fetch: authFetch(provider.settings?.fetch) } : {}), } @@ -121,8 +121,8 @@ export const GoogleVertexAnthropicPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/google-vertex/anthropic") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/google-vertex/anthropic") continue const project = item.provider.settings?.project ?? process.env.GOOGLE_CLOUD_PROJECT ?? diff --git a/packages/core/src/plugin/provider/kilo.ts b/packages/core/src/plugin/provider/kilo.ts index 9cfd5b2791..e3436cbea0 100644 --- a/packages/core/src/plugin/provider/kilo.ts +++ b/packages/core/src/plugin/provider/kilo.ts @@ -1,5 +1,6 @@ import { Effect } from "effect" import { define } from "../internal" +import { ProviderV2 } from "../../provider" export const KiloPlugin = define({ id: "kilo", @@ -7,8 +8,8 @@ export const KiloPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/openai-compatible") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue if (item.provider.settings?.baseURL !== "https://api.kilo.ai/api/gateway") continue evt.provider.update(item.provider.id, (provider) => { provider.headers = { ...provider.headers, "HTTP-Referer": "https://opencode.ai/", "X-Title": "opencode" } diff --git a/packages/core/src/plugin/provider/llmgateway.ts b/packages/core/src/plugin/provider/llmgateway.ts index 73ee23b876..82cc67727a 100644 --- a/packages/core/src/plugin/provider/llmgateway.ts +++ b/packages/core/src/plugin/provider/llmgateway.ts @@ -1,6 +1,7 @@ import { Effect } from "effect" import { define } from "../internal" import { Integration } from "../../integration" +import { ProviderV2 } from "../../provider" export const LLMGatewayPlugin = define({ id: "llmgateway", @@ -10,8 +11,8 @@ export const LLMGatewayPlugin = define({ Effect.fn(function* (evt) { for (const item of evt.provider.list()) { if (item.provider.disabled) continue - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/openai-compatible") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue if (item.provider.settings?.baseURL !== "https://api.llmgateway.io/v1") continue if (!(yield* integrations.get(Integration.ID.make(item.provider.id)))) continue evt.provider.update(item.provider.id, (provider) => { diff --git a/packages/core/src/plugin/provider/nvidia.ts b/packages/core/src/plugin/provider/nvidia.ts index 5a80180aa6..dbab4edbda 100644 --- a/packages/core/src/plugin/provider/nvidia.ts +++ b/packages/core/src/plugin/provider/nvidia.ts @@ -1,5 +1,6 @@ import { Effect } from "effect" import { define } from "../internal" +import { ProviderV2 } from "../../provider" export const NvidiaPlugin = define({ id: "nvidia", @@ -7,8 +8,8 @@ export const NvidiaPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/openai-compatible") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue if (item.provider.settings?.baseURL !== "https://integrate.api.nvidia.com/v1") continue evt.provider.update(item.provider.id, (provider) => { provider.headers = { diff --git a/packages/core/src/plugin/provider/openai.ts b/packages/core/src/plugin/provider/openai.ts index dda85b4688..6119b259da 100644 --- a/packages/core/src/plugin/provider/openai.ts +++ b/packages/core/src/plugin/provider/openai.ts @@ -156,8 +156,8 @@ export const OpenAIPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/openai") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai") continue if (!item.models.has(ModelV2.ID.make("gpt-5-chat-latest"))) continue evt.model.update(item.provider.id, ModelV2.ID.make("gpt-5-chat-latest"), (model) => { // OpenAIPlugin sends OpenAI models through Responses; this alias is a diff --git a/packages/core/src/plugin/provider/opencode.ts b/packages/core/src/plugin/provider/opencode.ts index 29e1eb704a..47d3d09648 100644 --- a/packages/core/src/plugin/provider/opencode.ts +++ b/packages/core/src/plugin/provider/opencode.ts @@ -111,8 +111,7 @@ export const OpencodePlugin = define { provider.integrationID = Integration.ID.make("opencode") if (item.name !== undefined) provider.name = item.name - provider.package = item.npm ?? "" - provider.aisdk = item.npm ? true : undefined + provider.package = item.npm ? ProviderV2.aisdk(item.npm) : "" provider.settings = { ...provider.settings, ...withoutCredentials(item.options), @@ -132,8 +131,7 @@ export const OpencodePlugin = define { provider.headers = { ...provider.headers, "HTTP-Referer": "https://opencode.ai/", "X-Title": "opencode" } }) diff --git a/packages/core/src/plugin/provider/vercel.ts b/packages/core/src/plugin/provider/vercel.ts index da67661abe..fba7898658 100644 --- a/packages/core/src/plugin/provider/vercel.ts +++ b/packages/core/src/plugin/provider/vercel.ts @@ -1,5 +1,6 @@ import { Effect } from "effect" import { define } from "../internal" +import { ProviderV2 } from "../../provider" export const VercelPlugin = define({ id: "vercel", @@ -7,8 +8,8 @@ export const VercelPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/vercel") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/vercel") continue evt.provider.update(item.provider.id, (provider) => { provider.headers = { ...provider.headers, "http-referer": "https://opencode.ai/", "x-title": "opencode" } }) diff --git a/packages/core/src/plugin/provider/zenmux.ts b/packages/core/src/plugin/provider/zenmux.ts index a37d7f0678..757d4babbe 100644 --- a/packages/core/src/plugin/provider/zenmux.ts +++ b/packages/core/src/plugin/provider/zenmux.ts @@ -1,5 +1,6 @@ import { Effect } from "effect" import { define } from "../internal" +import { ProviderV2 } from "../../provider" export const ZenmuxPlugin = define({ id: "zenmux", @@ -7,8 +8,8 @@ export const ZenmuxPlugin = define({ yield* ctx.catalog.transform( Effect.fn(function* (evt) { for (const item of evt.provider.list()) { - if (!item.provider.aisdk) continue - if (item.provider.package !== "@ai-sdk/openai-compatible") continue + if (!ProviderV2.isAISDK(item.provider.package)) continue + if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue if (item.provider.settings?.baseURL !== "https://zenmux.ai/api/v1") continue evt.provider.update(item.provider.id, (provider) => { provider.headers = { diff --git a/packages/core/src/plugin/variant.ts b/packages/core/src/plugin/variant.ts index ccdbd5a15c..41d1bfd106 100644 --- a/packages/core/src/plugin/variant.ts +++ b/packages/core/src/plugin/variant.ts @@ -2,6 +2,7 @@ export * as VariantPlugin from "./variant" import { Effect } from "effect" import { ModelV2 } from "../model" +import { ProviderV2 } from "../provider" import { define } from "./internal" export const Plugin = define({ @@ -29,9 +30,10 @@ export const Plugin = define({ export function generate( model: ModelV2.Info, - provider?: { readonly package: string; readonly aisdk?: true }, + provider?: { readonly package: string }, ): NonNullable { - if (!(model.aisdk ?? provider?.aisdk) || (model.package ?? provider?.package) !== "@ai-sdk/openai-compatible") return [] + const packageName = model.package ?? provider?.package + if (!ProviderV2.isAISDK(packageName) || ProviderV2.packageName(packageName) !== "@ai-sdk/openai-compatible") return [] const ids = `${model.id} ${model.modelID ?? ""}`.toLowerCase() if (!["glm-5.2", "glm-5-2", "glm-5p2"].some((name) => ids.includes(name))) return [] return ["high", "max"].map((id) => ({ diff --git a/packages/core/src/provider-overlay.ts b/packages/core/src/provider-overlay.ts new file mode 100644 index 0000000000..f5f7aca8e8 --- /dev/null +++ b/packages/core/src/provider-overlay.ts @@ -0,0 +1,38 @@ +export * as ProviderOverlay from "./provider-overlay" + +export function merge( + base: Readonly> | undefined, + overlay: Readonly> | undefined, +): Record | undefined { + if (base === undefined) return overlay && { ...overlay } + if (overlay === undefined) return { ...base } + return Object.fromEntries( + new Set([...Object.keys(base), ...Object.keys(overlay)]).values().map((key) => { + const left = base[key] + const right = overlay[key] + if (right === undefined) return [key, left] + if (plain(left) && plain(right)) return [key, merge(left, right)] + return [key, right] + }), + ) +} + +export function headers( + base: Readonly> | undefined, + overlay: Readonly> | undefined, +) { + return Object.fromEntries( + [...Object.entries(base ?? {}), ...Object.entries(overlay ?? {})] + .reduce((result, entry) => { + result.set(entry[0].toLowerCase(), entry) + return result + }, new Map()) + .values(), + ) +} + +function plain(input: unknown): input is Readonly> { + if (typeof input !== "object" || input === null || Array.isArray(input)) return false + const prototype = Object.getPrototypeOf(input) + return prototype === Object.prototype || prototype === null +} diff --git a/packages/core/src/provider-package.ts b/packages/core/src/provider-package.ts new file mode 100644 index 0000000000..559caf0d0f --- /dev/null +++ b/packages/core/src/provider-package.ts @@ -0,0 +1,75 @@ +export * as ProviderPackage from "./provider-package" + +import { Effect, Option, Schema } from "effect" +import { pathToFileURL } from "url" +import type { Model, ProviderPackageDefinition, ProviderPackageSettings } from "@opencode-ai/llm" +import { Npm } from "./npm" + +const cache = new Map>() + +export class LoadError extends Schema.TaggedErrorClass()("ProviderPackage.LoadError", { + package: Schema.String, + cause: Schema.Defect(), +}) {} + +export const load = Effect.fn("ProviderPackage.load")(function* (specifier: string) { + const npm = Option.getOrUndefined(yield* Effect.serviceOption(Npm.Service)) + const resolved = + specifier.startsWith("file://") || specifier.startsWith("@opencode-ai/llm/") + ? specifier + : yield* Effect.sync(() => { + try { + return import.meta.resolve(specifier) + } catch { + return undefined + } + }) + if (resolved) return yield* importProviderPackage(specifier, resolved) + if (!npm) { + return yield* new LoadError({ + package: specifier, + cause: new Error(`Provider package ${specifier} is not installed`), + }) + } + const installed = yield* npm + .add(packageName(specifier)) + .pipe(Effect.mapError((cause) => new LoadError({ package: specifier, cause }))) + const entrypoint = yield* Effect.try({ + try: () => import.meta.resolve(specifier, pathToFileURL(`${installed.directory}/`).href), + catch: (cause) => new LoadError({ package: specifier, cause }), + }) + return yield* importProviderPackage(specifier, entrypoint) +}) + +const importProviderPackage = Effect.fn("ProviderPackage.import")(function* (specifier: string, entrypoint: string) { + const module = yield* Effect.tryPromise({ + try: () => { + const existing = cache.get(entrypoint) + if (existing) return existing + const loaded = import(entrypoint) + cache.set(entrypoint, loaded) + return loaded + }, + catch: (cause) => new LoadError({ package: specifier, cause }), + }) + if (!isProviderPackage(module)) { + return yield* new LoadError({ + package: specifier, + cause: new Error(`Provider package ${specifier} does not export model(id, settings)`), + }) + } + return module +}) + +export const make = (module: ProviderPackageDefinition, modelID: string, settings: ProviderPackageSettings): Model => + module.model(modelID, settings) + +function isProviderPackage(input: unknown): input is ProviderPackageDefinition { + return typeof input === "object" && input !== null && "model" in input && typeof input.model === "function" +} + +function packageName(specifier: string) { + const parts = specifier.split("/") + if (specifier.startsWith("@")) return parts.slice(0, 2).join("/") + return parts[0] +} diff --git a/packages/core/src/provider.ts b/packages/core/src/provider.ts index 576abd3df1..3246c8d36e 100644 --- a/packages/core/src/provider.ts +++ b/packages/core/src/provider.ts @@ -1,15 +1,21 @@ export * as ProviderV2 from "./provider" -import { Types } from "effect" import { Provider } from "@opencode-ai/schema/provider" +import type { DeepMutable } from "./schema" export const ID = Provider.ID export type ID = typeof ID.Type +export const AISDK_PREFIX = "aisdk:" +export const isAISDK = (packageName: string | undefined) => packageName?.startsWith(AISDK_PREFIX) ?? false +export const aisdk = (packageName: string) => (isAISDK(packageName) ? packageName : `${AISDK_PREFIX}${packageName}`) +export const packageName = (packageName: string | undefined) => + isAISDK(packageName) ? packageName!.slice(AISDK_PREFIX.length) : packageName + export const Request = Provider.Request export type Request = Provider.Request export const Info = Provider.Info export type Info = Provider.Info -export type MutableInfo = Types.DeepMutable +export type MutableInfo = DeepMutable diff --git a/packages/core/src/session/runner/model.ts b/packages/core/src/session/runner/model.ts index f8cc794a86..464bab36a6 100644 --- a/packages/core/src/session/runner/model.ts +++ b/packages/core/src/session/runner/model.ts @@ -12,6 +12,8 @@ import { Credential } from "../../credential" import { Integration } from "../../integration" import { ModelV2 } from "../../model" import { ProviderV2 } from "../../provider" +import { ProviderPackage } from "../../provider-package" +import { ProviderOverlay } from "../../provider-overlay" import { SessionSchema } from "../schema" export class ModelNotSelectedError extends Schema.TaggedErrorClass()( @@ -117,9 +119,9 @@ const withVariant = ( return Effect.succeed( variant ? produce(model, (draft) => { - draft.settings = merge(draft.settings, variant.settings) - draft.headers = { ...draft.headers, ...variant.headers } - draft.body = merge(draft.body, variant.body) + draft.settings = ProviderOverlay.merge(draft.settings, variant.settings) + draft.headers = ProviderOverlay.headers(draft.headers, variant.headers) + draft.body = ProviderOverlay.merge(draft.body, variant.body) }) : model, ) @@ -133,17 +135,18 @@ export const fromCatalogModel = ( credential?.metadata === undefined ? model : produce(model, (draft) => { - draft.settings = { ...draft.settings, ...credential.metadata } + draft.settings = ProviderOverlay.merge(draft.settings, credential.metadata) }) const key = apiKey(resolved, credential) - if (resolved.aisdk && resolved.package === "@ai-sdk/openai") { + const packageName = ProviderV2.packageName(resolved.package) + if (ProviderV2.isAISDK(resolved.package) && packageName === "@ai-sdk/openai") { return Effect.succeed( withDefaults(resolved, OpenAIResponses.route) .with({ auth: key === undefined ? Auth.none : Auth.bearer(key) }) .model({ id: resolved.modelID ?? resolved.id }), ) } - if (resolved.aisdk && resolved.package === "@ai-sdk/anthropic") { + if (ProviderV2.isAISDK(resolved.package) && packageName === "@ai-sdk/anthropic") { return Effect.succeed( withDefaults(resolved, AnthropicMessages.route) .with({ auth: key === undefined ? Auth.none : Auth.header("x-api-key", key) }) @@ -151,8 +154,8 @@ export const fromCatalogModel = ( ) } if ( - resolved.aisdk && - resolved.package === "@ai-sdk/openai-compatible" && + ProviderV2.isAISDK(resolved.package) && + packageName === "@ai-sdk/openai-compatible" && typeof resolved.settings?.baseURL === "string" ) { return Effect.succeed( @@ -161,11 +164,44 @@ export const fromCatalogModel = ( .model({ id: resolved.modelID ?? resolved.id }), ) } + if (!ProviderV2.isAISDK(resolved.package) && resolved.package) { + const specifier = resolved.package + return Effect.gen(function* () { + const module = yield* ProviderPackage.load(specifier).pipe( + Effect.mapError( + () => + new UnsupportedPackageError({ + providerID: resolved.providerID, + modelID: resolved.id, + package: specifier, + }), + ), + ) + const settings = { + ...resolved.settings, + ...(credential?.type === "key" ? { apiKey: credential.key } : {}), + ...(credential?.type === "oauth" ? { apiKey: credential.access } : {}), + ...credential?.metadata, + headers: resolved.headers, + body: resolved.body, + limits: { context: resolved.limit.context, output: resolved.limit.output }, + } + return yield* Effect.try({ + try: () => ProviderPackage.make(module, resolved.modelID ?? resolved.id, settings), + catch: () => + new UnsupportedPackageError({ + providerID: resolved.providerID, + modelID: resolved.id, + package: specifier, + }), + }) + }) + } return Effect.fail( new UnsupportedPackageError({ providerID: resolved.providerID, modelID: resolved.id, - package: resolved.aisdk ? `aisdk:${resolved.package}` : (resolved.package ?? "unknown"), + package: resolved.package ?? "unknown", }), ) } @@ -174,10 +210,12 @@ export const resolve = (session: SessionSchema.Info, model: ModelV2.Info, creden withVariant(model, session.model?.variant).pipe(Effect.flatMap((model) => fromCatalogModel(model, credential))) export const supported = (model: ModelV2.Info) => - model.aisdk === true && - (model.package === "@ai-sdk/openai" || - model.package === "@ai-sdk/anthropic" || - (model.package === "@ai-sdk/openai-compatible" && typeof model.settings?.baseURL === "string")) + Boolean(model.package) && + (!ProviderV2.isAISDK(model.package) || + ProviderV2.packageName(model.package) === "@ai-sdk/openai" || + ProviderV2.packageName(model.package) === "@ai-sdk/anthropic" || + (ProviderV2.packageName(model.package) === "@ai-sdk/openai-compatible" && + typeof model.settings?.baseURL === "string")) /** Resolves models from the catalog belonging to the current Location runtime. */ export const locationLayer = Layer.effect( @@ -215,26 +253,3 @@ export const locationLayer = Layer.effect( }) }), ) - -function merge( - base: Readonly> | undefined, - overlay: Readonly> | undefined, -): Record | undefined { - if (base === undefined) return overlay && { ...overlay } - if (overlay === undefined) return { ...base } - return Object.fromEntries( - Array.from(new Set([...Object.keys(base), ...Object.keys(overlay)])).map((key) => { - const left = base[key] - const right = overlay[key] - if (right === undefined) return [key, left] - if (plain(left) && plain(right)) return [key, merge(left, right)] - return [key, right] - }), - ) -} - -function plain(input: unknown): input is Readonly> { - if (typeof input !== "object" || input === null || Array.isArray(input)) return false - const prototype = Object.getPrototypeOf(input) - return prototype === Object.prototype || prototype === null -} diff --git a/packages/core/src/v1/config/migrate.ts b/packages/core/src/v1/config/migrate.ts index f0fcd1402f..7489878c6e 100644 --- a/packages/core/src/v1/config/migrate.ts +++ b/packages/core/src/v1/config/migrate.ts @@ -6,6 +6,7 @@ import { ConfigMCPV1 } from "./mcp" import { ConfigPermissionV1 } from "./permission" import { ConfigProviderV1 } from "./provider" import { ConfigProviderOptionsV1 } from "./provider-options" +import { ProviderV2 } from "../../provider" const keys = new Set([ "logLevel", @@ -173,8 +174,7 @@ function migrateProvider(info: ConfigProviderV1.Info) { return { name: info.name, env: info.env, - package: info.npm, - aisdk: info.npm ? (true as const) : undefined, + package: info.npm ? ProviderV2.aisdk(info.npm) : undefined, settings: info.api ? { ...options.settings, baseURL: info.api } : options.settings, headers: info.options && options.headers, body: info.options && options.body, @@ -213,8 +213,7 @@ function migrateModel(info: typeof ConfigProviderV1.Model.Type, packageName?: st modelID: info.id, family: info.family, name: info.name, - package: info.provider?.npm, - aisdk: info.provider?.npm ? (true as const) : undefined, + package: info.provider?.npm ? ProviderV2.aisdk(info.provider.npm) : undefined, settings: info.provider?.api ? { ...settings, baseURL: info.provider.api } : settings, capabilities, headers: info.headers, diff --git a/packages/core/test/catalog.test.ts b/packages/core/test/catalog.test.ts index ec5cc3010a..2c30342a2f 100644 --- a/packages/core/test/catalog.test.ts +++ b/packages/core/test/catalog.test.ts @@ -141,15 +141,13 @@ describe("CatalogV2", () => { const providerID = ProviderV2.ID.make("test") yield* catalog.transform((catalog) => catalog.provider.update(providerID, (provider) => { - provider.package = "@ai-sdk/openai-compatible" - provider.aisdk = true + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { baseURL: "https://override.example.com" } }), ) expect(required(yield* catalog.provider.get(providerID))).toMatchObject({ - package: "@ai-sdk/openai-compatible", - aisdk: true, + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://override.example.com" }, }) }), @@ -162,8 +160,7 @@ describe("CatalogV2", () => { const modelID = ModelV2.ID.make("model") yield* catalog.transform((catalog) => { catalog.provider.update(providerID, (provider) => { - provider.package = "@ai-sdk/openai-compatible" - provider.aisdk = true + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { baseURL: "https://provider.example.com" } }) catalog.model.update(providerID, modelID, (model) => { @@ -175,8 +172,7 @@ describe("CatalogV2", () => { expect(required(yield* catalog.model.get(providerID, modelID))).toMatchObject({ id: modelID, modelID: ModelV2.ID.make("upstream-model"), - package: "@ai-sdk/openai-compatible", - aisdk: true, + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://override.example.com" }, }) }), @@ -189,8 +185,7 @@ describe("CatalogV2", () => { const modelID = ModelV2.ID.make("model") yield* catalog.transform((catalog) => { catalog.provider.update(providerID, (provider) => { - provider.package = "@ai-sdk/openai-compatible" - provider.aisdk = true + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { baseURL: "https://provider.example.com" } }) catalog.model.update(providerID, modelID, () => {}) @@ -198,8 +193,7 @@ describe("CatalogV2", () => { expect(required(yield* catalog.model.get(providerID, modelID))).toMatchObject({ id: modelID, - package: "@ai-sdk/openai-compatible", - aisdk: true, + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://provider.example.com" }, }) }), @@ -212,18 +206,36 @@ describe("CatalogV2", () => { const modelID = ModelV2.ID.make("model") yield* catalog.transform((catalog) => { catalog.provider.update(providerID, (provider) => { - provider.headers = { provider: "provider", shared: "provider" } - provider.body = { provider: true } + provider.headers = { provider: "provider", "X-Shared": "provider" } + provider.body = { + provider: true, + reasoning: { type: "enabled", budget: 8_000 }, + stop: ["END"], + disabled: { type: "enabled" }, + } }) catalog.model.update(providerID, modelID, (model) => { - model.headers = { model: "model", shared: "model" } - model.body = { model: true, request: true, shared: "model" } + model.headers = { model: "model", "x-shared": "model" } + model.body = { + model: true, + request: true, + reasoning: { budget: 32_000 }, + stop: ["STOP"], + disabled: null, + } }) }) const model = required(yield* catalog.model.get(providerID, modelID)) - expect(model.headers).toEqual({ provider: "provider", shared: "model", model: "model" }) - expect(model.body).toEqual({ provider: true, model: true, request: true, shared: "model" }) + expect(model.headers).toEqual({ provider: "provider", "x-shared": "model", model: "model" }) + expect(model.body).toEqual({ + provider: true, + model: true, + request: true, + reasoning: { type: "enabled", budget: 32_000 }, + stop: ["STOP"], + disabled: null, + }) }), ) diff --git a/packages/core/test/config/config.test.ts b/packages/core/test/config/config.test.ts index d74ea49c79..12fc4d408f 100644 --- a/packages/core/test/config/config.test.ts +++ b/packages/core/test/config/config.test.ts @@ -101,8 +101,7 @@ describe("Config", () => { }) expect(migrated.providers?.bedrock).toMatchObject({ - package: "@ai-sdk/amazon-bedrock", - aisdk: true, + package: "aisdk:@ai-sdk/amazon-bedrock", settings: { baseURL: "https://bedrock.example.com", region: "us-east-1", profile: "dev" }, headers: { "x-test": "1" }, body: { trace: true }, @@ -588,8 +587,7 @@ describe("Config", () => { }, }) expect(documents[0]?.info.providers?.openai).toMatchObject({ - package: "@ai-sdk/openai", - aisdk: true, + package: "aisdk:@ai-sdk/openai", settings: { apiKey: "secret", organization: "org" }, models: { model: { diff --git a/packages/core/test/config/provider.test.ts b/packages/core/test/config/provider.test.ts index 9ca8b8ca1e..d1d27dc6e9 100644 --- a/packages/core/test/config/provider.test.ts +++ b/packages/core/test/config/provider.test.ts @@ -61,8 +61,7 @@ describe("ConfigProviderPlugin.Plugin", () => { info: decode({ providers: { opencode: { - package: "@ai-sdk/openai", - aisdk: true, + package: "aisdk:@ai-sdk/openai", settings: { baseURL: "https://opencode.test/v1" }, models: { "alpha-gpt-next": { @@ -114,8 +113,7 @@ describe("ConfigProviderPlugin.Plugin", () => { info: decode({ providers: { opencode: { - package: "@ai-sdk/openai", - aisdk: true, + package: "aisdk:@ai-sdk/openai", settings: { baseURL: "https://opencode.test/v1" }, }, }, @@ -195,8 +193,7 @@ describe("ConfigProviderPlugin.Plugin", () => { model: "custom/default", providers: { custom: { - package: "custom-sdk", - aisdk: true, + package: "aisdk:custom-sdk", settings: { baseURL: "https://example.test" }, headers: { last: "last", shared: "last" }, models: { @@ -247,8 +244,7 @@ describe("ConfigProviderPlugin.Plugin", () => { }) expect((yield* integrations.get(Integration.ID.make("custom")))?.name).toBe("Renamed") expect(provider.disabled).toBeUndefined() - expect(provider.package).toBe("custom-sdk") - expect(provider.aisdk).toBe(true) + expect(provider.package).toBe("aisdk:custom-sdk") expect(provider.settings).toEqual({ baseURL: "https://example.test" }) expect(provider.headers).toEqual({ first: "first", shared: "last", last: "last" }) expect(model.id).toBe(modelID) diff --git a/packages/core/test/plugin/provider-alibaba.test.ts b/packages/core/test/plugin/provider-alibaba.test.ts index 3bf2e0b325..bb7f922e52 100644 --- a/packages/core/test/plugin/provider-alibaba.test.ts +++ b/packages/core/test/plugin/provider-alibaba.test.ts @@ -29,8 +29,7 @@ describe("AlibabaPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("alibaba"), ModelV2.ID.make("qwen")), modelID: ModelV2.ID.make("qwen"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/alibaba", options: { name: "alibaba" }, @@ -48,8 +47,7 @@ describe("AlibabaPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("alibaba"), ModelV2.ID.make("qwen")), modelID: ModelV2.ID.make("qwen"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "alibaba" }, @@ -67,8 +65,7 @@ describe("AlibabaPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-alibaba"), ModelV2.ID.make("qwen")), modelID: ModelV2.ID.make("qwen"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/alibaba", options: { name: "custom-alibaba", apiKey: "test" }, @@ -88,8 +85,7 @@ describe("AlibabaPlugin", () => { const item = ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("alibaba"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("qwen-plus"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }) const result = yield* aisdk.runSDK({ model: item, package: "@ai-sdk/alibaba", options: {} }) const language = result.sdk?.languageModel(item.modelID ?? item.id) diff --git a/packages/core/test/plugin/provider-amazon-bedrock.test.ts b/packages/core/test/plugin/provider-amazon-bedrock.test.ts index 42e9fc10ec..da47e55e90 100644 --- a/packages/core/test/plugin/provider-amazon-bedrock.test.ts +++ b/packages/core/test/plugin/provider-amazon-bedrock.test.ts @@ -85,13 +85,12 @@ describe("AmazonBedrockPlugin", () => { yield* catalog.transform((catalog) => { const bedrock = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.amazonBedrock), - aisdk: true, - package: "@ai-sdk/amazon-bedrock", + package: "aisdk:@ai-sdk/amazon-bedrock", headers: {}, settings: { endpoint: "https://bedrock.example" }, }) catalog.provider.update(bedrock.id, (item) => { - item.aisdk = bedrock.aisdk + item.package = bedrock.package item.package = bedrock.package item.headers = bedrock.headers item.settings = { endpoint: "https://bedrock.example" } @@ -100,8 +99,7 @@ describe("AmazonBedrockPlugin", () => { yield* addPlugin() const result = required(yield* catalog.provider.get(ProviderV2.ID.amazonBedrock)) expect(result).toMatchObject({ - aisdk: true, - package: "@ai-sdk/amazon-bedrock", + package: "aisdk:@ai-sdk/amazon-bedrock", settings: { baseURL: "https://bedrock.example" }, }) expect(result.settings?.endpoint).toBeUndefined() @@ -118,8 +116,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/amazon-bedrock", options: { @@ -145,8 +142,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/amazon-bedrock", options: { @@ -181,8 +177,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/amazon-bedrock", options: { name: "amazon-bedrock" }, @@ -203,8 +198,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/amazon-bedrock", options: { name: "amazon-bedrock", region: "eu-west-1" }, @@ -224,8 +218,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/amazon-bedrock", options: { name: "amazon-bedrock" }, @@ -245,8 +238,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/amazon-bedrock", options: { name: "amazon-bedrock" }, @@ -267,8 +259,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/amazon-bedrock", options: { @@ -298,8 +289,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/amazon-bedrock", options: { @@ -328,8 +318,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("openai.gpt-5.5")), modelID: ModelV2.ID.make("openai.gpt-5.5"), - aisdk: true, - package: "@ai-sdk/amazon-bedrock/mantle", + package: "aisdk:@ai-sdk/amazon-bedrock/mantle", }), package: "@ai-sdk/amazon-bedrock/mantle", options: { @@ -357,8 +346,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("openai.gpt-5.5")), modelID: ModelV2.ID.make("openai.gpt-5.5"), - aisdk: true, - package: "@ai-sdk/amazon-bedrock/mantle", + package: "aisdk:@ai-sdk/amazon-bedrock/mantle", }), sdk: fakeSelectorSdk(calls), options: { baseURL: "https://bedrock-mantle.us-east-2.api.aws/openai/v1", region: "us-east-2" }, @@ -367,8 +355,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("openai.gpt-oss-safeguard-120b")), modelID: ModelV2.ID.make("openai.gpt-oss-safeguard-120b"), - aisdk: true, - package: "@ai-sdk/amazon-bedrock/mantle", + package: "aisdk:@ai-sdk/amazon-bedrock/mantle", }), sdk: fakeSelectorSdk(calls), options: { region: "us-east-1" }, @@ -386,8 +373,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "@ai-sdk/amazon-bedrock/anthropic", + package: "aisdk:@ai-sdk/amazon-bedrock/anthropic", }), package: "@ai-sdk/amazon-bedrock/anthropic", options: { name: "amazon-bedrock" }, @@ -415,8 +401,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/amazon-bedrock", options: { @@ -448,8 +433,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: {}, @@ -458,8 +442,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: { region: "eu-west-1" }, @@ -468,8 +451,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("global.anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("global.anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: { region: "eu-west-1" }, @@ -478,8 +460,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: { region: "ap-northeast-1" }, @@ -488,8 +469,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: { region: "ap-southeast-2" }, @@ -515,8 +495,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: {}, @@ -603,8 +582,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.amazonBedrock, ModelV2.ID.make(item.modelID)), modelID: ModelV2.ID.make(item.modelID), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: { region: item.region }, @@ -624,8 +602,7 @@ describe("AmazonBedrockPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("anthropic.claude-sonnet-4-5")), modelID: ModelV2.ID.make("anthropic.claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: { region: "eu-west-1" }, diff --git a/packages/core/test/plugin/provider-anthropic.test.ts b/packages/core/test/plugin/provider-anthropic.test.ts index 53e68a8098..ab9fdf7007 100644 --- a/packages/core/test/plugin/provider-anthropic.test.ts +++ b/packages/core/test/plugin/provider-anthropic.test.ts @@ -31,13 +31,12 @@ describe("AnthropicPlugin", () => { yield* catalog.transform((catalog) => { const item = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.anthropic), - aisdk: true, - package: "@ai-sdk/anthropic", + package: "aisdk:@ai-sdk/anthropic", headers: { Existing: "1" }, settings: {}, }) catalog.provider.update(item.id, (draft) => { - draft.aisdk = item.aisdk + draft.package = item.package draft.package = item.package draft.headers = item.headers }) @@ -68,8 +67,7 @@ describe("AnthropicPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-anthropic"), ModelV2.ID.make("claude-sonnet-4-5")), modelID: ModelV2.ID.make("claude-sonnet-4-5"), - aisdk: true, - package: "@ai-sdk/anthropic", + package: "aisdk:@ai-sdk/anthropic", }), package: "@ai-sdk/anthropic", options: { name: "custom-anthropic", apiKey: "test" }, @@ -87,8 +85,7 @@ describe("AnthropicPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-5")), modelID: ModelV2.ID.make("claude-sonnet-4-5"), - aisdk: true, - package: "@ai-sdk/anthropic", + package: "aisdk:@ai-sdk/anthropic", }), package: "@ai-sdk/anthropic", options: { name: "anthropic", apiKey: "test" }, diff --git a/packages/core/test/plugin/provider-azure-cognitive-services.test.ts b/packages/core/test/plugin/provider-azure-cognitive-services.test.ts index f726f8bf90..f52f013105 100644 --- a/packages/core/test/plugin/provider-azure-cognitive-services.test.ts +++ b/packages/core/test/plugin/provider-azure-cognitive-services.test.ts @@ -66,15 +66,13 @@ describe("AzureCognitiveServicesPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("azure-cognitive-services"), (item) => { - item.aisdk = true - item.package = "@ai-sdk/openai-compatible" + item.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") }) }) yield* addPlugin() const result = required(yield* catalog.provider.get(ProviderV2.ID.make("azure-cognitive-services"))) expect(result).toMatchObject({ - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://cognitive.cognitiveservices.azure.com/openai" }, }) expect(result.settings?.resourceName).toBeUndefined() @@ -89,20 +87,18 @@ describe("AzureCognitiveServicesPlugin", () => { yield* catalog.transform((catalog) => { const azure = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services")), - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", }) const openai = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.openai), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }) catalog.provider.update(azure.id, (item) => { - item.aisdk = azure.aisdk + item.package = azure.package item.package = azure.package }) catalog.provider.update(openai.id, (item) => { - item.aisdk = openai.aisdk + item.package = openai.package item.package = openai.package }) }) @@ -110,9 +106,9 @@ describe("AzureCognitiveServicesPlugin", () => { const azure = required(yield* catalog.provider.get(ProviderV2.ID.make("azure-cognitive-services"))) const openai = required(yield* catalog.provider.get(ProviderV2.ID.openai)) expect(azure.settings?.baseURL).toBeUndefined() - expect(azure).toMatchObject({ aisdk: true, package: "@ai-sdk/openai-compatible" }) + expect(azure).toMatchObject({ package: "aisdk:@ai-sdk/openai-compatible" }) expect(openai.settings?.baseURL).toBeUndefined() - expect(openai).toMatchObject({ aisdk: true, package: "test-provider" }) + expect(openai).toMatchObject({ package: "aisdk:test-provider" }) }), ), ) @@ -127,8 +123,7 @@ describe("AzureCognitiveServicesPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: { useCompletionUrls: true }, @@ -147,8 +142,7 @@ describe("AzureCognitiveServicesPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -157,8 +151,7 @@ describe("AzureCognitiveServicesPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -179,8 +172,7 @@ describe("AzureCognitiveServicesPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("messages-deployment")), modelID: ModelV2.ID.make("messages-deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { messages: sdk.messages, chat: sdk.chat, languageModel: sdk.languageModel }, options: {}, @@ -189,8 +181,7 @@ describe("AzureCognitiveServicesPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("chat-deployment")), modelID: ModelV2.ID.make("chat-deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { chat: sdk.chat, languageModel: sdk.languageModel }, options: {}, @@ -199,8 +190,7 @@ describe("AzureCognitiveServicesPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("azure-cognitive-services"), ModelV2.ID.make("language-deployment")), modelID: ModelV2.ID.make("language-deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: sdk.languageModel }, options: {}, diff --git a/packages/core/test/plugin/provider-azure.test.ts b/packages/core/test/plugin/provider-azure.test.ts index 65bad6e289..204b61a089 100644 --- a/packages/core/test/plugin/provider-azure.test.ts +++ b/packages/core/test/plugin/provider-azure.test.ts @@ -66,8 +66,7 @@ describe("AzurePlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.azure, (item) => { - item.aisdk = true - item.package = "@ai-sdk/azure" + item.package = ProviderV2.aisdk("@ai-sdk/azure") }) }) yield* addPlugin() @@ -83,13 +82,12 @@ describe("AzurePlugin", () => { yield* catalog.transform((catalog) => { const azure = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.azure), - aisdk: true, - package: "@ai-sdk/azure", + package: "aisdk:@ai-sdk/azure", headers: {}, settings: { resourceName: "from-config" }, }) catalog.provider.update(azure.id, (item) => { - item.aisdk = azure.aisdk + item.package = azure.package item.package = azure.package item.headers = azure.headers item.settings = { resourceName: "from-config" } @@ -110,13 +108,12 @@ describe("AzurePlugin", () => { yield* catalog.transform((catalog) => { const azure = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.azure), - aisdk: true, - package: "@ai-sdk/azure", + package: "aisdk:@ai-sdk/azure", headers: {}, settings: { resourceName: "" }, }) catalog.provider.update(azure.id, (item) => { - item.aisdk = azure.aisdk + item.package = azure.package item.package = azure.package item.headers = azure.headers item.settings = { resourceName: "" } @@ -135,13 +132,12 @@ describe("AzurePlugin", () => { yield* catalog.transform((catalog) => { const azure = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.azure), - aisdk: true, - package: "@ai-sdk/azure", + package: "aisdk:@ai-sdk/azure", headers: {}, settings: { resourceName: " " }, }) catalog.provider.update(azure.id, (item) => { - item.aisdk = azure.aisdk + item.package = azure.package item.package = azure.package item.headers = azure.headers item.settings = { resourceName: " " } @@ -163,8 +159,7 @@ describe("AzurePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/azure", options: { name: "azure", baseURL: "https://proxy.example.com/openai" }, @@ -184,8 +179,7 @@ describe("AzurePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/azure", options: { name: "azure" }, @@ -206,8 +200,7 @@ describe("AzurePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: { useCompletionUrls: true }, @@ -226,8 +219,7 @@ describe("AzurePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: { useCompletionUrls: true }, @@ -246,8 +238,7 @@ describe("AzurePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", headers: {}, settings: { useCompletionUrls: true }, }), @@ -268,8 +259,7 @@ describe("AzurePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -278,8 +268,7 @@ describe("AzurePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("deployment")), modelID: ModelV2.ID.make("deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -303,8 +292,7 @@ describe("AzurePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("messages-deployment")), modelID: ModelV2.ID.make("messages-deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { messages: make("messages"), chat: make("chat"), languageModel: make("languageModel") }, options: {}, @@ -313,8 +301,7 @@ describe("AzurePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.azure, ModelV2.ID.make("language-deployment")), modelID: ModelV2.ID.make("language-deployment"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: make("languageModel") }, options: {}, diff --git a/packages/core/test/plugin/provider-cerebras.test.ts b/packages/core/test/plugin/provider-cerebras.test.ts index ae58572c64..eb5c4ec1bf 100644 --- a/packages/core/test/plugin/provider-cerebras.test.ts +++ b/packages/core/test/plugin/provider-cerebras.test.ts @@ -36,8 +36,7 @@ describe("CerebrasPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("cerebras"), (item) => { - item.aisdk = true - item.package = "@ai-sdk/cerebras" + item.package = ProviderV2.aisdk("@ai-sdk/cerebras") item.headers = { ...item.headers, Existing: "1" } }) }) @@ -71,8 +70,7 @@ describe("CerebrasPlugin", () => { ModelV2.ID.make("llama-4-scout-17b-16e-instruct"), ), modelID: ModelV2.ID.make("llama-4-scout-17b-16e-instruct"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/cerebras", options: { name: "custom-cerebras", apiKey: "test" }, @@ -95,8 +93,7 @@ describe("CerebrasPlugin", () => { ModelV2.ID.make("llama-4-scout-17b-16e-instruct"), ), modelID: ModelV2.ID.make("llama-4-scout-17b-16e-instruct"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/cerebras", options: { name: "configured-cerebras", apiKey: "test" }, @@ -118,8 +115,7 @@ describe("CerebrasPlugin", () => { ModelV2.ID.make("llama-4-scout-17b-16e-instruct"), ), modelID: ModelV2.ID.make("llama-4-scout-17b-16e-instruct"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/groq", options: { name: "custom-cerebras", apiKey: "test" }, diff --git a/packages/core/test/plugin/provider-cloudflare-ai-gateway.test.ts b/packages/core/test/plugin/provider-cloudflare-ai-gateway.test.ts index 7259f7ed56..cbd2b95c9e 100644 --- a/packages/core/test/plugin/provider-cloudflare-ai-gateway.test.ts +++ b/packages/core/test/plugin/provider-cloudflare-ai-gateway.test.ts @@ -119,8 +119,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { name: "cloudflare-ai-gateway" }, @@ -142,8 +141,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { @@ -188,8 +186,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { @@ -219,8 +216,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { @@ -258,8 +254,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { @@ -291,8 +286,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { name: "cloudflare-ai-gateway" }, @@ -315,8 +309,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { name: "cloudflare-ai-gateway" }, @@ -340,8 +333,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { name: "cloudflare-ai-gateway" }, @@ -371,8 +363,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { name: "cloudflare-ai-gateway", baseURL: "https://proxy.example/v1" }, @@ -399,8 +390,7 @@ describe("CloudflareAIGatewayPlugin", () => { ModelV2.ID.make("anthropic/claude-sonnet-4-5"), ), modelID: ModelV2.ID.make("anthropic/claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "ai-gateway-provider", options: { name: "cloudflare-ai-gateway" }, @@ -429,8 +419,7 @@ describe("CloudflareAIGatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-ai-gateway"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "cloudflare-ai-gateway" }, diff --git a/packages/core/test/plugin/provider-cloudflare-workers-ai.test.ts b/packages/core/test/plugin/provider-cloudflare-workers-ai.test.ts index 2eeb89caf2..d67b8d91cc 100644 --- a/packages/core/test/plugin/provider-cloudflare-workers-ai.test.ts +++ b/packages/core/test/plugin/provider-cloudflare-workers-ai.test.ts @@ -87,8 +87,7 @@ describe("CloudflareWorkersAIPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("cloudflare-workers-ai"), (provider) => { - provider.aisdk = true - provider.package = "test-provider" + provider.package = ProviderV2.aisdk("test-provider") }), ) yield* addPlugin() @@ -97,7 +96,6 @@ describe("CloudflareWorkersAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")), modelID: ModelV2.ID.make("@cf/model"), - aisdk: provider.aisdk, package: provider.package, settings: provider.settings, }), @@ -105,8 +103,7 @@ describe("CloudflareWorkersAIPlugin", () => { options: { name: "cloudflare-workers-ai", headers: { custom: "header" } }, }) expect(provider).toMatchObject({ - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", settings: { baseURL: "https://api.cloudflare.com/client/v4/accounts/acct/ai/v1" }, }) expect(sdk.sdk).toBeDefined() @@ -120,15 +117,13 @@ describe("CloudflareWorkersAIPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("cloudflare-workers-ai"), (provider) => { - provider.aisdk = true - provider.package = "test-provider" + provider.package = ProviderV2.aisdk("test-provider") provider.settings = { ...provider.settings, baseURL: "https://proxy.example/v1" } }), ) yield* addPlugin() expect(required(yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai")))).toMatchObject({ - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", settings: { baseURL: "https://proxy.example/v1" }, }) }), @@ -145,8 +140,7 @@ describe("CloudflareWorkersAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")), modelID: ModelV2.ID.make("@cf/model"), - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://proxy.example/v1" }, }), package: "@ai-sdk/openai-compatible", @@ -163,15 +157,13 @@ describe("CloudflareWorkersAIPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("cloudflare-workers-ai"), (provider) => { - provider.aisdk = true - provider.package = "test-provider" + provider.package = ProviderV2.aisdk("test-provider") provider.settings = { ...provider.settings, accountId: "configured-acct" } }), ) yield* addPlugin() expect(required(yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai")))).toMatchObject({ - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", settings: { baseURL: "https://api.cloudflare.com/client/v4/accounts/env-acct/ai/v1" }, }) }), @@ -188,8 +180,7 @@ describe("CloudflareWorkersAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")), modelID: ModelV2.ID.make("@cf/model"), - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://proxy.example/v1" }, }), package: "@ai-sdk/openai-compatible", @@ -218,8 +209,7 @@ describe("CloudflareWorkersAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")), modelID: ModelV2.ID.make("@cf/model"), - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/ai/v1" }, }), package: "@ai-sdk/openai-compatible", @@ -245,8 +235,7 @@ describe("CloudflareWorkersAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("@cf/api-model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -266,8 +255,7 @@ describe("CloudflareWorkersAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("@cf/model")), modelID: ModelV2.ID.make("@cf/model"), - aisdk: true, - package: "@ai-sdk/anthropic", + package: "aisdk:@ai-sdk/anthropic", settings: { baseURL: "https://proxy.example/v1" }, }), package: "@ai-sdk/anthropic", diff --git a/packages/core/test/plugin/provider-cohere.test.ts b/packages/core/test/plugin/provider-cohere.test.ts index fea89915bf..a4109f74bd 100644 --- a/packages/core/test/plugin/provider-cohere.test.ts +++ b/packages/core/test/plugin/provider-cohere.test.ts @@ -57,8 +57,7 @@ describe("CoherePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cohere"), ModelV2.ID.make("command")), modelID: ModelV2.ID.make("command"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "cohere" }, @@ -69,8 +68,7 @@ describe("CoherePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cohere"), ModelV2.ID.make("command")), modelID: ModelV2.ID.make("command"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/cohere", options: { name: "cohere" }, @@ -88,8 +86,7 @@ describe("CoherePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-cohere"), ModelV2.ID.make("command-r-plus")), modelID: ModelV2.ID.make("command-r-plus"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/cohere", options: { name: "custom-cohere", apiKey: "test", baseURL: "https://cohere.example" }, @@ -115,8 +112,7 @@ describe("CoherePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cohere"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("command-r-plus"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk, options: {}, diff --git a/packages/core/test/plugin/provider-deepinfra.test.ts b/packages/core/test/plugin/provider-deepinfra.test.ts index 6d1f74157d..14c41e550d 100644 --- a/packages/core/test/plugin/provider-deepinfra.test.ts +++ b/packages/core/test/plugin/provider-deepinfra.test.ts @@ -49,8 +49,7 @@ describe("DeepInfraPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "@ai-sdk/deepinfra", + package: "aisdk:@ai-sdk/deepinfra", }), package: "@ai-sdk/deepinfra", options: { name: "deepinfra" }, @@ -69,8 +68,7 @@ describe("DeepInfraPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-deepinfra"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "@ai-sdk/deepinfra", + package: "aisdk:@ai-sdk/deepinfra", }), package: "@ai-sdk/deepinfra", options: { name: "custom-deepinfra", apiKey: "test" }, @@ -90,8 +88,7 @@ describe("DeepInfraPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "@ai-sdk/deepinfra", + package: "aisdk:@ai-sdk/deepinfra", }), package: "@ai-sdk/deepinfra", options: { name: "deepinfra", apiKey: "test" }, @@ -118,8 +115,7 @@ describe("DeepInfraPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "@ai-sdk/deepinfra", + package: "aisdk:@ai-sdk/deepinfra", }), package: item, options: { name: "deepinfra" }, @@ -131,8 +127,7 @@ describe("DeepInfraPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "@ai-sdk/deepinfra", + package: "aisdk:@ai-sdk/deepinfra", }), package: "@ai-sdk/deepinfra", options: { name: "deepinfra" }, @@ -152,8 +147,7 @@ describe("DeepInfraPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("deepinfra"), ModelV2.ID.make("meta-llama/Llama-3.3-70B-Instruct")), modelID: ModelV2.ID.make("meta-llama/Llama-3.3-70B-Instruct"), - aisdk: true, - package: "@ai-sdk/deepinfra", + package: "aisdk:@ai-sdk/deepinfra", }), package: "@ai-sdk/deepinfra", options: { name: "deepinfra" }, diff --git a/packages/core/test/plugin/provider-dynamic.test.ts b/packages/core/test/plugin/provider-dynamic.test.ts index 68509bce9a..86e8864fb9 100644 --- a/packages/core/test/plugin/provider-dynamic.test.ts +++ b/packages/core/test/plugin/provider-dynamic.test.ts @@ -54,8 +54,7 @@ describe("DynamicProviderPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("test-model")), modelID: ModelV2.ID.make("test-model"), - aisdk: true, - package: fixtureProvider, + package: ProviderV2.aisdk(fixtureProvider), }), package: fixtureProvider, options: { name: "custom", marker: "dynamic" }, @@ -74,8 +73,7 @@ describe("DynamicProviderPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("test-model")), modelID: ModelV2.ID.make("test-model"), - aisdk: true, - package: fixtureProvider, + package: ProviderV2.aisdk(fixtureProvider), }), package: fixtureProvider, options: { name: "custom", marker: "dynamic" }, @@ -93,8 +91,7 @@ describe("DynamicProviderPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-provider"), ModelV2.ID.make("test-model")), modelID: ModelV2.ID.make("test-model"), - aisdk: true, - package: fixtureProvider, + package: ProviderV2.aisdk(fixtureProvider), }), package: fixtureProvider, options: { name: "custom-provider", marker: "dynamic" }, @@ -111,8 +108,7 @@ describe("DynamicProviderPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("npm-provider"), ModelV2.ID.make("test-model")), modelID: ModelV2.ID.make("test-model"), - aisdk: true, - package: "fixture-provider", + package: "aisdk:fixture-provider", }), package: "fixture-provider", options: { name: "npm-provider", marker: "npm" }, @@ -130,8 +126,7 @@ describe("DynamicProviderPlugin", () => { ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("missing-entrypoint"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("alias"), - aisdk: true, - package: "fixture-provider", + package: "aisdk:fixture-provider", }), ) .pipe(Effect.exit) @@ -149,8 +144,7 @@ describe("DynamicProviderPlugin", () => { ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("bad-import"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("alias"), - aisdk: true, - package: "file:///missing/provider-factory.js", + package: "aisdk:file:///missing/provider-factory.js", }), ) .pipe(Effect.exit) @@ -170,8 +164,7 @@ describe("DynamicProviderPlugin", () => { ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("missing-factory"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("alias"), - aisdk: true, - package: "fixture-provider", + package: "aisdk:fixture-provider", }), ) .pipe(Effect.exit) @@ -189,8 +182,7 @@ describe("DynamicProviderPlugin", () => { ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("test-model-api"), - aisdk: true, - package: fixtureProvider, + package: ProviderV2.aisdk(fixtureProvider), }), ) expect(language).toMatchObject({ modelID: "test-model-api", options: { name: "custom" } }) diff --git a/packages/core/test/plugin/provider-gateway.test.ts b/packages/core/test/plugin/provider-gateway.test.ts index 2c49e1a026..722bbde9b6 100644 --- a/packages/core/test/plugin/provider-gateway.test.ts +++ b/packages/core/test/plugin/provider-gateway.test.ts @@ -46,8 +46,7 @@ describe("GatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("gateway"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/gateway", options: { name: "gateway" }, @@ -68,8 +67,7 @@ describe("GatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("vercel"), ModelV2.ID.make("anthropic/claude-sonnet-4")), modelID: ModelV2.ID.make("anthropic/claude-sonnet-4"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/gateway", options: { name: "vercel", apiKey: "test-key" }, @@ -92,8 +90,7 @@ describe("GatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("vercel"), ModelV2.ID.make(modelID)), modelID: ModelV2.ID.make(modelID), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/vercel", options: { name: "vercel" }, @@ -104,8 +101,7 @@ describe("GatewayPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("vercel"), ModelV2.ID.make(modelID)), modelID: ModelV2.ID.make(modelID), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/gateway", options: { name: "vercel" }, diff --git a/packages/core/test/plugin/provider-github-copilot.test.ts b/packages/core/test/plugin/provider-github-copilot.test.ts index 44bea74ea4..4c5a3b1160 100644 --- a/packages/core/test/plugin/provider-github-copilot.test.ts +++ b/packages/core/test/plugin/provider-github-copilot.test.ts @@ -48,8 +48,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5")), modelID: ModelV2.ID.make("gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "github-copilot" }, @@ -58,8 +57,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5")), modelID: ModelV2.ID.make("gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/github-copilot", options: { name: "github-copilot" }, @@ -79,8 +77,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("claude-sonnet-4")), modelID: ModelV2.ID.make("claude-sonnet-4"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: {}, @@ -99,8 +96,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("claude-sonnet-4"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: {}, @@ -119,8 +115,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5")), modelID: ModelV2.ID.make("gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -129,8 +124,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5.1-codex")), modelID: ModelV2.ID.make("gpt-5.1-codex"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -139,8 +133,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-4o")), modelID: ModelV2.ID.make("gpt-4o"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -149,8 +142,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5-mini")), modelID: ModelV2.ID.make("gpt-5-mini"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -159,8 +151,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5-mini-2025-08-07")), modelID: ModelV2.ID.make("gpt-5-mini-2025-08-07"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -185,8 +176,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("default")), modelID: ModelV2.ID.make("gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -195,8 +185,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("small")), modelID: ModelV2.ID.make("gpt-5-mini"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -205,8 +194,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("sonnet")), modelID: ModelV2.ID.make("claude-sonnet-4"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -255,8 +243,7 @@ describe("GithubCopilotPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("openai"), ModelV2.ID.make("gpt-5")), modelID: ModelV2.ID.make("gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, diff --git a/packages/core/test/plugin/provider-gitlab.test.ts b/packages/core/test/plugin/provider-gitlab.test.ts index 6c72c65301..ae66a61aa8 100644 --- a/packages/core/test/plugin/provider-gitlab.test.ts +++ b/packages/core/test/plugin/provider-gitlab.test.ts @@ -71,8 +71,7 @@ describe("GitLabPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")), modelID: ModelV2.ID.make("claude"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "gitlab-ai-provider", options: { name: "gitlab" }, @@ -110,8 +109,7 @@ describe("GitLabPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")), modelID: ModelV2.ID.make("claude"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "gitlab-ai-provider", options: { name: "gitlab" }, @@ -137,8 +135,7 @@ describe("GitLabPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")), modelID: ModelV2.ID.make("claude"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "gitlab-ai-provider", options: { @@ -180,8 +177,7 @@ describe("GitLabPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")), modelID: ModelV2.ID.make("claude"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai", options: { name: "gitlab" }, @@ -201,8 +197,7 @@ describe("GitLabPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("duo-workflow-custom")), modelID: ModelV2.ID.make("duo-workflow-custom"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", headers: {}, settings: { workflowRef: "ref", workflowDefinition: "definition" }, }), @@ -236,8 +231,7 @@ describe("GitLabPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("duo-workflow-exact")), modelID: ModelV2.ID.make("duo-workflow-exact"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { workflowChat: (id: string, options: unknown) => { @@ -265,8 +259,7 @@ describe("GitLabPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("duo-workflow-custom")), modelID: ModelV2.ID.make("duo-workflow-custom"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", headers: {}, settings: { featureFlags: { request_flag: true } }, }), @@ -293,8 +286,7 @@ describe("GitLabPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("gitlab"), ModelV2.ID.make("claude")), modelID: ModelV2.ID.make("claude"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", headers: { h: "v" }, settings: {}, }), diff --git a/packages/core/test/plugin/provider-google-vertex-anthropic.test.ts b/packages/core/test/plugin/provider-google-vertex-anthropic.test.ts index 8afb38b1f8..090abb945c 100644 --- a/packages/core/test/plugin/provider-google-vertex-anthropic.test.ts +++ b/packages/core/test/plugin/provider-google-vertex-anthropic.test.ts @@ -64,8 +64,7 @@ describe("GoogleVertexAnthropicPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("google-vertex-anthropic"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/google-vertex/anthropic" + provider.package = ProviderV2.aisdk("@ai-sdk/google-vertex/anthropic") }), ) yield* addPlugin(GoogleVertexAnthropicPlugin) @@ -85,8 +84,7 @@ describe("GoogleVertexAnthropicPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("google-vertex-anthropic"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/google-vertex/anthropic" + provider.package = ProviderV2.aisdk("@ai-sdk/google-vertex/anthropic") provider.settings = { ...provider.settings, project: "configured-project", location: "configured-location" } }), ) @@ -123,8 +121,7 @@ describe("GoogleVertexAnthropicPlugin", () => { ModelV2.ID.make("claude-sonnet-4-5"), ), modelID: ModelV2.ID.make("claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/google-vertex/anthropic", options: { name: "google-vertex-anthropic" }, @@ -151,8 +148,7 @@ describe("GoogleVertexAnthropicPlugin", () => { ModelV2.ID.make("claude-sonnet-4-5"), ), modelID: ModelV2.ID.make("claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/google-vertex/anthropic", options: { name: "google-vertex-anthropic" }, @@ -173,8 +169,7 @@ describe("GoogleVertexAnthropicPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("claude-sonnet-4-5")), modelID: ModelV2.ID.make("claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/google-vertex/anthropic", options: { name: "google-vertex", project: "project", location: "eu" }, @@ -194,8 +189,7 @@ describe("GoogleVertexAnthropicPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("claude-sonnet-4-5")), modelID: ModelV2.ID.make("claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/google-vertex/anthropic", options: { name: "google-vertex", project: "project", location: "eu", baseURL: "https://proxy.example/v1" }, @@ -214,8 +208,7 @@ describe("GoogleVertexAnthropicPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make(" claude-sonnet-4-5 ")), modelID: ModelV2.ID.make(" claude-sonnet-4-5 "), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/google-vertex/anthropic", options: { name: "google-vertex", project: "project", location: "us" }, @@ -224,8 +217,7 @@ describe("GoogleVertexAnthropicPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make(" claude-sonnet-4-5 ")), modelID: ModelV2.ID.make(" claude-sonnet-4-5 "), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: sdkResult.sdk, options: {}, @@ -248,8 +240,7 @@ describe("GoogleVertexAnthropicPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex-anthropic"), ModelV2.ID.make(" claude-sonnet-4-5 ")), modelID: ModelV2.ID.make(" claude-sonnet-4-5 "), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: selector(calls) }, options: {}, @@ -268,8 +259,7 @@ describe("GoogleVertexAnthropicPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("claude-sonnet-4-5")), modelID: ModelV2.ID.make("claude-sonnet-4-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: selector(calls) }, options: {}, diff --git a/packages/core/test/plugin/provider-google-vertex.test.ts b/packages/core/test/plugin/provider-google-vertex.test.ts index 026bcd0282..fc7f398d75 100644 --- a/packages/core/test/plugin/provider-google-vertex.test.ts +++ b/packages/core/test/plugin/provider-google-vertex.test.ts @@ -92,8 +92,7 @@ describe("GoogleVertexPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.opencode, (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://opencode.ai/zen/v1" } }), ) @@ -119,8 +118,7 @@ describe("GoogleVertexPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: @@ -133,8 +131,7 @@ describe("GoogleVertexPlugin", () => { expect(provider.settings?.project).toBe("google-cloud-project") expect(provider.settings?.location).toBe("google-vertex-location") expect(provider).toMatchObject({ - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://google-vertex-location-aiplatform.googleapis.com/v1/projects/google-cloud-project/locations/google-vertex-location", @@ -163,8 +160,7 @@ describe("GoogleVertexPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: @@ -178,8 +174,7 @@ describe("GoogleVertexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("gemini")), modelID: ModelV2.ID.make("gemini"), - aisdk: true, - package: "@ai-sdk/google-vertex", + package: "aisdk:@ai-sdk/google-vertex", }), package: "@ai-sdk/google-vertex", options: { name: "google-vertex" }, @@ -187,8 +182,7 @@ describe("GoogleVertexPlugin", () => { expect(provider.settings?.project).toBe("vertex-project") expect(provider).toMatchObject({ - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://europe-west4-aiplatform.googleapis.com/v1/projects/vertex-project/locations/europe-west4", @@ -215,8 +209,7 @@ describe("GoogleVertexPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: @@ -230,8 +223,7 @@ describe("GoogleVertexPlugin", () => { expect(provider.settings?.project).toBe("config-project") expect(provider.settings?.location).toBe("global") expect(provider).toMatchObject({ - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://aiplatform.googleapis.com/v1/projects/config-project/locations/global" }, }) }), @@ -243,8 +235,7 @@ describe("GoogleVertexPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: @@ -256,8 +247,7 @@ describe("GoogleVertexPlugin", () => { yield* addPlugin() const provider = required(yield* catalog.provider.get(ProviderV2.ID.make("google-vertex"))) expect(provider).toMatchObject({ - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://eu-aiplatform.googleapis.com/v1/projects/config-project/locations/eu" }, }) }), @@ -278,8 +268,7 @@ describe("GoogleVertexPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/google-vertex" + provider.package = ProviderV2.aisdk("@ai-sdk/google-vertex") provider.settings = { ...provider.settings, project: "config-project" } }), ) @@ -307,8 +296,7 @@ describe("GoogleVertexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("gemini")), modelID: ModelV2.ID.make("gemini"), - aisdk: true, - package: "@ai-sdk/google-vertex", + package: "aisdk:@ai-sdk/google-vertex", }), package: "@ai-sdk/google-vertex", options: { name: "google-vertex" }, @@ -353,8 +341,7 @@ describe("GoogleVertexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make("gemini")), modelID: ModelV2.ID.make("gemini"), - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", }), package: "@ai-sdk/openai-compatible", options: { name: "google-vertex" }, @@ -382,8 +369,7 @@ describe("GoogleVertexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google-vertex"), ModelV2.ID.make(" gemini-2.5-pro ")), modelID: ModelV2.ID.make(" gemini-2.5-pro "), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: {}, diff --git a/packages/core/test/plugin/provider-google.test.ts b/packages/core/test/plugin/provider-google.test.ts index f2022d31d1..fd9a4c90dd 100644 --- a/packages/core/test/plugin/provider-google.test.ts +++ b/packages/core/test/plugin/provider-google.test.ts @@ -28,8 +28,7 @@ describe("GooglePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-google"), ModelV2.ID.make("gemini")), modelID: ModelV2.ID.make("gemini"), - aisdk: true, - package: "@ai-sdk/google", + package: "aisdk:@ai-sdk/google", }), package: "@ai-sdk/google", options: { name: "custom-google", apiKey: "test" }, @@ -48,8 +47,7 @@ describe("GooglePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("google"), ModelV2.ID.make("gemini")), modelID: ModelV2.ID.make("gemini"), - aisdk: true, - package: "@ai-sdk/google", + package: "aisdk:@ai-sdk/google", }), package: "@ai-sdk/google-vertex", options: { name: "google" }, @@ -67,8 +65,7 @@ describe("GooglePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-google"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("gemini-api"), - aisdk: true, - package: "@ai-sdk/google", + package: "aisdk:@ai-sdk/google", }), package: "@ai-sdk/google", options: { name: "custom-google", apiKey: "test" }, diff --git a/packages/core/test/plugin/provider-groq.test.ts b/packages/core/test/plugin/provider-groq.test.ts index 2e30264352..b8900384b7 100644 --- a/packages/core/test/plugin/provider-groq.test.ts +++ b/packages/core/test/plugin/provider-groq.test.ts @@ -29,8 +29,7 @@ describe("GroqPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("groq"), ModelV2.ID.make("llama")), modelID: ModelV2.ID.make("llama"), - aisdk: true, - package: "@ai-sdk/groq", + package: "aisdk:@ai-sdk/groq", }), package: "@ai-sdk/groq", options: { name: "groq" }, @@ -48,8 +47,7 @@ describe("GroqPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("groq"), ModelV2.ID.make("llama")), modelID: ModelV2.ID.make("llama"), - aisdk: true, - package: "@ai-sdk/groq", + package: "aisdk:@ai-sdk/groq", }), package: "@ai-sdk/openai-compatible", options: { name: "groq" }, @@ -67,8 +65,7 @@ describe("GroqPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("groq"), ModelV2.ID.make("llama")), modelID: ModelV2.ID.make("llama"), - aisdk: true, - package: "@ai-sdk/groq", + package: "aisdk:@ai-sdk/groq", }), package: "@ai-sdk/groq/compat", options: { name: "groq" }, @@ -86,8 +83,7 @@ describe("GroqPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-groq"), ModelV2.ID.make("llama")), modelID: ModelV2.ID.make("llama"), - aisdk: true, - package: "@ai-sdk/groq", + package: "aisdk:@ai-sdk/groq", }), package: "@ai-sdk/groq", options: { name: "custom-groq", apiKey: "test" }, @@ -113,8 +109,7 @@ describe("GroqPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("groq"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("llama-api"), - aisdk: true, - package: "@ai-sdk/groq", + package: "aisdk:@ai-sdk/groq", }), sdk, options: { name: "groq", apiKey: "test" }, diff --git a/packages/core/test/plugin/provider-kilo.test.ts b/packages/core/test/plugin/provider-kilo.test.ts index 7ad6b00382..8fc1287222 100644 --- a/packages/core/test/plugin/provider-kilo.test.ts +++ b/packages/core/test/plugin/provider-kilo.test.ts @@ -27,8 +27,7 @@ describe("KiloPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("kilo"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://api.kilo.ai/api/gateway" } provider.headers = { Existing: "value" } }) @@ -49,8 +48,7 @@ describe("KiloPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("kilo"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://api.kilo.ai/api/gateway" } }) }) @@ -71,13 +69,11 @@ describe("KiloPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("kilo"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://api.kilo.ai/api/gateway" } }) catalog.provider.update(ProviderV2.ID.make("custom-kilo"), (provider) => { - provider.aisdk = true - provider.package = "kilo" + provider.package = ProviderV2.aisdk("kilo") }) }) yield* addPlugin() diff --git a/packages/core/test/plugin/provider-llmgateway.test.ts b/packages/core/test/plugin/provider-llmgateway.test.ts index f0eb026aca..b3d451a473 100644 --- a/packages/core/test/plugin/provider-llmgateway.test.ts +++ b/packages/core/test/plugin/provider-llmgateway.test.ts @@ -34,8 +34,7 @@ describe("LLMGatewayPlugin", () => { }) yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("llmgateway"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://api.llmgateway.io/v1" } provider.headers = { Existing: "value" } }) @@ -62,8 +61,7 @@ describe("LLMGatewayPlugin", () => { yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("llmgateway"), (provider) => { provider.disabled = true - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://api.llmgateway.io/v1" } }) }) diff --git a/packages/core/test/plugin/provider-mistral.test.ts b/packages/core/test/plugin/provider-mistral.test.ts index 5e549e3ec8..182873482c 100644 --- a/packages/core/test/plugin/provider-mistral.test.ts +++ b/packages/core/test/plugin/provider-mistral.test.ts @@ -29,8 +29,7 @@ describe("MistralPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("mistral"), ModelV2.ID.make("mistral-large")), modelID: ModelV2.ID.make("mistral-large"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/mistral", options: { name: "mistral" }, @@ -48,8 +47,7 @@ describe("MistralPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("mistral"), ModelV2.ID.make("mistral-large")), modelID: ModelV2.ID.make("mistral-large"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "mistral" }, @@ -73,8 +71,7 @@ describe("MistralPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("mistral"), ModelV2.ID.make("mistral-large")), modelID: ModelV2.ID.make("mistral-large"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/mistral", options: { name: "mistral" }, @@ -99,8 +96,7 @@ describe("MistralPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-mistral"), ModelV2.ID.make("mistral-large")), modelID: ModelV2.ID.make("mistral-large"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/mistral", options: { name: "custom-mistral" }, @@ -125,8 +121,7 @@ describe("MistralPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("mistral"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("mistral-large"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk, options: {}, diff --git a/packages/core/test/plugin/provider-nvidia.test.ts b/packages/core/test/plugin/provider-nvidia.test.ts index b1f051ab9d..b5984d6237 100644 --- a/packages/core/test/plugin/provider-nvidia.test.ts +++ b/packages/core/test/plugin/provider-nvidia.test.ts @@ -27,8 +27,7 @@ describe("NvidiaPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("nvidia"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://integrate.api.nvidia.com/v1" } provider.headers = { Existing: "value" } }) @@ -50,8 +49,7 @@ describe("NvidiaPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("nvidia"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://integrate.api.nvidia.com/v1" } }) }) @@ -70,8 +68,7 @@ describe("NvidiaPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("nvidia"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://integrate.api.nvidia.com/v1" } provider.headers = { "X-BILLING-INVOKE-ORIGIN": "CustomOrigin" } }) diff --git a/packages/core/test/plugin/provider-openai-compatible.test.ts b/packages/core/test/plugin/provider-openai-compatible.test.ts index ac4e782cc6..a954af9f00 100644 --- a/packages/core/test/plugin/provider-openai-compatible.test.ts +++ b/packages/core/test/plugin/provider-openai-compatible.test.ts @@ -28,8 +28,7 @@ describe("OpenAICompatiblePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "custom" }, @@ -38,8 +37,7 @@ describe("OpenAICompatiblePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "custom", includeUsage: false }, @@ -58,8 +56,7 @@ describe("OpenAICompatiblePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "file:///tmp/@ai-sdk/openai-compatible-provider.js", options: { name: "custom" }, @@ -83,8 +80,7 @@ describe("OpenAICompatiblePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-provider"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "custom-provider", baseURL: "https://example.com/v1" }, @@ -105,8 +101,7 @@ describe("OpenAICompatiblePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("cloudflare-workers-ai"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "cloudflare-workers-ai" }, diff --git a/packages/core/test/plugin/provider-openai.test.ts b/packages/core/test/plugin/provider-openai.test.ts index c9866ea879..daf48310fd 100644 --- a/packages/core/test/plugin/provider-openai.test.ts +++ b/packages/core/test/plugin/provider-openai.test.ts @@ -68,8 +68,7 @@ describe("OpenAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-openai"), ModelV2.ID.make("gpt-5")), modelID: ModelV2.ID.make("gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai", options: { name: "custom-openai", apiKey: "test" }, @@ -87,8 +86,7 @@ describe("OpenAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("gpt-5")), modelID: ModelV2.ID.make("gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "openai" }, @@ -107,8 +105,7 @@ describe("OpenAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -128,8 +125,7 @@ describe("OpenAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.anthropic, ModelV2.ID.make("gpt-5")), modelID: ModelV2.ID.make("gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -145,11 +141,10 @@ describe("OpenAIPlugin", () => { yield* catalog.transform((catalog) => { const item = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.openai), - aisdk: true, - package: "@ai-sdk/openai", + package: "aisdk:@ai-sdk/openai", }) catalog.provider.update(item.id, (draft) => { - draft.aisdk = item.aisdk + draft.package = item.package draft.package = item.package }) catalog.model.update(item.id, ModelV2.ID.make("gpt-5"), () => {}) @@ -169,11 +164,10 @@ describe("OpenAIPlugin", () => { yield* catalog.transform((catalog) => { const item = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.make("custom-openai")), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }) catalog.provider.update(item.id, (draft) => { - draft.aisdk = item.aisdk + draft.package = item.package draft.package = item.package }) catalog.model.update(item.id, ModelV2.ID.make("gpt-5-chat-latest"), () => {}) diff --git a/packages/core/test/plugin/provider-opencode.test.ts b/packages/core/test/plugin/provider-opencode.test.ts index 3d8560b055..ebf7e6ff66 100644 --- a/packages/core/test/plugin/provider-opencode.test.ts +++ b/packages/core/test/plugin/provider-opencode.test.ts @@ -133,8 +133,7 @@ describe("OpencodePlugin", () => { expect(provider).toMatchObject({ name: "Remote", integrationID: "opencode", - aisdk: true, - package: "@ai-sdk/openai-compatible", + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: `${server.url.origin}/v1` }, }) expect(provider.headers).toEqual({ "x-org-id": "org" }) @@ -178,14 +177,12 @@ describe("OpencodePlugin", () => { yield* catalog.transform((catalog) => { const provider = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.opencode), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }) const model = ModelV2.Info.make({ ...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")), modelID: ModelV2.ID.make("paid"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", cost: cost(1), }) catalog.provider.update(provider.id, () => {}) @@ -207,14 +204,12 @@ describe("OpencodePlugin", () => { yield* catalog.transform((catalog) => { const provider = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.opencode), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }) const model = ModelV2.Info.make({ ...ModelV2.Info.empty(provider.id, ModelV2.ID.make("free")), modelID: ModelV2.ID.make("free"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", cost: cost(0), }) catalog.provider.update(provider.id, () => {}) @@ -236,14 +231,12 @@ describe("OpencodePlugin", () => { yield* catalog.transform((catalog) => { const provider = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.opencode), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }) const model = ModelV2.Info.make({ ...ModelV2.Info.empty(provider.id, ModelV2.ID.make("output-only")), modelID: ModelV2.ID.make("output-only"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", cost: cost(0, 1), }) catalog.provider.update(provider.id, () => {}) @@ -267,14 +260,12 @@ describe("OpencodePlugin", () => { yield* catalog.transform((catalog) => { const provider = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.opencode), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }) const model = ModelV2.Info.make({ ...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")), modelID: ModelV2.ID.make("paid"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", cost: cost(1), }) catalog.provider.update(provider.id, () => {}) @@ -303,14 +294,12 @@ describe("OpencodePlugin", () => { yield* catalog.transform((catalog) => { const provider = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.opencode), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }) const model = ModelV2.Info.make({ ...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")), modelID: ModelV2.ID.make("paid"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", cost: cost(1), }) catalog.provider.update(provider.id, () => {}) @@ -332,16 +321,14 @@ describe("OpencodePlugin", () => { yield* catalog.transform((catalog) => { const provider = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.opencode), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", headers: {}, settings: { apiKey: "configured" }, }) const model = ModelV2.Info.make({ ...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")), modelID: ModelV2.ID.make("paid"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", cost: cost(1), }) catalog.provider.update(provider.id, (draft) => { @@ -366,14 +353,12 @@ describe("OpencodePlugin", () => { yield* catalog.transform((catalog) => { const provider = ProviderV2.Info.make({ ...ProviderV2.Info.empty(ProviderV2.ID.openai), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }) const model = ModelV2.Info.make({ ...ModelV2.Info.empty(provider.id, ModelV2.ID.make("paid")), modelID: ModelV2.ID.make("paid"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", cost: cost(1), }) catalog.provider.update(provider.id, () => {}) diff --git a/packages/core/test/plugin/provider-openrouter.test.ts b/packages/core/test/plugin/provider-openrouter.test.ts index 5548b93597..7c3e140407 100644 --- a/packages/core/test/plugin/provider-openrouter.test.ts +++ b/packages/core/test/plugin/provider-openrouter.test.ts @@ -30,8 +30,7 @@ describe("OpenRouterPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.openrouter, (provider) => { - provider.aisdk = true - provider.package = "@openrouter/ai-sdk-provider" + provider.package = ProviderV2.aisdk("@openrouter/ai-sdk-provider") provider.headers = { Existing: "value" } provider.settings = {} }) @@ -58,8 +57,7 @@ describe("OpenRouterPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.openrouter, ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "openrouter" }, @@ -70,8 +68,7 @@ describe("OpenRouterPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("openai/gpt-5")), modelID: ModelV2.ID.make("openai/gpt-5"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@openrouter/ai-sdk-provider", options: { name: "custom" }, @@ -85,8 +82,7 @@ describe("OpenRouterPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.openrouter, (provider) => { - provider.aisdk = true - provider.package = "@openrouter/ai-sdk-provider" + provider.package = ProviderV2.aisdk("@openrouter/ai-sdk-provider") }) catalog.provider.update(ProviderV2.ID.openai, () => {}) catalog.model.update(ProviderV2.ID.openrouter, ModelV2.ID.make("openai/gpt-5-chat"), () => {}) diff --git a/packages/core/test/plugin/provider-perplexity.test.ts b/packages/core/test/plugin/provider-perplexity.test.ts index 121f5ddd54..d66f5dd71c 100644 --- a/packages/core/test/plugin/provider-perplexity.test.ts +++ b/packages/core/test/plugin/provider-perplexity.test.ts @@ -42,8 +42,7 @@ describe("PerplexityPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("perplexity"), ModelV2.ID.make("sonar")), modelID: ModelV2.ID.make("sonar"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/perplexity", options: { name: "perplexity" }, @@ -61,8 +60,7 @@ describe("PerplexityPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("perplexity"), ModelV2.ID.make("sonar")), modelID: ModelV2.ID.make("sonar"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/perplexity-compatible", options: { name: "perplexity" }, @@ -80,8 +78,7 @@ describe("PerplexityPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("perplexity"), ModelV2.ID.make("sonar")), modelID: ModelV2.ID.make("sonar"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/perplexity", options: { name: "perplexity" }, @@ -99,8 +96,7 @@ describe("PerplexityPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-perplexity"), ModelV2.ID.make("sonar")), modelID: ModelV2.ID.make("sonar"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/perplexity", options: { name: "custom-perplexity" }, @@ -119,8 +115,7 @@ describe("PerplexityPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("perplexity"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("sonar"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, diff --git a/packages/core/test/plugin/provider-sap-ai-core.test.ts b/packages/core/test/plugin/provider-sap-ai-core.test.ts index dd9bb4ec25..8822866be8 100644 --- a/packages/core/test/plugin/provider-sap-ai-core.test.ts +++ b/packages/core/test/plugin/provider-sap-ai-core.test.ts @@ -50,8 +50,7 @@ function model(providerID: string) { return ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make(providerID), ModelV2.ID.make("sap-model")), modelID: ModelV2.ID.make("sap-model"), - aisdk: true, - package: fixtureProvider, + package: ProviderV2.aisdk(fixtureProvider), }) } diff --git a/packages/core/test/plugin/provider-snowflake-cortex.test.ts b/packages/core/test/plugin/provider-snowflake-cortex.test.ts index 9fece1ecf6..f9be96b74b 100644 --- a/packages/core/test/plugin/provider-snowflake-cortex.test.ts +++ b/packages/core/test/plugin/provider-snowflake-cortex.test.ts @@ -58,8 +58,7 @@ describe("SnowflakeCortexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("openai"), ModelV2.ID.make("gpt-4")), modelID: ModelV2.ID.make("gpt-4"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai", options: { name: "openai" }, @@ -78,8 +77,7 @@ describe("SnowflakeCortexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")), modelID: ModelV2.ID.make("claude-sonnet-4-6"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "snowflake-cortex", baseURL: "https://test.snowflakecomputing.com/api/v2/cortex/v1" }, @@ -99,8 +97,7 @@ describe("SnowflakeCortexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")), modelID: ModelV2.ID.make("claude-sonnet-4-6"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { @@ -124,8 +121,7 @@ describe("SnowflakeCortexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")), modelID: ModelV2.ID.make("claude-sonnet-4-6"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "snowflake-cortex", baseURL: "https://test.snowflakecomputing.com/api/v2/cortex/v1" }, @@ -145,8 +141,7 @@ describe("SnowflakeCortexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")), modelID: ModelV2.ID.make("claude-sonnet-4-6"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { @@ -170,8 +165,7 @@ describe("SnowflakeCortexPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("snowflake-cortex"), ModelV2.ID.make("claude-sonnet-4-6")), modelID: ModelV2.ID.make("claude-sonnet-4-6"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "snowflake-cortex", baseURL: "https://test.snowflakecomputing.com/api/v2/cortex/v1" }, diff --git a/packages/core/test/plugin/provider-togetherai.test.ts b/packages/core/test/plugin/provider-togetherai.test.ts index fc87a0cfbd..1fffb03156 100644 --- a/packages/core/test/plugin/provider-togetherai.test.ts +++ b/packages/core/test/plugin/provider-togetherai.test.ts @@ -42,8 +42,7 @@ describe("TogetherAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("togetherai"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/togetherai", options: { name: "togetherai" }, @@ -62,8 +61,7 @@ describe("TogetherAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("togetherai"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "file:///tmp/@ai-sdk/togetherai-provider.js", options: { name: "togetherai" }, @@ -74,8 +72,7 @@ describe("TogetherAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("togetherai"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/togetherai", options: { name: "togetherai" }, @@ -94,8 +91,7 @@ describe("TogetherAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-togetherai"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/togetherai", options: { name: "custom-togetherai" }, @@ -119,8 +115,7 @@ describe("TogetherAIPlugin", () => { ModelV2.ID.make("meta-llama/Llama-3.3-70B-Instruct-Turbo"), ), modelID: ModelV2.ID.make("meta-llama/Llama-3.3-70B-Instruct-Turbo"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, options: {}, diff --git a/packages/core/test/plugin/provider-venice.test.ts b/packages/core/test/plugin/provider-venice.test.ts index ba4cfef8af..057d2c6ded 100644 --- a/packages/core/test/plugin/provider-venice.test.ts +++ b/packages/core/test/plugin/provider-venice.test.ts @@ -42,8 +42,7 @@ describe("VenicePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "venice-ai-sdk-provider", options: { name: "venice" }, @@ -61,8 +60,7 @@ describe("VenicePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-venice"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "venice-ai-sdk-provider", options: { name: "custom-venice", apiKey: "test" }, @@ -81,8 +79,7 @@ describe("VenicePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "file:///tmp/venice-ai-sdk-provider.js", options: { name: "venice" }, @@ -91,8 +88,7 @@ describe("VenicePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("model")), modelID: ModelV2.ID.make("model"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), package: "@ai-sdk/openai-compatible", options: { name: "venice" }, @@ -112,8 +108,7 @@ describe("VenicePlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("venice"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("alias"), - aisdk: true, - package: "test-provider", + package: "aisdk:test-provider", }), sdk: fakeSelectorSdk(calls), options: {}, diff --git a/packages/core/test/plugin/provider-vercel.test.ts b/packages/core/test/plugin/provider-vercel.test.ts index 08f169aa6e..46d5fe25b8 100644 --- a/packages/core/test/plugin/provider-vercel.test.ts +++ b/packages/core/test/plugin/provider-vercel.test.ts @@ -25,8 +25,7 @@ describe("VercelPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("vercel"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/vercel" + provider.package = ProviderV2.aisdk("@ai-sdk/vercel") provider.headers = { ...provider.headers, Existing: "1" } }) }) @@ -44,8 +43,7 @@ describe("VercelPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => catalog.provider.update(ProviderV2.ID.make("vercel"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/vercel" + provider.package = ProviderV2.aisdk("@ai-sdk/vercel") }), ) yield* addPlugin() @@ -63,8 +61,7 @@ describe("VercelPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-vercel"), ModelV2.ID.make("v0-1.0-md")), modelID: ModelV2.ID.make("v0-1.0-md"), - aisdk: true, - package: "@ai-sdk/vercel", + package: "aisdk:@ai-sdk/vercel", }), package: "@ai-sdk/vercel", options: { name: "custom-vercel" }, diff --git a/packages/core/test/plugin/provider-xai.test.ts b/packages/core/test/plugin/provider-xai.test.ts index 525b2bbb62..94824af339 100644 --- a/packages/core/test/plugin/provider-xai.test.ts +++ b/packages/core/test/plugin/provider-xai.test.ts @@ -43,8 +43,7 @@ describe("XAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("grok-4")), modelID: ModelV2.ID.make("grok-4"), - aisdk: true, - package: "@ai-sdk/xai", + package: "aisdk:@ai-sdk/xai", }), package: "@ai-sdk/openai-compatible", options: {}, @@ -54,8 +53,7 @@ describe("XAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("grok-4")), modelID: ModelV2.ID.make("grok-4"), - aisdk: true, - package: "@ai-sdk/xai", + package: "aisdk:@ai-sdk/xai", }), package: "@ai-sdk/xai", options: {}, @@ -76,8 +74,7 @@ describe("XAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("custom-xai"), ModelV2.ID.make("grok-4")), modelID: ModelV2.ID.make("grok-4"), - aisdk: true, - package: "@ai-sdk/xai", + package: "aisdk:@ai-sdk/xai", }), package: "@ai-sdk/xai", options: {}, @@ -98,8 +95,7 @@ describe("XAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("alias")), modelID: ModelV2.ID.make("grok-4"), - aisdk: true, - package: "@ai-sdk/xai", + package: "aisdk:@ai-sdk/xai", }), sdk: fakeSelectorSdk(calls), options: {}, @@ -121,8 +117,7 @@ describe("XAIPlugin", () => { model: ModelV2.Info.make({ ...ModelV2.Info.empty(ProviderV2.ID.openai, ModelV2.ID.make("grok-4")), modelID: ModelV2.ID.make("grok-4"), - aisdk: true, - package: "@ai-sdk/xai", + package: "aisdk:@ai-sdk/xai", }), sdk: fakeSelectorSdk(calls), options: {}, diff --git a/packages/core/test/plugin/provider-zenmux.test.ts b/packages/core/test/plugin/provider-zenmux.test.ts index 15da40167e..02856e232a 100644 --- a/packages/core/test/plugin/provider-zenmux.test.ts +++ b/packages/core/test/plugin/provider-zenmux.test.ts @@ -32,8 +32,7 @@ describe("ZenmuxPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("zenmux"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://zenmux.ai/api/v1" } }) }) @@ -49,8 +48,7 @@ describe("ZenmuxPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("zenmux"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://zenmux.ai/api/v1" } provider.headers = { ...provider.headers, Existing: "value" } }) @@ -70,8 +68,7 @@ describe("ZenmuxPlugin", () => { const catalog = yield* Catalog.Service yield* catalog.transform((catalog) => { catalog.provider.update(ProviderV2.ID.make("zenmux"), (provider) => { - provider.aisdk = true - provider.package = "@ai-sdk/openai-compatible" + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") provider.settings = { ...provider.settings, baseURL: "https://zenmux.ai/api/v1" } provider.headers = { "HTTP-Referer": "https://example.com/", "X-Title": "custom-title" } }) diff --git a/packages/core/test/plugin/variant.test.ts b/packages/core/test/plugin/variant.test.ts index e20fd3a11d..fc85cc69ce 100644 --- a/packages/core/test/plugin/variant.test.ts +++ b/packages/core/test/plugin/variant.test.ts @@ -23,13 +23,7 @@ const connections = Credential.defaultLayer.pipe(Layer.fresh) const integrations = Integration.locationLayer.pipe(Layer.provide(events), Layer.provide(connections)) const catalog = Catalog.layer.pipe( Layer.provide( - Layer.mergeAll( - events, - locationLayer, - Policy.layer.pipe(Layer.provide(locationLayer)), - connections, - integrations, - ), + Layer.mergeAll(events, locationLayer, Policy.layer.pipe(Layer.provide(locationLayer)), connections, integrations), ), ) const it = testEffect( @@ -42,13 +36,11 @@ describe("VariantPlugin", () => { const service = yield* Catalog.Service yield* service.transform((catalog) => { catalog.provider.update(ProviderV2.ID.opencode, (provider) => { - provider.package = "@ai-sdk/openai-compatible" - provider.aisdk = true + provider.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") }) catalog.model.update(ProviderV2.ID.opencode, ModelV2.ID.make("glm-5.2"), (model) => { model.modelID = ModelV2.ID.make("glm-5.2") - model.package = "@ai-sdk/openai-compatible" - model.aisdk = true + model.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") }) }) yield* VariantPlugin.Plugin.effect(host({ catalog: catalogHost(service) })) @@ -66,11 +58,8 @@ describe("VariantPlugin", () => { yield* service.transform((catalog) => { catalog.model.update(ProviderV2.ID.opencode, ModelV2.ID.make("glm-5.2"), (model) => { model.modelID = ModelV2.ID.make("glm-5.2") - model.package = "@ai-sdk/openai-compatible" - model.aisdk = true - model.variants = [ - { id: ModelV2.VariantID.make("high"), headers: { custom: "true" } }, - ] + model.package = ProviderV2.aisdk("@ai-sdk/openai-compatible") + model.variants = [{ id: ModelV2.VariantID.make("high"), headers: { custom: "true" } }] }) }) yield* VariantPlugin.Plugin.effect(host({ catalog: catalogHost(service) })) diff --git a/packages/core/test/session-runner-model.test.ts b/packages/core/test/session-runner-model.test.ts index d2283a1086..824e0278f1 100644 --- a/packages/core/test/session-runner-model.test.ts +++ b/packages/core/test/session-runner-model.test.ts @@ -14,7 +14,6 @@ import { it } from "./lib/effect" type Transport = { readonly package: string - readonly aisdk?: true readonly settings?: Record } @@ -38,10 +37,36 @@ const model = (transport: Transport, variants?: NonNullable { + it.effect("constructs native provider package models mechanically", () => + Effect.gen(function* () { + const resolved = yield* SessionRunnerModel.fromCatalogModel( + model({ + package: "@opencode-ai/llm/providers/openai", + settings: { baseURL: "https://openai.example/v1" }, + }), + Credential.Key.make({ type: "key", key: "runtime-secret" }), + ) + const headers = yield* resolved.route.auth.apply({ + request: LLM.request({ model: resolved, prompt: "Hello" }), + method: "POST", + url: "https://openai.example/v1/responses", + body: "{}", + headers: Headers.empty, + }) + + expect(String(resolved.id)).toBe("api-test-model") + expect(resolved.route.id).toBe("openai-responses") + expect(resolved.route.defaults.headers).toEqual({ "x-test": "header" }) + expect(resolved.route.defaults.http?.body).toEqual({ custom_extension: { enabled: true } }) + expect(resolved.route.defaults.limits).toEqual({ context: 100, output: 20 }) + expect(headers.authorization).toBe("Bearer runtime-secret") + }), + ) + it.effect("maps catalog OpenAI AI SDK models into native Responses routes", () => Effect.gen(function* () { const resolved = yield* SessionRunnerModel.fromCatalogModel( - model({ package: "@ai-sdk/openai", aisdk: true, settings: { baseURL: "https://openai.example/v1" } }), + model({ package: "aisdk:@ai-sdk/openai", settings: { baseURL: "https://openai.example/v1" } }), ) expect(resolved).toMatchObject({ id: "api-test-model", provider: "test-provider" }) @@ -60,7 +85,7 @@ describe("SessionRunnerModel", () => { it.effect("keeps catalog apiKey credentials out of provider JSON", () => Effect.gen(function* () { const resolved = yield* SessionRunnerModel.fromCatalogModel( - model({ package: "@ai-sdk/openai", aisdk: true, settings: { baseURL: "https://openai.example/v1" } }), + model({ package: "aisdk:@ai-sdk/openai", settings: { baseURL: "https://openai.example/v1" } }), ) const prepared = yield* LLMClient.prepare(LLM.request({ model: resolved, prompt: "Hello" })) @@ -74,8 +99,7 @@ describe("SessionRunnerModel", () => { const resolved = yield* SessionRunnerModel.fromCatalogModel( ModelV2.Info.make({ ...model({ - package: "@ai-sdk/openai-compatible", - aisdk: true, + package: "aisdk:@ai-sdk/openai-compatible", settings: { apiKey: "settings-secret", baseURL: "https://compatible.example/v1", @@ -102,7 +126,7 @@ describe("SessionRunnerModel", () => { it.effect("overlays selected OpenAI Session variant bodies", () => Effect.gen(function* () { - const catalog = model({ package: "@ai-sdk/openai", aisdk: true, settings: { baseURL: "https://openai.example/v1" } }, [ + const catalog = model({ package: "aisdk:@ai-sdk/openai", settings: { baseURL: "https://openai.example/v1" } }, [ { id: ModelV2.VariantID.make("high"), headers: { "x-variant": "high" }, @@ -146,8 +170,7 @@ describe("SessionRunnerModel", () => { Effect.gen(function* () { const catalog = model( { - package: "@ai-sdk/openai-compatible", - aisdk: true, + package: "aisdk:@ai-sdk/openai-compatible", settings: { baseURL: "https://compatible.example/v1" }, }, [ @@ -181,7 +204,7 @@ describe("SessionRunnerModel", () => { it.effect("rejects an explicit unavailable Session variant during model resolution", () => Effect.gen(function* () { - const catalog = model({ package: "@ai-sdk/openai", aisdk: true, settings: { baseURL: "https://openai.example/v1" } }) + const catalog = model({ package: "aisdk:@ai-sdk/openai", settings: { baseURL: "https://openai.example/v1" } }) const session = SessionV2.Info.make({ id: SessionV2.ID.make("ses_model_variant_unavailable"), projectID: ProjectV2.ID.global, @@ -211,13 +234,16 @@ describe("SessionRunnerModel", () => { it.effect("overlays selected Anthropic Session variant bodies", () => Effect.gen(function* () { - const catalog = model({ package: "@ai-sdk/anthropic", aisdk: true, settings: { baseURL: "https://anthropic.example/v1" } }, [ - { - id: ModelV2.VariantID.make("high"), - headers: {}, - body: { thinking: { type: "enabled", budget_tokens: 12000 } }, - }, - ]) + const catalog = model( + { package: "aisdk:@ai-sdk/anthropic", settings: { baseURL: "https://anthropic.example/v1" } }, + [ + { + id: ModelV2.VariantID.make("high"), + headers: {}, + body: { thinking: { type: "enabled", budget_tokens: 12000 } }, + }, + ], + ) const session = SessionV2.Info.make({ id: SessionV2.ID.make("ses_anthropic_variant"), projectID: ProjectV2.ID.global, @@ -241,7 +267,7 @@ describe("SessionRunnerModel", () => { it.effect("maps catalog Anthropic AI SDK models into native routes", () => Effect.gen(function* () { const resolved = yield* SessionRunnerModel.fromCatalogModel( - model({ package: "@ai-sdk/anthropic", aisdk: true, settings: { baseURL: "https://anthropic.example/v1" } }), + model({ package: "aisdk:@ai-sdk/anthropic", settings: { baseURL: "https://anthropic.example/v1" } }), ) expect(resolved.route).toMatchObject({ @@ -255,7 +281,7 @@ describe("SessionRunnerModel", () => { Effect.gen(function* () { const resolved = yield* SessionRunnerModel.fromCatalogModel( ModelV2.Info.make({ - ...model({ package: "@ai-sdk/openai", aisdk: true, settings: { baseURL: "https://openai.example/v1" } }), + ...model({ package: "aisdk:@ai-sdk/openai", settings: { baseURL: "https://openai.example/v1" } }), headers: {}, body: {}, }), @@ -279,7 +305,7 @@ describe("SessionRunnerModel", () => { const credential = Credential.Key.make({ type: "key", key: "stored-secret", metadata: { tenant: "work" } }) const resolved = yield* SessionRunnerModel.fromCatalogModel( ModelV2.Info.make({ - ...model({ package: "@ai-sdk/openai", aisdk: true, settings: { baseURL: "https://openai.example/v1" } }), + ...model({ package: "aisdk:@ai-sdk/openai", settings: { baseURL: "https://openai.example/v1" } }), settings: { apiKey: "configured-secret", baseURL: "https://openai.example/v1" }, headers: {}, body: {}, @@ -302,7 +328,7 @@ describe("SessionRunnerModel", () => { it.effect("rejects catalog APIs without a native route", () => Effect.gen(function* () { const failure = yield* SessionRunnerModel.fromCatalogModel( - model({ package: "@ai-sdk/google", aisdk: true, settings: { baseURL: "https://google.example/v1" } }), + model({ package: "aisdk:@ai-sdk/google", settings: { baseURL: "https://google.example/v1" } }), ).pipe(Effect.flip) expect(failure).toMatchObject({ @@ -319,15 +345,15 @@ describe("SessionRunnerModel", () => { Effect.sync(() => { expect( SessionRunnerModel.supported( - model({ package: "@ai-sdk/openai", aisdk: true, settings: { baseURL: "https://openai.example/v1" } }), + model({ package: "aisdk:@ai-sdk/openai", settings: { baseURL: "https://openai.example/v1" } }), ), ).toBe(true) expect( SessionRunnerModel.supported( - model({ package: "@ai-sdk/google", aisdk: true, settings: { baseURL: "https://google.example/v1" } }), + model({ package: "aisdk:@ai-sdk/google", settings: { baseURL: "https://google.example/v1" } }), ), ).toBe(false) - expect(SessionRunnerModel.supported(model({ package: "native" }))).toBe(false) + expect(SessionRunnerModel.supported(model({ package: "native-provider-package" }))).toBe(true) }), ) }) diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 694e00560c..6d91a3ac96 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -3991,7 +3991,6 @@ export type ModelV2Info = { family?: string name: string package?: string - aisdk?: true settings?: { [key: string]: unknown } @@ -4048,7 +4047,6 @@ export type ProviderV2Info = { name: string disabled?: boolean package: string - aisdk?: true settings?: { [key: string]: unknown }