Open History to see the last commit
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");
11const otherRunId = RunId.make("run:timeline-visibility:other");
12const otherNodeId = NodeId.make("node:timeline-visibility:other");
13type VisibilityInput = Parameters<typeof createOrchestrationV2TurnItemVisibility>[0];
14
15const ordinaryStatuses = [
16 "preparing",
17 "queued",
18 "starting",
19 "running",
20 "waiting",
21 "completed",
22 "interrupted",
23 "failed",
24] as const;
25
26describe.each([
27 ["point", isOrchestrationV2TurnItemVisible],
28 [
29 "indexed",
30 (input: Parameters<typeof isOrchestrationV2TurnItemVisible>[0]) =>
31 createOrchestrationV2TurnItemVisibility(input)(input.item),
32 ],
33] as const)("%s timeline visibility", (_, isVisible) => {
34 it("hides unpaired interruption results from superseded attempts", () => {
35 expect(
36 isVisible({
37 item: { type: "run_interrupt_result", runId, nodeId },
38 runs: [{ id: runId, status: "running" }],
39 attempts: [{ runId, rootNodeId: nodeId, status: "superseded" }],
40 items: [{ type: "run_interrupt_result", runId, nodeId }],
41 }),
42 ).toBe(false);
43 });
44
45 it.each([
46 { status: "running", visible: true },
47 { status: "cancelled", visible: true },
48 { status: "rolled_back", visible: false },
49 ] as const)(
50 "keeps paired superseded results unless the run is rolled back ($status)",
51 ({ status, visible }) => {
52 expect(
53 isVisible({
54 item: { type: "run_interrupt_result", runId, nodeId },
55 runs: [{ id: runId, status }],
56 attempts: [{ runId, rootNodeId: nodeId, status: "superseded" }],
57 items: [
58 { type: "run_interrupt_request", runId, nodeId },
59 { type: "run_interrupt_result", runId, nodeId },
60 ],
61 }),
62 ).toBe(visible);
63 },
64 );
65
66 it("keeps interruption results from terminal attempts without a request", () => {
67 expect(
68 isVisible({
69 item: { type: "run_interrupt_result", runId, nodeId },
70 runs: [{ id: runId, status: "interrupted" }],
71 attempts: [{ runId, rootNodeId: nodeId, status: "interrupted" }],
72 items: [{ type: "run_interrupt_result", runId, nodeId }],
73 }),
74 ).toBe(true);
75 });
76
77 it("does not hide an interruption because another attempt was superseded", () => {
78 expect(
79 isVisible({
80 item: { type: "run_interrupt_result", runId, nodeId },
81 runs: [{ id: runId, status: "interrupted" }],
82 attempts: [
83 {
84 runId,
85 rootNodeId: NodeId.make("node:timeline-visibility:older"),
86 status: "superseded",
87 },
88 { runId, rootNodeId: nodeId, status: "interrupted" },
89 ],
90 items: [{ type: "run_interrupt_result", runId, nodeId }],
91 }),
92 ).toBe(true);
93 });
94
95 it.each([
96 ...ordinaryStatuses.map((status) => ({ status, hidden: [] })),
97 { status: "cancelled", hidden: ["queued"] },
98 {
99 status: "rolled_back",
100 hidden: ["queued", "start", "steer", "promoted", "legacy", "assistant", "request", "result"],
101 },
102 ] satisfies ReadonlyArray<{
103 status: VisibilityInput["runs"][number]["status"];
104 hidden: string[];
105 }>)("keeps the correct transcript rows for $status runs", ({ status, hidden }) => {
106 const rows = [
107 { id: "queued", type: "user_message", inputIntent: "queued_turn", runId, nodeId },
108 { id: "start", type: "user_message", inputIntent: "turn_start", runId, nodeId },
109 { id: "steer", type: "user_message", inputIntent: "steer", runId, nodeId },
110 {
111 id: "promoted",
112 type: "user_message",
113 inputIntent: "promoted_queued_to_steer",
114 runId,
115 nodeId,
116 },
117 { id: "legacy", type: "user_message", runId, nodeId },
118 { id: "assistant", type: "assistant_message", inputIntent: "queued_turn", runId, nodeId },
119 { id: "request", type: "run_interrupt_request", runId, nodeId },
120 { id: "result", type: "run_interrupt_result", runId, nodeId },
121 { id: "null", type: "user_message", inputIntent: "queued_turn", runId: null, nodeId },
122 {
123 id: "missing",
124 type: "user_message",
125 inputIntent: "queued_turn",
126 runId: otherRunId,
127 nodeId,
128 },
129 ] satisfies ReadonlyArray<VisibilityInput["items"][number] & { id: string }>;
130 const input = {
131 runs: [{ id: runId, status }],
132 attempts: [],
133 items: rows,
134 } satisfies VisibilityInput;
135 expect(rows.filter((item) => isVisible({ ...input, item })).map((item) => item.id)).toEqual(
136 [
137 "queued",
138 "start",
139 "steer",
140 "promoted",
141 "legacy",
142 "assistant",
143 "request",
144 "result",
145 "null",
146 "missing",
147 ].filter((id) => !hidden.some((hiddenId) => hiddenId === id)),
148 );
149 });
150
151 it.each([
152 { name: "empty history", runs: [], attempts: [] },
153 {
154 name: "ordinary attempts",
155 runs: [{ id: runId, status: "completed" }],
156 attempts: [{ runId, rootNodeId: nodeId, status: "completed" }],
157 },
158 ] satisfies ReadonlyArray<Pick<VisibilityInput, "runs" | "attempts"> & { name: string }>)(
159 "keeps all rows with $name",
160 ({ runs, attempts }) => {
161 const items = [
162 { type: "user_message", inputIntent: "queued_turn", runId, nodeId },
163 { type: "run_interrupt_result", runId, nodeId },
164 { type: "assistant_message", runId: null, nodeId: null },
165 ] satisfies VisibilityInput["items"];
166 expect(items.filter((item) => isVisible({ item, runs, attempts, items }))).toEqual(items);
167 },
168 );
169
170 it.each([
171 { name: "unpaired", runId, nodeId, requests: [], visible: false },
172 { name: "second root", runId, nodeId: otherNodeId, requests: [], visible: false },
173 { name: "other run", runId: otherRunId, nodeId, requests: [], visible: true },
174 {
175 name: "unknown root",
176 runId,
177 nodeId: NodeId.make("node:unknown"),
178 requests: [],
179 visible: true,
180 },
181 { name: "null run", runId: null, nodeId, requests: [], visible: true },
182 { name: "null node", runId, nodeId: null, requests: [], visible: true },
183 { name: "other request", runId, nodeId, requests: [otherRunId], visible: false },
184 { name: "null request", runId, nodeId, requests: [null], visible: false },
185 { name: "paired request", runId, nodeId, requests: [runId], visible: true },
186 ] satisfies ReadonlyArray<{
187 name: string;
188 runId: VisibilityInput["items"][number]["runId"];
189 nodeId: VisibilityInput["items"][number]["nodeId"];
190 requests: VisibilityInput["items"][number]["runId"][];
191 visible: boolean;
192 }>)("matches superseded roots and requests for $name results", (row) => {
193 const item = { type: "run_interrupt_result", runId: row.runId, nodeId: row.nodeId } as const;
194 const requests = row.requests.map((requestRunId) => ({
195 type: "run_interrupt_request" as const,
196 runId: requestRunId,
197 nodeId: otherNodeId,
198 }));
199 for (const items of [
200 [...requests, item],
201 [item, ...requests],
202 ]) {
203 expect(
204 isVisible({
205 item,
206 runs: [],
207 attempts: [
208 { runId, rootNodeId: nodeId, status: "superseded" },
209 { runId, rootNodeId: otherNodeId, status: "superseded" },
210 ],
211 items,
212 }),
213 ).toBe(row.visible);
214 }
215 });
216});
217
218describe("indexed timeline visibility", () => {
219 it.each([
220 ...ordinaryStatuses.flatMap(
221 (status) =>
222 [
223 { statuses: ["rolled_back", status], visible: true, ordinaryVisible: true },
224 { statuses: ["cancelled", status], visible: true, ordinaryVisible: true },
225 { statuses: [status, "rolled_back"], visible: false, ordinaryVisible: false },
226 { statuses: [status, "cancelled"], visible: false, ordinaryVisible: true },
227 ] as const,
228 ),
229 { statuses: ["rolled_back", "cancelled"], visible: false, ordinaryVisible: true },
230 { statuses: ["cancelled", "rolled_back"], visible: false, ordinaryVisible: false },
231 {
232 statuses: ["rolled_back", "running", "cancelled", "completed"],
233 visible: true,
234 ordinaryVisible: true,
235 },
236 ] satisfies ReadonlyArray<{
237 statuses: ReadonlyArray<VisibilityInput["runs"][number]["status"]>;
238 visible: boolean;
239 ordinaryVisible: boolean;
240 }>)(
241 "uses the last duplicate run status in $statuses",
242 ({ statuses, visible, ordinaryVisible }) => {
243 const queued = { type: "user_message", inputIntent: "queued_turn", runId, nodeId } as const;
244 const ordinary = { type: "assistant_message", runId, nodeId } as const;
245 const isVisible = createOrchestrationV2TurnItemVisibility({
246 runs: statuses.map((status) => ({ id: runId, status })),
247 attempts: [],
248 items: [queued, ordinary],
249 });
250 expect(isVisible(queued)).toBe(visible);
251 expect(isVisible(ordinary)).toBe(ordinaryVisible);
252 },
253 );
254
255 it("preserves frozen rows and reads fresh status and attempt snapshots", () => {
256 const item = Object.freeze({ type: "run_interrupt_result", runId, nodeId } as const);
257 const queued = Object.freeze({
258 type: "user_message",
259 inputIntent: "queued_turn",
260 runId,
261 nodeId,
262 } as const);
263 const items = Object.freeze([item, queued]);
264 const attempts = Object.freeze([
265 Object.freeze({ runId, rootNodeId: nodeId, status: "superseded" } as const),
266 ]);
267 const runs = Object.freeze([Object.freeze({ id: runId, status: "running" } as const)]);
268 const input = Object.freeze({ runs, attempts, items });
269 const before = structuredClone(input);
270 const visible = items.filter(createOrchestrationV2TurnItemVisibility(input));
271 expect(visible).toEqual([queued]);
272 expect(visible[0]).toBe(queued);
273 expect(input).toEqual(before);
274 expect(
275 items.filter(createOrchestrationV2TurnItemVisibility({ ...input, attempts: [] })),
276 ).toEqual(items);
277 expect(
278 items.filter(
279 createOrchestrationV2TurnItemVisibility({
280 ...input,
281 runs: [{ id: runId, status: "cancelled" }],
282 }),
283 ),
284 ).toEqual([]);
285 expect(
286 items.filter(
287 createOrchestrationV2TurnItemVisibility({
288 ...input,
289 items: [...items, { type: "run_interrupt_request", runId, nodeId: null }],
290 }),
291 ),
292 ).toEqual(items);
293 });
294});