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"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestComputerValidation:参数校验失败必须发生在任何真实 GUI 调用之前
|
||||
// (三平台通用:错误先行,即使依赖缺失也应报校验错——实际上 Linux/Windows
|
||||
// 上 Available() 先失败也是合法错误,本测试在任一平台都应通过)。
|
||||
func TestComputerValidation(t *testing.T) {
|
||||
c := Computer()
|
||||
cases := []string{
|
||||
`{"action":"bogus"}`,
|
||||
`{"action":"left_click"}`, // 缺坐标
|
||||
`{"action":"type"}`, // 缺文本
|
||||
`{"action":"key","key":"cmd"}`, // 无主键
|
||||
`{`,
|
||||
}
|
||||
for _, in := range cases {
|
||||
if _, err := c.Run(context.Background(), in); err == nil {
|
||||
t.Fatalf("input %q should fail", in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseChord(t *testing.T) {
|
||||
mods, main, err := parseChord("cmd+shift+t")
|
||||
if err != nil || main != "t" || len(mods) != 2 || mods[0] != "cmd" || mods[1] != "shift" {
|
||||
t.Fatalf("cmd+shift+t: mods=%v main=%q err=%v", mods, main, err)
|
||||
}
|
||||
if _, main, _ := parseChord("ENTER"); main != "enter" {
|
||||
t.Fatalf("case normalization failed: %q", main)
|
||||
}
|
||||
for _, bad := range []string{"", "cmd", "cmd+a+b", "cmd++q", "foo", "ctrl+enter+esc"} {
|
||||
if _, _, err := parseChord(bad); err == nil {
|
||||
t.Fatalf("%q should be rejected", bad)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestChordToXdotool(t *testing.T) {
|
||||
cases := []struct{ in, want string }{
|
||||
{"ctrl+c", "ctrl+c"},
|
||||
{"cmd+c", "super+c"},
|
||||
{"ctrl+alt+delete", "ctrl+alt+BackSpace"},
|
||||
{"pageup", "Page_Up"},
|
||||
{"cmd+shift+t", "super+shift+t"},
|
||||
{"enter", "Return"},
|
||||
{"space", "space"},
|
||||
{"a", "a"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
mods, main, err := parseChord(c.in)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", c.in, err)
|
||||
}
|
||||
got, err := chordToXdotool(mods, main, c.in)
|
||||
if err != nil || got != c.want {
|
||||
t.Fatalf("%s: got %q (%v), want %q", c.in, got, err, c.want)
|
||||
}
|
||||
}
|
||||
if _, err := chordToXdotool([]string{"fn"}, "a", "fn+a"); err == nil {
|
||||
t.Fatal("fn should be rejected on Linux")
|
||||
}
|
||||
}
|
||||
|
||||
func TestChordToSendKeys(t *testing.T) {
|
||||
cases := []struct{ in, want string }{
|
||||
{"ctrl+c", "^c"},
|
||||
{"alt+f4", "%{F4}"},
|
||||
{"ctrl+shift+esc", "^+{ESC}"},
|
||||
{"enter", "{ENTER}"},
|
||||
{"pageup", "{PGUP}"},
|
||||
{"ctrl+{", "^{{}"},
|
||||
{"a", "a"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
mods, main, err := parseChord(c.in)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", c.in, err)
|
||||
}
|
||||
got, err := chordToSendKeys(mods, main, c.in)
|
||||
if err != nil || got != c.want {
|
||||
t.Fatalf("%s: got %q (%v), want %q", c.in, got, err, c.want)
|
||||
}
|
||||
}
|
||||
for _, bad := range []string{"cmd+c", "win+r", "fn+left"} {
|
||||
mods, main, err := parseChord(bad)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", bad, err)
|
||||
}
|
||||
if _, err := chordToSendKeys(mods, main, bad); err == nil {
|
||||
t.Fatalf("%s should be rejected on Windows", bad)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendKeysEscape(t *testing.T) {
|
||||
got := sendKeysEscape("a+b\nc{d}\t]")
|
||||
want := "a{+}b{ENTER}c{{}d{}}{TAB}{]}"
|
||||
if got != want {
|
||||
t.Fatalf("got %q want %q", got, want)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user