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
+18 -1
View File
@@ -402,7 +402,7 @@ func (m Model) changesRows(w, h int) []string {
t := m.theme
turns, toks := 0, 0
for _, e := range m.routerMessages[m.selectedID] {
if e.Role == "router" && e.Metrics != nil {
if (e.Role == "router" || e.Role == "narration_llm") && e.Metrics != nil {
turns++
toks += e.Metrics.TotalTokens
}
@@ -822,6 +822,23 @@ func (m Model) buildTranscriptRows(w int) ([]string, []int) {
rows = append(rows, t.span(s, t.P.Faint))
}
case "tool":
if e.Reasoning != "" {
if m.thinkingShown {
for _, ln := range strings.Split(strings.TrimRight(e.Reasoning, "\n"), "\n") {
rows = append(rows, t.span("✼ "+ln, t.P.Faint))
}
} else {
rows = append(rows, t.span("✼ reasoning — palette: thinking", t.P.Faint))
}
} else if m.lastReasoning != "" {
if m.thinkingShown {
for _, ln := range strings.Split(strings.TrimRight(m.lastReasoning, "\n"), "\n") {
rows = append(rows, t.span("✼ "+ln, t.P.Faint))
}
} else {
rows = append(rows, t.span("✼ reasoning — palette: thinking", t.P.Faint))
}
}
rows = append(rows, t.span(toolRowSummary(e.Content), t.P.Dim))
case "thinking":
// Collapsed by default to a single muted line so the reasoning trace doesn't bury