Skip to content
Source
Sign inSign up

agentActivityWidgetTimeline.test.ts

72 lines2.1 KB

1import { describe, expect, it } from "vite-plus/test";
2​
3import type { EnvironmentId, ThreadId } from "@t3tools/contracts";
4import type { RelayAgentActivityAggregateState } from "@t3tools/contracts/relay";
5​
6import {
7 AGENT_ACTIVITY_WIDGET_STALE_AFTER_MS,
8 agentActivityWidgetTimeline,
9} from "./agentActivityWidgetTimeline";
10​
11const now = Date.parse("2026-10-18T10:00:00.000Z");
12​
13type Row = RelayAgentActivityAggregateState["activities"][number];
14​
15function row(phase: Row["phase"], status: string): Row {
16 return {
17 environmentId: "env-1" as EnvironmentId,
18 threadId: `thread-${phase}` as ThreadId,
19 projectTitle: "t3code",
20 threadTitle: `Thread ${phase}`,
21 modelTitle: "GPT-5.5",
22 phase,
23 status,
24 updatedAt: "2026-10-18T09:59:00.000Z",
25 deepLink: `/threads/env-1/thread-${phase}`,
26 };
28​
29function aggregate(activities: ReadonlyArray<Row>): RelayAgentActivityAggregateState {
30 return {
31 title: "T3 Code",
32 subtitle: "Agent work in progress",
33 activeCount: activities.length,
34 updatedAt: "2026-10-18T09:59:00.000Z",
35 activities,
36 };
38​
39describe("agentActivityWidgetTimeline", () => {
40 it("marks unfinished rows out of date once the widget can no longer vouch for them", () => {
41 const timeline = agentActivityWidgetTimeline(
42 {
43 kind: "snapshot",
44 aggregate: aggregate([row("running", "Working"), row("completed", "Done")]),
45 },
46 now,
47 );
48​
49 expect(timeline.map((entry) => entry.date.getTime())).toEqual([
50 now,
51 now + AGENT_ACTIVITY_WIDGET_STALE_AFTER_MS,
52 ]);
53 expect(timeline[0]?.props.activities.map((entry) => entry.phase)).toEqual([
54 "running",
55 "completed",
56 ]);
57 expect(timeline[1]?.props.activities.map((entry) => [entry.phase, entry.status])).toEqual([
58 ["stale", "Out of date"],
59 ["completed", "Done"],
60 ]);
61 });
62​
63 it("keeps finished outcomes on a single entry", () => {
64 const timeline = agentActivityWidgetTimeline(
65 { kind: "snapshot", aggregate: aggregate([row("failed", "Failed")]) },
66 now,
67 );
68​
69 expect(timeline).toHaveLength(1);
70 expect(timeline[0]?.props.activities[0]?.phase).toBe("failed");
71 });
72});