mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
fix(context): show both summarize and compress thresholds in /context
The /context command previously showed only the hard budget compression threshold (contextWindow - maxTokens), which confused users who expected to see the soft summarization trigger from summarize_token_percent. This commit adds SummarizeAtTokens alongside the existing CompressAtTokens so that both thresholds are visible: - Compress at: contextWindow - maxTokens (hard budget, triggers proactive compression when exceeded) - Summarize at: contextWindow * summarizeTokenPercent / 100 (soft trigger, matches maybeSummarize's threshold) The fix updates the /context command output, the Web UI popover, and the pico channel WebSocket payload. Fixes #2968
This commit is contained in:
@@ -350,11 +350,12 @@ func (al *AgentLoop) buildCommandsRuntime(
|
||||
}
|
||||
history := agent.Sessions.GetHistory(opts.SessionKey)
|
||||
return &commands.ContextStats{
|
||||
UsedTokens: usage.UsedTokens,
|
||||
TotalTokens: usage.TotalTokens,
|
||||
CompressAtTokens: usage.CompressAtTokens,
|
||||
UsedPercent: usage.UsedPercent,
|
||||
MessageCount: len(history),
|
||||
UsedTokens: usage.UsedTokens,
|
||||
TotalTokens: usage.TotalTokens,
|
||||
CompressAtTokens: usage.CompressAtTokens,
|
||||
SummarizeAtTokens: usage.SummarizeAtTokens,
|
||||
UsedPercent: usage.UsedPercent,
|
||||
MessageCount: len(history),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,13 @@ func computeContextUsage(agent *AgentInstance, sessionKey string) *bus.ContextUs
|
||||
// proactive trigger (msgTokens + toolTokens + maxTokens > contextWindow).
|
||||
compressAt := effectiveWindow
|
||||
|
||||
// summarizeAt = soft summarization trigger: matches maybeSummarize's
|
||||
// threshold (contextWindow * SummarizeTokenPercent / 100).
|
||||
summarizeAt := contextWindow * agent.SummarizeTokenPercent / 100
|
||||
if summarizeAt <= 0 {
|
||||
summarizeAt = compressAt
|
||||
}
|
||||
|
||||
usedPercent := 0
|
||||
if compressAt > 0 {
|
||||
usedPercent = usedTokens * 100 / compressAt
|
||||
@@ -70,9 +77,10 @@ func computeContextUsage(agent *AgentInstance, sessionKey string) *bus.ContextUs
|
||||
}
|
||||
|
||||
return &bus.ContextUsage{
|
||||
UsedTokens: usedTokens,
|
||||
TotalTokens: contextWindow,
|
||||
CompressAtTokens: compressAt,
|
||||
UsedPercent: usedPercent,
|
||||
UsedTokens: usedTokens,
|
||||
TotalTokens: contextWindow,
|
||||
CompressAtTokens: compressAt,
|
||||
SummarizeAtTokens: summarizeAt,
|
||||
UsedPercent: usedPercent,
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -64,10 +64,11 @@ type OutboundScope struct {
|
||||
// ContextUsage describes how much of the model's context window the current
|
||||
// session consumes, and how far it is from triggering compression.
|
||||
type ContextUsage struct {
|
||||
UsedTokens int `json:"used_tokens"`
|
||||
TotalTokens int `json:"total_tokens"` // model context window
|
||||
CompressAtTokens int `json:"compress_at_tokens"` // threshold that triggers compression
|
||||
UsedPercent int `json:"used_percent"` // 0-100
|
||||
UsedTokens int `json:"used_tokens"`
|
||||
TotalTokens int `json:"total_tokens"` // model context window
|
||||
CompressAtTokens int `json:"compress_at_tokens"` // hard budget compression threshold (contextWindow - maxTokens)
|
||||
SummarizeAtTokens int `json:"summarize_at_tokens"` // soft summarization trigger (contextWindow * summarizeTokenPercent / 100)
|
||||
UsedPercent int `json:"used_percent"` // 0-100, relative to compressAt
|
||||
}
|
||||
|
||||
type OutboundMessage struct {
|
||||
|
||||
@@ -1394,10 +1394,11 @@ func setContextUsagePayload(payload map[string]any, u *bus.ContextUsage) {
|
||||
return
|
||||
}
|
||||
payload["context_usage"] = map[string]any{
|
||||
"used_tokens": u.UsedTokens,
|
||||
"total_tokens": u.TotalTokens,
|
||||
"compress_at_tokens": u.CompressAtTokens,
|
||||
"used_percent": u.UsedPercent,
|
||||
"used_tokens": u.UsedTokens,
|
||||
"total_tokens": u.TotalTokens,
|
||||
"compress_at_tokens": u.CompressAtTokens,
|
||||
"summarize_at_tokens": u.SummarizeAtTokens,
|
||||
"used_percent": u.UsedPercent,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +29,16 @@ func formatContextStats(s *ContextStats) string {
|
||||
remaining = 0
|
||||
}
|
||||
usedWindowPercent := s.UsedTokens * 100 / max(s.TotalTokens, 1)
|
||||
return fmt.Sprintf(
|
||||
"Context usage \nMessages: %d \nUsed: ~%d / %d tokens (%d%%) \nCompress at: %d tokens \nCompression progress: %d%% \nRemaining: ~%d tokens",
|
||||
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",
|
||||
s.MessageCount,
|
||||
s.UsedTokens,
|
||||
s.TotalTokens,
|
||||
usedWindowPercent,
|
||||
s.CompressAtTokens,
|
||||
s.SummarizeAtTokens,
|
||||
s.UsedPercent,
|
||||
remaining,
|
||||
)
|
||||
return msg
|
||||
}
|
||||
|
||||
@@ -29,11 +29,12 @@ type MCPToolInfo struct {
|
||||
|
||||
// ContextStats describes current session context window usage.
|
||||
type ContextStats struct {
|
||||
UsedTokens int
|
||||
TotalTokens int // model context window
|
||||
CompressAtTokens int // compression threshold
|
||||
UsedPercent int // 0-100
|
||||
MessageCount int
|
||||
UsedTokens int
|
||||
TotalTokens int // model context window
|
||||
CompressAtTokens int // hard budget compression threshold
|
||||
SummarizeAtTokens int // soft summarization trigger
|
||||
UsedPercent int // 0-100
|
||||
MessageCount int
|
||||
}
|
||||
|
||||
// StopResult describes the outcome of a stop request for the current session.
|
||||
|
||||
@@ -145,6 +145,23 @@ export function ContextUsageRing({
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-2 space-y-0.5">
|
||||
<div className="flex items-center justify-between text-[10px]">
|
||||
<span className="text-muted-foreground">Compress at</span>
|
||||
<span className="tabular-nums">
|
||||
{formatTokens(usage.compress_at_tokens)}
|
||||
</span>
|
||||
</div>
|
||||
{usage.summarize_at_tokens != null && usage.summarize_at_tokens > 0 && (
|
||||
<div className="flex items-center justify-between text-[10px]">
|
||||
<span className="text-muted-foreground">Summarize at</span>
|
||||
<span className="tabular-nums">
|
||||
{formatTokens(usage.summarize_at_tokens)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleDetail}
|
||||
|
||||
@@ -79,6 +79,7 @@ function parseContextUsage(
|
||||
used_tokens: used,
|
||||
total_tokens: total,
|
||||
compress_at_tokens: Number(obj.compress_at_tokens) || 0,
|
||||
summarize_at_tokens: obj.summarize_at_tokens != null ? Number(obj.summarize_at_tokens) : undefined,
|
||||
used_percent: Number(obj.used_percent) || 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ export interface ContextUsage {
|
||||
used_tokens: number
|
||||
total_tokens: number
|
||||
compress_at_tokens: number
|
||||
summarize_at_tokens?: number
|
||||
used_percent: number
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user