| 80 | } |
| 81 | |
| 82 | export async function commitTerminalRunWithRuntimeFact( |
| 83 | input: CommitTerminalRunWithRuntimeFactInput, |
| 84 | ): Promise<void> { |
| 85 | if (isPartialRuntimeEvent(input.terminalEvent)) { |
| 86 | throw new Error('terminal RuntimeEvent must be final before terminal run header'); |
| 87 | } |
| 88 | const terminalStatus = terminalRunStatusFromRuntimeEvent(input.terminalEvent); |
| 89 | if (!terminalStatus) { |
| 90 | throw new Error('terminal RuntimeEvent must carry a terminal status'); |
| 91 | } |
| 92 | if (terminalStatus !== input.status) { |
| 93 | throw new Error( |
| 94 | `terminal RuntimeEvent status ${input.terminalEvent.status} cannot commit ${input.status} run header`, |
| 95 | ); |
| 96 | } |
| 97 | if ( |
| 98 | input.terminalEvent.sessionId !== input.sessionId || |
| 99 | input.terminalEvent.runId !== input.runId || |
| 100 | input.terminalEvent.turnId !== input.turnId |
| 101 | ) { |
| 102 | throw new Error('terminal RuntimeEvent identity does not match run header commit'); |
| 103 | } |
| 104 | await input.runtimeEventStore.ensureTerminalRuntimeEventDurable( |
| 105 | input.sessionId, |
| 106 | input.runId, |
| 107 | input.terminalEvent, |
| 108 | ); |
| 109 | |
| 110 | await commitTerminalRunProjection(input); |
| 111 | } |
| 112 | |
| 113 | async function commitTerminalRunProjection( |
| 114 | input: CommitTerminalRunWithRuntimeFactInput, |