feat(tui): render workflow progress as dim router-feed narration lines
This commit is contained in:
@@ -47,6 +47,35 @@ func inferCategory(t string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// narrationLine maps a progress frame to a dim router-feed line, or "" if the
|
||||
// frame is not a narration trigger.
|
||||
func narrationLine(msg protocol.ServerMessage) string {
|
||||
switch msg.Type {
|
||||
case protocol.TypeStageStarted:
|
||||
return "→ " + msg.StageID
|
||||
case protocol.TypeStageCompleted:
|
||||
return "✓ " + msg.StageID
|
||||
case protocol.TypeStageFailed:
|
||||
if msg.Reason != "" {
|
||||
return "⚠ " + msg.StageID + ": " + msg.Reason
|
||||
}
|
||||
return "⚠ " + msg.StageID
|
||||
case protocol.TypeSessionPaused:
|
||||
return "⏸ paused"
|
||||
case protocol.TypeSessionResumed:
|
||||
return "▶ resumed"
|
||||
case protocol.TypeSessionCompleted:
|
||||
return "✓ workflow complete"
|
||||
case protocol.TypeSessionFailed:
|
||||
if msg.Reason != "" {
|
||||
return "✗ workflow failed: " + msg.Reason
|
||||
}
|
||||
return "✗ workflow failed"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// applyServer mutates the model for a single (non-buffered) server message.
|
||||
func (m *Model) applyServer(msg protocol.ServerMessage) {
|
||||
debugLog("SRV type=%s session=%s reason=%s", msg.Type, msg.SessionID, msg.Reason)
|
||||
@@ -55,6 +84,11 @@ func (m *Model) applyServer(msg protocol.ServerMessage) {
|
||||
if msg.IsEventBearing() && msg.SessionID != "" {
|
||||
m.ensureSession(msg.SessionID)
|
||||
}
|
||||
// Inject dim narration lines for progress frames. Runs in addition to the
|
||||
// per-type handling below (which feeds the events panel separately).
|
||||
if line := narrationLine(msg); line != "" {
|
||||
m.appendRouter(msg.SessionID, RouterEntry{Role: "narration", Content: line})
|
||||
}
|
||||
switch msg.Type {
|
||||
case protocol.TypeSessionAnnounced:
|
||||
m.onSessionAnnounced(msg)
|
||||
@@ -102,19 +136,16 @@ func (m *Model) applyServer(msg protocol.ServerMessage) {
|
||||
s.Tools = nil
|
||||
s.addEvent(msg.OccurredAt, "StageStarted", msg.StageID)
|
||||
}
|
||||
m.appendRouter(msg.SessionID, RouterEntry{"stage", "⟐ stage " + msg.StageID + " started"})
|
||||
case protocol.TypeStageCompleted:
|
||||
if s := m.session(msg.SessionID); s != nil {
|
||||
s.CurrentStage = ""
|
||||
s.addEvent(msg.OccurredAt, "StageCompleted", msg.StageID)
|
||||
}
|
||||
m.appendRouter(msg.SessionID, RouterEntry{"stage", "⟐ stage " + msg.StageID + " completed"})
|
||||
case protocol.TypeStageFailed:
|
||||
if s := m.session(msg.SessionID); s != nil {
|
||||
s.CurrentStage = ""
|
||||
s.addEvent(msg.OccurredAt, "StageFailed", msg.StageID)
|
||||
}
|
||||
m.appendRouter(msg.SessionID, RouterEntry{"stage", "⟐ stage " + msg.StageID + " failed"})
|
||||
case protocol.TypeInferenceStarted:
|
||||
if s := m.session(msg.SessionID); s != nil {
|
||||
s.Active = true
|
||||
|
||||
Reference in New Issue
Block a user