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)) } }