mirror of
https://github.com/Heretek-AI/opencode.git
synced 2026-11-09 17:16:05 -10:00
56 lines
2.2 KiB
TypeScript
56 lines
2.2 KiB
TypeScript
import { expect } from "bun:test"
|
|
import { Agent } from "@opencode/core/agent"
|
|
import { Plugin } from "@opencode/core/plugin"
|
|
import { PluginHost } from "@opencode/core/plugin/host"
|
|
import { PluginPromise } from "@opencode/core/plugin/promise"
|
|
import { Tool } from "@opencode/core/tool"
|
|
import { Session } from "@opencode/schema/session"
|
|
import { SessionMessage } from "@opencode/schema/session-message"
|
|
import { Cause, Deferred, Effect, Exit, Fiber } from "effect"
|
|
import { testEffect } from "../lib/effect"
|
|
import { PluginTestLayer } from "./fixture"
|
|
|
|
const it = testEffect(PluginTestLayer)
|
|
|
|
it.live("Promise tool executors receive interruption through their AbortSignal", () =>
|
|
Effect.gen(function* () {
|
|
const plugins = yield* Plugin.Service
|
|
const tools = yield* Tool.Service
|
|
const started = yield* Deferred.make<AbortSignal>()
|
|
yield* PluginPromise.fromPromise({
|
|
id: "cancel-tool",
|
|
async setup(context) {
|
|
await context.tool.transform((editor) =>
|
|
editor.add({
|
|
name: "wait",
|
|
description: "Wait until cancelled",
|
|
input: { type: "object", properties: {}, additionalProperties: false },
|
|
options: { codemode: false },
|
|
execute: (_input, context) =>
|
|
new Promise<never>((_resolve, reject) => {
|
|
context.signal.addEventListener("abort", () => reject(new Error("cancelled")), { once: true })
|
|
Effect.runSync(Deferred.succeed(started, context.signal))
|
|
}),
|
|
}),
|
|
)
|
|
},
|
|
}).effect(yield* PluginHost.make(plugins))
|
|
|
|
const snapshot = yield* tools.snapshot()
|
|
const fiber = yield* snapshot
|
|
.execute({
|
|
sessionID: Session.ID.make("ses_promise_tool_cancel"),
|
|
agent: Agent.ID.make("build"),
|
|
messageID: SessionMessage.ID.make("msg_promise_tool_cancel"),
|
|
call: { type: "tool-call", id: "call_promise_tool_cancel", name: "wait", input: {} },
|
|
})
|
|
.pipe(Effect.forkScoped)
|
|
const signal = yield* Deferred.await(started)
|
|
expect(signal.aborted).toBe(false)
|
|
yield* Fiber.interrupt(fiber)
|
|
const exit = yield* Fiber.await(fiber)
|
|
expect(signal.aborted).toBe(true)
|
|
expect(Exit.isFailure(exit) && Cause.hasInterruptsOnly(exit.cause)).toBe(true)
|
|
}),
|
|
)
|