refactor(core): nest model api id (#30603)
This commit is contained in:
@@ -164,7 +164,7 @@ export const layer = Layer.effect(
|
|||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
.pipe(initError(model.providerID))
|
.pipe(initError(model.providerID))
|
||||||
const language = yield* Effect.sync(() => result.language ?? sdk.languageModel(model.apiID)).pipe(
|
const language = yield* Effect.sync(() => result.language ?? sdk.languageModel(model.api.id)).pipe(
|
||||||
initError(model.providerID),
|
initError(model.providerID),
|
||||||
)
|
)
|
||||||
languages.set(key, language)
|
languages.set(key, language)
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export const layer = Layer.effect(
|
|||||||
const provider = state.get().providers.get(model.providerID)!.provider
|
const provider = state.get().providers.get(model.providerID)!.provider
|
||||||
const api =
|
const api =
|
||||||
model.api.type === "native" && !model.api.url && Object.keys(model.api.settings).length === 0
|
model.api.type === "native" && !model.api.url && Object.keys(model.api.settings).length === 0
|
||||||
? provider.api
|
? { ...provider.api, id: model.api.id }
|
||||||
: model.api.type === "aisdk" && provider.api.type === "aisdk" && !model.api.url
|
: model.api.type === "aisdk" && provider.api.type === "aisdk" && !model.api.url
|
||||||
? { ...model.api, url: provider.api.url, settings: { ...provider.api.settings, ...model.api.settings } }
|
? { ...model.api, url: provider.api.url, settings: { ...provider.api.settings, ...model.api.settings } }
|
||||||
: model.api.type === "aisdk" && provider.api.type === "aisdk"
|
: model.api.type === "aisdk" && provider.api.type === "aisdk"
|
||||||
|
|||||||
@@ -32,10 +32,9 @@ export const Plugin = PluginV2.define({
|
|||||||
|
|
||||||
for (const [id, config] of Object.entries(item.models ?? {})) {
|
for (const [id, config] of Object.entries(item.models ?? {})) {
|
||||||
catalog.model.update(providerID, ModelV2.ID.make(id), (model) => {
|
catalog.model.update(providerID, ModelV2.ID.make(id), (model) => {
|
||||||
if (config.api_id !== undefined) model.apiID = config.api_id
|
|
||||||
if (config.family !== undefined) model.family = config.family
|
if (config.family !== undefined) model.family = config.family
|
||||||
if (config.name !== undefined) model.name = config.name
|
if (config.name !== undefined) model.name = config.name
|
||||||
if (config.api !== undefined) model.api = { ...config.api }
|
if (config.api !== undefined) model.api = { ...model.api, ...config.api }
|
||||||
if (config.capabilities !== undefined) {
|
if (config.capabilities !== undefined) {
|
||||||
model.capabilities = {
|
model.capabilities = {
|
||||||
tools: config.capabilities.tools,
|
tools: config.capabilities.tools,
|
||||||
|
|||||||
@@ -30,11 +30,24 @@ class Limit extends Schema.Class<Limit>("ConfigV2.Model.Limit")({
|
|||||||
output: Schema.Int.pipe(Schema.optional),
|
output: Schema.Int.pipe(Schema.optional),
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
|
const ModelApi = Schema.Union([
|
||||||
|
Schema.Struct({
|
||||||
|
id: ModelV2.ID.pipe(Schema.optional),
|
||||||
|
...ProviderV2.AISDK.fields,
|
||||||
|
}),
|
||||||
|
Schema.Struct({
|
||||||
|
id: ModelV2.ID.pipe(Schema.optional),
|
||||||
|
...ProviderV2.Native.fields,
|
||||||
|
}),
|
||||||
|
Schema.Struct({
|
||||||
|
id: ModelV2.ID,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
|
||||||
class Model extends Schema.Class<Model>("ConfigV2.Model")({
|
class Model extends Schema.Class<Model>("ConfigV2.Model")({
|
||||||
api_id: ModelV2.ID.pipe(Schema.optional),
|
|
||||||
family: ModelV2.Family.pipe(Schema.optional),
|
family: ModelV2.Family.pipe(Schema.optional),
|
||||||
name: Schema.String.pipe(Schema.optional),
|
name: Schema.String.pipe(Schema.optional),
|
||||||
api: ProviderV2.Api.pipe(Schema.optional),
|
api: ModelApi.pipe(Schema.optional),
|
||||||
capabilities: ModelV2.Capabilities.pipe(Schema.optional),
|
capabilities: ModelV2.Capabilities.pipe(Schema.optional),
|
||||||
request: Schema.Struct({
|
request: Schema.Struct({
|
||||||
...Request.fields,
|
...Request.fields,
|
||||||
|
|||||||
@@ -40,13 +40,24 @@ export const Ref = Schema.Struct({
|
|||||||
})
|
})
|
||||||
export type Ref = typeof Ref.Type
|
export type Ref = typeof Ref.Type
|
||||||
|
|
||||||
|
export const Api = Schema.Union([
|
||||||
|
Schema.Struct({
|
||||||
|
id: ID,
|
||||||
|
...ProviderV2.AISDK.fields,
|
||||||
|
}),
|
||||||
|
Schema.Struct({
|
||||||
|
id: ID,
|
||||||
|
...ProviderV2.Native.fields,
|
||||||
|
}),
|
||||||
|
]).pipe(Schema.toTaggedUnion("type"))
|
||||||
|
export type Api = typeof Api.Type
|
||||||
|
|
||||||
export class Info extends Schema.Class<Info>("ModelV2.Info")({
|
export class Info extends Schema.Class<Info>("ModelV2.Info")({
|
||||||
id: ID,
|
id: ID,
|
||||||
apiID: ID,
|
|
||||||
providerID: ProviderV2.ID,
|
providerID: ProviderV2.ID,
|
||||||
family: Family.pipe(Schema.optional),
|
family: Family.pipe(Schema.optional),
|
||||||
name: Schema.String,
|
name: Schema.String,
|
||||||
api: ProviderV2.Api,
|
api: Api,
|
||||||
capabilities: Capabilities,
|
capabilities: Capabilities,
|
||||||
request: Schema.Struct({
|
request: Schema.Struct({
|
||||||
...ProviderV2.Request.fields,
|
...ProviderV2.Request.fields,
|
||||||
@@ -71,10 +82,10 @@ export class Info extends Schema.Class<Info>("ModelV2.Info")({
|
|||||||
static empty(providerID: ProviderV2.ID, modelID: ID): Info {
|
static empty(providerID: ProviderV2.ID, modelID: ID): Info {
|
||||||
return new Info({
|
return new Info({
|
||||||
id: modelID,
|
id: modelID,
|
||||||
apiID: modelID,
|
|
||||||
providerID,
|
providerID,
|
||||||
name: modelID,
|
name: modelID,
|
||||||
api: {
|
api: {
|
||||||
|
id: modelID,
|
||||||
type: "native",
|
type: "native",
|
||||||
settings: {},
|
settings: {},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -82,11 +82,13 @@ export const ModelsDevPlugin = PluginV2.define({
|
|||||||
draft.family = model.family ? ModelV2.Family.make(model.family) : undefined
|
draft.family = model.family ? ModelV2.Family.make(model.family) : undefined
|
||||||
draft.api = model.provider?.npm
|
draft.api = model.provider?.npm
|
||||||
? {
|
? {
|
||||||
|
id: draft.api.id,
|
||||||
type: "aisdk",
|
type: "aisdk",
|
||||||
package: model.provider?.npm,
|
package: model.provider?.npm,
|
||||||
url: model.provider.api,
|
url: model.provider.api,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
|
id: draft.api.id,
|
||||||
type: "native",
|
type: "native",
|
||||||
url: model.provider?.api,
|
url: model.provider?.api,
|
||||||
settings: {},
|
settings: {},
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export const AmazonBedrockPlugin = PluginV2.define({
|
|||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.amazonBedrock) return
|
if (evt.model.providerID !== ProviderV2.ID.amazonBedrock) return
|
||||||
const region = typeof evt.options.region === "string" ? evt.options.region : process.env.AWS_REGION
|
const region = typeof evt.options.region === "string" ? evt.options.region : process.env.AWS_REGION
|
||||||
evt.language = evt.sdk.languageModel(resolveModelID(evt.model.apiID, region))
|
evt.language = evt.sdk.languageModel(resolveModelID(evt.model.api.id, region))
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export const AzurePlugin = PluginV2.define({
|
|||||||
}),
|
}),
|
||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.azure) return
|
if (evt.model.providerID !== ProviderV2.ID.azure) return
|
||||||
evt.language = selectLanguage(evt.sdk, evt.model.apiID, Boolean(evt.options.useCompletionUrls))
|
evt.language = selectLanguage(evt.sdk, evt.model.api.id, Boolean(evt.options.useCompletionUrls))
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -69,7 +69,7 @@ export const AzureCognitiveServicesPlugin = PluginV2.define({
|
|||||||
}),
|
}),
|
||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("azure-cognitive-services")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("azure-cognitive-services")) return
|
||||||
evt.language = selectLanguage(evt.sdk, evt.model.apiID, Boolean(evt.options.useCompletionUrls))
|
evt.language = selectLanguage(evt.sdk, evt.model.api.id, Boolean(evt.options.useCompletionUrls))
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const CloudflareWorkersAIPlugin = PluginV2.define({
|
|||||||
}),
|
}),
|
||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== providerID) return
|
if (evt.model.providerID !== providerID) return
|
||||||
evt.language = evt.sdk.languageModel(evt.model.apiID)
|
evt.language = evt.sdk.languageModel(evt.model.api.id)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ export const GithubCopilotPlugin = PluginV2.define({
|
|||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.githubCopilot) return
|
if (evt.model.providerID !== ProviderV2.ID.githubCopilot) return
|
||||||
if (evt.sdk.responses === undefined && evt.sdk.chat === undefined) {
|
if (evt.sdk.responses === undefined && evt.sdk.chat === undefined) {
|
||||||
evt.language = evt.sdk.languageModel(evt.model.apiID)
|
evt.language = evt.sdk.languageModel(evt.model.api.id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
evt.language = shouldUseResponses(evt.model.apiID)
|
evt.language = shouldUseResponses(evt.model.api.id)
|
||||||
? evt.sdk.responses(evt.model.apiID)
|
? evt.sdk.responses(evt.model.api.id)
|
||||||
: evt.sdk.chat(evt.model.apiID)
|
: evt.sdk.chat(evt.model.api.id)
|
||||||
}),
|
}),
|
||||||
"catalog.transform": Effect.fn(function* (evt) {
|
"catalog.transform": Effect.fn(function* (evt) {
|
||||||
const item = evt.provider.get(ProviderV2.ID.githubCopilot)
|
const item = evt.provider.get(ProviderV2.ID.githubCopilot)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export const GitLabPlugin = PluginV2.define({
|
|||||||
if (evt.model.providerID !== ProviderV2.ID.gitlab) return
|
if (evt.model.providerID !== ProviderV2.ID.gitlab) return
|
||||||
const featureFlags =
|
const featureFlags =
|
||||||
typeof evt.options.featureFlags === "object" && evt.options.featureFlags ? evt.options.featureFlags : {}
|
typeof evt.options.featureFlags === "object" && evt.options.featureFlags ? evt.options.featureFlags : {}
|
||||||
if (evt.model.apiID.startsWith("duo-workflow-")) {
|
if (evt.model.api.id.startsWith("duo-workflow-")) {
|
||||||
const gitlab = yield* Effect.promise(() => import("gitlab-ai-provider")).pipe(Effect.orDie)
|
const gitlab = yield* Effect.promise(() => import("gitlab-ai-provider")).pipe(Effect.orDie)
|
||||||
const workflowRef =
|
const workflowRef =
|
||||||
typeof evt.model.request.body.workflowRef === "string" ? evt.model.request.body.workflowRef : undefined
|
typeof evt.model.request.body.workflowRef === "string" ? evt.model.request.body.workflowRef : undefined
|
||||||
@@ -43,7 +43,7 @@ export const GitLabPlugin = PluginV2.define({
|
|||||||
? evt.model.request.body.workflowDefinition
|
? evt.model.request.body.workflowDefinition
|
||||||
: undefined
|
: undefined
|
||||||
const language = evt.sdk.workflowChat(
|
const language = evt.sdk.workflowChat(
|
||||||
gitlab.isWorkflowModel(evt.model.apiID) ? evt.model.apiID : "duo-workflow",
|
gitlab.isWorkflowModel(evt.model.api.id) ? evt.model.api.id : "duo-workflow",
|
||||||
{
|
{
|
||||||
featureFlags,
|
featureFlags,
|
||||||
workflowDefinition,
|
workflowDefinition,
|
||||||
@@ -53,7 +53,7 @@ export const GitLabPlugin = PluginV2.define({
|
|||||||
evt.language = language
|
evt.language = language
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
evt.language = evt.sdk.agenticChat(evt.model.apiID, {
|
evt.language = evt.sdk.agenticChat(evt.model.api.id, {
|
||||||
aiGatewayHeaders: evt.options.aiGatewayHeaders,
|
aiGatewayHeaders: evt.options.aiGatewayHeaders,
|
||||||
featureFlags,
|
featureFlags,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export const GoogleVertexPlugin = PluginV2.define({
|
|||||||
}),
|
}),
|
||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.googleVertex) return
|
if (evt.model.providerID !== ProviderV2.ID.googleVertex) return
|
||||||
evt.language = evt.sdk.languageModel(String(evt.model.apiID).trim())
|
evt.language = evt.sdk.languageModel(String(evt.model.api.id).trim())
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -155,7 +155,7 @@ export const GoogleVertexAnthropicPlugin = PluginV2.define({
|
|||||||
}),
|
}),
|
||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("google-vertex-anthropic")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("google-vertex-anthropic")) return
|
||||||
evt.language = evt.sdk.languageModel(String(evt.model.apiID).trim())
|
evt.language = evt.sdk.languageModel(String(evt.model.api.id).trim())
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const OpenAIPlugin = PluginV2.define({
|
|||||||
}),
|
}),
|
||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.openai) return
|
if (evt.model.providerID !== ProviderV2.ID.openai) return
|
||||||
evt.language = evt.sdk.responses(evt.model.apiID)
|
evt.language = evt.sdk.responses(evt.model.api.id)
|
||||||
}),
|
}),
|
||||||
"catalog.transform": Effect.fn(function* (evt) {
|
"catalog.transform": Effect.fn(function* (evt) {
|
||||||
for (const item of evt.provider.list()) {
|
for (const item of evt.provider.list()) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export const SapAICorePlugin = PluginV2.define({
|
|||||||
}),
|
}),
|
||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return
|
||||||
evt.language = evt.sdk(evt.model.apiID)
|
evt.language = evt.sdk(evt.model.api.id)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export const XAIPlugin = PluginV2.define({
|
|||||||
}),
|
}),
|
||||||
"aisdk.language": Effect.fn(function* (evt) {
|
"aisdk.language": Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("xai")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("xai")) return
|
||||||
evt.language = evt.sdk.responses(evt.model.apiID)
|
evt.language = evt.sdk.responses(evt.model.api.id)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -25,14 +25,14 @@ export type ID = typeof ID.Type
|
|||||||
export const ModelID = Schema.String.pipe(Schema.brand("ModelID"))
|
export const ModelID = Schema.String.pipe(Schema.brand("ModelID"))
|
||||||
export type ModelID = typeof ModelID.Type
|
export type ModelID = typeof ModelID.Type
|
||||||
|
|
||||||
const AISDK = Schema.Struct({
|
export const AISDK = Schema.Struct({
|
||||||
type: Schema.Literal("aisdk"),
|
type: Schema.Literal("aisdk"),
|
||||||
package: Schema.String,
|
package: Schema.String,
|
||||||
url: Schema.String.pipe(Schema.optional),
|
url: Schema.String.pipe(Schema.optional),
|
||||||
settings: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
settings: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||||
})
|
})
|
||||||
|
|
||||||
const Native = Schema.Struct({
|
export const Native = Schema.Struct({
|
||||||
type: Schema.Literal("native"),
|
type: Schema.Literal("native"),
|
||||||
url: Schema.String.pipe(Schema.optional),
|
url: Schema.String.pipe(Schema.optional),
|
||||||
settings: Schema.Record(Schema.String, Schema.Unknown),
|
settings: Schema.Record(Schema.String, Schema.Unknown),
|
||||||
|
|||||||
@@ -205,12 +205,19 @@ function migrateModel(info: typeof ConfigProviderV1.Model.Type, packageName?: st
|
|||||||
: undefined
|
: undefined
|
||||||
const lowerer = ConfigProviderOptionsV1.get(info.provider?.npm ?? packageName)
|
const lowerer = ConfigProviderOptionsV1.get(info.provider?.npm ?? packageName)
|
||||||
return {
|
return {
|
||||||
api_id: info.id,
|
|
||||||
family: info.family,
|
family: info.family,
|
||||||
name: info.name,
|
name: info.name,
|
||||||
api: info.provider?.npm
|
api: info.provider?.npm
|
||||||
? { type: "aisdk" as const, package: info.provider.npm, url: info.provider.api, settings: {} }
|
? {
|
||||||
: undefined,
|
...(info.id === undefined ? {} : { id: info.id }),
|
||||||
|
type: "aisdk" as const,
|
||||||
|
package: info.provider.npm,
|
||||||
|
url: info.provider.api,
|
||||||
|
settings: {},
|
||||||
|
}
|
||||||
|
: info.id === undefined
|
||||||
|
? undefined
|
||||||
|
: { id: info.id },
|
||||||
capabilities,
|
capabilities,
|
||||||
request: (info.headers || info.options) && {
|
request: (info.headers || info.options) && {
|
||||||
headers: info.headers,
|
headers: info.headers,
|
||||||
|
|||||||
@@ -61,12 +61,18 @@ describe("CatalogV2", () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
catalog.model.update(providerID, modelID, (model) => {
|
catalog.model.update(providerID, modelID, (model) => {
|
||||||
model.api = { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://model.example.com" }
|
model.api = {
|
||||||
|
id: modelID,
|
||||||
|
type: "aisdk",
|
||||||
|
package: "@ai-sdk/openai-compatible",
|
||||||
|
url: "https://model.example.com",
|
||||||
|
}
|
||||||
model.request.body.baseURL = "https://override.example.com"
|
model.request.body.baseURL = "https://override.example.com"
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
expect((yield* catalog.model.get(providerID, modelID)).api).toEqual({
|
expect((yield* catalog.model.get(providerID, modelID)).api).toEqual({
|
||||||
|
id: modelID,
|
||||||
type: "aisdk",
|
type: "aisdk",
|
||||||
package: "@ai-sdk/openai-compatible",
|
package: "@ai-sdk/openai-compatible",
|
||||||
url: "https://override.example.com",
|
url: "https://override.example.com",
|
||||||
@@ -94,6 +100,7 @@ describe("CatalogV2", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect((yield* catalog.model.get(providerID, modelID)).api).toEqual({
|
expect((yield* catalog.model.get(providerID, modelID)).api).toEqual({
|
||||||
|
id: modelID,
|
||||||
type: "aisdk",
|
type: "aisdk",
|
||||||
package: "@ai-sdk/openai-compatible",
|
package: "@ai-sdk/openai-compatible",
|
||||||
url: "https://provider.example.com",
|
url: "https://provider.example.com",
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ describe("ConfigProviderPlugin.Plugin", () => {
|
|||||||
request: request({ last: "last", shared: "last" }),
|
request: request({ last: "last", shared: "last" }),
|
||||||
models: {
|
models: {
|
||||||
chat: {
|
chat: {
|
||||||
api_id: "api-chat",
|
api: { id: "api-chat" },
|
||||||
name: "Last",
|
name: "Last",
|
||||||
limit: { output: 75 },
|
limit: { output: 75 },
|
||||||
request: request({ last: "last", shared: "last" }),
|
request: request({ last: "last", shared: "last" }),
|
||||||
@@ -112,7 +112,7 @@ describe("ConfigProviderPlugin.Plugin", () => {
|
|||||||
expect(provider.enabled).toEqual({ via: "custom", data: {} })
|
expect(provider.enabled).toEqual({ via: "custom", data: {} })
|
||||||
expect(provider.api).toEqual({ type: "aisdk", package: "custom-sdk", url: "https://example.test" })
|
expect(provider.api).toEqual({ type: "aisdk", package: "custom-sdk", url: "https://example.test" })
|
||||||
expect(provider.request.headers).toEqual({ first: "first", shared: "last", last: "last" })
|
expect(provider.request.headers).toEqual({ first: "first", shared: "last", last: "last" })
|
||||||
expect(model.apiID).toBe(ModelV2.ID.make("api-chat"))
|
expect(model.api.id).toBe(ModelV2.ID.make("api-chat"))
|
||||||
expect(model.name).toBe("Last")
|
expect(model.name).toBe("Last")
|
||||||
expect(model.capabilities).toEqual({ tools: true, input: ["text"], output: ["text"] })
|
expect(model.capabilities).toEqual({ tools: true, input: ["text"], output: ["text"] })
|
||||||
expect(model.enabled).toBe(false)
|
expect(model.enabled).toBe(false)
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ describe("AlibabaPlugin", () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
it.effect("uses the old default languageModel(apiID) behavior", () =>
|
it.effect("uses the old default languageModel(api.id) behavior", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugin = yield* PluginV2.Service
|
const plugin = yield* PluginV2.Service
|
||||||
yield* plugin.add(AlibabaPlugin)
|
yield* plugin.add(AlibabaPlugin)
|
||||||
const item = model("alibaba", "alias", { apiID: ModelV2.ID.make("qwen-plus") })
|
const item = model("alibaba", "alias", { api: { id: ModelV2.ID.make("qwen-plus") } })
|
||||||
const result = yield* plugin.trigger("aisdk.sdk", { model: item, package: "@ai-sdk/alibaba", options: {} }, {})
|
const result = yield* plugin.trigger("aisdk.sdk", { model: item, package: "@ai-sdk/alibaba", options: {} }, {})
|
||||||
const language = result.sdk?.languageModel(item.apiID)
|
const language = result.sdk?.languageModel(item.api.id)
|
||||||
expect(language?.modelId).toBe("qwen-plus")
|
expect(language?.modelId).toBe("qwen-plus")
|
||||||
expect(language?.provider).toBe("alibaba.chat")
|
expect(language?.provider).toBe("alibaba.chat")
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
|||||||
const result = yield* plugin.trigger(
|
const result = yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{
|
{
|
||||||
model: model("cloudflare-workers-ai", "alias", { apiID: ModelV2.ID.make("@cf/api-model") }),
|
model: model("cloudflare-workers-ai", "alias", { api: { id: ModelV2.ID.make("@cf/api-model") } }),
|
||||||
sdk: fakeSelectorSdk(calls),
|
sdk: fakeSelectorSdk(calls),
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ describe("CoherePlugin", () => {
|
|||||||
yield* plugin.add(CoherePlugin)
|
yield* plugin.add(CoherePlugin)
|
||||||
const result = yield* plugin.trigger(
|
const result = yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{ model: model("cohere", "alias", { apiID: ModelV2.ID.make("command-r-plus") }), sdk, options: {} },
|
{ model: model("cohere", "alias", { api: { id: ModelV2.ID.make("command-r-plus") } }), sdk, options: {} },
|
||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -158,15 +158,14 @@ describe("DynamicProviderPlugin", () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
itWithAISDK.effect("uses the model apiID for the default language model", () =>
|
itWithAISDK.effect("uses the model api.id for the default language model", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugin = yield* PluginV2.Service
|
const plugin = yield* PluginV2.Service
|
||||||
const aisdk = yield* AISDK.Service
|
const aisdk = yield* AISDK.Service
|
||||||
yield* plugin.add(dynamicPlugin())
|
yield* plugin.add(dynamicPlugin())
|
||||||
const language = yield* aisdk.language(
|
const language = yield* aisdk.language(
|
||||||
model("custom", "alias", {
|
model("custom", "alias", {
|
||||||
apiID: ModelV2.ID.make("test-model-api"),
|
api: { id: ModelV2.ID.make("test-model-api"), type: "aisdk", package: fixtureProvider },
|
||||||
api: { type: "aisdk", package: fixtureProvider },
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
expect(language).toMatchObject({ modelID: "test-model-api", options: { name: "custom" } })
|
expect(language).toMatchObject({ modelID: "test-model-api", options: { name: "custom" } })
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ describe("GithubCopilotPlugin", () => {
|
|||||||
yield* plugin.trigger(
|
yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{
|
{
|
||||||
model: model("github-copilot", "alias", { apiID: ModelV2.ID.make("claude-sonnet-4") }),
|
model: model("github-copilot", "alias", { api: { id: ModelV2.ID.make("claude-sonnet-4") } }),
|
||||||
sdk: { languageModel: fakeSelectorSdk(calls).languageModel },
|
sdk: { languageModel: fakeSelectorSdk(calls).languageModel },
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
@@ -119,7 +119,7 @@ describe("GithubCopilotPlugin", () => {
|
|||||||
yield* plugin.trigger(
|
yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{
|
{
|
||||||
model: model("github-copilot", "default", { apiID: ModelV2.ID.make("gpt-5") }),
|
model: model("github-copilot", "default", { api: { id: ModelV2.ID.make("gpt-5") } }),
|
||||||
sdk: fakeSelectorSdk(calls),
|
sdk: fakeSelectorSdk(calls),
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
@@ -128,7 +128,7 @@ describe("GithubCopilotPlugin", () => {
|
|||||||
yield* plugin.trigger(
|
yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{
|
{
|
||||||
model: model("github-copilot", "small", { apiID: ModelV2.ID.make("gpt-5-mini") }),
|
model: model("github-copilot", "small", { api: { id: ModelV2.ID.make("gpt-5-mini") } }),
|
||||||
sdk: fakeSelectorSdk(calls),
|
sdk: fakeSelectorSdk(calls),
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
@@ -137,7 +137,7 @@ describe("GithubCopilotPlugin", () => {
|
|||||||
yield* plugin.trigger(
|
yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{
|
{
|
||||||
model: model("github-copilot", "sonnet", { apiID: ModelV2.ID.make("claude-sonnet-4") }),
|
model: model("github-copilot", "sonnet", { api: { id: ModelV2.ID.make("claude-sonnet-4") } }),
|
||||||
sdk: fakeSelectorSdk(calls),
|
sdk: fakeSelectorSdk(calls),
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ describe("GooglePlugin", () => {
|
|||||||
yield* plugin.add(GooglePlugin)
|
yield* plugin.add(GooglePlugin)
|
||||||
const language = yield* aisdk.language(
|
const language = yield* aisdk.language(
|
||||||
model("custom-google", "alias", {
|
model("custom-google", "alias", {
|
||||||
apiID: ModelV2.ID.make("gemini-api"),
|
|
||||||
api: {
|
api: {
|
||||||
|
id: ModelV2.ID.make("gemini-api"),
|
||||||
type: "aisdk",
|
type: "aisdk",
|
||||||
package: "@ai-sdk/google",
|
package: "@ai-sdk/google",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -75,15 +75,15 @@ describe("GroqPlugin", () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
aisdkIt.effect("uses the default languageModel(apiID) behavior", () =>
|
aisdkIt.effect("uses the default languageModel(api.id) behavior", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugin = yield* PluginV2.Service
|
const plugin = yield* PluginV2.Service
|
||||||
const aisdk = yield* AISDK.Service
|
const aisdk = yield* AISDK.Service
|
||||||
yield* plugin.add(GroqPlugin)
|
yield* plugin.add(GroqPlugin)
|
||||||
const result = yield* aisdk.language(
|
const result = yield* aisdk.language(
|
||||||
model("groq", "alias", {
|
model("groq", "alias", {
|
||||||
apiID: ModelV2.ID.make("llama-api"),
|
|
||||||
api: {
|
api: {
|
||||||
|
id: ModelV2.ID.make("llama-api"),
|
||||||
type: "aisdk",
|
type: "aisdk",
|
||||||
package: "@ai-sdk/groq",
|
package: "@ai-sdk/groq",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ type ProviderInput = Partial<Omit<ProviderV2.Info, "api" | "request">> & {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ModelInput = Partial<Omit<ModelV2.Info, "api" | "request">> & {
|
type ModelInput = Partial<Omit<ModelV2.Info, "api" | "request">> & {
|
||||||
api?: ProviderV2.Api
|
api?: (ProviderV2.Api & { id?: ModelV2.ID }) | { id: ModelV2.ID }
|
||||||
request?: ModelV2.Info["request"]
|
request?: ModelV2.Info["request"]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,12 +83,16 @@ export function provider(providerID: string, options?: ProviderInput) {
|
|||||||
export function model(providerID: string, modelID: string, options?: ModelInput) {
|
export function model(providerID: string, modelID: string, options?: ModelInput) {
|
||||||
return new ModelV2.Info({
|
return new ModelV2.Info({
|
||||||
...ModelV2.Info.empty(ProviderV2.ID.make(providerID), ModelV2.ID.make(modelID)),
|
...ModelV2.Info.empty(ProviderV2.ID.make(providerID), ModelV2.ID.make(modelID)),
|
||||||
apiID: ModelV2.ID.make(modelID),
|
|
||||||
api: options?.api ?? {
|
|
||||||
type: "aisdk",
|
|
||||||
package: "test-provider",
|
|
||||||
},
|
|
||||||
...options,
|
...options,
|
||||||
|
api:
|
||||||
|
options?.api && "type" in options.api
|
||||||
|
? { id: ModelV2.ID.make(modelID), ...options.api }
|
||||||
|
: {
|
||||||
|
id: ModelV2.ID.make(modelID),
|
||||||
|
...options?.api,
|
||||||
|
type: "aisdk",
|
||||||
|
package: "test-provider",
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
headers: {},
|
headers: {},
|
||||||
body: {},
|
body: {},
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ describe("MistralPlugin", () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
it.effect("leaves Mistral language selection on the default sdk.languageModel(apiID) path", () =>
|
it.effect("leaves Mistral language selection on the default sdk.languageModel(api.id) path", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugin = yield* PluginV2.Service
|
const plugin = yield* PluginV2.Service
|
||||||
const calls: string[] = []
|
const calls: string[] = []
|
||||||
@@ -95,10 +95,10 @@ describe("MistralPlugin", () => {
|
|||||||
yield* plugin.add(MistralPlugin)
|
yield* plugin.add(MistralPlugin)
|
||||||
const result = yield* plugin.trigger(
|
const result = yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{ model: model("mistral", "alias", { apiID: ModelV2.ID.make("mistral-large") }), sdk, options: {} },
|
{ model: model("mistral", "alias", { api: { id: ModelV2.ID.make("mistral-large") } }), sdk, options: {} },
|
||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
const language = result.language ?? sdk.languageModel(result.model.apiID)
|
const language = result.language ?? sdk.languageModel(result.model.api.id)
|
||||||
expect(calls).toEqual(["languageModel:mistral-large"])
|
expect(calls).toEqual(["languageModel:mistral-large"])
|
||||||
expect(language).toBeDefined()
|
expect(language).toBeDefined()
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -46,7 +46,9 @@ describe("OpenAIPlugin", () => {
|
|||||||
const result = yield* plugin.trigger(
|
const result = yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{
|
{
|
||||||
model: model("openai", "alias", { apiID: ModelV2.ID.make("gpt-5") }),
|
model: model("openai", "alias", {
|
||||||
|
api: { id: ModelV2.ID.make("gpt-5"), type: "aisdk", package: "test-provider" },
|
||||||
|
}),
|
||||||
sdk: fakeSelectorSdk(calls),
|
sdk: fakeSelectorSdk(calls),
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ describe("PerplexityPlugin", () => {
|
|||||||
const result = yield* plugin.trigger(
|
const result = yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{
|
{
|
||||||
model: model("perplexity", "alias", { apiID: ModelV2.ID.make("sonar") }),
|
model: model("perplexity", "alias", { api: { id: ModelV2.ID.make("sonar") } }),
|
||||||
sdk: fakeSelectorSdk(calls),
|
sdk: fakeSelectorSdk(calls),
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ describe("TogetherAIPlugin", () => {
|
|||||||
|
|
||||||
expect(result.language).toBeUndefined()
|
expect(result.language).toBeUndefined()
|
||||||
expect(calls).toEqual([])
|
expect(calls).toEqual([])
|
||||||
expect(result.language ?? fakeSelectorSdk(calls).languageModel(result.model.apiID)).toBeDefined()
|
expect(result.language ?? fakeSelectorSdk(calls).languageModel(result.model.api.id)).toBeDefined()
|
||||||
expect(calls).toEqual(["languageModel:meta-llama/Llama-3.3-70B-Instruct-Turbo"])
|
expect(calls).toEqual(["languageModel:meta-llama/Llama-3.3-70B-Instruct-Turbo"])
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ const it = testEffect(PluginV2.locationLayer.pipe(Layer.provide(EventV2.defaultL
|
|||||||
|
|
||||||
const model = new ModelV2.Info({
|
const model = new ModelV2.Info({
|
||||||
...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("grok-4")),
|
...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("grok-4")),
|
||||||
apiID: ModelV2.ID.make("grok-4"),
|
|
||||||
api: {
|
api: {
|
||||||
|
id: ModelV2.ID.make("grok-4"),
|
||||||
type: "aisdk",
|
type: "aisdk",
|
||||||
package: "@ai-sdk/xai",
|
package: "@ai-sdk/xai",
|
||||||
},
|
},
|
||||||
@@ -72,7 +72,7 @@ describe("XAIPlugin", () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
it.effect("uses responses with the model apiID for xAI language models", () =>
|
it.effect("uses responses with the model api.id for xAI language models", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugin = yield* PluginV2.Service
|
const plugin = yield* PluginV2.Service
|
||||||
const calls: string[] = []
|
const calls: string[] = []
|
||||||
@@ -81,7 +81,7 @@ describe("XAIPlugin", () => {
|
|||||||
const result = yield* plugin.trigger(
|
const result = yield* plugin.trigger(
|
||||||
"aisdk.language",
|
"aisdk.language",
|
||||||
{
|
{
|
||||||
model: new ModelV2.Info({ ...model, id: ModelV2.ID.make("alias"), apiID: ModelV2.ID.make("grok-4") }),
|
model: new ModelV2.Info({ ...model, id: ModelV2.ID.make("alias") }),
|
||||||
sdk: fakeSelectorSdk(calls),
|
sdk: fakeSelectorSdk(calls),
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2685,12 +2685,12 @@ export type EventTuiSessionSelect2 = {
|
|||||||
|
|
||||||
export type ModelV2Info = {
|
export type ModelV2Info = {
|
||||||
id: string
|
id: string
|
||||||
apiID: string
|
|
||||||
providerID: string
|
providerID: string
|
||||||
family?: string
|
family?: string
|
||||||
name: string
|
name: string
|
||||||
api:
|
api:
|
||||||
| {
|
| {
|
||||||
|
id: string
|
||||||
type: "aisdk"
|
type: "aisdk"
|
||||||
package: string
|
package: string
|
||||||
url?: string
|
url?: string
|
||||||
@@ -2699,6 +2699,7 @@ export type ModelV2Info = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
|
id: string
|
||||||
type: "native"
|
type: "native"
|
||||||
url?: string
|
url?: string
|
||||||
settings: {
|
settings: {
|
||||||
@@ -3694,12 +3695,12 @@ export type EventPluginAdded = {
|
|||||||
|
|
||||||
export type ModelV2Info1 = {
|
export type ModelV2Info1 = {
|
||||||
id: string
|
id: string
|
||||||
apiID: string
|
|
||||||
providerID: string
|
providerID: string
|
||||||
family?: string
|
family?: string
|
||||||
name: string
|
name: string
|
||||||
api:
|
api:
|
||||||
| {
|
| {
|
||||||
|
id: string
|
||||||
type: "aisdk"
|
type: "aisdk"
|
||||||
package: string
|
package: string
|
||||||
url?: string
|
url?: string
|
||||||
@@ -3708,6 +3709,7 @@ export type ModelV2Info1 = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
|
id: string
|
||||||
type: "native"
|
type: "native"
|
||||||
url?: string
|
url?: string
|
||||||
settings: {
|
settings: {
|
||||||
|
|||||||
+16
-12
@@ -19300,9 +19300,6 @@
|
|||||||
"id": {
|
"id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"apiID": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"providerID": {
|
"providerID": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -19317,6 +19314,9 @@
|
|||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["aisdk"]
|
"enum": ["aisdk"]
|
||||||
@@ -19331,12 +19331,15 @@
|
|||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["type", "package"],
|
"required": ["id", "type", "package"],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["native"]
|
"enum": ["native"]
|
||||||
@@ -19348,7 +19351,7 @@
|
|||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["type", "settings"],
|
"required": ["id", "type", "settings"],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -19515,7 +19518,6 @@
|
|||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"id",
|
"id",
|
||||||
"apiID",
|
|
||||||
"providerID",
|
"providerID",
|
||||||
"name",
|
"name",
|
||||||
"api",
|
"api",
|
||||||
@@ -22371,9 +22373,6 @@
|
|||||||
"id": {
|
"id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"apiID": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"providerID": {
|
"providerID": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -22388,6 +22387,9 @@
|
|||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["aisdk"]
|
"enum": ["aisdk"]
|
||||||
@@ -22402,12 +22404,15 @@
|
|||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["type", "package"],
|
"required": ["id", "type", "package"],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["native"]
|
"enum": ["native"]
|
||||||
@@ -22419,7 +22424,7 @@
|
|||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["type", "settings"],
|
"required": ["id", "type", "settings"],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -22582,7 +22587,6 @@
|
|||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"id",
|
"id",
|
||||||
"apiID",
|
|
||||||
"providerID",
|
"providerID",
|
||||||
"name",
|
"name",
|
||||||
"api",
|
"api",
|
||||||
|
|||||||
+2
-2
@@ -211,7 +211,7 @@ Provider, model, variant, and provisional agent `options` are authored as partia
|
|||||||
|
|
||||||
Keep provider `env` as an authored list of recognized credential environment variable names. Built-in catalog providers already carry this metadata for automatic environment-backed availability, and configured providers may need to declare the same source. For a configured provider this is additive metadata, not a requirement that one of the variables exists: the provider may instead be usable through configured options, a stored account, or an endpoint that needs no credential.
|
Keep provider `env` as an authored list of recognized credential environment variable names. Built-in catalog providers already carry this metadata for automatic environment-backed availability, and configured providers may need to declare the same source. For a configured provider this is additive metadata, not a requirement that one of the variables exists: the provider may instead be usable through configured options, a stored account, or an endpoint that needs no credential.
|
||||||
|
|
||||||
Within configured models, rename legacy upstream model identifier `id` to `api_id` rather than exposing camelCase runtime `apiID`. Model `limit` is an authored patch, so an override may change only `context`, `input`, or `output`. Model `cost` accepts one simple pricing object or an array of tiered pricing entries; omitted cache prices default to zero.
|
Within configured models, nest the legacy upstream model identifier `id` under `api.id` with the rest of the model API override. Model `limit` is an authored patch, so an override may change only `context`, `input`, or `output`. Model `cost` accepts one simple pricing object or an array of tiered pricing entries; omitted cache prices default to zero.
|
||||||
|
|
||||||
Do not port legacy provider model `reasoning`, `temperature`, or `interleaved` flags as first-class config fields; provider/request behavior belongs in structured `options` or model variants. Do not port `release_date`, `status`, `experimental`, `whitelist`, or `blacklist` in this v2 surface.
|
Do not port legacy provider model `reasoning`, `temperature`, or `interleaved` flags as first-class config fields; provider/request behavior belongs in structured `options` or model variants. Do not port `release_date`, `status`, `experimental`, `whitelist`, or `blacklist` in this v2 surface.
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ Do not port legacy provider model `reasoning`, `temperature`, or `interleaved` f
|
|||||||
"options": { "headers": { "Authorization": "Bearer {env:API_KEY}" } },
|
"options": { "headers": { "Authorization": "Bearer {env:API_KEY}" } },
|
||||||
"models": {
|
"models": {
|
||||||
"chat": {
|
"chat": {
|
||||||
"api_id": "upstream-chat-model",
|
"api": { "id": "upstream-chat-model" },
|
||||||
"limit": { "output": 32768 },
|
"limit": { "output": 32768 },
|
||||||
"cost": { "input": 1.25, "output": 10 },
|
"cost": { "input": 1.25, "output": 10 },
|
||||||
"variants": [{ "id": "high", "aisdk": { "request": { "reasoningEffort": "high" } } }],
|
"variants": [{ "id": "high", "aisdk": { "request": { "reasoningEffort": "high" } } }],
|
||||||
|
|||||||
Reference in New Issue
Block a user