| 1 | import { |
| 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"; |
| 13 | import * as DateTime from "effect/DateTime"; |
| 14 | import { |
| 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 | |
| 22 | export const THREAD_ID = ThreadId.make("transfer-budget-thread"); |
| 23 | export 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 | } |
| 58 | export 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 | } |