#2: approval pauses narrate from ApprovalRequestedEvent (carries tool/tier/preview/stage directly) instead of OrchestrationPaused + a pending-approvals map the next event had not yet populated — the narrator always lost that race and produced generic text. #3: NarrationTrigger now carries the triggering event's stageId; the narration status line and RouterNarrationEvent.stageId use it instead of the router projection's currentStageId, which terminal events have already cleared ('Stage: none'). #9: ExecutionPlanLocked -> plan.locked and ArtifactValidated -> artifact.validated mapped to the TUI (Go: feed lines, plan shows the compiled stage chain); ArtifactValidating explicitly dropped. #10: blank router turn guard — a length-finish with empty text now emits an explanatory turn naming the max_tokens budget instead of a silent blank; blank steering responses no longer emit steering notes. #12: resumeAbandoned only auto-resumes sessions whose last event is within orchestration.resume_abandoned_max_age_minutes (default 24h, 0 disables); staler sessions stay parked for POST /resume. Knob is TUI-editable and persisted.
This commit is contained in:
@@ -227,6 +227,15 @@ func (m *Model) applyServer(msg protocol.ServerMessage) {
|
||||
if s := m.session(msg.SessionID); s != nil {
|
||||
s.addEvent(nowMillis(), "ArtifactCreated", msg.ArtifactID)
|
||||
}
|
||||
case protocol.TypeArtifactValid:
|
||||
if s := m.session(msg.SessionID); s != nil {
|
||||
s.addEvent(nowMillis(), "ArtifactValidated", msg.ArtifactID)
|
||||
}
|
||||
case protocol.TypePlanLocked:
|
||||
if s := m.session(msg.SessionID); s != nil {
|
||||
s.addEvent(nowMillis(), "PlanLocked", strings.Join(msg.StageIDs, " → "))
|
||||
s.LastOutput = "plan locked: " + strings.Join(msg.StageIDs, " → ")
|
||||
}
|
||||
case protocol.TypeWorkspaceBound:
|
||||
if s := m.session(msg.SessionID); s != nil {
|
||||
s.WorkspaceRoot = msg.WorkspaceRoot
|
||||
|
||||
Reference in New Issue
Block a user