"""把组织包装成 cabinet 可调用的高阶 tool。 每个组织 → 一个 ``dispatch_to_(task_description)`` 工具。 ConsciousnessNode/ControlNode 通过这个工具向部门派单,等待部门完成。 """ from __future__ import annotations from typing import Callable, Dict def make_dispatch_tool(org_name: str, display_name: str, description: str) -> Callable: """生成对应组织的 dispatch tool。 工具签名故意保持简单:只收一个自然语言任务描述,cabinet 不需要懂部门内部 capability 划分;部门内部 ReAct 自己决定怎么干。 """ tool_name = f"dispatch_to_{org_name}" desc_text = description or f"把任务派给{display_name or org_name}部门,由部门内部多 agent 协作完成。" async def _impl(task_description: str) -> str: from kilostar.utils.ray_hook import ray_actor_hook actor_name = f"org_{org_name}" actor = ray_actor_hook(actor_name) target = getattr(actor, actor_name) result = await target.dispatch.remote(task_description, {}) if result.get("status") == "completed": return str(result.get("result") or "") return f"[{org_name} 任务失败] {result.get('error') or 'unknown'}" _impl.__name__ = tool_name _impl.__doc__ = ( f"{desc_text}\n\n" "Args:\n" " task_description: 用自然语言描述要部门完成的任务。\n\n" "Returns:\n" " 部门交付的结果文本,失败时返回错误说明。\n" ) return _impl def collect_dispatch_tools(org_specs: Dict[str, Dict[str, str]]) -> Dict[str, Callable]: """根据 ``{org_name: {"display_name": ..., "description": ...}}`` 批量生成。""" return { f"dispatch_to_{name}": make_dispatch_tool( name, spec.get("display_name", ""), spec.get("description", ""), ) for name, spec in org_specs.items() }