| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- """
- 测试新的 Plan 系统
- 测试 GoalTree、Message、TraceStore 的基本功能
- """
- import asyncio
- import sys
- from pathlib import Path
- # 添加项目根目录到 Python 路径
- sys.path.insert(0, str(Path(__file__).parent.parent.parent))
- from agent.models.goal import GoalTree, Goal, GoalStats
- from agent.execution.models import Trace, Message
- from agent.execution.fs_store import FileSystemTraceStore
- from agent.tools.builtin.goal import goal
- async def test_basic_plan():
- """测试基本的计划功能"""
- print("=" * 60)
- print("测试 1: 基本计划功能")
- print("=" * 60)
- print()
- # 1. 创建 GoalTree
- tree = GoalTree(mission="实现用户认证功能")
- print("1. 创建 GoalTree")
- print(f" Mission: {tree.mission}")
- print()
- # 2. 添加顶层目标
- print("2. 添加顶层目标")
- result = goal_tool(tree, add="分析代码, 实现功能, 测试")
- print(result)
- print()
- # 3. Focus 到目标 2
- print("3. Focus 到目标 2")
- result = goal_tool(tree, focus="2")
- print(result)
- print()
- # 4. 添加子目标
- print("4. 在目标 2 下添加子目标")
- result = goal_tool(tree, add="设计接口, 实现代码, 单元测试")
- print(result)
- print()
- # 5. Focus 到子目标并完成
- print("5. Focus 到 2.1 并完成")
- result = goal_tool(tree, focus="3") # 内部 ID 是 3("2.1" 的内部 ID)
- print(result)
- print()
- # 通过显示 ID 完成
- print("6. 完成目标(使用内部 ID)")
- result = goal_tool(tree, done="API 接口设计完成,定义了登录和注册端点")
- print(result)
- print()
- # 7. 测试 abandon
- print("7. Focus 到 4(2.2)并放弃")
- result = goal_tool(tree, focus="4")
- print(result)
- print()
- result = goal_tool(tree, abandon="发现需求变更,需要改用 OAuth")
- print(result)
- print()
- # 8. 添加新方案
- print("8. 添加新的实现方案")
- result = goal_tool(tree, add="实现 OAuth 认证")
- print(result)
- print()
- # 9. 查看最终状态
- print("9. 查看完整计划(包含废弃目标)")
- print(tree.to_prompt(include_abandoned=True))
- print()
- # 10. 查看过滤后的计划(默认不显示废弃目标)
- print("10. 查看过滤后的计划(默认)")
- print(tree.to_prompt())
- print()
- async def test_trace_store():
- """测试 TraceStore 的 GoalTree 和 Message 存储"""
- print("=" * 60)
- print("测试 2: TraceStore 存储功能")
- print("=" * 60)
- print()
- # 创建 TraceStore
- store = FileSystemTraceStore(base_path=".trace_test")
- # 1. 创建 Trace
- print("1. 创建 Trace")
- trace = Trace.create(
- mode="agent",
- task="测试任务"
- )
- await store.create_trace(trace)
- print(f" Trace ID: {trace.trace_id[:8]}...")
- print()
- # 2. 创建并保存 GoalTree
- print("2. 创建并保存 GoalTree")
- tree = GoalTree(mission="测试任务")
- tree.add_goals(["分析", "实现", "测试"])
- await store.update_goal_tree(trace.trace_id, tree)
- print(f" 添加了 {len(tree.goals)} 个目标")
- print()
- # 3. 添加 Messages
- print("3. 添加 Messages")
- # Focus 到第一个目标
- tree.focus("1")
- await store.update_goal_tree(trace.trace_id, tree)
- # 添加 assistant message
- msg1 = Message.create(
- trace_id=trace.trace_id,
- role="assistant",
- sequence=1,
- goal_id="1",
- content={"text": "开始分析代码", "tool_calls": [
- {
- "id": "call_1",
- "function": {
- "name": "read_file",
- "arguments": '{"path": "src/main.py"}'
- }
- }
- ]},
- tokens=100,
- cost=0.002
- )
- await store.add_message(msg1)
- print(f" Message 1: {msg1.description}")
- # 添加 tool message
- msg2 = Message.create(
- trace_id=trace.trace_id,
- role="tool",
- sequence=2,
- goal_id="1",
- tool_call_id="call_1",
- content={"tool_name": "read_file", "result": "文件内容..."},
- tokens=50,
- cost=0.001
- )
- await store.add_message(msg2)
- print(f" Message 2: {msg2.description}")
- print()
- # 4. 查看更新后的 GoalTree(stats 应该自动更新)
- print("4. 查看更新后的 GoalTree(含 stats)")
- updated_tree = await store.get_goal_tree(trace.trace_id)
- goal1 = updated_tree.find("1")
- print(f" Goal 1 stats:")
- print(f" - message_count: {goal1.self_stats.message_count}")
- print(f" - total_tokens: {goal1.self_stats.total_tokens}")
- print(f" - total_cost: ${goal1.self_stats.total_cost:.4f}")
- print()
- # 5. 添加子目标和 Message
- print("5. 添加子目标和 Message")
- updated_tree.add_goals(["读取配置", "解析代码"], parent_id="1")
- updated_tree.focus("4") # Focus 到第一个子目标
- await store.update_goal_tree(trace.trace_id, updated_tree)
- msg3 = Message.create(
- trace_id=trace.trace_id,
- role="assistant",
- sequence=3,
- goal_id="4",
- content={"text": "读取配置文件"},
- tokens=80,
- cost=0.0015
- )
- await store.add_message(msg3)
- print(f" 添加子目标 Message: {msg3.description}")
- print()
- # 6. 查看累计 stats(父节点应该包含子节点的统计)
- print("6. 查看累计 stats")
- updated_tree = await store.get_goal_tree(trace.trace_id)
- goal1 = updated_tree.find("1")
- print(f" Goal 1 cumulative stats:")
- print(f" - message_count: {goal1.cumulative_stats.message_count}")
- print(f" - total_tokens: {goal1.cumulative_stats.total_tokens}")
- print(f" - total_cost: ${goal1.cumulative_stats.total_cost:.4f}")
- print()
- # 7. 查看 Messages
- print("7. 查询 Messages")
- all_messages = await store.get_trace_messages(trace.trace_id)
- print(f" 总共 {len(all_messages)} 条 Messages")
- goal1_messages = await store.get_messages_by_goal(trace.trace_id, "1")
- print(f" Goal 1 的 Messages: {len(goal1_messages)} 条")
- print()
- # 8. 显示完整 GoalTree
- print("8. 完整 GoalTree")
- print(updated_tree.to_prompt())
- print()
- # 9. 测试级联完成
- print("9. 测试级联完成")
- updated_tree.focus("4")
- updated_tree.complete("4", "配置读取完成")
- updated_tree.focus("5")
- updated_tree.complete("5", "代码解析完成")
- # 检查父节点是否自动完成
- goal1 = updated_tree.find("1")
- print(f" Goal 1 status: {goal1.status}")
- print(f" Goal 1 summary: {goal1.summary}")
- print()
- print("✅ TraceStore 测试完成!")
- print(f" 数据保存在: .trace_test/{trace.trace_id[:8]}...")
- print()
- async def test_display_ids():
- """测试显示 ID 的生成"""
- print("=" * 60)
- print("测试 3: 显示 ID 生成")
- print("=" * 60)
- print()
- tree = GoalTree(mission="测试显示 ID")
- # 添加多层嵌套目标
- tree.add_goals(["A", "B", "C"])
- tree.focus("2")
- tree.add_goals(["B1", "B2"])
- tree.focus("4")
- tree.add_goals(["B1-1", "B1-2"])
- print("完整结构:")
- print(tree.to_prompt())
- print()
- # 测试 abandon 后的重新编号
- print("放弃 B1-1 后:")
- tree.focus("6")
- tree.abandon("6", "测试废弃")
- print(tree.to_prompt())
- print()
- print("包含废弃目标的完整视图:")
- print(tree.to_prompt(include_abandoned=True))
- print()
- async def main():
- """运行所有测试"""
- await test_basic_plan()
- await test_trace_store()
- await test_display_ids()
- print("=" * 60)
- print("所有测试完成!")
- print("=" * 60)
- if __name__ == "__main__":
- asyncio.run(main())
|