diff --git a/cmd/hxclaw/main.go b/cmd/hxclaw/main.go index 0c512db..4d1d34c 100644 --- a/cmd/hxclaw/main.go +++ b/cmd/hxclaw/main.go @@ -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) +}