Files
AutoZero/tools/instructions_test.go
Sakurasan d5dac5a6fc 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。
2026-10-26 00:54:46 +08:00

104 lines
3.0 KiB
Go

package tools
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
)
func writeTree(t *testing.T, root string, files map[string]string) {
t.Helper()
for name, content := range files {
p := filepath.Join(root, 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)
}
}
}
// TestDiscoverNestedInstructions:只发现目标子树到工作区根之间的 AGENTS.md,
// 根自己的那份跳过(它已在基础 system 提示里)。
func TestDiscoverNestedInstructions(t *testing.T) {
root := t.TempDir()
writeTree(t, root, map[string]string{
"AGENTS.md": "ROOT-RULES",
"sub/AGENTS.md": "SUB-RULES",
"sub/deep/AGENTS.md": "DEEP-RULES",
"sub/deep/x.go": "package deep",
})
var got []string
discoverInstructions(filepath.Join(root, "sub/deep/x.go"), false, root, func(p, text string) {
got = append(got, text)
})
joined := strings.Join(got, ",")
if !strings.Contains(joined, "DEEP-RULES") || !strings.Contains(joined, "SUB-RULES") {
t.Fatalf("nested instructions not discovered: %v", got)
}
if strings.Contains(joined, "ROOT-RULES") {
t.Fatalf("root AGENTS.md must be skipped: %v", got)
}
if len(got) != 2 || got[0] != "DEEP-RULES" || got[1] != "SUB-RULES" {
t.Fatalf("order = %v, want nearest first", got)
}
// 目录目标:目录自己的 AGENTS.md 也要发现。
got = nil
discoverInstructions(filepath.Join(root, "sub"), true, root, func(_ string, text string) {
got = append(got, text)
})
if len(got) != 1 || got[0] != "SUB-RULES" {
t.Fatalf("directory discovery = %v", got)
}
// 工作区外:不发现。
outside := t.TempDir()
writeTree(t, outside, map[string]string{"AGENTS.md": "OUTSIDE"})
got = nil
discoverInstructions(filepath.Join(outside, "x.go"), false, root, func(_ string, text string) {
got = append(got, text)
})
if len(got) != 0 {
t.Fatalf("outside instructions leaked: %v", got)
}
}
// TestReadFeedsNestedInstructions:读取子目录文件时,read 把发现的约定交给宿主钩子。
func TestReadFeedsNestedInstructions(t *testing.T) {
root := t.TempDir()
writeTree(t, root, map[string]string{
"AGENTS.md": "ROOT-RULES",
"sub/AGENTS.md": "SUB-RULES",
"sub/x.txt": "hello",
})
var got []string
reg := NewRegistry()
for _, tl := range BuiltinWithHooks(root, NewFence(), nil, BuiltinHooks{
OnInstructions: func(path, text string) { got = append(got, text) },
}) {
if err := reg.Register(tl); err != nil {
t.Fatal(err)
}
}
r, _ := reg.Get("read")
if _, err := r.Run(context.Background(), `{"path":"sub/x.txt"}`); err != nil {
t.Fatal(err)
}
if len(got) != 1 || got[0] != "SUB-RULES" {
t.Fatalf("read hooks = %v", got)
}
// 根目录的文件不重复注入根约定。
got = nil
if _, err := r.Run(context.Background(), `{"path":"AGENTS.md"}`); err != nil {
t.Fatal(err)
}
if len(got) != 0 {
t.Fatalf("root instructions should not be discovered again: %v", got)
}
}