refactor(agent): simplify inbox-driven turn admission
This commit is contained in:
@@ -87,6 +87,10 @@ function validateEvent(
|
||||
if (trace.openStep !== null) {
|
||||
fail(`turn/end ${event.data.turn} while step ${trace.openStep} is still open`)
|
||||
}
|
||||
const lastStep = trace.nextStep - 1
|
||||
if (event.data.step !== lastStep) {
|
||||
fail(`turn/end ${event.data.turn} expected last step ${lastStep}, got ${event.data.step}`)
|
||||
}
|
||||
openTurn = null
|
||||
nextTurn += 1
|
||||
break
|
||||
|
||||
@@ -46,6 +46,7 @@ export const TOOL_OUTCOME_UNKNOWN = 'TOOL_OUTCOME_UNKNOWN'
|
||||
export function interruptedTurnClosers(events: readonly SessionEvent[]): SessionEvent[] {
|
||||
let openTurn: number | null = null
|
||||
let openStep: number | null = null
|
||||
let lastStep = 0
|
||||
// Reset at each turn boundary so earlier calls cannot leak into tail repair.
|
||||
// Assistant blocks register calls; later tool/call events add provenance seqs.
|
||||
const pendingCalls = new Map<CallId, { step: number; callSeq?: number }>()
|
||||
@@ -54,15 +55,18 @@ export function interruptedTurnClosers(events: readonly SessionEvent[]): Session
|
||||
case 'turn/start':
|
||||
openTurn = event.data.turn
|
||||
openStep = null
|
||||
lastStep = 0
|
||||
pendingCalls.clear()
|
||||
break
|
||||
case 'turn/end':
|
||||
openTurn = null
|
||||
openStep = null
|
||||
lastStep = 0
|
||||
pendingCalls.clear()
|
||||
break
|
||||
case 'step/start':
|
||||
openStep = event.data.step
|
||||
lastStep = event.data.step
|
||||
break
|
||||
case 'step/end':
|
||||
pendingCalls.clear()
|
||||
@@ -147,6 +151,6 @@ export function interruptedTurnClosers(events: readonly SessionEvent[]): Session
|
||||
if (openStep !== null) {
|
||||
closers.push({ type: 'step/end', seq: seq++, time, data: { turn: openTurn, step: openStep } })
|
||||
}
|
||||
closers.push({ type: 'turn/end', seq: seq++, time, data: { turn: openTurn, reason: { kind: 'interrupted' } } })
|
||||
closers.push({ type: 'turn/end', seq: seq++, time, data: { turn: openTurn, step: lastStep, reason: { kind: 'interrupted' } } })
|
||||
return closers
|
||||
}
|
||||
|
||||
@@ -183,12 +183,13 @@ export interface SessionEventMap {
|
||||
*/
|
||||
'turn/start': { turn: number }
|
||||
/**
|
||||
* Closes turn `turn` with the {@link TurnEndReason} that ended it. The loop
|
||||
* awaits `session/flush` after an ordinary turn ends before claiming the next
|
||||
* queued item. Success commits the turn; rejection is reported live and does
|
||||
* not prevent later work.
|
||||
* Closes turn `turn` after `step`, the last entered step (`0` when none),
|
||||
* with the {@link TurnEndReason} that ended it. The loop awaits
|
||||
* `session/flush` after an ordinary turn ends before claiming the next queued
|
||||
* item. Success commits the turn; rejection is reported live and does not
|
||||
* prevent later work.
|
||||
*/
|
||||
'turn/end': { turn: number; reason: TurnEndReason }
|
||||
'turn/end': { turn: number; step: number; reason: TurnEndReason }
|
||||
/** Opens step `step` of turn `turn` — one model call plus the tool executions it requested. */
|
||||
'step/start': { turn: number; step: number }
|
||||
/** Closes step `step` of turn `turn`. */
|
||||
|
||||
Reference in New Issue
Block a user