diff --git a/extensions/llm-task/src/llm-task-tool.test.ts b/extensions/llm-task/src/llm-task-tool.test.ts index 8b18c1f581cd..8df3fb0477e8 100644 --- a/extensions/llm-task/src/llm-task-tool.test.ts +++ b/extensions/llm-task/src/llm-task-tool.test.ts @@ -382,6 +382,20 @@ describe("llm-task tool (json-only)", () => { expect(call.messages).toEqual([{ role: "user", content: expect.stringContaining("TASK:\nx") }]); }); + it("forwards caller cancellation to the isolated completion", async () => { + const controller = new AbortController(); + const cancellation = new Error("caller cancelled"); + complete.mockImplementationOnce(async (params) => { + controller.abort(cancellation); + params.signal?.throwIfAborted(); + return completionResult(params, '{"ok":true}'); + }); + + const tool = createLlmTaskTool(fakeApi()); + await expect(tool.execute("id", { prompt: "x" }, controller.signal)).rejects.toBe(cancellation); + expect(firstIsolatedCompletionCall().signal).toBe(controller.signal); + }); + it("rejects malformed numeric run options before dispatch", async () => { const tool = createLlmTaskTool(fakeApi()); diff --git a/extensions/llm-task/src/llm-task-tool.ts b/extensions/llm-task/src/llm-task-tool.ts index 6b1f487ead1e..4cfb47b4689b 100644 --- a/extensions/llm-task/src/llm-task-tool.ts +++ b/extensions/llm-task/src/llm-task-tool.ts @@ -132,7 +132,7 @@ export function createLlmTaskTool(api: OpenClawPluginApi) { return { ...llmTaskToolDefinition, - async execute(_id: string, params: LlmTaskParams) { + async execute(_id: string, params: LlmTaskParams, signal?: AbortSignal) { const prompt = typeof params.prompt === "string" ? params.prompt : ""; if (!prompt.trim()) { throw new Error("prompt required"); @@ -235,6 +235,7 @@ export function createLlmTaskTool(api: OpenClawPluginApi) { reasoning: thinkLevel, maxTokens: streamParams.maxTokens, temperature: streamParams.temperature, + signal, purpose: "llm-task", execution: { mode: "isolated-agent-runtime",