1import { NodeId, RunId } from "@t3tools/contracts";
2import { describe, expect, it } from "vite-plus/test";
3
4import {
5 createOrchestrationV2TurnItemVisibility,
6 isOrchestrationV2TurnItemVisible,
7} from "./orchestrationV2Timeline.ts";
8
9const runId = RunId.make("run:timeline-visibility");
10const nodeId = NodeId.make("node:timeline-visibility");
11
12describe.each([
13 ["point", isOrchestrationV2TurnItemVisible],
14 [
15 "indexed",
16 (input: Parameters<typeof isOrchestrationV2TurnItemVisible>[0]) =>
17 createOrchestrationV2TurnItemVisibility(input)(input.item),
18 ],
19] as const)("%s timeline visibility", (_, isVisible) => {
20 it("hides unpaired interruption results from superseded attempts", () => {
21 expect(
22 isVisible({
23 item: { type: "run_interrupt_result", runId, nodeId },
24 runs: [{ id: runId, status: "running" }],
25 attempts: [{ runId, rootNodeId: nodeId, status: "superseded" }],
26 items: [{ type: "run_interrupt_result", runId, nodeId }],
27 }),
28 ).toBe(false);
29 });
30
31 it("keeps paired interruption results from superseded attempts", () => {
32 expect(
33 isVisible({
34 item: { type: "run_interrupt_result", runId, nodeId },
35 runs: [{ id: runId, status: "running" }],
36 attempts: [{ runId, rootNodeId: nodeId, status: "superseded" }],
37 items: [
38 { type: "run_interrupt_request", runId, nodeId },
39 { type: "run_interrupt_result", runId, nodeId },
40 ],
41 }),
42 ).toBe(true);
43 });
44
45 it("keeps interruption results from terminal attempts without a request", () => {
46 expect(
47 isVisible({
48 item: { type: "run_interrupt_result", runId, nodeId },
49 runs: [{ id: runId, status: "interrupted" }],
50 attempts: [{ runId, rootNodeId: nodeId, status: "interrupted" }],
51 items: [{ type: "run_interrupt_result", runId, nodeId }],
52 }),
53 ).toBe(true);
54 });
55
56 it("keeps interruption results from terminal attempts with a request", () => {
57 expect(
58 isVisible({
59 item: { type: "run_interrupt_result", runId, nodeId },
60 runs: [{ id: runId, status: "interrupted" }],
61 attempts: [{ runId, rootNodeId: nodeId, status: "interrupted" }],
62 items: [
63 { type: "run_interrupt_request", runId, nodeId },
64 { type: "run_interrupt_result", runId, nodeId },
65 ],
66 }),
67 ).toBe(true);
68 });
69
70 it("hides queued user messages once their run is cancelled", () => {
71 expect(
72 isVisible({
73 item: { type: "user_message", inputIntent: "queued_turn", runId, nodeId },
74 runs: [{ id: runId, status: "cancelled" }],
75 attempts: [],
76 items: [{ type: "user_message", inputIntent: "queued_turn", runId, nodeId }],
77 }),
78 ).toBe(false);
79 });
80
81 it("keeps queued user messages while their run is queued", () => {
82 expect(
83 isVisible({
84 item: { type: "user_message", inputIntent: "queued_turn", runId, nodeId },
85 runs: [{ id: runId, status: "queued" }],
86 attempts: [],
87 items: [{ type: "user_message", inputIntent: "queued_turn", runId, nodeId }],
88 }),
89 ).toBe(true);
90 });
91
92 it("keeps non-queued user messages on cancelled runs", () => {
93 expect(
94 isVisible({
95 item: { type: "user_message", inputIntent: "turn_start", runId, nodeId },
96 runs: [{ id: runId, status: "cancelled" }],
97 attempts: [],
98 items: [{ type: "user_message", inputIntent: "turn_start", runId, nodeId }],
99 }),
100 ).toBe(true);
101 });
102
103 it("does not hide an interruption because another attempt was superseded", () => {
104 expect(
105 isVisible({
106 item: { type: "run_interrupt_result", runId, nodeId },
107 runs: [{ id: runId, status: "interrupted" }],
108 attempts: [
109 {
110 runId,
111 rootNodeId: NodeId.make("node:timeline-visibility:older"),
112 status: "superseded",
113 },
114 { runId, rootNodeId: nodeId, status: "interrupted" },
115 ],
116 items: [{ type: "run_interrupt_result", runId, nodeId }],
117 }),
118 ).toBe(true);
119 });
120});