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:
commit
d5dac5a6fc
140 files changed
+26497
No files matched your search
@@ -0,0 +1,105 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func readIn(t *testing.T, input string, files map[string]string) (string, error) {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
for name, content := range files {
|
||||
p := filepath.Join(dir, name)
|
||||
if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(p, []byte(content), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
reg := NewRegistry()
|
||||
for _, tl := range BuiltinIn(dir, NewFence(), nil) {
|
||||
if err := reg.Register(tl); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
r, _ := reg.Get("read")
|
||||
res, err := r.Run(context.Background(), input)
|
||||
return res.Text, err
|
||||
}
|
||||
|
||||
// TestReadSmallFileUnchanged:不分页的小文件保持原样,不加头尾。
|
||||
func TestReadSmallFileUnchanged(t *testing.T) {
|
||||
got, err := readIn(t, `{"path":"f.txt"}`, map[string]string{"f.txt": "a\nb\nc\n"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got != "a\nb\nc\n" {
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadOffsetLimit(t *testing.T) {
|
||||
got, err := readIn(t, `{"path":"f.txt","offset":2,"limit":2}`,
|
||||
map[string]string{"f.txt": "l1\nl2\nl3\nl4\nl5\n"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(got, "lines 2-3 of 5") || !strings.Contains(got, "l2\nl3") {
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
if !strings.Contains(got, "continue with offset: 4") {
|
||||
t.Fatalf("missing continuation: %q", got)
|
||||
}
|
||||
if strings.Contains(got, "l1") || strings.Contains(got, "l4") {
|
||||
t.Fatalf("paging leaked other lines: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadBeyondEOF(t *testing.T) {
|
||||
got, err := readIn(t, `{"path":"f.txt","offset":99}`, map[string]string{"f.txt": "a\nb\n"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(got, "beyond EOF") {
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadDirectoryListing(t *testing.T) {
|
||||
got, err := readIn(t, `{"path":".","offset":2,"limit":1}`, map[string]string{
|
||||
"a.txt": "x",
|
||||
"sub/b.go": "y",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(got, "entries 2-2 of 2") || !strings.Contains(got, "sub/") {
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
if strings.Contains(got, "a.txt") {
|
||||
t.Fatalf("paging leaked other entries: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadRejectsBinary(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
p := filepath.Join(dir, "bin")
|
||||
if err := os.WriteFile(p, []byte{'a', 0, 'b'}, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
reg := NewRegistry()
|
||||
for _, tl := range BuiltinIn(dir, NewFence(), nil) {
|
||||
if err := reg.Register(tl); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
r, _ := reg.Get("read")
|
||||
if _, err := r.Run(context.Background(), `{"path":"bin"}`); err == nil ||
|
||||
!strings.Contains(err.Error(), "binary") {
|
||||
t.Fatalf("want binary error, got %v", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user