context.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. """
  2. 上下文工具 - 获取当前执行上下文
  3. 提供 get_current_context 工具,让 Agent 可以主动获取:
  4. - 当前计划(legacy 为 GoalTree,explicit 为 TaskLedger 读模型)
  5. - 焦点提醒
  6. - 协作者状态
  7. 框架也会在特定轮次自动调用此工具进行周期性上下文刷新。
  8. """
  9. from agent.orchestration.models import CompletionPolicy
  10. from agent.tools import tool, ToolResult, ToolContext
  11. @tool(
  12. description="获取当前执行上下文,包括计划状态、焦点提醒、协作者信息等。当你感到困惑或需要回顾当前任务状态时调用。",
  13. hidden_params=["context"],
  14. groups=["core"],
  15. capabilities=["read"],
  16. )
  17. async def get_current_context(
  18. context: ToolContext,
  19. ) -> ToolResult:
  20. """
  21. 获取当前执行上下文
  22. Returns:
  23. ToolResult: 包含当前模式的计划、焦点提醒和协作者状态
  24. """
  25. runner = context.get("runner")
  26. goal_tree = context.get("goal_tree")
  27. trace_id = context.get("trace_id")
  28. policy = CompletionPolicy(
  29. context.get("completion_policy", CompletionPolicy.LEGACY_AUTO.value)
  30. )
  31. if not runner:
  32. return ToolResult(
  33. title="❌ 无法获取上下文",
  34. output="Runner 未初始化",
  35. error="Runner not available"
  36. )
  37. # 获取 trace 对象
  38. trace = None
  39. if runner.trace_store and trace_id:
  40. trace = await runner.trace_store.get_trace(trace_id)
  41. task_context = ""
  42. if policy == CompletionPolicy.EXPLICIT_VALIDATION:
  43. if hasattr(runner, "_build_task_context"):
  44. task_context = await runner._build_task_context(trace)
  45. else:
  46. coordinator = context.get("coordinator")
  47. root_trace_id = context.get("root_trace_id")
  48. if coordinator and root_trace_id:
  49. task_context = await coordinator.task_context(root_trace_id)
  50. # 构建上下文内容(复用 runner 的周期注入格式)
  51. if hasattr(runner, '_build_context_injection'):
  52. context_content = runner._build_context_injection(
  53. trace,
  54. goal_tree,
  55. task_context=task_context,
  56. )
  57. else:
  58. if task_context:
  59. context_content = task_context
  60. elif goal_tree and goal_tree.goals:
  61. context_content = f"## Current Plan\n\n{goal_tree.to_prompt()}"
  62. else:
  63. context_content = "暂无计划信息"
  64. # Fallback 也检查 IM 通知
  65. im_config = trace.context.get("im_config") if trace else None
  66. if im_config:
  67. contact_id = im_config.get("contact_id")
  68. chat_id = im_config.get("chat_id")
  69. if contact_id and chat_id:
  70. try:
  71. from agent.tools.builtin.im import chat as im_chat
  72. notification = im_chat._notifications.get((contact_id, chat_id))
  73. if notification:
  74. count = notification.get("count", 0)
  75. senders = notification.get("from", [])
  76. senders_str = ", ".join(senders)
  77. context_content += (
  78. f"\n\n## IM 消息通知\n\n"
  79. f"你有 {count} 条新消息,来自: {senders_str}\n"
  80. f"使用 `im_receive_messages(contact_id=\"{contact_id}\", chat_id=\"{chat_id}\")` 查看消息内容。"
  81. )
  82. else:
  83. context_content += "\n\n## IM 消息通知\n\n暂无新消息"
  84. except (ImportError, AttributeError):
  85. pass
  86. if not context_content:
  87. context_content = "当前无需要刷新的上下文信息"
  88. return ToolResult(
  89. title="📋 当前执行上下文",
  90. output=context_content,
  91. long_term_memory="已刷新执行上下文",
  92. include_output_only_once=True,
  93. )