refactor(core): remove ai sdk option fields (#30581)
This commit is contained in:
@@ -19,7 +19,7 @@ function bedrockFetch(sdk: unknown, modelID = "anthropic.claude-sonnet-4-5") {
|
||||
}
|
||||
|
||||
describe("AmazonBedrockPlugin", () => {
|
||||
it.effect("moves endpoint option to endpoint URL", () =>
|
||||
it.effect("moves endpoint option to api URL", () =>
|
||||
Effect.gen(function* () {
|
||||
const plugin = yield* PluginV2.Service
|
||||
const catalog = yield* Catalog.Service
|
||||
@@ -27,25 +27,24 @@ describe("AmazonBedrockPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const bedrock = provider("amazon-bedrock", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/amazon-bedrock" },
|
||||
options: {
|
||||
api: { type: "aisdk", package: "@ai-sdk/amazon-bedrock" },
|
||||
request: {
|
||||
headers: {},
|
||||
body: {},
|
||||
aisdk: { provider: { endpoint: "https://bedrock.example" }, request: {} },
|
||||
body: { endpoint: "https://bedrock.example" },
|
||||
},
|
||||
})
|
||||
catalog.provider.update(bedrock.id, (item) => {
|
||||
item.endpoint = bedrock.endpoint
|
||||
item.options = bedrock.options
|
||||
item.api = bedrock.api
|
||||
item.request = bedrock.request
|
||||
})
|
||||
})
|
||||
const result = yield* catalog.provider.get(ProviderV2.ID.amazonBedrock)
|
||||
expect(result.endpoint).toEqual({
|
||||
expect(result.api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/amazon-bedrock",
|
||||
url: "https://bedrock.example",
|
||||
})
|
||||
expect(result.options.aisdk.provider.endpoint).toBeUndefined()
|
||||
expect(result.request.body.endpoint).toBeUndefined()
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
@@ -15,18 +15,18 @@ describe("AnthropicPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("anthropic", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/anthropic" },
|
||||
options: { headers: { Existing: "1" }, body: {}, aisdk: { provider: {}, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/anthropic" },
|
||||
request: { headers: { Existing: "1" }, body: {} },
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.options = item.options
|
||||
draft.api = item.api
|
||||
draft.request = item.request
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.anthropic)).options.headers["anthropic-beta"]).toBe(
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.anthropic)).request.headers["anthropic-beta"]).toBe(
|
||||
"interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14",
|
||||
)
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.anthropic)).options.headers.Existing).toBe("1")
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.anthropic)).request.headers.Existing).toBe("1")
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -37,7 +37,7 @@ describe("AnthropicPlugin", () => {
|
||||
yield* plugin.add(AnthropicPlugin)
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => catalog.provider.update(provider("openai").id, () => {}))
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openai)).options.headers["anthropic-beta"]).toBeUndefined()
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openai)).request.headers["anthropic-beta"]).toBeUndefined()
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
@@ -16,17 +16,17 @@ describe("AzureCognitiveServicesPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
catalog.provider.update(ProviderV2.ID.make("azure-cognitive-services"), (item) => {
|
||||
item.endpoint = { type: "aisdk", package: "@ai-sdk/openai-compatible" }
|
||||
item.api = { type: "aisdk", package: "@ai-sdk/openai-compatible" }
|
||||
})
|
||||
})
|
||||
const result = yield* catalog.provider.get(ProviderV2.ID.make("azure-cognitive-services"))
|
||||
expect(result.endpoint).toEqual({
|
||||
expect(result.api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://cognitive.cognitiveservices.azure.com/openai",
|
||||
})
|
||||
expect(result.options.aisdk.provider.baseURL).toBeUndefined()
|
||||
expect(result.options.aisdk.provider.resourceName).toBeUndefined()
|
||||
expect(result.request.body.baseURL).toBeUndefined()
|
||||
expect(result.request.body.resourceName).toBeUndefined()
|
||||
}),
|
||||
),
|
||||
)
|
||||
@@ -40,22 +40,22 @@ describe("AzureCognitiveServicesPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const azure = provider("azure-cognitive-services", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible" },
|
||||
})
|
||||
const openai = provider("openai")
|
||||
catalog.provider.update(azure.id, (item) => {
|
||||
item.endpoint = azure.endpoint
|
||||
item.api = azure.api
|
||||
})
|
||||
catalog.provider.update(openai.id, (item) => {
|
||||
item.endpoint = openai.endpoint
|
||||
item.api = openai.api
|
||||
})
|
||||
})
|
||||
const azure = yield* catalog.provider.get(ProviderV2.ID.make("azure-cognitive-services"))
|
||||
const openai = yield* catalog.provider.get(ProviderV2.ID.openai)
|
||||
expect(azure.options.aisdk.provider.baseURL).toBeUndefined()
|
||||
expect(azure.endpoint).toEqual({ type: "aisdk", package: "@ai-sdk/openai-compatible" })
|
||||
expect(openai.options.aisdk.provider.baseURL).toBeUndefined()
|
||||
expect(openai.endpoint).toEqual({ type: "aisdk", package: "test-provider" })
|
||||
expect(azure.request.body.baseURL).toBeUndefined()
|
||||
expect(azure.api).toEqual({ type: "aisdk", package: "@ai-sdk/openai-compatible" })
|
||||
expect(openai.request.body.baseURL).toBeUndefined()
|
||||
expect(openai.api).toEqual({ type: "aisdk", package: "test-provider" })
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -34,10 +34,10 @@ describe("AzurePlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
catalog.provider.update(ProviderV2.ID.azure, (item) => {
|
||||
item.endpoint = { type: "aisdk", package: "@ai-sdk/azure" }
|
||||
item.api = { type: "aisdk", package: "@ai-sdk/azure" }
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).options.aisdk.provider.resourceName).toBe("from-env")
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).request.body.resourceName).toBe("from-env")
|
||||
}),
|
||||
),
|
||||
)
|
||||
@@ -51,19 +51,19 @@ describe("AzurePlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const azure = provider("azure", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/azure" },
|
||||
options: { headers: {}, body: {}, aisdk: { provider: { resourceName: "from-config" }, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/azure" },
|
||||
request: { headers: {}, body: { resourceName: "from-config" } },
|
||||
})
|
||||
catalog.provider.update(azure.id, (item) => {
|
||||
item.endpoint = azure.endpoint
|
||||
item.options = azure.options
|
||||
item.api = azure.api
|
||||
item.request = azure.request
|
||||
})
|
||||
catalog.provider.update(ProviderV2.ID.openai, () => {})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).options.aisdk.provider.resourceName).toBe(
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).request.body.resourceName).toBe(
|
||||
"from-config",
|
||||
)
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openai)).options.aisdk.provider.resourceName).toBeUndefined()
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openai)).request.body.resourceName).toBeUndefined()
|
||||
}),
|
||||
),
|
||||
)
|
||||
@@ -100,10 +100,10 @@ describe("AzurePlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
catalog.provider.update(ProviderV2.ID.azure, (item) => {
|
||||
item.endpoint = { type: "aisdk", package: "@ai-sdk/azure" }
|
||||
item.api = { type: "aisdk", package: "@ai-sdk/azure" }
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).options.aisdk.provider.resourceName).toBe(
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).request.body.resourceName).toBe(
|
||||
"from-account",
|
||||
)
|
||||
}),
|
||||
@@ -119,15 +119,15 @@ describe("AzurePlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const azure = provider("azure", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/azure" },
|
||||
options: { headers: {}, body: {}, aisdk: { provider: { resourceName: "" }, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/azure" },
|
||||
request: { headers: {}, body: { resourceName: "" } },
|
||||
})
|
||||
catalog.provider.update(azure.id, (item) => {
|
||||
item.endpoint = azure.endpoint
|
||||
item.options = azure.options
|
||||
item.api = azure.api
|
||||
item.request = azure.request
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).options.aisdk.provider.resourceName).toBe("from-env")
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).request.body.resourceName).toBe("from-env")
|
||||
}),
|
||||
),
|
||||
)
|
||||
@@ -141,15 +141,15 @@ describe("AzurePlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const azure = provider("azure", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/azure" },
|
||||
options: { headers: {}, body: {}, aisdk: { provider: { resourceName: " " }, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/azure" },
|
||||
request: { headers: {}, body: { resourceName: " " } },
|
||||
})
|
||||
catalog.provider.update(azure.id, (item) => {
|
||||
item.endpoint = azure.endpoint
|
||||
item.options = azure.options
|
||||
item.api = azure.api
|
||||
item.request = azure.request
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).options.aisdk.provider.resourceName).toBe("from-env")
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.azure)).request.body.resourceName).toBe("from-env")
|
||||
}),
|
||||
),
|
||||
)
|
||||
@@ -227,7 +227,7 @@ describe("AzurePlugin", () => {
|
||||
"aisdk.language",
|
||||
{
|
||||
model: model("azure", "deployment", {
|
||||
options: { headers: {}, body: {}, aisdk: { provider: {}, request: { useCompletionUrls: true } } },
|
||||
request: { headers: {}, body: { useCompletionUrls: true } },
|
||||
}),
|
||||
sdk: fakeSelectorSdk(calls),
|
||||
options: {},
|
||||
|
||||
@@ -27,11 +27,11 @@ describe("CerebrasPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
catalog.provider.update(ProviderV2.ID.make("cerebras"), (item) => {
|
||||
item.endpoint = { type: "aisdk", package: "@ai-sdk/cerebras" }
|
||||
item.options.headers.Existing = "1"
|
||||
item.api = { type: "aisdk", package: "@ai-sdk/cerebras" }
|
||||
item.request.headers.Existing = "1"
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("cerebras"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("cerebras"))).request.headers).toEqual({
|
||||
Existing: "1",
|
||||
"X-Cerebras-3rd-Party-Integration": "opencode",
|
||||
})
|
||||
@@ -45,7 +45,7 @@ describe("CerebrasPlugin", () => {
|
||||
yield* plugin.add(CerebrasPlugin)
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => catalog.provider.update(ProviderV2.ID.make("groq"), () => {}))
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("groq"))).options.headers).toEqual({})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("groq"))).request.headers).toEqual({})
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
@@ -54,20 +54,20 @@ describe("CloudflareWorkersAIPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("cloudflare-workers-ai"), (provider) => {
|
||||
provider.endpoint = { type: "aisdk", package: "test-provider" }
|
||||
provider.api = { type: "aisdk", package: "test-provider" }
|
||||
}),
|
||||
)
|
||||
const provider = yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai"))
|
||||
const sdk = yield* plugin.trigger(
|
||||
"aisdk.sdk",
|
||||
{
|
||||
model: model("cloudflare-workers-ai", "@cf/model", { endpoint: provider.endpoint }),
|
||||
model: model("cloudflare-workers-ai", "@cf/model", { api: provider.api }),
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
options: { name: "cloudflare-workers-ai", headers: { custom: "header" } },
|
||||
},
|
||||
{},
|
||||
)
|
||||
expect(provider.endpoint).toEqual({
|
||||
expect(provider.api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "test-provider",
|
||||
url: "https://api.cloudflare.com/client/v4/accounts/acct/ai/v1",
|
||||
@@ -86,10 +86,10 @@ describe("CloudflareWorkersAIPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("cloudflare-workers-ai"), (provider) => {
|
||||
provider.endpoint = { type: "aisdk", package: "test-provider", url: "https://proxy.example/v1" }
|
||||
provider.api = { type: "aisdk", package: "test-provider", url: "https://proxy.example/v1" }
|
||||
}),
|
||||
)
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai"))).endpoint).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai"))).api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "test-provider",
|
||||
url: "https://proxy.example/v1",
|
||||
@@ -107,7 +107,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
||||
"aisdk.sdk",
|
||||
{
|
||||
model: model("cloudflare-workers-ai", "@cf/model", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://proxy.example/v1" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://proxy.example/v1" },
|
||||
}),
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
options: { name: "cloudflare-workers-ai", baseURL: "https://proxy.example/v1" },
|
||||
@@ -152,10 +152,10 @@ describe("CloudflareWorkersAIPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("cloudflare-workers-ai"), (provider) => {
|
||||
provider.endpoint = { type: "aisdk", package: "test-provider" }
|
||||
provider.api = { type: "aisdk", package: "test-provider" }
|
||||
}),
|
||||
)
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai"))).endpoint).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai"))).api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "test-provider",
|
||||
url: "https://api.cloudflare.com/client/v4/accounts/account-acct/ai/v1",
|
||||
@@ -173,11 +173,11 @@ describe("CloudflareWorkersAIPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("cloudflare-workers-ai"), (provider) => {
|
||||
provider.endpoint = { type: "aisdk", package: "test-provider" }
|
||||
provider.options.aisdk.provider.accountId = "configured-acct"
|
||||
provider.api = { type: "aisdk", package: "test-provider" }
|
||||
provider.request.body.accountId = "configured-acct"
|
||||
}),
|
||||
)
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai"))).endpoint).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("cloudflare-workers-ai"))).api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "test-provider",
|
||||
url: "https://api.cloudflare.com/client/v4/accounts/env-acct/ai/v1",
|
||||
@@ -195,7 +195,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
||||
"aisdk.sdk",
|
||||
{
|
||||
model: model("cloudflare-workers-ai", "@cf/model", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://proxy.example/v1" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://proxy.example/v1" },
|
||||
}),
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
options: {
|
||||
@@ -224,7 +224,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
||||
"aisdk.sdk",
|
||||
{
|
||||
model: model("cloudflare-workers-ai", "@cf/model", {
|
||||
endpoint: {
|
||||
api: {
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/ai/v1",
|
||||
@@ -273,7 +273,7 @@ describe("CloudflareWorkersAIPlugin", () => {
|
||||
"aisdk.sdk",
|
||||
{
|
||||
model: model("cloudflare-workers-ai", "@cf/model", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/anthropic", url: "https://proxy.example/v1" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/anthropic", url: "https://proxy.example/v1" },
|
||||
}),
|
||||
package: "@ai-sdk/anthropic",
|
||||
options: { name: "cloudflare-workers-ai" },
|
||||
|
||||
@@ -122,7 +122,7 @@ describe("DeepInfraPlugin", () => {
|
||||
yield* plugin.add(DeepInfraPlugin)
|
||||
const language = yield* aisdk.language(
|
||||
model("deepinfra", "meta-llama/Llama-3.3-70B-Instruct", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/deepinfra" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/deepinfra" },
|
||||
}),
|
||||
)
|
||||
expect(language.provider).toBe("deepinfra.chat")
|
||||
|
||||
@@ -122,7 +122,7 @@ describe("DynamicProviderPlugin", () => {
|
||||
const aisdk = yield* AISDK.Service
|
||||
yield* plugin.add(dynamicPlugin(npmEntrypointLayer(Option.none<string>())))
|
||||
const exit = yield* aisdk
|
||||
.language(model("missing-entrypoint", "alias", { endpoint: { type: "aisdk", package: "fixture-provider" } }))
|
||||
.language(model("missing-entrypoint", "alias", { api: { type: "aisdk", package: "fixture-provider" } }))
|
||||
.pipe(Effect.exit)
|
||||
expect(exit._tag).toBe("Failure")
|
||||
if (exit._tag === "Failure") expect(Cause.prettyErrors(exit.cause).join("\n")).toContain("AISDK.InitError")
|
||||
@@ -136,7 +136,7 @@ describe("DynamicProviderPlugin", () => {
|
||||
yield* plugin.add(dynamicPlugin())
|
||||
const exit = yield* aisdk
|
||||
.language(
|
||||
model("bad-import", "alias", { endpoint: { type: "aisdk", package: "file:///missing/provider-factory.js" } }),
|
||||
model("bad-import", "alias", { api: { type: "aisdk", package: "file:///missing/provider-factory.js" } }),
|
||||
)
|
||||
.pipe(Effect.exit)
|
||||
expect(exit._tag).toBe("Failure")
|
||||
@@ -151,7 +151,7 @@ describe("DynamicProviderPlugin", () => {
|
||||
const tmp = yield* tempEntrypoint("export const notAProviderFactory = true\n")
|
||||
yield* plugin.add(dynamicPlugin(npmEntrypointLayer(Option.some(tmp.entrypoint))))
|
||||
const exit = yield* aisdk
|
||||
.language(model("missing-factory", "alias", { endpoint: { type: "aisdk", package: "fixture-provider" } }))
|
||||
.language(model("missing-factory", "alias", { api: { type: "aisdk", package: "fixture-provider" } }))
|
||||
.pipe(Effect.exit)
|
||||
expect(exit._tag).toBe("Failure")
|
||||
if (exit._tag === "Failure") expect(Cause.prettyErrors(exit.cause).join("\n")).toContain("AISDK.InitError")
|
||||
@@ -166,7 +166,7 @@ describe("DynamicProviderPlugin", () => {
|
||||
const language = yield* aisdk.language(
|
||||
model("custom", "alias", {
|
||||
apiID: ModelV2.ID.make("test-model-api"),
|
||||
endpoint: { type: "aisdk", package: fixtureProvider },
|
||||
api: { type: "aisdk", package: fixtureProvider },
|
||||
}),
|
||||
)
|
||||
expect(language).toMatchObject({ modelID: "test-model-api", options: { name: "custom" } })
|
||||
|
||||
@@ -190,7 +190,7 @@ describe("GitLabPlugin", () => {
|
||||
{
|
||||
model: model("gitlab", "claude"),
|
||||
package: "gitlab-ai-provider",
|
||||
options: provider.options.aisdk.provider,
|
||||
options: provider.request.body,
|
||||
},
|
||||
{},
|
||||
)
|
||||
@@ -238,7 +238,7 @@ describe("GitLabPlugin", () => {
|
||||
{
|
||||
model: model("gitlab", "claude"),
|
||||
package: "gitlab-ai-provider",
|
||||
options: provider.options.aisdk.provider,
|
||||
options: provider.request.body,
|
||||
},
|
||||
{},
|
||||
)
|
||||
@@ -256,10 +256,9 @@ describe("GitLabPlugin", () => {
|
||||
"aisdk.language",
|
||||
{
|
||||
model: model("gitlab", "duo-workflow-custom", {
|
||||
options: {
|
||||
request: {
|
||||
headers: {},
|
||||
body: {},
|
||||
aisdk: { provider: {}, request: { workflowRef: "ref", workflowDefinition: "definition" } },
|
||||
body: { workflowRef: "ref", workflowDefinition: "definition" },
|
||||
},
|
||||
}),
|
||||
sdk: {
|
||||
@@ -320,10 +319,9 @@ describe("GitLabPlugin", () => {
|
||||
"aisdk.language",
|
||||
{
|
||||
model: model("gitlab", "duo-workflow-custom", {
|
||||
options: {
|
||||
request: {
|
||||
headers: {},
|
||||
body: {},
|
||||
aisdk: { provider: {}, request: { featureFlags: { request_flag: true } } },
|
||||
body: { featureFlags: { request_flag: true } },
|
||||
},
|
||||
}),
|
||||
sdk: {
|
||||
@@ -350,7 +348,7 @@ describe("GitLabPlugin", () => {
|
||||
"aisdk.language",
|
||||
{
|
||||
model: model("gitlab", "claude", {
|
||||
options: { headers: { h: "v" }, body: {}, aisdk: { provider: {}, request: {} } },
|
||||
request: { headers: { h: "v" }, body: {} },
|
||||
}),
|
||||
sdk: {
|
||||
workflowChat: () => undefined,
|
||||
|
||||
@@ -25,12 +25,12 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("google-vertex-anthropic"), (provider) => {
|
||||
provider.endpoint = { type: "aisdk", package: "@ai-sdk/google-vertex/anthropic" }
|
||||
provider.api = { type: "aisdk", package: "@ai-sdk/google-vertex/anthropic" }
|
||||
}),
|
||||
)
|
||||
const provider = yield* catalog.provider.get(ProviderV2.ID.make("google-vertex-anthropic"))
|
||||
expect(provider.options.aisdk.provider.project).toBe("cloud-project")
|
||||
expect(provider.options.aisdk.provider.location).toBe("cloud-location")
|
||||
expect(provider.request.body.project).toBe("cloud-project")
|
||||
expect(provider.request.body.location).toBe("cloud-location")
|
||||
}),
|
||||
),
|
||||
)
|
||||
@@ -44,14 +44,14 @@ describe("GoogleVertexAnthropicPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("google-vertex-anthropic"), (provider) => {
|
||||
provider.endpoint = { type: "aisdk", package: "@ai-sdk/google-vertex/anthropic" }
|
||||
provider.options.aisdk.provider.project = "configured-project"
|
||||
provider.options.aisdk.provider.location = "configured-location"
|
||||
provider.api = { type: "aisdk", package: "@ai-sdk/google-vertex/anthropic" }
|
||||
provider.request.body.project = "configured-project"
|
||||
provider.request.body.location = "configured-location"
|
||||
}),
|
||||
)
|
||||
const provider = yield* catalog.provider.get(ProviderV2.ID.make("google-vertex-anthropic"))
|
||||
expect(provider.options.aisdk.provider.project).toBe("configured-project")
|
||||
expect(provider.options.aisdk.provider.location).toBe("configured-location")
|
||||
expect(provider.request.body.project).toBe("configured-project")
|
||||
expect(provider.request.body.location).toBe("configured-location")
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@ describe("GoogleVertexPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => {
|
||||
provider.endpoint = {
|
||||
provider.api = {
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}",
|
||||
@@ -61,9 +61,9 @@ describe("GoogleVertexPlugin", () => {
|
||||
}),
|
||||
)
|
||||
const provider = yield* catalog.provider.get(ProviderV2.ID.make("google-vertex"))
|
||||
expect(provider.options.aisdk.provider.project).toBe("google-cloud-project")
|
||||
expect(provider.options.aisdk.provider.location).toBe("google-vertex-location")
|
||||
expect(provider.endpoint).toEqual({
|
||||
expect(provider.request.body.project).toBe("google-cloud-project")
|
||||
expect(provider.request.body.location).toBe("google-vertex-location")
|
||||
expect(provider.api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://google-vertex-location-aiplatform.googleapis.com/v1/projects/google-cloud-project/locations/google-vertex-location",
|
||||
@@ -92,7 +92,7 @@ describe("GoogleVertexPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => {
|
||||
provider.endpoint = {
|
||||
provider.api = {
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}",
|
||||
@@ -104,7 +104,7 @@ describe("GoogleVertexPlugin", () => {
|
||||
"aisdk.sdk",
|
||||
{
|
||||
model: model("google-vertex", "gemini", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/google-vertex" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/google-vertex" },
|
||||
}),
|
||||
package: "@ai-sdk/google-vertex",
|
||||
options: { name: "google-vertex" },
|
||||
@@ -112,8 +112,8 @@ describe("GoogleVertexPlugin", () => {
|
||||
{},
|
||||
)
|
||||
|
||||
expect(provider.options.aisdk.provider.project).toBe("vertex-project")
|
||||
expect(provider.endpoint).toEqual({
|
||||
expect(provider.request.body.project).toBe("vertex-project")
|
||||
expect(provider.api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://europe-west4-aiplatform.googleapis.com/v1/projects/vertex-project/locations/europe-west4",
|
||||
@@ -142,19 +142,19 @@ describe("GoogleVertexPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => {
|
||||
provider.endpoint = {
|
||||
provider.api = {
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}",
|
||||
}
|
||||
provider.options.aisdk.provider.project = "config-project"
|
||||
provider.options.aisdk.provider.location = "global"
|
||||
provider.request.body.project = "config-project"
|
||||
provider.request.body.location = "global"
|
||||
}),
|
||||
)
|
||||
const provider = yield* catalog.provider.get(ProviderV2.ID.make("google-vertex"))
|
||||
expect(provider.options.aisdk.provider.project).toBe("config-project")
|
||||
expect(provider.options.aisdk.provider.location).toBe("global")
|
||||
expect(provider.endpoint).toEqual({
|
||||
expect(provider.request.body.project).toBe("config-project")
|
||||
expect(provider.request.body.location).toBe("global")
|
||||
expect(provider.api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://aiplatform.googleapis.com/v1/projects/config-project/locations/global",
|
||||
@@ -171,17 +171,17 @@ describe("GoogleVertexPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => {
|
||||
provider.endpoint = {
|
||||
provider.api = {
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}",
|
||||
}
|
||||
provider.options.aisdk.provider.project = "config-project"
|
||||
provider.options.aisdk.provider.location = "eu"
|
||||
provider.request.body.project = "config-project"
|
||||
provider.request.body.location = "eu"
|
||||
}),
|
||||
)
|
||||
const provider = yield* catalog.provider.get(ProviderV2.ID.make("google-vertex"))
|
||||
expect(provider.endpoint).toEqual({
|
||||
expect(provider.api).toEqual({
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
url: "https://eu-aiplatform.googleapis.com/v1/projects/config-project/locations/eu",
|
||||
@@ -207,13 +207,13 @@ describe("GoogleVertexPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) =>
|
||||
catalog.provider.update(ProviderV2.ID.make("google-vertex"), (provider) => {
|
||||
provider.endpoint = { type: "aisdk", package: "@ai-sdk/google-vertex" }
|
||||
provider.options.aisdk.provider.project = "config-project"
|
||||
provider.api = { type: "aisdk", package: "@ai-sdk/google-vertex" }
|
||||
provider.request.body.project = "config-project"
|
||||
}),
|
||||
)
|
||||
const provider = yield* catalog.provider.get(ProviderV2.ID.make("google-vertex"))
|
||||
expect(provider.options.aisdk.provider.project).toBe("config-project")
|
||||
expect(provider.options.aisdk.provider.location).toBe("us-central1")
|
||||
expect(provider.request.body.project).toBe("config-project")
|
||||
expect(provider.request.body.location).toBe("us-central1")
|
||||
}),
|
||||
),
|
||||
)
|
||||
@@ -233,7 +233,7 @@ describe("GoogleVertexPlugin", () => {
|
||||
"aisdk.sdk",
|
||||
{
|
||||
model: model("google-vertex", "gemini", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/google-vertex" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/google-vertex" },
|
||||
}),
|
||||
package: "@ai-sdk/google-vertex",
|
||||
options: { name: "google-vertex" },
|
||||
@@ -283,7 +283,7 @@ describe("GoogleVertexPlugin", () => {
|
||||
"aisdk.sdk",
|
||||
{
|
||||
model: model("google-vertex", "gemini", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible" },
|
||||
}),
|
||||
package: "@ai-sdk/openai-compatible",
|
||||
options: { name: "google-vertex" },
|
||||
|
||||
@@ -52,17 +52,13 @@ describe("GooglePlugin", () => {
|
||||
const language = yield* aisdk.language(
|
||||
model("custom-google", "alias", {
|
||||
apiID: ModelV2.ID.make("gemini-api"),
|
||||
endpoint: {
|
||||
api: {
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/google",
|
||||
},
|
||||
options: {
|
||||
request: {
|
||||
headers: {},
|
||||
body: {},
|
||||
aisdk: {
|
||||
provider: { apiKey: "test" },
|
||||
request: {},
|
||||
},
|
||||
body: { apiKey: "test" },
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -83,17 +83,13 @@ describe("GroqPlugin", () => {
|
||||
const result = yield* aisdk.language(
|
||||
model("groq", "alias", {
|
||||
apiID: ModelV2.ID.make("llama-api"),
|
||||
endpoint: {
|
||||
api: {
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/groq",
|
||||
},
|
||||
options: {
|
||||
request: {
|
||||
headers: {},
|
||||
body: {},
|
||||
aisdk: {
|
||||
provider: { apiKey: "test" },
|
||||
request: {},
|
||||
},
|
||||
body: { apiKey: "test" },
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -54,43 +54,45 @@ export const it = testEffect(
|
||||
),
|
||||
)
|
||||
|
||||
export function provider(providerID: string, options?: Partial<ProviderV2.Info>) {
|
||||
type ProviderInput = Partial<Omit<ProviderV2.Info, "api" | "request">> & {
|
||||
api?: ProviderV2.Api
|
||||
request?: ProviderV2.Request
|
||||
}
|
||||
|
||||
type ModelInput = Partial<Omit<ModelV2.Info, "api" | "request">> & {
|
||||
api?: ProviderV2.Api
|
||||
request?: ModelV2.Info["request"]
|
||||
}
|
||||
|
||||
export function provider(providerID: string, options?: ProviderInput) {
|
||||
return new ProviderV2.Info({
|
||||
...ProviderV2.Info.empty(ProviderV2.ID.make(providerID)),
|
||||
endpoint: {
|
||||
api: options?.api ?? {
|
||||
type: "aisdk",
|
||||
package: "test-provider",
|
||||
},
|
||||
...options,
|
||||
options: {
|
||||
request: {
|
||||
headers: {},
|
||||
body: {},
|
||||
aisdk: {
|
||||
provider: {},
|
||||
request: {},
|
||||
},
|
||||
...options?.options,
|
||||
...options?.request,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function model(providerID: string, modelID: string, options?: Partial<ModelV2.Info>) {
|
||||
export function model(providerID: string, modelID: string, options?: ModelInput) {
|
||||
return new ModelV2.Info({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make(providerID), ModelV2.ID.make(modelID)),
|
||||
apiID: ModelV2.ID.make(modelID),
|
||||
endpoint: {
|
||||
api: options?.api ?? {
|
||||
type: "aisdk",
|
||||
package: "test-provider",
|
||||
},
|
||||
...options,
|
||||
options: {
|
||||
request: {
|
||||
headers: {},
|
||||
body: {},
|
||||
aisdk: {
|
||||
provider: {},
|
||||
request: {},
|
||||
},
|
||||
...options?.options,
|
||||
...options?.request,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -25,21 +25,21 @@ describe("KiloPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const kilo = provider("kilo", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.kilo.ai/api/gateway" },
|
||||
options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.kilo.ai/api/gateway" },
|
||||
request: { headers: { Existing: "value" }, body: {} },
|
||||
})
|
||||
catalog.provider.update(kilo.id, (draft) => {
|
||||
draft.endpoint = kilo.endpoint
|
||||
draft.options = kilo.options
|
||||
draft.api = kilo.api
|
||||
draft.request = kilo.request
|
||||
})
|
||||
catalog.provider.update(provider("openrouter").id, () => {})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("kilo"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("kilo"))).request.headers).toEqual({
|
||||
Existing: "value",
|
||||
"HTTP-Referer": "https://opencode.ai/",
|
||||
"X-Title": "opencode",
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openrouter)).options.headers).toEqual({})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openrouter)).request.headers).toEqual({})
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -51,21 +51,21 @@ describe("KiloPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("kilo", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.kilo.ai/api/gateway" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.kilo.ai/api/gateway" },
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.api = item.api
|
||||
})
|
||||
})
|
||||
|
||||
const result = yield* catalog.provider.get(ProviderV2.ID.make("kilo"))
|
||||
expect(result.options.headers).toEqual({
|
||||
expect(result.request.headers).toEqual({
|
||||
"HTTP-Referer": "https://opencode.ai/",
|
||||
"X-Title": "opencode",
|
||||
})
|
||||
expect(result.options.headers).not.toHaveProperty("http-referer")
|
||||
expect(result.options.headers).not.toHaveProperty("x-title")
|
||||
expect(result.options.headers).not.toHaveProperty("X-Source")
|
||||
expect(result.request.headers).not.toHaveProperty("http-referer")
|
||||
expect(result.request.headers).not.toHaveProperty("x-title")
|
||||
expect(result.request.headers).not.toHaveProperty("X-Source")
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -77,24 +77,24 @@ describe("KiloPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const kilo = provider("kilo", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.kilo.ai/api/gateway" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.kilo.ai/api/gateway" },
|
||||
})
|
||||
catalog.provider.update(kilo.id, (draft) => {
|
||||
draft.endpoint = kilo.endpoint
|
||||
draft.api = kilo.api
|
||||
})
|
||||
const custom = provider("custom-kilo", {
|
||||
endpoint: { type: "aisdk", package: "kilo" },
|
||||
api: { type: "aisdk", package: "kilo" },
|
||||
})
|
||||
catalog.provider.update(custom.id, (draft) => {
|
||||
draft.endpoint = custom.endpoint
|
||||
draft.api = custom.api
|
||||
})
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("kilo"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("kilo"))).request.headers).toEqual({
|
||||
"HTTP-Referer": "https://opencode.ai/",
|
||||
"X-Title": "opencode",
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("custom-kilo"))).options.headers).toEqual({})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("custom-kilo"))).request.headers).toEqual({})
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -26,13 +26,13 @@ describe("LLMGatewayPlugin", () => {
|
||||
yield* transform((catalog) => {
|
||||
const llmgateway = provider("llmgateway", {
|
||||
enabled: { via: "env", name: "LLMGATEWAY_API_KEY" },
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.llmgateway.io/v1" },
|
||||
options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.llmgateway.io/v1" },
|
||||
request: { headers: { Existing: "value" }, body: {} },
|
||||
})
|
||||
catalog.provider.update(llmgateway.id, (draft) => {
|
||||
draft.enabled = llmgateway.enabled
|
||||
draft.endpoint = llmgateway.endpoint
|
||||
draft.options = llmgateway.options
|
||||
draft.api = llmgateway.api
|
||||
draft.request = llmgateway.request
|
||||
})
|
||||
const openrouter = provider("openrouter", {
|
||||
enabled: { via: "env", name: "OPENROUTER_API_KEY" },
|
||||
@@ -41,13 +41,13 @@ describe("LLMGatewayPlugin", () => {
|
||||
draft.enabled = openrouter.enabled
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("llmgateway"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("llmgateway"))).request.headers).toEqual({
|
||||
Existing: "value",
|
||||
"HTTP-Referer": "https://opencode.ai/",
|
||||
"X-Title": "opencode",
|
||||
"X-Source": "opencode",
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openrouter)).options.headers).toEqual({})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openrouter)).request.headers).toEqual({})
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -59,15 +59,15 @@ describe("LLMGatewayPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("llmgateway", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.llmgateway.io/v1" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.llmgateway.io/v1" },
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.api = item.api
|
||||
})
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("llmgateway"))).enabled).toBe(false)
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("llmgateway"))).options.headers).toEqual({})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("llmgateway"))).request.headers).toEqual({})
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -25,22 +25,22 @@ describe("NvidiaPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const nvidia = provider("nvidia", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://integrate.api.nvidia.com/v1" },
|
||||
options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://integrate.api.nvidia.com/v1" },
|
||||
request: { headers: { Existing: "value" }, body: {} },
|
||||
})
|
||||
catalog.provider.update(nvidia.id, (draft) => {
|
||||
draft.endpoint = nvidia.endpoint
|
||||
draft.options = nvidia.options
|
||||
draft.api = nvidia.api
|
||||
draft.request = nvidia.request
|
||||
})
|
||||
catalog.provider.update(provider("openrouter").id, () => {})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("nvidia"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("nvidia"))).request.headers).toEqual({
|
||||
Existing: "value",
|
||||
"HTTP-Referer": "https://opencode.ai/",
|
||||
"X-Title": "opencode",
|
||||
"X-BILLING-INVOKE-ORIGIN": "OpenCode",
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openrouter)).options.headers).toEqual({})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openrouter)).request.headers).toEqual({})
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -52,16 +52,16 @@ describe("NvidiaPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("nvidia", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://integrate.api.nvidia.com/v1" },
|
||||
options: { headers: {}, body: {}, aisdk: { provider: {}, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://integrate.api.nvidia.com/v1" },
|
||||
request: { headers: {}, body: {} },
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.options = item.options
|
||||
draft.api = item.api
|
||||
draft.request = item.request
|
||||
})
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("nvidia"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("nvidia"))).request.headers).toEqual({
|
||||
"HTTP-Referer": "https://opencode.ai/",
|
||||
"X-Title": "opencode",
|
||||
"X-BILLING-INVOKE-ORIGIN": "OpenCode",
|
||||
@@ -77,20 +77,19 @@ describe("NvidiaPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("nvidia", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://integrate.api.nvidia.com/v1" },
|
||||
options: {
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://integrate.api.nvidia.com/v1" },
|
||||
request: {
|
||||
headers: { "X-BILLING-INVOKE-ORIGIN": "CustomOrigin" },
|
||||
body: {},
|
||||
aisdk: { provider: { baseURL: "https://integrate.api.nvidia.com/v1" }, request: {} },
|
||||
body: { baseURL: "https://integrate.api.nvidia.com/v1" },
|
||||
},
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.options = item.options
|
||||
draft.api = item.api
|
||||
draft.request = item.request
|
||||
})
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("nvidia"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("nvidia"))).request.headers).toEqual({
|
||||
"HTTP-Referer": "https://opencode.ai/",
|
||||
"X-Title": "opencode",
|
||||
"X-BILLING-INVOKE-ORIGIN": "CustomOrigin",
|
||||
|
||||
@@ -79,9 +79,9 @@ describe("OpenAIPlugin", () => {
|
||||
yield* plugin.add(OpenAIPlugin)
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("openai", { endpoint: { type: "aisdk", package: "@ai-sdk/openai" } })
|
||||
const item = provider("openai", { api: { type: "aisdk", package: "@ai-sdk/openai" } })
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.api = item.api
|
||||
})
|
||||
catalog.model.update(item.id, ModelV2.ID.make("gpt-5"), () => {})
|
||||
catalog.model.update(item.id, ModelV2.ID.make("gpt-5-chat-latest"), () => {})
|
||||
|
||||
@@ -33,7 +33,7 @@ describe("OpencodePlugin", () => {
|
||||
draft.cost = [...paid.cost]
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).options.aisdk.provider.apiKey).toBe("public")
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).request.body.apiKey).toBe("public")
|
||||
expect((yield* catalog.model.get(ProviderV2.ID.opencode, ModelV2.ID.make("paid"))).enabled).toBe(false)
|
||||
}),
|
||||
),
|
||||
@@ -54,7 +54,7 @@ describe("OpencodePlugin", () => {
|
||||
draft.cost = [...free.cost]
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).options.aisdk.provider.apiKey).toBe("public")
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).request.body.apiKey).toBe("public")
|
||||
expect((yield* catalog.model.get(ProviderV2.ID.opencode, ModelV2.ID.make("free"))).enabled).toBe(true)
|
||||
}),
|
||||
),
|
||||
@@ -75,7 +75,7 @@ describe("OpencodePlugin", () => {
|
||||
draft.cost = [...outputOnly.cost]
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).options.aisdk.provider.apiKey).toBe("public")
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).request.body.apiKey).toBe("public")
|
||||
expect((yield* catalog.model.get(ProviderV2.ID.opencode, ModelV2.ID.make("output-only"))).enabled).toBe(true)
|
||||
}),
|
||||
),
|
||||
@@ -96,7 +96,7 @@ describe("OpencodePlugin", () => {
|
||||
draft.cost = [...paid.cost]
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).options.aisdk.provider.apiKey).toBeUndefined()
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).request.body.apiKey).toBeUndefined()
|
||||
expect((yield* catalog.model.get(ProviderV2.ID.opencode, ModelV2.ID.make("paid"))).enabled).toBe(true)
|
||||
}),
|
||||
),
|
||||
@@ -119,7 +119,7 @@ describe("OpencodePlugin", () => {
|
||||
draft.cost = [...paid.cost]
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).options.aisdk.provider.apiKey).toBeUndefined()
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).request.body.apiKey).toBeUndefined()
|
||||
expect((yield* catalog.model.get(ProviderV2.ID.opencode, ModelV2.ID.make("paid"))).enabled).toBe(true)
|
||||
}),
|
||||
),
|
||||
@@ -134,24 +134,20 @@ describe("OpencodePlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("opencode", {
|
||||
options: {
|
||||
request: {
|
||||
headers: {},
|
||||
body: {},
|
||||
aisdk: {
|
||||
provider: { apiKey: "configured" },
|
||||
request: {},
|
||||
},
|
||||
body: { apiKey: "configured" },
|
||||
},
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.options = item.options
|
||||
draft.request = item.request
|
||||
})
|
||||
const paid = model("opencode", "paid", { cost: cost(1) })
|
||||
catalog.model.update(item.id, paid.id, (draft) => {
|
||||
draft.cost = [...paid.cost]
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).options.aisdk.provider.apiKey).toBe("configured")
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).request.body.apiKey).toBe("configured")
|
||||
expect((yield* catalog.model.get(ProviderV2.ID.opencode, ModelV2.ID.make("paid"))).enabled).toBe(true)
|
||||
}),
|
||||
),
|
||||
@@ -174,7 +170,7 @@ describe("OpencodePlugin", () => {
|
||||
draft.cost = [...paid.cost]
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).options.aisdk.provider.apiKey).toBeUndefined()
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.opencode)).request.body.apiKey).toBeUndefined()
|
||||
expect((yield* catalog.model.get(ProviderV2.ID.opencode, ModelV2.ID.make("paid"))).enabled).toBe(true)
|
||||
}),
|
||||
),
|
||||
@@ -195,7 +191,7 @@ describe("OpencodePlugin", () => {
|
||||
draft.cost = [...paid.cost]
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openai)).options.aisdk.provider.apiKey).toBeUndefined()
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openai)).request.body.apiKey).toBeUndefined()
|
||||
expect((yield* catalog.model.get(ProviderV2.ID.openai, ModelV2.ID.make("paid"))).enabled).toBe(true)
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -26,22 +26,22 @@ describe("OpenRouterPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const openrouter = provider("openrouter", {
|
||||
endpoint: { type: "aisdk", package: "@openrouter/ai-sdk-provider" },
|
||||
options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } },
|
||||
api: { type: "aisdk", package: "@openrouter/ai-sdk-provider" },
|
||||
request: { headers: { Existing: "value" }, body: {} },
|
||||
})
|
||||
catalog.provider.update(openrouter.id, (item) => {
|
||||
item.endpoint = openrouter.endpoint
|
||||
item.options = openrouter.options
|
||||
item.api = openrouter.api
|
||||
item.request = openrouter.request
|
||||
})
|
||||
catalog.provider.update(ProviderV2.ID.make("nvidia"), () => {})
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("openrouter"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("openrouter"))).request.headers).toEqual({
|
||||
Existing: "value",
|
||||
"HTTP-Referer": "https://opencode.ai/",
|
||||
"X-Title": "opencode",
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("nvidia"))).options.headers).toEqual({})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("nvidia"))).request.headers).toEqual({})
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -78,10 +78,10 @@ describe("OpenRouterPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const openrouter = provider("openrouter", {
|
||||
endpoint: { type: "aisdk", package: "@openrouter/ai-sdk-provider" },
|
||||
api: { type: "aisdk", package: "@openrouter/ai-sdk-provider" },
|
||||
})
|
||||
catalog.provider.update(openrouter.id, (item) => {
|
||||
item.endpoint = openrouter.endpoint
|
||||
item.api = openrouter.api
|
||||
})
|
||||
catalog.provider.update(ProviderV2.ID.openai, () => {})
|
||||
for (const item of [
|
||||
|
||||
@@ -15,15 +15,15 @@ describe("VercelPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("vercel", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/vercel" },
|
||||
options: { headers: { Existing: "1" }, body: {}, aisdk: { provider: {}, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/vercel" },
|
||||
request: { headers: { Existing: "1" }, body: {} },
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.options = item.options
|
||||
draft.api = item.api
|
||||
draft.request = item.request
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).request.headers).toEqual({
|
||||
Existing: "1",
|
||||
"http-referer": "https://opencode.ai/",
|
||||
"x-title": "opencode",
|
||||
@@ -38,15 +38,15 @@ describe("VercelPlugin", () => {
|
||||
yield* plugin.add(VercelPlugin)
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("vercel", { endpoint: { type: "aisdk", package: "@ai-sdk/vercel" } })
|
||||
const item = provider("vercel", { api: { type: "aisdk", package: "@ai-sdk/vercel" } })
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.api = item.api
|
||||
})
|
||||
})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).options.headers).not.toHaveProperty(
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).request.headers).not.toHaveProperty(
|
||||
"HTTP-Referer",
|
||||
)
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).options.headers).not.toHaveProperty("X-Title")
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).request.headers).not.toHaveProperty("X-Title")
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -71,7 +71,7 @@ describe("VercelPlugin", () => {
|
||||
yield* plugin.add(VercelPlugin)
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => catalog.provider.update(provider("gateway").id, () => {}))
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("gateway"))).options.headers).toEqual({})
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("gateway"))).request.headers).toEqual({})
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -13,7 +13,7 @@ const it = testEffect(PluginV2.locationLayer.pipe(Layer.provide(EventV2.defaultL
|
||||
const model = new ModelV2.Info({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("grok-4")),
|
||||
apiID: ModelV2.ID.make("grok-4"),
|
||||
endpoint: {
|
||||
api: {
|
||||
type: "aisdk",
|
||||
package: "@ai-sdk/xai",
|
||||
},
|
||||
|
||||
@@ -25,15 +25,15 @@ describe("ZenmuxPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("zenmux", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.api = item.api
|
||||
})
|
||||
})
|
||||
const result = yield* catalog.provider.get(ProviderV2.ID.make("zenmux"))
|
||||
expect(result.options.headers).toEqual({ "HTTP-Referer": "https://opencode.ai/", "X-Title": "opencode" })
|
||||
expect(Object.keys(result.options.headers).sort()).toEqual(["HTTP-Referer", "X-Title"])
|
||||
expect(result.request.headers).toEqual({ "HTTP-Referer": "https://opencode.ai/", "X-Title": "opencode" })
|
||||
expect(Object.keys(result.request.headers).sort()).toEqual(["HTTP-Referer", "X-Title"])
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -45,16 +45,16 @@ describe("ZenmuxPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("zenmux", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
|
||||
options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } },
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
|
||||
request: { headers: { Existing: "value" }, body: {} },
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.options = item.options
|
||||
draft.api = item.api
|
||||
draft.request = item.request
|
||||
})
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("zenmux"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("zenmux"))).request.headers).toEqual({
|
||||
Existing: "value",
|
||||
"HTTP-Referer": "https://opencode.ai/",
|
||||
"X-Title": "opencode",
|
||||
@@ -70,20 +70,19 @@ describe("ZenmuxPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("zenmux", {
|
||||
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
|
||||
options: {
|
||||
api: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
|
||||
request: {
|
||||
headers: { "HTTP-Referer": "https://example.com/", "X-Title": "custom-title" },
|
||||
body: {},
|
||||
aisdk: { provider: {}, request: {} },
|
||||
},
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.endpoint = item.endpoint
|
||||
draft.options = item.options
|
||||
draft.api = item.api
|
||||
draft.request = item.request
|
||||
})
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("zenmux"))).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.make("zenmux"))).request.headers).toEqual({
|
||||
"HTTP-Referer": "https://example.com/",
|
||||
"X-Title": "custom-title",
|
||||
})
|
||||
@@ -98,18 +97,17 @@ describe("ZenmuxPlugin", () => {
|
||||
const transform = yield* catalog.transform()
|
||||
yield* transform((catalog) => {
|
||||
const item = provider("openrouter", {
|
||||
options: {
|
||||
request: {
|
||||
headers: { "HTTP-Referer": "https://example.com/", "X-Title": "custom-title" },
|
||||
body: {},
|
||||
aisdk: { provider: {}, request: {} },
|
||||
},
|
||||
})
|
||||
catalog.provider.update(item.id, (draft) => {
|
||||
draft.options = item.options
|
||||
draft.request = item.request
|
||||
})
|
||||
})
|
||||
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openrouter)).options.headers).toEqual({
|
||||
expect((yield* catalog.provider.get(ProviderV2.ID.openrouter)).request.headers).toEqual({
|
||||
"HTTP-Referer": "https://example.com/",
|
||||
"X-Title": "custom-title",
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user