Files
2026-08-14 23:41:57 +08:00

77 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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))
}
}