refactor(core): consolidate tool architecture
This commit is contained in:
parent
0fd73a2976
commit
8db7487c89
466 changed files with 9405 additions and 11071 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const AlibabaPlugin = define({
|
||||
id: "opencode.provider.alibaba",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Effect } from "effect"
|
||||
import type { LanguageModelV3 } from "@ai-sdk/provider"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
type MantleSDK = {
|
||||
languageModel: (modelID: string) => LanguageModelV3
|
||||
|
|
@ -64,8 +64,8 @@ export const AmazonBedrockPlugin = define({
|
|||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/amazon-bedrock") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/amazon-bedrock") continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
if (typeof provider.settings?.endpoint !== "string") return
|
||||
// The AI SDK expects a base URL, but users configure Bedrock private/VPC
|
||||
|
|
@ -112,10 +112,10 @@ export const AmazonBedrockPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.amazonBedrock) return
|
||||
if (evt.model.providerID !== Provider.ID.amazonBedrock) return
|
||||
if (
|
||||
ProviderV2.isAISDK(evt.model.package) &&
|
||||
ProviderV2.packageName(evt.model.package) === "@ai-sdk/amazon-bedrock/mantle"
|
||||
Provider.isAISDK(evt.model.package) &&
|
||||
Provider.packageName(evt.model.package) === "@ai-sdk/amazon-bedrock/mantle"
|
||||
) {
|
||||
evt.language = selectMantleModel(evt.sdk, evt.model.modelID ?? evt.model.id)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
export const AnthropicPlugin = define({
|
||||
id: "opencode.provider.anthropic",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/anthropic") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/anthropic") continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
provider.headers = {
|
||||
...provider.headers,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
function selectLanguage(sdk: any, modelID: string, useChat: boolean) {
|
||||
if (useChat && sdk.chat) return sdk.chat(modelID)
|
||||
|
|
@ -15,8 +15,8 @@ export const AzurePlugin = define({
|
|||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/azure") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/azure") continue
|
||||
const configured = item.provider.settings?.resourceName
|
||||
const resourceName =
|
||||
typeof configured === "string" && configured.trim() !== "" ? configured : process.env.AZURE_RESOURCE_NAME
|
||||
|
|
@ -30,11 +30,11 @@ export const AzurePlugin = define({
|
|||
"sdk",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.package !== "@ai-sdk/azure") return
|
||||
if (evt.model.providerID === ProviderV2.ID.azure) {
|
||||
if (evt.model.providerID === Provider.ID.azure) {
|
||||
if (
|
||||
!evt.options.resourceName &&
|
||||
!evt.options.baseURL &&
|
||||
(!ProviderV2.isAISDK(evt.model.package) || typeof evt.model.settings?.baseURL !== "string")
|
||||
(!Provider.isAISDK(evt.model.package) || typeof evt.model.settings?.baseURL !== "string")
|
||||
) {
|
||||
throw new Error(
|
||||
"AZURE_RESOURCE_NAME is missing, set it using env var or reconnecting the azure provider and setting it",
|
||||
|
|
@ -48,7 +48,7 @@ export const AzurePlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.azure) return
|
||||
if (evt.model.providerID !== Provider.ID.azure) return
|
||||
evt.language = selectLanguage(
|
||||
evt.sdk,
|
||||
evt.model.modelID ?? evt.model.id,
|
||||
|
|
@ -66,8 +66,8 @@ export const AzureCognitiveServicesPlugin = define({
|
|||
const resourceName = process.env.AZURE_COGNITIVE_SERVICES_RESOURCE_NAME
|
||||
if (!resourceName) return
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (!item.provider.id.includes("azure-cognitive-services")) continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
provider.settings = {
|
||||
|
|
@ -80,7 +80,7 @@ export const AzureCognitiveServicesPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.make("azure-cognitive-services")) return
|
||||
if (evt.model.providerID !== Provider.ID.make("azure-cognitive-services")) return
|
||||
evt.language = selectLanguage(
|
||||
evt.sdk,
|
||||
evt.model.modelID ?? evt.model.id,
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
export const CerebrasPlugin = define({
|
||||
id: "opencode.provider.cerebras",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/cerebras") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/cerebras") continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
provider.headers = { ...provider.headers, "X-Cerebras-3rd-Party-Integration": "opencode" }
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import os from "os"
|
||||
import { App } from "../../app"
|
||||
import { Effect, Option, Schema } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const CloudflareAIGatewayPlugin = define({
|
||||
id: "opencode.provider.cloudflare-ai-gateway",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import os from "os"
|
||||
import { App } from "../../app"
|
||||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
const providerID = ProviderV2.ID.make("cloudflare-workers-ai")
|
||||
const providerID = Provider.ID.make("cloudflare-workers-ai")
|
||||
|
||||
export const CloudflareWorkersAIPlugin = define({
|
||||
id: "opencode.provider.cloudflare-workers-ai",
|
||||
|
|
@ -13,7 +13,7 @@ export const CloudflareWorkersAIPlugin = define({
|
|||
const item = evt.provider.get(providerID)
|
||||
if (!item) return
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
if (!ProviderV2.isAISDK(provider.package)) return
|
||||
if (!Provider.isAISDK(provider.package)) return
|
||||
if (typeof provider.settings?.baseURL === "string") return
|
||||
const accountId = resolveAccountId(provider.settings ?? {})
|
||||
if (accountId) provider.settings = { ...provider.settings, baseURL: workersEndpoint(accountId) }
|
||||
|
|
@ -61,7 +61,7 @@ function hasWorkersEndpoint(model: {
|
|||
readonly package?: string
|
||||
readonly settings?: Readonly<Record<string, unknown>>
|
||||
}) {
|
||||
return ProviderV2.isAISDK(model.package) && typeof model.settings?.baseURL === "string"
|
||||
return Provider.isAISDK(model.package) && typeof model.settings?.baseURL === "string"
|
||||
}
|
||||
|
||||
function sdkOptions(options: Record<string, any>, app: App.Info) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const CoherePlugin = define({
|
||||
id: "opencode.provider.cohere",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const DeepInfraPlugin = define({
|
||||
id: "opencode.provider.deepinfra",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Effect } from "effect"
|
||||
import { pathToFileURL } from "url"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Npm } from "@opencode-ai/util/npm"
|
||||
import { importModule } from "@opencode-ai/util/runtime-import"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const GatewayPlugin = define({
|
||||
id: "opencode.provider.gateway",
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import type { IntegrationOAuthMethodRegistration } from "@opencode-ai/plugin/v2/effect/integration"
|
||||
import type { IntegrationOAuthMethodRegistration } from "@opencode-ai/plugin/effect/integration"
|
||||
import { Effect, Option, Schema, Semaphore, Stream } from "effect"
|
||||
import { Catalog } from "../../catalog"
|
||||
import { Credential } from "../../credential"
|
||||
import { EventV2 } from "../../event"
|
||||
import { Bus } from "../../bus"
|
||||
import { CopilotModels } from "../../github-copilot/models"
|
||||
import { App } from "../../app"
|
||||
import { Integration } from "../../integration"
|
||||
import { ModelV2 } from "../../model"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { Model } from "../../model"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
import type { PluginInternal } from "../internal"
|
||||
|
||||
const clientID = "Ov23li8tweQw6odWQebz"
|
||||
|
|
@ -152,11 +152,11 @@ export const GithubCopilotPlugin = define({
|
|||
id: "opencode.provider.github-copilot",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
const catalog = yield* Catalog.Service
|
||||
const events = yield* EventV2.Service
|
||||
const bus = yield* Bus.Service
|
||||
const loading = Semaphore.makeUnsafe(1)
|
||||
const loaded: {
|
||||
baseURL?: string
|
||||
models?: Map<ModelV2.ID, ModelV2.Info>
|
||||
models?: Map<Model.ID, Model.Info>
|
||||
} = {}
|
||||
|
||||
const load = Effect.fn("GithubCopilotPlugin.load")(function* () {
|
||||
|
|
@ -171,8 +171,8 @@ export const GithubCopilotPlugin = define({
|
|||
}
|
||||
|
||||
loaded.baseURL = copilotBaseURL(credential.metadata)
|
||||
const provider = yield* catalog.provider.get(ProviderV2.ID.githubCopilot)
|
||||
const existing = (yield* catalog.model.all()).filter((model) => model.providerID === ProviderV2.ID.githubCopilot)
|
||||
const provider = yield* catalog.provider.get(Provider.ID.githubCopilot)
|
||||
const existing = (yield* catalog.model.all()).filter((model) => model.providerID === Provider.ID.githubCopilot)
|
||||
loaded.models = yield* Effect.tryPromise({
|
||||
try: () =>
|
||||
CopilotModels.get(
|
||||
|
|
@ -197,11 +197,11 @@ export const GithubCopilotPlugin = define({
|
|||
draft.method.update(oauth(ctx.app))
|
||||
})
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
const item = evt.provider.get(ProviderV2.ID.githubCopilot)
|
||||
const item = evt.provider.get(Provider.ID.githubCopilot)
|
||||
if (!item) return
|
||||
if (loaded.models) {
|
||||
for (const id of item.models.keys()) {
|
||||
if (!loaded.models.has(ModelV2.ID.make(id))) evt.model.remove(item.provider.id, id)
|
||||
if (!loaded.models.has(Model.ID.make(id))) evt.model.remove(item.provider.id, id)
|
||||
}
|
||||
for (const [id, model] of loaded.models) {
|
||||
evt.model.update(item.provider.id, id, (draft) => Object.assign(draft, structuredClone(model)))
|
||||
|
|
@ -209,12 +209,12 @@ export const GithubCopilotPlugin = define({
|
|||
} else if (loaded.baseURL) {
|
||||
for (const id of item.models.keys()) {
|
||||
evt.model.update(item.provider.id, id, (model) => {
|
||||
model.settings = ProviderV2.mergeOverlay(model.settings, { baseURL: loaded.baseURL })
|
||||
model.settings = Provider.mergeOverlay(model.settings, { baseURL: loaded.baseURL })
|
||||
})
|
||||
}
|
||||
}
|
||||
if (item.models.has(ModelV2.ID.make("gpt-5-chat-latest"))) {
|
||||
evt.model.update(item.provider.id, ModelV2.ID.make("gpt-5-chat-latest"), (model) => {
|
||||
if (item.models.has(Model.ID.make("gpt-5-chat-latest"))) {
|
||||
evt.model.update(item.provider.id, Model.ID.make("gpt-5-chat-latest"), (model) => {
|
||||
// This chat-only alias conflicts with the Copilot GPT-5 Responses route,
|
||||
// so hide it only for Copilot rather than for every provider catalog.
|
||||
model.enabled = false
|
||||
|
|
@ -222,7 +222,7 @@ export const GithubCopilotPlugin = define({
|
|||
}
|
||||
})
|
||||
const refresh = () => loading.withPermit(load().pipe(Effect.andThen(ctx.catalog.reload())))
|
||||
yield* events.subscribe(Integration.Event.ConnectionUpdated).pipe(
|
||||
yield* bus.subscribe(Integration.Event.ConnectionUpdated).pipe(
|
||||
Stream.filter((event) => event.data.integrationID === Integration.ID.make("github-copilot")),
|
||||
Stream.runForEach(refresh),
|
||||
Effect.forkScoped({ startImmediately: true }),
|
||||
|
|
@ -231,7 +231,7 @@ export const GithubCopilotPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"sdk",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.githubCopilot) return
|
||||
if (evt.model.providerID !== Provider.ID.githubCopilot) return
|
||||
if (evt.package !== "@ai-sdk/github-copilot" && evt.package !== "@ai-sdk/anthropic") return
|
||||
evt.options.fetch = copilotFetch(
|
||||
typeof evt.options.apiKey === "string" ? evt.options.apiKey : undefined,
|
||||
|
|
@ -255,7 +255,7 @@ export const GithubCopilotPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.githubCopilot) return
|
||||
if (evt.model.providerID !== Provider.ID.githubCopilot) return
|
||||
if (evt.sdk.responses === undefined && evt.sdk.chat === undefined) {
|
||||
evt.language = evt.sdk.languageModel(evt.model.modelID ?? evt.model.id)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import os from "os"
|
||||
import { App } from "../../app"
|
||||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
export const GitLabPlugin = define({
|
||||
id: "opencode.provider.gitlab",
|
||||
|
|
@ -35,7 +35,7 @@ export const GitLabPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.gitlab) return
|
||||
if (evt.model.providerID !== Provider.ID.gitlab) return
|
||||
const featureFlags =
|
||||
typeof evt.options.featureFlags === "object" && evt.options.featureFlags ? evt.options.featureFlags : {}
|
||||
const id = evt.model.modelID ?? evt.model.id
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
function resolveProject(options: Record<string, any>) {
|
||||
// models.dev advertises GOOGLE_VERTEX_PROJECT for Vertex, while Google SDKs
|
||||
|
|
@ -59,12 +59,12 @@ export const GoogleVertexPlugin = define({
|
|||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (
|
||||
ProviderV2.packageName(item.provider.package) !== "@ai-sdk/google-vertex" &&
|
||||
Provider.packageName(item.provider.package) !== "@ai-sdk/google-vertex" &&
|
||||
!(
|
||||
item.provider.id === ProviderV2.ID.googleVertex &&
|
||||
ProviderV2.packageName(item.provider.package)?.includes("@ai-sdk/openai-compatible")
|
||||
item.provider.id === Provider.ID.googleVertex &&
|
||||
Provider.packageName(item.provider.package)?.includes("@ai-sdk/openai-compatible")
|
||||
)
|
||||
)
|
||||
continue
|
||||
|
|
@ -78,7 +78,7 @@ export const GoogleVertexPlugin = define({
|
|||
...(typeof provider.settings?.baseURL === "string"
|
||||
? { baseURL: replaceVertexVars(provider.settings.baseURL, project, location) }
|
||||
: {}),
|
||||
...(ProviderV2.packageName(provider.package)?.includes("@ai-sdk/openai-compatible")
|
||||
...(Provider.packageName(provider.package)?.includes("@ai-sdk/openai-compatible")
|
||||
? { fetch: authFetch(provider.settings?.fetch) }
|
||||
: {}),
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ export const GoogleVertexPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"sdk",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID === ProviderV2.ID.googleVertex && evt.package.includes("@ai-sdk/openai-compatible")) {
|
||||
if (evt.model.providerID === Provider.ID.googleVertex && evt.package.includes("@ai-sdk/openai-compatible")) {
|
||||
evt.options.fetch = authFetch(evt.options.fetch)
|
||||
return
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ export const GoogleVertexPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.googleVertex) return
|
||||
if (evt.model.providerID !== Provider.ID.googleVertex) return
|
||||
evt.language = evt.sdk.languageModel(String(evt.model.modelID ?? evt.model.id).trim())
|
||||
}),
|
||||
)
|
||||
|
|
@ -120,8 +120,8 @@ export const GoogleVertexAnthropicPlugin = define({
|
|||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/google-vertex/anthropic") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/google-vertex/anthropic") continue
|
||||
const project =
|
||||
item.provider.settings?.project ??
|
||||
process.env.GOOGLE_CLOUD_PROJECT ??
|
||||
|
|
@ -167,7 +167,7 @@ export const GoogleVertexAnthropicPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.make("google-vertex-anthropic")) return
|
||||
if (evt.model.providerID !== Provider.ID.make("google-vertex-anthropic")) return
|
||||
evt.language = evt.sdk.languageModel(String(evt.model.modelID ?? evt.model.id).trim())
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const GooglePlugin = define({
|
||||
id: "opencode.provider.google",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const GroqPlugin = define({
|
||||
id: "opencode.provider.groq",
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
export const KiloPlugin = define({
|
||||
id: "opencode.provider.kilo",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (item.provider.settings?.baseURL !== "https://api.kilo.ai/api/gateway") continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
provider.headers = { ...provider.headers, "HTTP-Referer": "https://opencode.ai/", "X-Title": "opencode" }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Integration } from "../../integration"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
export const LLMGatewayPlugin = define({
|
||||
id: "opencode.provider.llmgateway",
|
||||
|
|
@ -11,8 +11,8 @@ export const LLMGatewayPlugin = define({
|
|||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (item.provider.disabled) continue
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (item.provider.settings?.baseURL !== "https://api.llmgateway.io/v1") continue
|
||||
if (!configured.has(Integration.ID.make(item.provider.id))) continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const MistralPlugin = define({
|
||||
id: "opencode.provider.mistral",
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
export const NvidiaPlugin = define({
|
||||
id: "opencode.provider.nvidia",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (item.provider.settings?.baseURL !== "https://integrate.api.nvidia.com/v1") continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
provider.headers = {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const OpenAICompatiblePlugin = define({
|
||||
id: "opencode.provider.openai-compatible",
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { createServer } from "node:http"
|
||||
import type { IntegrationOAuthMethodRegistration } from "@opencode-ai/plugin/v2/effect/integration"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import type { IntegrationOAuthMethodRegistration } from "@opencode-ai/plugin/effect/integration"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Deferred, Effect, Option, Schema, Semaphore, Stream } from "effect"
|
||||
import { App } from "../../app"
|
||||
import { Credential } from "../../credential"
|
||||
import { EventV2 } from "../../event"
|
||||
import { Bus } from "../../bus"
|
||||
import { Integration } from "../../integration"
|
||||
import { ModelV2 } from "../../model"
|
||||
import { Model } from "../../model"
|
||||
import { OauthCallbackPage } from "../../oauth/page"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { Provider } from "../../provider"
|
||||
import type { PluginInternal } from "../internal"
|
||||
import { OpenAICodex } from "./openai-codex"
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ const headless = (app: App.Info) => ({
|
|||
export const OpenAIPlugin = define({
|
||||
id: "opencode.provider.openai",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
const events = yield* EventV2.Service
|
||||
const bus = yield* Bus.Service
|
||||
const loading = Semaphore.makeUnsafe(1)
|
||||
let chatgpt = false
|
||||
|
||||
|
|
@ -181,17 +181,17 @@ export const OpenAIPlugin = define({
|
|||
yield* load()
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai") continue
|
||||
if (!item.models.has(ModelV2.ID.make("gpt-5-chat-latest"))) continue
|
||||
evt.model.update(item.provider.id, ModelV2.ID.make("gpt-5-chat-latest"), (model) => {
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/openai") continue
|
||||
if (!item.models.has(Model.ID.make("gpt-5-chat-latest"))) continue
|
||||
evt.model.update(item.provider.id, Model.ID.make("gpt-5-chat-latest"), (model) => {
|
||||
// OpenAIPlugin sends OpenAI models through Responses; this alias is a
|
||||
// chat-completions-only model, so hide it only from OpenAI's catalog.
|
||||
model.enabled = false
|
||||
})
|
||||
}
|
||||
if (!chatgpt) return
|
||||
const item = evt.provider.get(ProviderV2.ID.openai)
|
||||
const item = evt.provider.get(Provider.ID.openai)
|
||||
if (!item) return
|
||||
for (const model of item.models.values()) {
|
||||
// ChatGPT-plan tokens only authorize codex-eligible models, and the
|
||||
|
|
@ -211,7 +211,7 @@ export const OpenAIPlugin = define({
|
|||
})
|
||||
|
||||
const refresh = () => loading.withPermit(load().pipe(Effect.andThen(ctx.catalog.reload())))
|
||||
yield* events.subscribe(Integration.Event.ConnectionUpdated).pipe(
|
||||
yield* bus.subscribe(Integration.Event.ConnectionUpdated).pipe(
|
||||
Stream.filter((event) => event.data.integrationID === Integration.ID.make("openai")),
|
||||
Stream.runForEach(refresh),
|
||||
Effect.forkScoped({ startImmediately: true }),
|
||||
|
|
@ -227,7 +227,7 @@ export const OpenAIPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.openai) return
|
||||
if (evt.model.providerID !== Provider.ID.openai) return
|
||||
evt.language = evt.sdk.responses(evt.model.modelID ?? evt.model.id)
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { Duration, Effect, Schema, Semaphore, Stream } from "effect"
|
||||
import type { Scope } from "effect"
|
||||
import type { IntegrationOAuthMethodRegistration } from "@opencode-ai/plugin/v2/effect/integration"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import type { IntegrationOAuthMethodRegistration } from "@opencode-ai/plugin/effect/integration"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import type { CredentialValue } from "@opencode-ai/sdk/v2/types"
|
||||
import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
|
||||
import { EventV2 } from "../../event"
|
||||
import { Bus } from "../../bus"
|
||||
import { Credential } from "../../credential"
|
||||
import { Integration } from "../../integration"
|
||||
import { ModelV2 } from "../../model"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { Model } from "../../model"
|
||||
import { Provider } from "../../provider"
|
||||
import { ConfigProviderV1 } from "../../v1/config/provider"
|
||||
import { Money } from "@opencode-ai/schema/money"
|
||||
import { ConfigProviderOptionsV1 } from "../../v1/config/provider-options"
|
||||
|
|
@ -82,10 +82,10 @@ function oauth(http: HttpClient.HttpClient) {
|
|||
} satisfies IntegrationOAuthMethodRegistration
|
||||
}
|
||||
|
||||
export const OpencodePlugin = define<HttpClient.HttpClient | EventV2.Service | Scope.Scope>({
|
||||
export const OpencodePlugin = define<HttpClient.HttpClient | Bus.Service | Scope.Scope>({
|
||||
id: "opencode.provider.opencode",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
const events = yield* EventV2.Service
|
||||
const bus = yield* Bus.Service
|
||||
const http = yield* HttpClient.HttpClient
|
||||
const loading = Semaphore.makeUnsafe(1)
|
||||
let connected = false
|
||||
|
|
@ -120,7 +120,7 @@ export const OpencodePlugin = define<HttpClient.HttpClient | EventV2.Service | S
|
|||
catalog.provider.update(providerID, (provider) => {
|
||||
provider.integrationID = Integration.ID.make("opencode")
|
||||
if (item.name !== undefined) provider.name = item.name
|
||||
provider.package = item.npm ? ProviderV2.aisdk(item.npm) : ""
|
||||
provider.package = item.npm ? Provider.aisdk(item.npm) : ""
|
||||
provider.settings = {
|
||||
...provider.settings,
|
||||
...withoutCredentials(item.options),
|
||||
|
|
@ -131,12 +131,12 @@ export const OpencodePlugin = define<HttpClient.HttpClient | EventV2.Service | S
|
|||
|
||||
for (const [modelID, config] of Object.entries(item.models ?? {})) {
|
||||
catalog.model.update(providerID, modelID, (model) => {
|
||||
if (config.family !== undefined) model.family = config.family
|
||||
if (config.family !== undefined) model.family = Model.Family.make(config.family)
|
||||
if (config.name !== undefined) model.name = config.name
|
||||
if (config.id !== undefined) model.modelID = config.id
|
||||
model.compatibility = ModelV2.compatibility(config.interleaved) ?? model.compatibility
|
||||
if (config.id !== undefined) model.modelID = Model.ID.make(config.id)
|
||||
model.compatibility = Model.compatibility(config.interleaved) ?? model.compatibility
|
||||
if (config.provider !== undefined) {
|
||||
model.package = config.provider.npm ? ProviderV2.aisdk(config.provider.npm) : undefined
|
||||
model.package = config.provider.npm ? Provider.aisdk(config.provider.npm) : undefined
|
||||
if (config.provider.api) model.settings = { ...model.settings, baseURL: config.provider.api }
|
||||
}
|
||||
if (config.tool_call !== undefined) model.capabilities.tools = config.tool_call
|
||||
|
|
@ -147,7 +147,7 @@ export const OpencodePlugin = define<HttpClient.HttpClient | EventV2.Service | S
|
|||
if (config.variants !== undefined) {
|
||||
model.variants ??= []
|
||||
for (const [id, options] of Object.entries(config.variants)) {
|
||||
const variantID = ModelV2.VariantID.make(id)
|
||||
const variantID = Model.VariantID.make(id)
|
||||
let existing = model.variants.find((item) => item.id === variantID)
|
||||
if (!existing) {
|
||||
existing = { id: variantID }
|
||||
|
|
@ -174,7 +174,7 @@ export const OpencodePlugin = define<HttpClient.HttpClient | EventV2.Service | S
|
|||
}
|
||||
}
|
||||
|
||||
const item = catalog.provider.get(ProviderV2.ID.opencode)
|
||||
const item = catalog.provider.get(Provider.ID.opencode)
|
||||
if (!item) return
|
||||
const hasKey = Boolean(process.env.OPENCODE_API_KEY || connected || item.provider.settings?.apiKey)
|
||||
catalog.provider.update(item.provider.id, (provider) => {
|
||||
|
|
@ -190,7 +190,7 @@ export const OpencodePlugin = define<HttpClient.HttpClient | EventV2.Service | S
|
|||
})
|
||||
|
||||
const refresh = () => loading.withPermit(load().pipe(Effect.andThen(ctx.catalog.reload())))
|
||||
yield* events.subscribe(Integration.Event.ConnectionUpdated).pipe(
|
||||
yield* bus.subscribe(Integration.Event.ConnectionUpdated).pipe(
|
||||
Stream.filter((event) => event.data.integrationID === Integration.ID.make("opencode")),
|
||||
Stream.runForEach(refresh),
|
||||
Effect.forkScoped({ startImmediately: true }),
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
import { Effect } from "effect"
|
||||
import { ModelV2 } from "../../model"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { Model } from "../../model"
|
||||
import { Provider } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const OpenRouterPlugin = define({
|
||||
id: "opencode.provider.openrouter",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@openrouter/ai-sdk-provider") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@openrouter/ai-sdk-provider") continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
provider.headers = { ...provider.headers, "HTTP-Referer": "https://opencode.ai/", "X-Title": "opencode" }
|
||||
})
|
||||
for (const modelID of [ModelV2.ID.make("gpt-5-chat-latest"), ModelV2.ID.make("openai/gpt-5-chat")]) {
|
||||
for (const modelID of [Model.ID.make("gpt-5-chat-latest"), Model.ID.make("openai/gpt-5-chat")]) {
|
||||
if (!item.models.has(modelID)) continue
|
||||
evt.model.update(item.provider.id, modelID, (model) => {
|
||||
// These are OpenRouter-specific OpenAI chat aliases that do not work
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const PerplexityPlugin = define({
|
||||
id: "opencode.provider.perplexity",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { Effect } from "effect"
|
||||
import { pathToFileURL } from "url"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Npm } from "@opencode-ai/util/npm"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { Provider } from "../../provider"
|
||||
import { importModule } from "@opencode-ai/util/runtime-import"
|
||||
|
||||
export const SapAICorePlugin = define({
|
||||
|
|
@ -12,7 +12,7 @@ export const SapAICorePlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"sdk",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return
|
||||
if (evt.model.providerID !== Provider.ID.make("sap-ai-core")) return
|
||||
const serviceKey =
|
||||
process.env.AICORE_SERVICE_KEY ??
|
||||
(typeof evt.options.serviceKey === "string" ? evt.options.serviceKey : undefined)
|
||||
|
|
@ -42,7 +42,7 @@ export const SapAICorePlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return
|
||||
if (evt.model.providerID !== Provider.ID.make("sap-ai-core")) return
|
||||
evt.language = evt.sdk(evt.model.modelID ?? evt.model.id)
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
type FetchLike = (url: string | URL | Request, init?: RequestInit) => Promise<Response>
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ export const SnowflakeCortexPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"sdk",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.make("snowflake-cortex")) return
|
||||
if (evt.model.providerID !== Provider.ID.make("snowflake-cortex")) return
|
||||
const token =
|
||||
process.env.SNOWFLAKE_CORTEX_TOKEN ??
|
||||
process.env.SNOWFLAKE_CORTEX_PAT ??
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const TogetherAIPlugin = define({
|
||||
id: "opencode.provider.togetherai",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
|
||||
export const VenicePlugin = define({
|
||||
id: "opencode.provider.venice",
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
export const VercelPlugin = define({
|
||||
id: "opencode.provider.vercel",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/vercel") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/vercel") continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
provider.headers = { ...provider.headers, "http-referer": "https://opencode.ai/", "x-title": "opencode" }
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { createServer } from "node:http"
|
||||
import type { IntegrationOAuthMethodRegistration } from "@opencode-ai/plugin/v2/effect/integration"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import type { IntegrationOAuthMethodRegistration } from "@opencode-ai/plugin/effect/integration"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Clock, Deferred, Effect, Option, Schema } from "effect"
|
||||
import { App } from "../../app"
|
||||
import { Credential } from "../../credential"
|
||||
import { Integration } from "../../integration"
|
||||
import { OauthCallbackPage } from "../../oauth/page"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
const clientID = "b1a00492-073a-47ea-816f-4c329264a828"
|
||||
const issuer = "https://auth.x.ai/oauth2"
|
||||
|
|
@ -173,7 +173,7 @@ export const XAIPlugin = define({
|
|||
yield* ctx.aisdk.hook(
|
||||
"language",
|
||||
Effect.fn(function* (evt) {
|
||||
if (evt.model.providerID !== ProviderV2.ID.make("xai")) return
|
||||
if (evt.model.providerID !== Provider.ID.make("xai")) return
|
||||
evt.language = evt.sdk.responses(evt.model.modelID ?? evt.model.id)
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { Effect } from "effect"
|
||||
import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import { define } from "@opencode-ai/plugin/effect/plugin"
|
||||
import { Provider } from "../../provider"
|
||||
|
||||
export const ZenmuxPlugin = define({
|
||||
id: "opencode.provider.zenmux",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
yield* ctx.catalog.transform((evt) => {
|
||||
for (const item of evt.provider.list()) {
|
||||
if (!ProviderV2.isAISDK(item.provider.package)) continue
|
||||
if (ProviderV2.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (!Provider.isAISDK(item.provider.package)) continue
|
||||
if (Provider.packageName(item.provider.package) !== "@ai-sdk/openai-compatible") continue
|
||||
if (item.provider.settings?.baseURL !== "https://zenmux.ai/api/v1") continue
|
||||
evt.provider.update(item.provider.id, (provider) => {
|
||||
provider.headers = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue