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,67 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.gopher.ink/mirrors2/AutoZero/llm"
|
||||
"git.gopher.ink/mirrors2/AutoZero/skills"
|
||||
)
|
||||
|
||||
// TestLoadSkillTool:load_skill 返回正文;allowed-tools 白名单过滤生效,
|
||||
// 白名单外工具被拒。
|
||||
func TestLoadSkillTool(t *testing.T) {
|
||||
prov := &scriptedProvider{fn: func(call int, _ string, _ []llm.Message, tools []llm.ToolDef) (llm.Message, error) {
|
||||
switch call {
|
||||
case 1: // 模型加载 skill(工具全量可见)
|
||||
if !hasName(tools, "grep") || !hasName(tools, "load_skill") {
|
||||
t.Errorf("call 1: expected full toolset, got %v", toolNames(tools))
|
||||
}
|
||||
return llm.Message{Role: llm.RoleAssistant, ToolCalls: []llm.ToolCall{
|
||||
{ID: "sk1", Name: "load_skill", Input: `{"name":"review"}`},
|
||||
}}, nil
|
||||
case 2: // 白名单生效:只剩 load_skill + read
|
||||
if hasName(tools, "grep") || !hasName(tools, "read") || !hasName(tools, "load_skill") {
|
||||
t.Errorf("call 2: expected filtered toolset [load_skill read], got %v", toolNames(tools))
|
||||
}
|
||||
return llm.Message{Role: llm.RoleAssistant, ToolCalls: []llm.ToolCall{
|
||||
{ID: "t1", Name: "grep", Input: `{"pattern":"x"}`}, // 白名单外 → 应得到错误结果
|
||||
}}, nil
|
||||
case 3:
|
||||
return llm.Message{Role: llm.RoleAssistant, Content: "done"}, nil
|
||||
}
|
||||
t.Errorf("unexpected call %d", call)
|
||||
return llm.Message{}, nil
|
||||
}}
|
||||
|
||||
a, sess := newTestAgent(t)
|
||||
a.Provider = prov
|
||||
a.Skills = []skills.Skill{{
|
||||
Name: "review",
|
||||
Description: "code review",
|
||||
AllowedTools: []string{"read"},
|
||||
Body: "Read the diff and comment.",
|
||||
}}
|
||||
if err := a.Tools.Register(a.SkillTool()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := a.Run(context.Background(), "review the code"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// skill 正文作为工具结果回填
|
||||
var gotBody bool
|
||||
for _, m := range sess.Messages {
|
||||
if m.Role == llm.RoleTool && strings.Contains(m.Content, "Read the diff") {
|
||||
gotBody = true
|
||||
}
|
||||
// grep 调用应被白名单拒绝
|
||||
if m.ToolCallID == "t1" && !strings.Contains(m.Content, "not allowed") {
|
||||
t.Fatalf("grep should be denied by skill filter, got %q", m.Content)
|
||||
}
|
||||
}
|
||||
if !gotBody {
|
||||
t.Fatal("skill body not fed back as tool result")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user