fix: close three seams the message-machine refactor left open
agent-loop lifecycle: dispose drains machine.done to true quiescence. cancel()'s own running-to-idle transition can legitimately re-enter through an automation listener (goal-session's idle drive runs synchronously to its first await) and replace done with a fresh admission after the single capture; teardown now re-cancels and re-awaits until the slot stabilizes, so the scope never unwinds under a live run. tools: a nested concludeTurn() stages on its own execution and promotes to the enclosing composite only on the call's authoritative successful verdict. A post-execute policy that converts the nested success into an error no longer lets a recovering composite stop the turn on a failed terminal operation (the Code Mode structured-output shape). goal-session: the driver owns its round durability barrier again. The loop's persistence is eager write-behind with no turn-end flush, so the old post-turn agent/error signal for flush failures never fires; a settled round now sets needsCheckpoint and re-enters drive, flushing before the next reservation and disarming on failure instead of queueing an autonomous round on state that was never persisted.
This commit is contained in:
@@ -192,6 +192,14 @@ export function apply(ctx: Context): void {
|
||||
if (!attempt.stale) applyOutcome(state, goal, outcome)
|
||||
}
|
||||
if (!readyToDrive(state)) return
|
||||
// The loop's persistence is eager write-behind with no turn-end flush,
|
||||
// so this driver owns the round's durability barrier: checkpoint the
|
||||
// settled round before reserving another (re-entering drive through
|
||||
// the flush path above), disarming on failure instead of queueing an
|
||||
// autonomous round on state that was never persisted.
|
||||
state.needsCheckpoint = true
|
||||
state.requested = true
|
||||
return
|
||||
}
|
||||
|
||||
const goal = currentGoal(state)
|
||||
|
||||
Reference in New Issue
Block a user