feat(tui): token metrics aggregation, plan overlay, tool reasoning, clar dismissal

#295 — include narration_llm tokens in changes-panel aggregate count
#296 — execution plan overlay (Ctrl+P in-session)
#298 — surface reasoning/CoT on tool-call turns in output view
#265 — dismiss clarification modal when answered externally (session.resumed)
This commit is contained in:
kami
2026-07-21 11:52:00 +04:00
parent d69cb12ce9
commit d6155691c8
6 changed files with 115 additions and 6 deletions
+7 -1
View File
@@ -136,8 +136,12 @@ func (m *Model) applyServer(msg protocol.ServerMessage) {
if s := m.session(msg.SessionID); s != nil {
s.Status = "ACTIVE"
s.clearApprovals()
s.Clar = nil
s.LastEventAt = nowMillis()
}
if msg.SessionID == m.selectedID {
m.clarResetState()
}
case protocol.TypeSessionCompleted:
m.touch(msg.SessionID, "COMPLETED")
if s := m.session(msg.SessionID); s != nil {
@@ -190,6 +194,7 @@ func (m *Model) applyServer(msg protocol.ServerMessage) {
}
}
case protocol.TypeInferenceStarted:
m.lastReasoning = ""
if s := m.session(msg.SessionID); s != nil {
s.Active = true
s.addEvent(nowMillis(), "InferenceStarted", msg.StageID)
@@ -209,6 +214,7 @@ func (m *Model) applyServer(msg protocol.ServerMessage) {
// row (revealed via the palette). Skipped when the model emits no separate channel.
if strings.TrimSpace(msg.Reasoning) != "" {
m.appendRouter(msg.SessionID, RouterEntry{Role: "thinking", Content: msg.Reasoning})
m.lastReasoning = msg.Reasoning
}
}
case protocol.TypeInferenceTimeout:
@@ -249,7 +255,7 @@ func (m *Model) applyServer(msg protocol.ServerMessage) {
// existing collapsed diff row (^x opens the full diff).
path, add, del := diffSummary(*msg.Diff)
m.appendAction(msg.SessionID, "✎", "wrote "+path+countSuffix(add, del))
m.appendRouter(msg.SessionID, RouterEntry{Role: "tool", Content: *msg.Diff})
m.appendRouter(msg.SessionID, RouterEntry{Role: "tool", Content: *msg.Diff, Reasoning: m.lastReasoning})
} else {
label := msg.ToolName
// Prefer the actual call args (path=…, command="…") over the affected-entities