mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
fix(context): expose history tokens and remove leaked state files
Address remaining review feedback: 1) Add HistoryTokens field to ContextUsage/ContextStats, showing history-only token count in /context and frontend UI alongside SummarizeAtTokens so users can see the actual summarization trigger comparison. 2) Remove .codebuddy/github-contribute/ state files accidentally included in the PR.
This commit is contained in:
@@ -352,6 +352,7 @@ func (al *AgentLoop) buildCommandsRuntime(
|
||||
return &commands.ContextStats{
|
||||
UsedTokens: usage.UsedTokens,
|
||||
TotalTokens: usage.TotalTokens,
|
||||
HistoryTokens: usage.HistoryTokens,
|
||||
CompressAtTokens: usage.CompressAtTokens,
|
||||
SummarizeAtTokens: usage.SummarizeAtTokens,
|
||||
UsedPercent: usage.UsedPercent,
|
||||
|
||||
@@ -64,12 +64,9 @@ func computeContextUsage(agent *AgentInstance, sessionKey string) *bus.ContextUs
|
||||
// summarizeAt = soft summarization trigger: matches maybeSummarize's
|
||||
// threshold (contextWindow * SummarizeTokenPercent / 100).
|
||||
//
|
||||
// NOTE: The engine's maybeSummarize compares this threshold against
|
||||
// history-message tokens only (via estimateTokens), while UsedTokens
|
||||
// (shown in /context) includes system prompt, summary, and tool
|
||||
// definitions on top of history tokens. A "Used > SummarizeAt" display
|
||||
// does not necessarily mean summarization will fire — the engine may
|
||||
// still consider the history-token budget to be under threshold.
|
||||
// The engine compares this against history-message tokens ONLY (not
|
||||
// UsedTokens). HistoryTokens is exposed alongside UsedTokens so the
|
||||
// UI can show both values and avoid user confusion.
|
||||
summarizeAt := contextWindow * agent.SummarizeTokenPercent / 100
|
||||
if summarizeAt <= 0 {
|
||||
summarizeAt = compressAt
|
||||
@@ -86,6 +83,7 @@ func computeContextUsage(agent *AgentInstance, sessionKey string) *bus.ContextUs
|
||||
return &bus.ContextUsage{
|
||||
UsedTokens: usedTokens,
|
||||
TotalTokens: contextWindow,
|
||||
HistoryTokens: historyTokens,
|
||||
CompressAtTokens: compressAt,
|
||||
SummarizeAtTokens: summarizeAt,
|
||||
UsedPercent: usedPercent,
|
||||
|
||||
+2
-1
@@ -66,8 +66,9 @@ type OutboundScope struct {
|
||||
type ContextUsage struct {
|
||||
UsedTokens int `json:"used_tokens"`
|
||||
TotalTokens int `json:"total_tokens"` // model context window
|
||||
HistoryTokens int `json:"history_tokens"` // history-message tokens only (what maybeSummarize checks)
|
||||
CompressAtTokens int `json:"compress_at_tokens"` // hard budget compression threshold (contextWindow - maxTokens)
|
||||
SummarizeAtTokens int `json:"summarize_at_tokens"` // soft summarization trigger (contextWindow * summarizeTokenPercent / 100)
|
||||
SummarizeAtTokens int `json:"summarize_at_tokens"` // soft summarization trigger (vs history tokens)
|
||||
UsedPercent int `json:"used_percent"` // 0-100, relative to compressAt
|
||||
}
|
||||
|
||||
|
||||
@@ -1396,6 +1396,7 @@ func setContextUsagePayload(payload map[string]any, u *bus.ContextUsage) {
|
||||
payload["context_usage"] = map[string]any{
|
||||
"used_tokens": u.UsedTokens,
|
||||
"total_tokens": u.TotalTokens,
|
||||
"history_tokens": u.HistoryTokens,
|
||||
"compress_at_tokens": u.CompressAtTokens,
|
||||
"summarize_at_tokens": u.SummarizeAtTokens,
|
||||
"used_percent": u.UsedPercent,
|
||||
|
||||
@@ -604,6 +604,7 @@ func TestBeginStream_FinalizeIncludesContextUsage(t *testing.T) {
|
||||
if err := contextStreamer.FinalizeWithContext(context.Background(), "final", &bus.ContextUsage{
|
||||
UsedTokens: 10,
|
||||
TotalTokens: 100,
|
||||
HistoryTokens: 5,
|
||||
CompressAtTokens: 80,
|
||||
SummarizeAtTokens: 60,
|
||||
UsedPercent: 10,
|
||||
@@ -628,6 +629,9 @@ func TestBeginStream_FinalizeIncludesContextUsage(t *testing.T) {
|
||||
if got := rawUsage["used_tokens"]; got != float64(10) {
|
||||
t.Fatalf("used_tokens = %#v, want 10", got)
|
||||
}
|
||||
if got := rawUsage["history_tokens"]; got != float64(5) {
|
||||
t.Fatalf("history_tokens = %#v, want 5", got)
|
||||
}
|
||||
if got := rawUsage["summarize_at_tokens"]; got != float64(60) {
|
||||
t.Fatalf("summarize_at_tokens = %#v, want 60", got)
|
||||
}
|
||||
|
||||
@@ -30,11 +30,12 @@ func formatContextStats(s *ContextStats) string {
|
||||
}
|
||||
usedWindowPercent := s.UsedTokens * 100 / max(s.TotalTokens, 1)
|
||||
msg := fmt.Sprintf(
|
||||
"Context usage \nMessages: %d \nUsed: ~%d / %d tokens (%d%%) \nCompress at: %d tokens \nSummarize at: %d tokens \nCompression progress: %d%% \nRemaining: ~%d tokens",
|
||||
"Context usage \nMessages: %d \nUsed: ~%d / %d tokens (%d%%) \nHistory: ~%d tokens \nCompress at: %d tokens \nSummarize at: %d tokens \nCompression progress: %d%% \nRemaining: ~%d tokens",
|
||||
s.MessageCount,
|
||||
s.UsedTokens,
|
||||
s.TotalTokens,
|
||||
usedWindowPercent,
|
||||
s.HistoryTokens,
|
||||
s.CompressAtTokens,
|
||||
s.SummarizeAtTokens,
|
||||
s.UsedPercent,
|
||||
|
||||
@@ -31,6 +31,7 @@ type MCPToolInfo struct {
|
||||
type ContextStats struct {
|
||||
UsedTokens int
|
||||
TotalTokens int // model context window
|
||||
HistoryTokens int // history-only tokens (what maybeSummarize checks)
|
||||
CompressAtTokens int // hard budget compression threshold
|
||||
SummarizeAtTokens int // soft summarization trigger
|
||||
UsedPercent int // 0-100
|
||||
|
||||
Reference in New Issue
Block a user