|
|
@@ -8,11 +8,15 @@ from typing import Optional, List, TYPE_CHECKING
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
from agent.goal.models import GoalTree
|
|
|
+ from agent.execution.protocols import TraceStore
|
|
|
|
|
|
|
|
|
-def goal_tool(
|
|
|
+async def goal_tool(
|
|
|
tree: "GoalTree",
|
|
|
+ store: Optional["TraceStore"] = None,
|
|
|
+ trace_id: Optional[str] = None,
|
|
|
add: Optional[str] = None,
|
|
|
+ reason: Optional[str] = None,
|
|
|
done: Optional[str] = None,
|
|
|
abandon: Optional[str] = None,
|
|
|
focus: Optional[str] = None,
|
|
|
@@ -22,7 +26,10 @@ def goal_tool(
|
|
|
|
|
|
Args:
|
|
|
tree: GoalTree 实例
|
|
|
+ store: TraceStore 实例(用于推送事件)
|
|
|
+ trace_id: 当前 Trace ID
|
|
|
add: 添加目标(逗号分隔多个)。添加到当前 focus 的 goal 下作为子目标。
|
|
|
+ reason: 创建理由(逗号分隔多个,与 add 一一对应)
|
|
|
done: 完成当前目标,值为 summary
|
|
|
abandon: 放弃当前目标,值为原因
|
|
|
focus: 切换焦点到指定内部 id
|
|
|
@@ -40,6 +47,13 @@ def goal_tool(
|
|
|
display_id = tree._generate_display_id(goal)
|
|
|
changes.append(f"已放弃: {display_id}. {goal.description}")
|
|
|
|
|
|
+ # 推送事件
|
|
|
+ if store and trace_id:
|
|
|
+ print(f"[DEBUG] goal_tool: calling store.update_goal for abandon: goal_id={goal.id}")
|
|
|
+ await store.update_goal(trace_id, goal.id, status="abandoned", summary=abandon)
|
|
|
+ else:
|
|
|
+ print(f"[DEBUG] goal_tool: skip event push (store={store}, trace_id={trace_id})")
|
|
|
+
|
|
|
# 2. 处理 done
|
|
|
if done is not None:
|
|
|
if not tree.current_id:
|
|
|
@@ -48,6 +62,13 @@ def goal_tool(
|
|
|
display_id = tree._generate_display_id(goal)
|
|
|
changes.append(f"已完成: {display_id}. {goal.description}")
|
|
|
|
|
|
+ # 推送事件
|
|
|
+ if store and trace_id:
|
|
|
+ print(f"[DEBUG] goal_tool: calling store.update_goal for done: goal_id={goal.id}")
|
|
|
+ await store.update_goal(trace_id, goal.id, status="completed", summary=done)
|
|
|
+ else:
|
|
|
+ print(f"[DEBUG] goal_tool: skip event push (store={store}, trace_id={trace_id})")
|
|
|
+
|
|
|
# 检查是否有级联完成的父目标
|
|
|
if goal.parent_id:
|
|
|
parent = tree.find(goal.parent_id)
|
|
|
@@ -80,9 +101,25 @@ def goal_tool(
|
|
|
if add is not None:
|
|
|
descriptions = [d.strip() for d in add.split(",") if d.strip()]
|
|
|
if descriptions:
|
|
|
+ # 解析 reasons(与 descriptions 一一对应)
|
|
|
+ reasons = None
|
|
|
+ if reason:
|
|
|
+ reasons = [r.strip() for r in reason.split(",")]
|
|
|
+ # 如果 reasons 数量少于 descriptions,补空字符串
|
|
|
+ while len(reasons) < len(descriptions):
|
|
|
+ reasons.append("")
|
|
|
+
|
|
|
# 添加到当前焦点下(如果有焦点),否则添加到顶层
|
|
|
parent_id = tree.current_id
|
|
|
- new_goals = tree.add_goals(descriptions, parent_id=parent_id)
|
|
|
+ new_goals = tree.add_goals(descriptions, reasons=reasons, parent_id=parent_id)
|
|
|
+
|
|
|
+ # 推送事件
|
|
|
+ if store and trace_id:
|
|
|
+ print(f"[DEBUG] goal_tool: calling store.add_goal for {len(new_goals)} new goals")
|
|
|
+ for goal in new_goals:
|
|
|
+ await store.add_goal(trace_id, goal)
|
|
|
+ else:
|
|
|
+ print(f"[DEBUG] goal_tool: skip event push (store={store}, trace_id={trace_id})")
|
|
|
|
|
|
if parent_id:
|
|
|
parent_display_id = tree._generate_display_id(tree.find(parent_id))
|
|
|
@@ -116,18 +153,20 @@ def create_goal_tool_schema() -> dict:
|
|
|
"description": """管理执行计划。
|
|
|
|
|
|
- add: 添加目标(逗号分隔多个)。添加到当前 focus 的 goal 下作为子目标。
|
|
|
+- reason: 创建理由(逗号分隔多个,与 add 一一对应)。说明为什么要做这些目标。
|
|
|
- done: 完成当前目标,值为 summary
|
|
|
- abandon: 放弃当前目标,值为原因(会触发 context 压缩)
|
|
|
- focus: 切换焦点到指定 id(可以是内部 ID 或显示 ID)
|
|
|
|
|
|
示例:
|
|
|
-- goal(add="分析代码, 实现功能, 测试") - 添加顶层目标
|
|
|
-- goal(focus="2", add="设计接口, 实现代码") - 切换到目标2,并添加子目标
|
|
|
+- goal(add="分析代码, 实现功能, 测试", reason="了解现有结构, 完成需求, 确保质量") - 添加顶层目标
|
|
|
+- goal(focus="2", add="设计接口, 实现代码", reason="明确API规范, 编写核心逻辑") - 切换到目标2,并添加子目标
|
|
|
- goal(done="发现用户模型在 models/user.py") - 完成当前目标
|
|
|
-- goal(abandon="方案A需要Redis,环境没有", add="实现方案B") - 放弃当前并添加新目标
|
|
|
+- goal(abandon="方案A需要Redis,环境没有", add="实现方案B", reason="使用现有技术栈") - 放弃当前并添加新目标
|
|
|
|
|
|
注意:内部 ID 是纯自增数字("1", "2", "3"),显示 ID 是带层级的("1", "2.1", "2.2")。
|
|
|
focus 参数可以使用任意格式的 ID。
|
|
|
+reason 应该与 add 的目标数量一致,如果数量不一致,缺少的 reason 将为空。
|
|
|
""",
|
|
|
"parameters": {
|
|
|
"type": "object",
|
|
|
@@ -136,6 +175,10 @@ focus 参数可以使用任意格式的 ID。
|
|
|
"type": "string",
|
|
|
"description": "添加目标(逗号分隔多个)。添加到当前 focus 的 goal 下作为子目标。"
|
|
|
},
|
|
|
+ "reason": {
|
|
|
+ "type": "string",
|
|
|
+ "description": "创建理由(逗号分隔多个,与 add 一一对应)。说明为什么要做这些目标。"
|
|
|
+ },
|
|
|
"done": {
|
|
|
"type": "string",
|
|
|
"description": "完成当前目标,值为 summary"
|