feat(core): manage configurable plugin generations

This commit is contained in:
Dax Raad 2026-07-05 15:51:15 -04:00
commit a9b7bd9e2f
83 changed files with 1116 additions and 819 deletions

View file

@ -0,0 +1,7 @@
import { define } from "@opencode-ai/plugin/v2/effect"
import { Effect } from "effect"
export default define({
id: "failing-plugin",
effect: () => Effect.die("plugin failed"),
})

View file

@ -0,0 +1,29 @@
import { define } from "@opencode-ai/plugin/v2/effect"
import { Effect } from "effect"
export default define({
id: "variant-source",
effect: (ctx) =>
ctx.catalog
.transform((catalog) => {
catalog.provider.update("configured", (provider) => {
provider.api = { type: "aisdk", package: "@ai-sdk/openai-compatible" }
})
catalog.model.update("configured", "glm-5.2", (model) => {
model.api = {
id: "glm-5.2",
type: "aisdk",
package: "@ai-sdk/openai-compatible",
}
model.variants = [
{
id: "high",
settings: {},
headers: { custom: "true" },
body: {},
},
]
})
})
.pipe(Effect.asVoid),
})

View file

@ -59,8 +59,6 @@ export function host(overrides: Overrides = {}): PluginContext {
},
plugin: overrides.plugin ?? {
list: () => Effect.die("unused plugin.list"),
add: () => Effect.die("unused plugin.add"),
remove: () => Effect.die("unused plugin.remove"),
},
reference: overrides.reference ?? {
list: () => Effect.die("unused reference.list"),

View file

@ -19,7 +19,9 @@ const addPlugin = Effect.fn(function* () {
describe("KiloPlugin", () => {
it.effect("is registered so legacy referer headers can be applied", () =>
Effect.sync(() => expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("kilo"))),
Effect.sync(() =>
expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("opencode.provider.kilo")),
),
)
it.effect("applies legacy referer headers only to kilo", () =>

View file

@ -21,7 +21,9 @@ const addPlugin = Effect.fn(function* () {
describe("LLMGatewayPlugin", () => {
it.effect("is registered so legacy referer headers can be applied", () =>
Effect.sync(() => expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("llmgateway"))),
Effect.sync(() =>
expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("opencode.provider.llmgateway")),
),
)
it.effect("applies legacy referer headers only to enabled llmgateway", () =>

View file

@ -19,7 +19,9 @@ const addPlugin = Effect.fn(function* () {
describe("NvidiaPlugin", () => {
it.effect("is registered so legacy referer headers can be applied", () =>
Effect.sync(() => expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("nvidia"))),
Effect.sync(() =>
expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("opencode.provider.nvidia")),
),
)
it.effect("applies NVIDIA tracking headers only to nvidia", () =>

View file

@ -22,7 +22,9 @@ const addPlugin = Effect.fn(function* () {
describe("OpenRouterPlugin", () => {
it.effect("is registered so legacy OpenRouter behavior can be applied", () =>
Effect.sync(() => expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("openrouter"))),
Effect.sync(() =>
expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("opencode.provider.openrouter")),
),
)
it.effect("applies legacy referer headers only to openrouter", () =>

View file

@ -43,9 +43,11 @@ function withEnv<A, E, R>(vars: Record<string, string | undefined>, effect: () =
describe("SnowflakeCortexPlugin", () => {
it.effect("is registered in ProviderPlugins before OpenAICompatiblePlugin", () =>
Effect.sync(() => {
expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("snowflake-cortex"))
expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("opencode.provider.snowflake-cortex"))
const ids = ProviderPlugins.map((p) => p.id)
expect(ids.indexOf("snowflake-cortex")).toBeLessThan(ids.indexOf("openai-compatible"))
expect(ids.indexOf("opencode.provider.snowflake-cortex")).toBeLessThan(
ids.indexOf("opencode.provider.openai-compatible"),
)
}),
)

View file

@ -24,7 +24,9 @@ function required<T>(value: T | undefined): T {
describe("ZenmuxPlugin", () => {
it.effect("is registered so legacy referer headers can be applied", () =>
Effect.sync(() => expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("zenmux"))),
Effect.sync(() =>
expect(ProviderPlugins.map((item) => item.id)).toContain(PluginV2.ID.make("opencode.provider.zenmux")),
),
)
it.effect("applies the exact legacy Zenmux headers", () =>