1import {
2 EventId,
3 MessageId,
4 NodeId,
5 ProjectId,
6 ProviderInstanceId,
7 RunId,
8 ThreadId,
9 TurnItemId,
10 type ProviderDriverKind,
11 type OrchestrationV2DomainEvent,
12} from "@t3tools/contracts";
13import * as DateTime from "effect/DateTime";
14import {
15 diagnosticOutput,
16 TRANSFER_HISTORY_TOOLS_PER_TURN,
17 TRANSFER_MEASURED_TOOLS,
18 TRANSFER_HISTORY_MCP_RESULT_BYTES,
19 TRANSFER_MEASURED_MCP_RESULT_BYTES,
20} from "./fixtures/transferBudget.ts";
21
22export const THREAD_ID = ThreadId.make("transfer-budget-thread");
23export function threadCreated(provider: ProviderDriverKind): OrchestrationV2DomainEvent {
24 const now = DateTime.makeUnsafe("2026-06-01T00:00:00Z");
25 return {
26 id: EventId.make("thread-created"),
27 type: "thread.created",
28 threadId: THREAD_ID,
29 occurredAt: now,
30 payload: {
31 id: THREAD_ID,
32 projectId: ProjectId.make("transfer-project"),
33 title: "Transfer budget",
34 providerInstanceId: ProviderInstanceId.make(provider),
35 modelSelection: {
36 instanceId: ProviderInstanceId.make(provider),
37 model: provider === "codex" ? "gpt-5.4" : "claude-sonnet-4-6",
38 },
39 runtimeMode: "full-access",
40 interactionMode: "default",
41 branch: null,
42 worktreePath: null,
43 activeProviderThreadId: null,
44 lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: THREAD_ID },
45 forkedFrom: null,
46 createdBy: "user",
47 creationSource: "web",
48 createdAt: now,
49 updatedAt: now,
50 archivedAt: null,
51 settledOverride: null,
52 settledAt: null,
53 lastVisitedAt: null,
54 deletedAt: null,
55 },
56 };
57}
58export function turnEvents(
59 provider: ProviderDriverKind,
60 index: number,
61 measured: boolean,
62): ReadonlyArray<OrchestrationV2DomainEvent> {
63 const now = DateTime.makeUnsafe(`2026-06-01T00:${String(index + 1).padStart(2, "0")}:00Z`);
64 const runId = RunId.make(`run-${index}`);
65 const nodeId = NodeId.make(`node-${index}`);
66 const userMessageId = MessageId.make(`user-${index}`);
67 const providerInstanceId = ProviderInstanceId.make(provider);
68 const run = {
69 id: runId,
70 threadId: THREAD_ID,
71 ordinal: index + 1,
72 providerInstanceId,
73 modelSelection: {
74 instanceId: ProviderInstanceId.make(provider),
75 model: provider === "codex" ? "gpt-5.4" : "claude-sonnet-4-6",
76 },
77 providerThreadId: null,
78 userMessageId,
79 rootNodeId: nodeId,
80 activeAttemptId: null,
81 status: "running" as const,
82 requestedAt: now,
83 startedAt: now,
84 completedAt: null,
85 checkpointId: null,
86 contextHandoffId: null,
87 };
88 const common = {
89 threadId: THREAD_ID,
90 runId,
91 nodeId,
92 driver: provider,
93 providerInstanceId,
94 occurredAt: now,
95 };
96 const events: OrchestrationV2DomainEvent[] = [
97 { ...common, id: EventId.make(`run-${index}`), type: "run.created", payload: run },
98 ];
99 for (const role of ["user", "assistant"] as const) {
100 events.push({
101 ...common,
102 id: EventId.make(`${role}-${index}`),
103 type: "message.updated",
104 payload: {
105 id: MessageId.make(`${role}-${index}`),
106 threadId: THREAD_ID,
107 runId,
108 nodeId,
109 role,
110 text:
111 role === "user"
112 ? `Inspect transfer ${index}`
113 : `Completed ${provider} inspection ${index}. ` +
114 "The projection preserves transcript text and bounds tool output. ".repeat(60),
115 attachments: [],
116 streaming: false,
117 createdAt: now,
118 updatedAt: now,
119 createdBy: role === "user" ? "user" : "agent",
120 creationSource: "web",
121 },
122 });
123 }
124 const toolCount = measured ? TRANSFER_MEASURED_TOOLS : TRANSFER_HISTORY_TOOLS_PER_TURN;
125 for (let tool = 0; tool <= toolCount; tool++) {
126 const mcp = tool === toolCount;
127 const output = diagnosticOutput({
128 provider,
129 turnIndex: index,
130 toolIndex: tool,
131 targetBytes: mcp
132 ? measured
133 ? TRANSFER_MEASURED_MCP_RESULT_BYTES
134 : TRANSFER_HISTORY_MCP_RESULT_BYTES
135 : 4096,
136 });
137 const base = {
138 id: TurnItemId.make(`item-${index}-${tool}`),
139 threadId: THREAD_ID,
140 runId,
141 nodeId,
142 providerThreadId: null,
143 providerTurnId: null,
144 nativeItemRef: null,
145 parentItemId: null,
146 ordinal: tool + 1,
147 status: "completed" as const,
148 title: mcp ? "MCP search" : `Inspect source ${tool}`,
149 startedAt: now,
150 completedAt: now,
151 updatedAt: now,
152 };
153 events.push({
154 ...common,
155 id: EventId.make(`tool-${index}-${tool}`),
156 type: "turn-item.updated",
157 payload: mcp
158 ? {
159 ...base,
160 type: "dynamic_tool",
161 toolName: "mcp__test__search",
162 input: { query: "transfer" },
163 output: { text: output },
164 }
165 : {
166 ...base,
167 type: "command_execution",
168 input: `cat src/module-${tool}.ts`,
169 output,
170 exitCode: 0,
171 },
172 });
173 }
174 events.push({
175 ...common,
176 id: EventId.make(`complete-${index}`),
177 type: "run.updated",
178 payload: { ...run, status: "completed", completedAt: now },
179 });
180 return events;
181}