first commit
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestPathWithin 验证路径越界校验:read_file / write_file / run_coop 的 blackboard
|
||||
// 都依赖该函数拦截指向项目根目录之外的路径,是核心安全边界。
|
||||
func TestPathWithin(t *testing.T) {
|
||||
var parent string
|
||||
if runtime.GOOS == "windows" {
|
||||
parent = `e:\proj`
|
||||
} else {
|
||||
parent = "/proj"
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
child string
|
||||
expect bool
|
||||
}{
|
||||
{"自身", parent, true},
|
||||
{"直接子文件", filepath.Join(parent, "a.txt"), true},
|
||||
{"嵌套子目录", filepath.Join(parent, "sub", "deep", "f.txt"), true},
|
||||
{"上级目录", filepath.Join(parent, "..", "secret"), false},
|
||||
{"同级兄弟目录", filepath.Join(filepath.Dir(parent), "other"), false},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got := pathWithin(tc.child, parent); got != tc.expect {
|
||||
t.Fatalf("pathWithin(%q, %q) = %v, want %v", tc.child, parent, got, tc.expect)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestMergeToolCall 验证 SSE 流式 tool_call 增量合并:
|
||||
// 跨多个 chunk 按 index 聚合 id / name / arguments,是 LLM 工具调用协议正确性的关键。
|
||||
func TestMergeToolCall(t *testing.T) {
|
||||
var calls []ToolCall
|
||||
// 第一个 chunk:声明 index 0 的调用(id + name)
|
||||
calls = mergeToolCall(calls, ToolCallDelta{Index: 0, ID: "call_1", Name: "run_bash"})
|
||||
// 同一调用的参数分片到达
|
||||
calls = mergeToolCall(calls, ToolCallDelta{Index: 0, ArgumentsDelta: `{"comm`})
|
||||
calls = mergeToolCall(calls, ToolCallDelta{Index: 0, ArgumentsDelta: `and":"ls"}`})
|
||||
|
||||
if len(calls) != 1 {
|
||||
t.Fatalf("应合并为 1 个调用,got %d", len(calls))
|
||||
}
|
||||
c := calls[0]
|
||||
if c.ID != "call_1" || c.Function.Name != "run_bash" {
|
||||
t.Fatalf("id/name 不匹配: %+v", c)
|
||||
}
|
||||
if c.Function.Arguments != `{"command":"ls"}` {
|
||||
t.Fatalf("arguments 拼接错误: %q", c.Function.Arguments)
|
||||
}
|
||||
|
||||
// 第二个调用在 index 1
|
||||
calls = mergeToolCall(calls, ToolCallDelta{Index: 1, ID: "call_2", Name: "read_file"})
|
||||
calls = mergeToolCall(calls, ToolCallDelta{Index: 1, ArgumentsDelta: `{"path":"a"}`})
|
||||
if len(calls) != 2 {
|
||||
t.Fatalf("应有 2 个调用,got %d", len(calls))
|
||||
}
|
||||
if calls[1].Function.Name != "read_file" {
|
||||
t.Fatalf("第二个调用名错误: %+v", calls[1])
|
||||
}
|
||||
|
||||
// index 为负时回退为追加新调用
|
||||
prev := len(calls)
|
||||
calls = mergeToolCall(calls, ToolCallDelta{Index: -1, ID: "call_3", Name: "list_directory"})
|
||||
if len(calls) != prev+1 {
|
||||
t.Fatalf("负 index 应追加新调用,got %d", len(calls))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user