Files
BlackBean/internal/agent/compress_test.go
T
2026-08-14 23:41:57 +08:00

72 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package agent
import (
"strings"
"testing"
)
// TestFallbackSummary 验证 LLM 压缩失败时的兜底摘要:
// 纯文本、保留最近消息要点、无孤立 tool 消息。
func TestFallbackSummary(t *testing.T) {
history := []Message{
{Role: "user", Content: stringPointer("第一轮任务:分析日志")},
{Role: "assistant", Content: stringPointer("已确认方案,开始执行")},
{Role: "assistant", ToolCalls: []ToolCall{{ID: "c1", Type: "function", Function: ToolFunctionCall{Name: "run_bash", Arguments: `{"command":"ls"}`}}}},
{Role: "tool", ToolCallID: "c1", Content: stringPointer("file.txt")},
{Role: "user", Content: stringPointer("继续,报告结果")},
}
summary := fallbackSummary(history)
if summary == "" {
t.Fatal("fallbackSummary 不应返回空")
}
if strings.Contains(summary, "tool_calls") || strings.Contains(summary, "\"id\"") {
t.Fatalf("fallbackSummary 必须为纯文本,不得包含结构化 tool_calls: %s", summary)
}
if !strings.Contains(summary, "用户") || !strings.Contains(summary, "助手") || !strings.Contains(summary, "工具结果") {
t.Fatalf("fallbackSummary 应包含用户/助手/工具结果要点: %s", summary)
}
if !strings.Contains(summary, "调用了 run_bash") {
t.Fatalf("fallbackSummary 应记录工具调用名: %s", summary)
}
}
// TestCompactionInputBudget 验证单次压缩输入预算随窗口放大而放大,
// 且始终留出输出与安全余量。
func TestCompactionInputBudget(t *testing.T) {
a := &Agent{cfg: Config{MaxContextTokens: 96000, CompactionTokens: 4096, StreamOutputTokens: 4096}}
budget := a.compactionInputBudget()
if budget <= 0 || budget >= 96000 {
t.Fatalf("预算应介于 (0, 96000)got %d", budget)
}
// 窗口放大后预算也应放大
a2 := &Agent{cfg: Config{MaxContextTokens: 48000, CompactionTokens: 4096, StreamOutputTokens: 4096}}
if a2.compactionInputBudget() >= budget {
t.Fatalf("窗口更大的预算应更大,got %d vs %d", a2.compactionInputBudget(), budget)
}
// 极端小窗口时兜底下限 4096
a3 := &Agent{cfg: Config{MaxContextTokens: 2000, CompactionTokens: 512, StreamOutputTokens: 512}}
if got := a3.compactionInputBudget(); got < 4096 {
t.Fatalf("小窗口预算应有下限,got %d", got)
}
}
// TestEstimateMessageTokens 验证单条消息估算包含 content、tool_calls 与开销。
func TestEstimateMessageTokens(t *testing.T) {
m := Message{
Role: "assistant",
Content: stringPointer("你好"),
ToolCalls: []ToolCall{{
ID: "c1", Type: "function",
Function: ToolFunctionCall{Name: "read_file", Arguments: `{"path":"a.txt"}`},
}},
}
n := estimateMessageTokens(m)
if n <= 0 {
t.Fatalf("估算应大于 0got %d", n)
}
plain := estimateMessageTokens(Message{Role: "user", Content: stringPointer("你好")})
if n <= plain {
t.Fatalf("含 tool_calls 的消息估算应大于纯文本,got %d vs %d", n, plain)
}
}