feat: 添加 /context 命令显示会话上下文使用情况

- 集成 picoclaw v0.2.7 的上下文统计功能
- 显示消息数、token 使用量、压缩阈值和剩余空间
- 在 interactiveMode 和 simpleInteractiveMode 中均支持
This commit is contained in:
2026-05-03 02:43:27 +08:00
parent e3f902d25d
commit 532466c343

View File

@@ -156,6 +156,11 @@ func interactiveMode(agentLoop *agent.AgentLoop, sessionKey string) {
continue
}
if strings.HasPrefix(input, "/context") {
handleContextCommand(agentLoop, sessionKey)
continue
}
if isTempTTS {
enabled := internal.ToggleTTS()
if enabled {
@@ -224,6 +229,11 @@ func simpleInteractiveMode(agentLoop *agent.AgentLoop, sessionKey string) {
continue
}
if strings.HasPrefix(input, "/context") {
handleContextCommand(agentLoop, sessionKey)
continue
}
if isTempTTS {
internal.ToggleTTS()
}
@@ -513,3 +523,80 @@ func handleSessionsCommand() {
fmt.Printf(" %s | %d 条消息 | %s\n", s.UUID[:8], len(s.ChatIDs), summary)
}
}
func handleContextCommand(agentLoop *agent.AgentLoop, sessionKey string) {
if agentLoop == nil {
fmt.Println("无法获取上下文信息")
return
}
cfg := agentLoop.GetConfig()
if cfg == nil {
fmt.Println("无法获取配置信息")
return
}
registry := agentLoop.GetRegistry()
if registry == nil {
fmt.Println("无法获取代理注册信息")
return
}
instance := registry.GetDefaultAgent()
if instance == nil {
fmt.Println("无可用代理")
return
}
contextWindow := instance.ContextWindow
if contextWindow <= 0 {
fmt.Println("上下文窗口大小未知")
return
}
history := instance.Sessions.GetHistory(sessionKey)
historyTokens := 0
for _, m := range history {
historyTokens += agent.EstimateMessageTokens(m)
}
systemTokens := 0
if instance.ContextBuilder != nil {
summary := instance.Sessions.GetSummary(sessionKey)
systemTokens = instance.ContextBuilder.EstimateSystemTokens(summary, nil)
}
toolTokens := 0
if instance.Tools != nil {
toolDefs := instance.Tools.ToProviderDefs()
toolTokens = agent.EstimateToolDefsTokens(toolDefs)
}
usedTokens := historyTokens + systemTokens + toolTokens
effectiveWindow := contextWindow - instance.MaxTokens
if effectiveWindow < 0 {
effectiveWindow = contextWindow
}
compressAt := effectiveWindow
usedPercent := 0
if compressAt > 0 {
usedPercent = usedTokens * 100 / compressAt
}
if usedPercent > 100 {
usedPercent = 100
}
remaining := compressAt - usedTokens
if remaining < 0 {
remaining = 0
}
fmt.Println("上下文使用情况")
fmt.Printf("消息数: %d\n", len(history))
fmt.Printf("已用: ~%d / %d tokens (%d%%)\n", usedTokens, contextWindow, usedPercent)
fmt.Printf("压缩阈值: %d tokens\n", compressAt)
fmt.Printf("压缩进度: %d%%\n", usedPercent)
fmt.Printf("剩余: ~%d tokens\n", remaining)
}