import { Plugin, Agent, Model, Provider } from "@opencode/plugin/effect"; import { Rpc } from "@opencode/plugin/rpc"; import { Session } from "@opencode/schema/session"; import { SessionMessage } from "@opencode/schema/session-message"; import { Tool } from "@opencode/schema/tool"; import { Cause, Effect } from "effect"; import { z } from "zod"; import { appendFile } from "node:fs/promises"; import plugin from "../../src/index.js"; const probe = Rpc.define({ id: "multi-work-test", events: {}, methods: { delegate: { input: z.object({ parent: z.string(), child: z.string().optional(), background: z.boolean(), }), output: z.string(), }, }, }); export default Plugin.define({ id: plugin.id, effect: (context) => Effect.gen(function* () { const providerID = Provider.ID.make("fixture"); yield* context.provider.transform((editor) => editor.add({ info: { ...Provider.Info.empty(providerID), name: "Isolated fixture", activation: "enabled", package: "@opencode/ai/providers/openai-compatible", settings: { baseURL: process.env.FIXTURE_MODEL_URL! }, }, models: ["gpt-6-luna", "gpt-6.1-sol", "gpt-6-astra"].map((id) => Model.Info.default(providerID, Model.ID.make(id)), ), }), ); yield* plugin.effect({ ...context, options: { provider: "fixture" } }); let delegate: Tool.Info | undefined; yield* context.tool.transform((editor) => { delegate = editor.get("subagent"); }); yield* context.session.hook("prompt", (event) => Effect.gen(function* () { const child = yield* context.session.get({ sessionID: event.sessionID }); yield* Effect.promise(() => appendFile( process.env.FIXTURE_TRACE!, JSON.stringify({ id: child.id, parent: child.parentID, agent: child.agent, directory: child.location.directory, }) + "\n", ), ); }).pipe(Effect.orDie), ); yield* context.rpc .register(probe, { delegate: (input) => Effect.gen(function* () { if (!delegate) throw new Error("Native subagent missing"); const result = yield* delegate.execute( { agent: "coordinate", description: "native host proof", prompt: "Reply with FIXTURE_COMPLETE", background: input.background, ...(input.child ? { sessionID: input.child } : { worktree: { base: "main", branch: "fix/native-host", label: "Fix native host", }, }), }, { sessionID: Session.ID.make(input.parent), agent: Agent.ID.make("multi-work"), messageID: SessionMessage.ID.create(), id: Tool.CallID.make(`call_${crypto.randomUUID()}`), progress: () => Effect.void, }, ); return JSON.stringify(result); }).pipe( Effect.catchCause((cause) => Cause.hasInterrupts(cause) ? Effect.interrupt : Effect.succeed( JSON.stringify({ failure: Cause.pretty(cause) }), ), ), ), }) .pipe(Effect.orDie); }), });