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

+85
View File
@@ -0,0 +1,85 @@
package tools
import (
"os"
"path/filepath"
"strings"
)
const (
// 嵌套指令最多注入 5 个文件、每个 20KB:这些内容每轮都会进 system,
// 不设上限等于给模型塞一棵子树。
maxInstructionFiles = 5
maxInstructionBytes = 20 * 1024
)
// discoverInstructions 从 target(文件所在目录或目录本身)向上走到工作区根,
// 把沿途的 AGENTS.md 交给 emit。根自己的 AGENTS.md 已在基础 system 提示里,
// 这里跳过;工作区外的路径一律不发现。错误全部静默——读文件成功不该因为
// 顺带发现指令失败而失败。
func discoverInstructions(target string, isDir bool, root string, emit func(path, text string)) {
if emit == nil {
return
}
if root == "" {
root, _ = os.Getwd()
}
rootAbs, ok := canonicalPath(root)
if !ok {
return
}
start := target
if !isDir {
start = filepath.Dir(target)
}
startAbs, ok := canonicalPath(start)
if !ok {
return
}
if !withinDir(rootAbs, startAbs) {
return
}
found := 0
for dir := startAbs; ; dir = filepath.Dir(dir) {
if dir == rootAbs || !withinDir(rootAbs, dir) {
return
}
p := filepath.Join(dir, "AGENTS.md")
data, err := os.ReadFile(p)
if err == nil && len(data) > 0 && len(data) <= maxInstructionBytes {
text := strings.TrimSpace(string(data))
if text != "" {
emit(p, text)
found++
if found >= maxInstructionFiles {
return
}
}
}
parent := filepath.Dir(dir)
if parent == dir {
return
}
}
}
// canonicalPath 返回绝对路径,尽量解开符号链接(macOS 的 /var → /private/var)。
func canonicalPath(p string) (string, bool) {
abs, err := filepath.Abs(p)
if err != nil {
return "", false
}
if resolved, err := filepath.EvalSymlinks(abs); err == nil {
return resolved, true
}
return abs, true
}
// withinDir 报告 p 是否等于 root 或位于 root 之下(都已是绝对路径)。
func withinDir(root, p string) bool {
rel, err := filepath.Rel(root, p)
if err != nil {
return false
}
return rel == "." || (rel != ".." && !strings.HasPrefix(rel, ".."+string(filepath.Separator)))
}