Skip to content

Commit 4ae84ef

Browse files
committed
Only show Compacting context on spinner when compaction runs
1 parent 2d63727 commit 4ae84ef

7 files changed

Lines changed: 43 additions & 16 deletions

File tree

cmd/chat.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -933,8 +933,10 @@ func (m chatModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
933933
return m, nil
934934

935935
case streamChunkMsg:
936-
m.compacting = false
937-
m.compactStatus = ""
936+
if m.compacting {
937+
m.compacting = false
938+
m.brailleSpinner.SetLabel(m.spinnerVerb)
939+
}
938940
m.partial.WriteString(string(msg))
939941
m.markPartialDirty()
940942
return m, nil
@@ -990,9 +992,15 @@ func (m chatModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
990992
m.viewDirty = true
991993
}
992994

995+
case compactStartMsg:
996+
m.compacting = true
997+
m.brailleSpinner.SetLabel("Compacting context")
998+
m.viewDirty = true
999+
return m, nil
1000+
9931001
case compactMsg:
9941002
m.compacting = false
995-
m.compactStatus = ""
1003+
m.brailleSpinner.SetLabel(m.spinnerVerb)
9961004
line := fmt.Sprintf("Context compacted (%s): ~%s → ~%s tokens",
9971005
msg.strategy,
9981006
formatHawkTokenCount(msg.tokensBefore),
@@ -1004,8 +1012,10 @@ func (m chatModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
10041012
return m, nil
10051013

10061014
case streamDoneMsg:
1007-
m.compacting = false
1008-
m.compactStatus = ""
1015+
if m.compacting {
1016+
m.compacting = false
1017+
m.brailleSpinner.SetLabel(m.spinnerVerb)
1018+
}
10091019
m.flushPartialDirty()
10101020
if m.partial.Len() > 0 {
10111021
content := sanitizeIdentity(m.partial.String())
@@ -1248,6 +1258,8 @@ func runChat() error {
12481258
p.Send(toolUseMsg{name: ev.ToolName, id: ev.ToolID})
12491259
case "tool_result":
12501260
p.Send(toolResultMsg{name: ev.ToolName, content: ev.Content})
1261+
case "compact_start":
1262+
p.Send(compactStartMsg{})
12511263
case "compact":
12521264
p.Send(compactMsg{
12531265
strategy: ev.Content,

cmd/chat_commands_session.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (m *chatModel) handleSessionCommand(cmd string, parts []string, text string
7474
}
7575
m.messages = append(m.messages, displayMsg{role: "system", content: msg})
7676
m.compacting = false
77-
m.compactStatus = ""
77+
m.brailleSpinner.SetLabel(m.spinnerVerb)
7878
m.invalidateConnStatus()
7979
return m, nil
8080

cmd/chat_model.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ type (
8484
blinkTickMsg struct{}
8585
spinnerVerbTickMsg struct{}
8686
usageUpdateMsg struct{ usage *engine.StreamUsage }
87+
compactStartMsg struct{}
8788
compactMsg struct {
88-
strategy string
89+
strategy string
8990
tokensBefore, tokensAfter int
9091
}
9192
)
@@ -178,8 +179,7 @@ type chatModel struct {
178179
// Reset each time the user submits a message; updated by usageUpdateMsg.
179180
turnInputTokens int
180181
turnOutputTokens int
181-
compacting bool // true while context governor runs
182-
compactStatus string // short label on spinner line
182+
compacting bool // true while context governor runs (spinner label = Compacting context)
183183
// Display values lerped toward the turn targets each render frame
184184
// (factor 0.10). Smooths the counter animation.
185185
displayInTok float64

cmd/chat_stream.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ func (m *chatModel) startPromptCommand(display, prompt string) (tea.Model, tea.C
2121

2222
func (m *chatModel) startStream() {
2323
m.syncSessionSelection()
24-
m.compacting = true
25-
m.compactStatus = "Compacting context"
26-
m.viewDirty = true
2724
sess := m.session
2825
ref := m.ref
2926
ctx, cancel := context.WithCancel(context.Background())
@@ -46,6 +43,8 @@ func (m *chatModel) startStream() {
4643
ref.Send(toolResultMsg{name: ev.ToolName, content: ev.Content})
4744
case "blast_radius":
4845
ref.Send(blastRadiusMsg{message: ev.Content})
46+
case "compact_start":
47+
ref.Send(compactStartMsg{})
4948
case "compact":
5049
ref.Send(compactMsg{
5150
strategy: ev.Content,

cmd/chat_view.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -604,10 +604,6 @@ func (m chatModel) renderWaitingSpinnerLine() string {
604604
sep := ansiDim + " " + iconSpinnerSep + " " + ansiReset
605605

606606
var b strings.Builder
607-
if m.compacting && m.compactStatus != "" {
608-
b.WriteString(ansiYellow + m.compactStatus + ansiReset)
609-
b.WriteString(sep)
610-
}
611607
b.WriteString(m.brailleSpinner.Frame())
612608
b.WriteString(sep)
613609
b.WriteString(ansiTeal + fmt.Sprintf("%.1fs", m.spinnerElapsed().Seconds()) + ansiReset)

internal/engine/context_governor.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ func (s *Session) refreshContextWindowCache() {
8787
s.EnsureAutoCompactor()
8888
}
8989

90+
// WillCompactBeforeTurn reports whether the next ManageContextBeforeTurn call will compact.
91+
func (s *Session) WillCompactBeforeTurn() bool {
92+
if s == nil {
93+
return false
94+
}
95+
s.EnsureAutoCompactor()
96+
if s.AutoCompactor.ShouldAutoCompact(s) {
97+
return true
98+
}
99+
if len(s.messages) > maxContextMessages {
100+
return true
101+
}
102+
convTokens := EstimateTokens(s.messages)
103+
budget := ctxmgr.NewContextBudget(s.ContextWindowSize())
104+
return budget.ShouldCompact(convTokens)
105+
}
106+
90107
// ManageContextBeforeTurn collapses noise, then compacts via the strategy registry when needed.
91108
// Returns the compaction strategy name (if any) and whether messages were reduced.
92109
func (s *Session) ManageContextBeforeTurn(ctx context.Context) (strategy string, compacted bool) {

internal/engine/stream.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ func (s *Session) agentLoop(ctx context.Context, ch chan<- StreamEvent) {
171171
}
172172
// Context governor: collapse → micro/smart/truncate (settings threshold %).
173173
tokensBefore := EstimateTokens(s.messages)
174+
if s.WillCompactBeforeTurn() {
175+
ch <- StreamEvent{Type: "compact_start"}
176+
}
174177
if strat, didCompact := s.ManageContextBeforeTurn(ctx); didCompact {
175178
tokensAfter := EstimateTokens(s.messages)
176179
s.log.Info("context compacted", map[string]interface{}{

0 commit comments

Comments
 (0)