Skip to content
Source
Sign inSign up

orchestrationV2Timeline.test.ts

298 lines10.5 KB

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 "starting",
18 "running",
19 "waiting",
20 "completed",
21 "interrupted",
22 "failed",
23] as const;
24​
25describe.each([
26 ["point", isOrchestrationV2TurnItemVisible],
27 [
28 "indexed",
29 (input: Parameters<typeof isOrchestrationV2TurnItemVisible>[0]) =>
30 createOrchestrationV2TurnItemVisibility(input)(input.item),
31 ],
32] as const)("%s timeline visibility", (_, isVisible) => {
33 it("hides unpaired interruption results from superseded attempts", () => {
34 expect(
35 isVisible({
36 item: { type: "run_interrupt_result", runId, nodeId },
37 runs: [{ id: runId, status: "running" }],
38 attempts: [{ runId, rootNodeId: nodeId, status: "superseded" }],
39 items: [{ type: "run_interrupt_result", runId, nodeId }],
40 }),
41 ).toBe(false);
42 });
43​
44 it.each([
45 { status: "running", visible: true },
46 { status: "cancelled", visible: true },
47 { status: "rolled_back", visible: false },
48 ] as const)(
49 "keeps paired superseded results unless the run is rolled back ($status)",
50 ({ status, visible }) => {
51 expect(
52 isVisible({
53 item: { type: "run_interrupt_result", runId, nodeId },
54 runs: [{ id: runId, status }],
55 attempts: [{ runId, rootNodeId: nodeId, status: "superseded" }],
56 items: [
57 { type: "run_interrupt_request", runId, nodeId },
58 { type: "run_interrupt_result", runId, nodeId },
59 ],
60 }),
61 ).toBe(visible);
62 },
63 );
64​
65 it("keeps interruption results from terminal attempts without a request", () => {
66 expect(
67 isVisible({
68 item: { type: "run_interrupt_result", runId, nodeId },
69 runs: [{ id: runId, status: "interrupted" }],
70 attempts: [{ runId, rootNodeId: nodeId, status: "interrupted" }],
71 items: [{ type: "run_interrupt_result", runId, nodeId }],
72 }),
73 ).toBe(true);
74 });
75​
76 it("does not hide an interruption because another attempt was superseded", () => {
77 expect(
78 isVisible({
79 item: { type: "run_interrupt_result", runId, nodeId },
80 runs: [{ id: runId, status: "interrupted" }],
81 attempts: [
82 {
83 runId,
84 rootNodeId: NodeId.make("node:timeline-visibility:older"),
85 status: "superseded",
86 },
87 { runId, rootNodeId: nodeId, status: "interrupted" },
88 ],
89 items: [{ type: "run_interrupt_result", runId, nodeId }],
90 }),
91 ).toBe(true);
92 });
93​
94 it.each([
95 ...ordinaryStatuses.map((status) => ({ status, hidden: [] })),
96 { status: "queued", hidden: ["queued"] },
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, "queued" as const].flatMap(
221 (status) =>
222 [
223 {
224 statuses: ["rolled_back", status],
225 visible: status !== "queued",
226 ordinaryVisible: true,
227 },
228 { statuses: ["cancelled", status], visible: status !== "queued", ordinaryVisible: true },
229 { statuses: [status, "rolled_back"], visible: false, ordinaryVisible: false },
230 { statuses: [status, "cancelled"], visible: false, ordinaryVisible: true },
231 ] as const,
232 ),
233 { statuses: ["rolled_back", "cancelled"], visible: false, ordinaryVisible: true },
234 { statuses: ["cancelled", "rolled_back"], visible: false, ordinaryVisible: false },
235 {
236 statuses: ["rolled_back", "running", "cancelled", "completed"],
237 visible: true,
238 ordinaryVisible: true,
239 },
240 ] satisfies ReadonlyArray<{
241 statuses: ReadonlyArray<VisibilityInput["runs"][number]["status"]>;
242 visible: boolean;
243 ordinaryVisible: boolean;
244 }>)(
245 "uses the last duplicate run status in $statuses",
246 ({ statuses, visible, ordinaryVisible }) => {
247 const queued = { type: "user_message", inputIntent: "queued_turn", runId, nodeId } as const;
248 const ordinary = { type: "assistant_message", runId, nodeId } as const;
249 const isVisible = createOrchestrationV2TurnItemVisibility({
250 runs: statuses.map((status) => ({ id: runId, status })),
251 attempts: [],
252 items: [queued, ordinary],
253 });
254 expect(isVisible(queued)).toBe(visible);
255 expect(isVisible(ordinary)).toBe(ordinaryVisible);
256 },
257 );
258​
259 it("preserves frozen rows and reads fresh status and attempt snapshots", () => {
260 const item = Object.freeze({ type: "run_interrupt_result", runId, nodeId } as const);
261 const queued = Object.freeze({
262 type: "user_message",
263 inputIntent: "queued_turn",
264 runId,
265 nodeId,
266 } as const);
267 const items = Object.freeze([item, queued]);
268 const attempts = Object.freeze([
269 Object.freeze({ runId, rootNodeId: nodeId, status: "superseded" } as const),
270 ]);
271 const runs = Object.freeze([Object.freeze({ id: runId, status: "running" } as const)]);
272 const input = Object.freeze({ runs, attempts, items });
273 const before = structuredClone(input);
274 const visible = items.filter(createOrchestrationV2TurnItemVisibility(input));
275 expect(visible).toEqual([queued]);
276 expect(visible[0]).toBe(queued);
277 expect(input).toEqual(before);
278 expect(
279 items.filter(createOrchestrationV2TurnItemVisibility({ ...input, attempts: [] })),
280 ).toEqual(items);
281 expect(
282 items.filter(
283 createOrchestrationV2TurnItemVisibility({
284 ...input,
285 runs: [{ id: runId, status: "cancelled" }],
286 }),
287 ),
288 ).toEqual([]);
289 expect(
290 items.filter(
291 createOrchestrationV2TurnItemVisibility({
292 ...input,
293 items: [...items, { type: "run_interrupt_request", runId, nodeId: null }],
294 }),
295 ),
296 ).toEqual(items);
297 });
298});