109 lines
4.7 KiB
TypeScript
109 lines
4.7 KiB
TypeScript
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-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);
|
|
}),
|
|
});
|