| 1 | import { initialState, reducer } from "../lib/useController"; |
| 2 | |
| 3 | function equal(actual: unknown, expected: unknown, message: string) { |
| 4 | if (actual !== expected) throw new Error(`${message}: got ${String(actual)}, want ${String(expected)}`); |
| 5 | } |
| 6 | |
| 7 | let state = reducer(initialState, { type: "event", e: { kind: "turn_status", turnId: "turn-1", status: "queued" } }); |
| 8 | equal(state.activeTurnId, "turn-1", "queued lifecycle admits the exact turn id"); |
| 9 | state = reducer(state, { type: "event", e: { kind: "turn_started", turnId: "turn-1", status: "in_progress" } }); |
| 10 | equal(state.currentAssistant, "a:turn-1:0", "first assistant sampling segment has a stable turn-local identity"); |
| 11 | state = reducer(state, { type: "event", e: { kind: "ask_request", turnId: "turn-1", itemId: "ask-1", ask: { id: "ask-1", questions: [] } } }); |
| 12 | const stale = reducer(state, { type: "event", e: { kind: "prompt_answered", turnId: "turn-old", itemId: "ask-1", status: "in_progress" } }); |
| 13 | equal(stale.ask?.id, "ask-1", "a stale turn cannot answer the prompt"); |
| 14 | state = reducer(state, { type: "event", e: { kind: "prompt_answered", turnId: "turn-1", itemId: "ask-1", status: "in_progress" } }); |
| 15 | equal(state.ask, undefined, "the exact prompt answer resumes its turn"); |
| 16 | state = reducer(state, { type: "event", e: { kind: "text", turnId: "turn-1", text: "partial" } }); |
| 17 | state = reducer(state, { type: "event", e: { kind: "turn_done", turnId: "turn-1", status: "interrupted" } }); |
| 18 | equal(state.activeTurnId, undefined, "the terminal event releases the lane"); |
| 19 | if (!state.items.some((item) => item.kind === "notice" && item.text.includes("interrupted"))) { |
| 20 | throw new Error("interruption must preserve partial output with an explicit notice"); |
| 21 | } |
| 22 | |
| 23 | let empty = reducer(initialState, { type: "event", e: { kind: "turn_started", turnId: "turn-empty", status: "in_progress" } }); |
| 24 | empty = reducer(empty, { type: "event", e: { kind: "turn_done", turnId: "turn-empty", status: "interrupted" } }); |
| 25 | equal(empty.items.some((item) => item.kind === "assistant"), false, "cancelling an empty turn removes its placeholder segment"); |
| 26 | |
| 27 | console.log("turn lifecycle reducer tests passed"); |
| 28 |