feat: AutoZero 通用 Agent 框架(从 AutoGo 五阶段拆分完成)

llm(三协议 Provider)/ session(JSONL 持久化)/ tools(Registry、围栏、
builtin、computer)/ cdp(browser)/ skills / mcp / agent(循环、两级压缩、
编排、审批门控)+ 底座 jsonl/textx/execx/diag/scratch/spill/imagecache。

产品装配代码(config 桥接、schedule 工具、memory/plan/retro/prompt)
留在 AutoGo,宿主接入方式见 MIGRATION.md。
This commit is contained in:
Sakurasan committed 2026-10-26 00:54:46 +08:00
commit d5dac5a6fc
140 files changed
+26497

No files matched your search

+61
View File
@@ -0,0 +1,61 @@
package agent
import (
"errors"
"strings"
"testing"
"git.gopher.ink/mirrors2/AutoZero/llm"
)
// TestTruncateSpillSavesAndReferences:截断时把原文落盘并在提示里给出可读路径。
func TestTruncateSpillSavesAndReferences(t *testing.T) {
long := "HEAD" + strings.Repeat("m", 50000) + "TAIL"
msgs := []llm.Message{{Role: llm.RoleTool, ToolCallID: "call-1", Content: long}}
var gotID, gotFull string
spillFn := func(callID, full string) (string, error) {
gotID, gotFull = callID, full
return "/tmp/results/call-1.txt", nil
}
view := truncateToolResultsSpill(msgs, 20000, spillFn)
if gotID != "call-1" {
t.Errorf("spillFn got callID %q, want call-1", gotID)
}
if gotFull != long {
t.Errorf("spillFn must receive the full original text (got %d bytes, want %d)", len(gotFull), len(long))
}
content := view[0].Content
if !strings.Contains(content, "/tmp/results/call-1.txt") {
t.Errorf("notice should reference the spilled path:\n%s", content)
}
if !strings.Contains(content, "use the read tool") {
t.Errorf("notice should tell the model how to retrieve it:\n%s", content)
}
if !strings.Contains(content, "[truncated") {
t.Errorf("notice should mention truncation:\n%s", content)
}
if len(content) > 20000 {
t.Errorf("truncated content too long: %d", len(content))
}
// transcript(传入的切片)不能被修改。
if msgs[0].Content != long {
t.Error("original message must not be mutated")
}
}
// TestTruncateSpillFailureDegrades:落盘失败时退回"重跑工具"提示,不 panic。
func TestTruncateSpillFailureDegrades(t *testing.T) {
msgs := []llm.Message{{Role: llm.RoleTool, ToolCallID: "c", Content: strings.Repeat("b", 50000)}}
view := truncateToolResultsSpill(msgs, 20000, func(_, _ string) (string, error) {
return "", errors.New("disk full")
})
if strings.Contains(view[0].Content, "full output saved") {
t.Errorf("failed spill must not advertise a path:\n%s", view[0].Content)
}
if !strings.Contains(view[0].Content, "narrower query") {
t.Errorf("failed spill should fall back to the rerun hint:\n%s", view[0].Content)
}
}