第一次提交

This commit is contained in:
2026-03-13 16:40:08 +08:00
commit 0a49bcfb2d
277 changed files with 61890 additions and 0 deletions

View File

@ -0,0 +1,105 @@
"""spawn 工具:用于把任务委派给后台 agent。"""
from typing import TYPE_CHECKING, Any
from nanobot.agent.tools.base import Tool
if TYPE_CHECKING:
from nanobot.agent.delegation import DelegationManager
class SpawnTool(Tool):
"""
后台委派工具。
作用:
1. 把耗时/可并行的任务委派给 DelegationManager
2. 目标可以是本地 agent、A2A 远端 agent 或 agent group
3. 后台任务异步执行,不阻塞当前对话回合。
"""
def __init__(self, manager: "DelegationManager"):
# manager 负责真正创建 asyncio 后台任务并管理生命周期。
self._manager = manager
# 默认来源会话CLI 直连场景)。实际会在每轮由 loop._set_tool_context 覆盖。
self._origin_channel = "cli"
self._origin_chat_id = "direct"
self._announce_via_bus = True
def set_context(self, channel: str, chat_id: str, announce_via_bus: bool = True) -> None:
"""设置后台委派结果回传的目标会话。"""
# 委派任务完成后并不会直接给用户发消息,
# 而是把结果发回这里记录的 originchannel/chat_id对应会话。
self._origin_channel = channel
self._origin_chat_id = chat_id
self._announce_via_bus = announce_via_bus
@property
def name(self) -> str:
# 暴露给 LLM 的工具名;模型会用这个名字发起 function call。
return "spawn"
@property
def description(self) -> str:
# 给模型看的能力描述,强调“后台执行 + 完成后回报”语义。
return (
"Delegate a task to a background agent. "
"Use this for complex or time-consuming work that can run independently. "
"You can target a specific agent, a group of agents, or let the system choose. "
"The delegated agent(s) will report back when done."
)
@property
def parameters(self) -> dict[str, Any]:
# OpenAI function schema定义模型可传入的参数结构。
return {
"type": "object",
"properties": {
"task": {
"type": "string",
"description": "The task for the delegated agent to complete",
},
"label": {
"type": "string",
"description": "Optional short label for the task (for display)",
},
"target": {
"type": "string",
"description": "Optional agent ID or name for a single target",
},
"targets": {
"type": "array",
"items": {"type": "string"},
"description": "Optional list of agent IDs/names for a group task",
},
"strategy": {
"type": "string",
"enum": ["auto", "local", "plugin", "a2a", "group"],
"description": "Routing strategy. Default is auto.",
},
},
"required": ["task"],
}
async def execute(
self,
task: str,
label: str | None = None,
target: str | None = None,
targets: list[str] | None = None,
strategy: str = "auto",
**kwargs: Any,
) -> str:
"""创建并启动一个后台委派任务。"""
# 这里仅负责转发请求,不在本工具内执行实际任务逻辑。
# 返回值是“已启动”状态文本,真正结果稍后通过主消息总线回传。
return await self._manager.dispatch(
task=task,
label=label,
target=target,
targets=targets,
strategy=strategy,
origin_channel=self._origin_channel,
origin_chat_id=self._origin_chat_id,
announce_via_bus=self._announce_via_bus,
)