// What the terminal page decides about cancelling a turn. Run by `npm test`. import assert from "node:assert/strict"; import { test } from "node:test"; import { canCancel, cancelNote, cancelPath, statusOnTurnChange, } from "../src/agent/terminal/cancel.ts"; test("cancel is offered while the agent is in a turn, and only then", () => { assert.equal(canCancel("thinking"), true); assert.equal(canCancel("idle"), false); assert.equal(canCancel("compacting"), false); assert.equal(canCancel(undefined), false); }); test("the cancel path names the agent, escaped", () => { assert.equal(cancelPath("iris"), "/api/agents/iris/cancel"); assert.equal(cancelPath("a/b"), "/api/agents/a%2Fb/cancel"); }); test("the note says whether a turn was stopped", () => { assert.equal(cancelNote(true), "turn cancelled"); assert.equal(cancelNote(false), "nothing was running"); }); test("the answer stays after its turn ends and clears when the next starts", () => { assert.equal(statusOnTurnChange("done", "thinking", "idle"), "done"); assert.equal(statusOnTurnChange("done", "idle", "idle"), "done"); assert.equal(statusOnTurnChange("done", "idle", "thinking"), "idle"); }); test("a failure clears when its turn ends, or a new one starts", () => { assert.equal(statusOnTurnChange("error", "thinking", "thinking"), "error"); assert.equal(statusOnTurnChange("error", "thinking", "idle"), "idle"); assert.equal(statusOnTurnChange("error", "idle", "thinking"), "idle"); }); test("a cancel in flight is left alone", () => { assert.equal( statusOnTurnChange("cancelling", "thinking", "idle"), "cancelling", ); assert.equal( statusOnTurnChange("cancelling", "idle", "thinking"), "cancelling", ); });