638 lines
17 KiB
Markdown
638 lines
17 KiB
Markdown
|
|
# Phase 10:高级编排(Advanced Orchestration)
|
|||
|
|
|
|||
|
|
日期:2026-04-04
|
|||
|
|
状态:待开始
|
|||
|
|
前置依赖:Phase 6-9(工具系统、Hook、插件、Skills)
|
|||
|
|
Demo参考:claw-code-main — assistant/, cli/, structuredIO.ts, remoteIO.ts
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 阶段目标
|
|||
|
|
|
|||
|
|
实现**高级 Agent 编排能力**,包括:
|
|||
|
|
- Team 多 Agent 协作
|
|||
|
|
- 远程/结构化传输
|
|||
|
|
- 高级会话管理
|
|||
|
|
- 后台任务系统
|
|||
|
|
|
|||
|
|
这是 claw-code 与 Jarvis 架构差距最大的地方,也是最复杂的功能。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. Team 多 Agent 协作
|
|||
|
|
|
|||
|
|
### 2.1 TeamLeader
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# backend/app/agents/team/leader.py
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class TeamMember:
|
|||
|
|
"""团队成员"""
|
|||
|
|
agent_id: str
|
|||
|
|
role: str
|
|||
|
|
capabilities: list[str]
|
|||
|
|
status: AgentStatus
|
|||
|
|
current_task: str | None = None
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class TeamTask:
|
|||
|
|
"""团队任务"""
|
|||
|
|
task_id: str
|
|||
|
|
description: str
|
|||
|
|
parent_id: str | None = None
|
|||
|
|
assignee: str | None = None
|
|||
|
|
status: TaskStatus
|
|||
|
|
dependencies: list[str] = field(default_factory=list)
|
|||
|
|
result: Any = None
|
|||
|
|
|
|||
|
|
class TeamLeader:
|
|||
|
|
"""
|
|||
|
|
团队领导者
|
|||
|
|
|
|||
|
|
负责协调多个 Agent 的协作
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def __init__(
|
|||
|
|
self,
|
|||
|
|
team_id: str,
|
|||
|
|
tool_registry: ToolRegistry,
|
|||
|
|
hook_manager: HookManager
|
|||
|
|
):
|
|||
|
|
self.team_id = team_id
|
|||
|
|
self.tool_registry = tool_registry
|
|||
|
|
self.hook_manager = hook_manager
|
|||
|
|
|
|||
|
|
self.members: dict[str, TeamMember] = {}
|
|||
|
|
self.tasks: dict[str, TeamTask] = {}
|
|||
|
|
self.task_queue: asyncio.Queue = asyncio.Queue()
|
|||
|
|
|
|||
|
|
async def create_team(
|
|||
|
|
self,
|
|||
|
|
config: TeamConfig
|
|||
|
|
) -> str:
|
|||
|
|
"""创建团队"""
|
|||
|
|
self.team_id = config.team_id
|
|||
|
|
|
|||
|
|
# 创建团队成员
|
|||
|
|
for member_config in config.members:
|
|||
|
|
member = TeamMember(
|
|||
|
|
agent_id=member_config.agent_id,
|
|||
|
|
role=member_config.role,
|
|||
|
|
capabilities=member_config.capabilities,
|
|||
|
|
status=AgentStatus.IDLE
|
|||
|
|
)
|
|||
|
|
self.members[member.agent_id] = member
|
|||
|
|
|
|||
|
|
return self.team_id
|
|||
|
|
|
|||
|
|
async def assign_task(
|
|||
|
|
self,
|
|||
|
|
task: TeamTask
|
|||
|
|
) -> str:
|
|||
|
|
"""分配任务"""
|
|||
|
|
self.tasks[task.task_id] = task
|
|||
|
|
|
|||
|
|
# 找到最合适的成员
|
|||
|
|
assignee = await self._find_assignee(task)
|
|||
|
|
|
|||
|
|
if assignee:
|
|||
|
|
task.assignee = assignee.agent_id
|
|||
|
|
assignee.current_task = task.task_id
|
|||
|
|
assignee.status = AgentStatus.WORKING
|
|||
|
|
|
|||
|
|
return task.task_id
|
|||
|
|
|
|||
|
|
async def _find_assignee(
|
|||
|
|
self,
|
|||
|
|
task: TeamTask
|
|||
|
|
) -> TeamMember | None:
|
|||
|
|
"""找到最适合执行任务的成员"""
|
|||
|
|
# 过滤掉忙碌的成员
|
|||
|
|
available = [
|
|||
|
|
m for m in self.members.values()
|
|||
|
|
if m.status == AgentStatus.IDLE
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
if not available:
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
# 按能力匹配
|
|||
|
|
for cap in task.required_capabilities:
|
|||
|
|
matches = [m for m in available if cap in m.capabilities]
|
|||
|
|
if matches:
|
|||
|
|
return matches[0]
|
|||
|
|
|
|||
|
|
return available[0] if available else None
|
|||
|
|
|
|||
|
|
async def broadcast_task(
|
|||
|
|
self,
|
|||
|
|
description: str,
|
|||
|
|
required_capabilities: list[str]
|
|||
|
|
) -> list[str]:
|
|||
|
|
"""广播任务给所有符合条件的成员"""
|
|||
|
|
task_ids = []
|
|||
|
|
|
|||
|
|
for member in self.members.values():
|
|||
|
|
if member.status != AgentStatus.IDLE:
|
|||
|
|
continue
|
|||
|
|
|
|||
|
|
# 检查能力匹配
|
|||
|
|
if not any(cap in member.capabilities for cap in required_capabilities):
|
|||
|
|
continue
|
|||
|
|
|
|||
|
|
# 创建任务
|
|||
|
|
task = TeamTask(
|
|||
|
|
task_id=generate_id(),
|
|||
|
|
description=description,
|
|||
|
|
assignee=member.agent_id,
|
|||
|
|
status=TaskStatus.PENDING
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
await self.assign_task(task)
|
|||
|
|
task_ids.append(task.task_id)
|
|||
|
|
|
|||
|
|
return task_ids
|
|||
|
|
|
|||
|
|
async def collect_results(
|
|||
|
|
self,
|
|||
|
|
task_ids: list[str],
|
|||
|
|
timeout: float = 300
|
|||
|
|
) -> dict[str, Any]:
|
|||
|
|
"""收集任务结果"""
|
|||
|
|
results = {}
|
|||
|
|
start_time = time.time()
|
|||
|
|
|
|||
|
|
while len(results) < len(task_ids):
|
|||
|
|
if time.time() - start_time > timeout:
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
for task_id in task_ids:
|
|||
|
|
if task_id in results:
|
|||
|
|
continue
|
|||
|
|
|
|||
|
|
task = self.tasks.get(task_id)
|
|||
|
|
if task and task.status == TaskStatus.COMPLETED:
|
|||
|
|
results[task_id] = task.result
|
|||
|
|
|
|||
|
|
await asyncio.sleep(0.1)
|
|||
|
|
|
|||
|
|
return results
|
|||
|
|
|
|||
|
|
async def get_team_status(self) -> TeamStatus:
|
|||
|
|
"""获取团队状态"""
|
|||
|
|
return TeamStatus(
|
|||
|
|
team_id=self.team_id,
|
|||
|
|
members={
|
|||
|
|
agent_id: {
|
|||
|
|
"role": m.role,
|
|||
|
|
"status": m.status.value,
|
|||
|
|
"current_task": m.current_task
|
|||
|
|
}
|
|||
|
|
for agent_id, m in self.members.items()
|
|||
|
|
},
|
|||
|
|
active_tasks=sum(1 for t in self.tasks.values() if t.status == TaskStatus.PENDING),
|
|||
|
|
completed_tasks=sum(1 for t in self.tasks.values() if t.status == TaskStatus.COMPLETED)
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 远程传输层
|
|||
|
|
|
|||
|
|
### 3.1 StructuredIO
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# backend/app/agents/transport/structured_io.py
|
|||
|
|
|
|||
|
|
class StructuredIO:
|
|||
|
|
"""
|
|||
|
|
结构化 IO
|
|||
|
|
|
|||
|
|
支持结构化的输入输出格式
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
async def send_response(
|
|||
|
|
self,
|
|||
|
|
channel: str,
|
|||
|
|
data: dict
|
|||
|
|
):
|
|||
|
|
"""发送结构化响应"""
|
|||
|
|
message = {
|
|||
|
|
"channel": channel,
|
|||
|
|
"type": "structured",
|
|||
|
|
"data": data,
|
|||
|
|
"timestamp": datetime.now().isoformat()
|
|||
|
|
}
|
|||
|
|
await self.transport.send(message)
|
|||
|
|
|
|||
|
|
async def send_event(
|
|||
|
|
self,
|
|||
|
|
event_type: str,
|
|||
|
|
payload: dict
|
|||
|
|
):
|
|||
|
|
"""发送事件"""
|
|||
|
|
message = {
|
|||
|
|
"type": "event",
|
|||
|
|
"event": event_type,
|
|||
|
|
"payload": payload,
|
|||
|
|
"timestamp": datetime.now().isoformat()
|
|||
|
|
}
|
|||
|
|
await self.transport.send(message)
|
|||
|
|
|
|||
|
|
async def send_tool_call(
|
|||
|
|
self,
|
|||
|
|
tool_name: str,
|
|||
|
|
arguments: dict,
|
|||
|
|
call_id: str
|
|||
|
|
):
|
|||
|
|
"""发送工具调用"""
|
|||
|
|
message = {
|
|||
|
|
"type": "tool_call",
|
|||
|
|
"tool": tool_name,
|
|||
|
|
"args": arguments,
|
|||
|
|
"call_id": call_id,
|
|||
|
|
"timestamp": datetime.now().isoformat()
|
|||
|
|
}
|
|||
|
|
await self.transport.send(message)
|
|||
|
|
|
|||
|
|
async def receive(self) -> dict:
|
|||
|
|
"""接收消息"""
|
|||
|
|
raw = await self.transport.receive()
|
|||
|
|
return self._parse(raw)
|
|||
|
|
|
|||
|
|
def _parse(self, raw: bytes) -> dict:
|
|||
|
|
"""解析消息"""
|
|||
|
|
# 支持 JSON 和流式格式
|
|||
|
|
pass
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.2 RemoteTransport
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# backend/app/agents/transport/remote.py
|
|||
|
|
|
|||
|
|
class RemoteTransport:
|
|||
|
|
"""
|
|||
|
|
远程传输
|
|||
|
|
|
|||
|
|
支持远程 Agent 通信
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def __init__(
|
|||
|
|
self,
|
|||
|
|
endpoint: str,
|
|||
|
|
auth_token: str
|
|||
|
|
):
|
|||
|
|
self.endpoint = endpoint
|
|||
|
|
self.auth_token = auth_token
|
|||
|
|
self.websocket: WebSocket | None = None
|
|||
|
|
|
|||
|
|
async def connect(self):
|
|||
|
|
"""建立连接"""
|
|||
|
|
self.websocket = await websockets.connect(
|
|||
|
|
self.endpoint,
|
|||
|
|
extra_headers={"Authorization": f"Bearer {self.auth_token}"}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
async def send(self, message: dict):
|
|||
|
|
"""发送消息"""
|
|||
|
|
if not self.websocket:
|
|||
|
|
await self.connect()
|
|||
|
|
|
|||
|
|
await self.websocket.send(json.dumps(message))
|
|||
|
|
|
|||
|
|
async def receive(self) -> dict:
|
|||
|
|
"""接收消息"""
|
|||
|
|
if not self.websocket:
|
|||
|
|
await self.connect()
|
|||
|
|
|
|||
|
|
raw = await self.websocket.recv()
|
|||
|
|
return json.loads(raw)
|
|||
|
|
|
|||
|
|
async def close(self):
|
|||
|
|
"""关闭连接"""
|
|||
|
|
if self.websocket:
|
|||
|
|
await self.websocket.close()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 高级会话管理
|
|||
|
|
|
|||
|
|
### 4.1 AgentSession
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# backend/app/agents/session/manager.py
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class SessionConfig:
|
|||
|
|
"""会话配置"""
|
|||
|
|
session_id: str
|
|||
|
|
user_id: str
|
|||
|
|
parent_session_id: str | None = None
|
|||
|
|
|
|||
|
|
max_rounds: int = 50
|
|||
|
|
max_tokens: int = 100000
|
|||
|
|
timeout: float = 3600
|
|||
|
|
|
|||
|
|
isolation_mode: IsolationMode = IsolationMode.NONE
|
|||
|
|
|
|||
|
|
capabilities: list[str] = field(default_factory=list)
|
|||
|
|
permissions: list[str] = field(default_factory=list)
|
|||
|
|
|
|||
|
|
class AgentSession:
|
|||
|
|
"""
|
|||
|
|
Agent 会话
|
|||
|
|
|
|||
|
|
管理会话的生命周期和状态
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def __init__(
|
|||
|
|
self,
|
|||
|
|
config: SessionConfig,
|
|||
|
|
agent_runtime: AgentRuntime
|
|||
|
|
):
|
|||
|
|
self.config = config
|
|||
|
|
self.agent_runtime = agent_runtime
|
|||
|
|
|
|||
|
|
self.state: SessionState = SessionState.INITIALIZING
|
|||
|
|
self.round_count: int = 0
|
|||
|
|
self.token_count: int = 0
|
|||
|
|
|
|||
|
|
self.messages: list[Message] = []
|
|||
|
|
self.tool_calls: list[ToolCall] = []
|
|||
|
|
self.events: list[SessionEvent] = []
|
|||
|
|
|
|||
|
|
async def initialize(self) -> str:
|
|||
|
|
"""初始化会话"""
|
|||
|
|
# 创建会话记录
|
|||
|
|
await self._create_session_record()
|
|||
|
|
|
|||
|
|
# 初始化隔离环境
|
|||
|
|
if self.config.isolation_mode != IsolationMode.NONE:
|
|||
|
|
await self._initialize_isolation()
|
|||
|
|
|
|||
|
|
self.state = SessionState.ACTIVE
|
|||
|
|
return self.config.session_id
|
|||
|
|
|
|||
|
|
async def process_message(
|
|||
|
|
self,
|
|||
|
|
message: str
|
|||
|
|
) -> Response:
|
|||
|
|
"""处理消息"""
|
|||
|
|
if self.state != SessionState.ACTIVE:
|
|||
|
|
raise SessionStateError(f"Session not active: {self.state}")
|
|||
|
|
|
|||
|
|
# 检查轮次限制
|
|||
|
|
self.round_count += 1
|
|||
|
|
if self.round_count > self.config.max_rounds:
|
|||
|
|
raise SessionLimitError("Max rounds exceeded")
|
|||
|
|
|
|||
|
|
# 处理消息
|
|||
|
|
response = await self.agent_runtime.process(
|
|||
|
|
message,
|
|||
|
|
context=self._get_context()
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 记录
|
|||
|
|
self.messages.append(Message(role="user", content=message))
|
|||
|
|
self.messages.append(Message(role="assistant", content=response.content))
|
|||
|
|
|
|||
|
|
# 更新 token 计数
|
|||
|
|
self.token_count += response.usage.total_tokens
|
|||
|
|
|
|||
|
|
return response
|
|||
|
|
|
|||
|
|
async def spawn_child_session(
|
|||
|
|
self,
|
|||
|
|
config: SessionConfig
|
|||
|
|
) -> "AgentSession":
|
|||
|
|
"""创建子会话"""
|
|||
|
|
child_config = SessionConfig(
|
|||
|
|
**{
|
|||
|
|
**asdict(config),
|
|||
|
|
"parent_session_id": self.config.session_id
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
child_session = AgentSession(
|
|||
|
|
config=child_config,
|
|||
|
|
agent_runtime=self.agent_runtime
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
await child_session.initialize()
|
|||
|
|
|
|||
|
|
return child_session
|
|||
|
|
|
|||
|
|
async def get_session_summary(self) -> SessionSummary:
|
|||
|
|
"""获取会话摘要"""
|
|||
|
|
return SessionSummary(
|
|||
|
|
session_id=self.config.session_id,
|
|||
|
|
user_id=self.config.user_id,
|
|||
|
|
round_count=self.round_count,
|
|||
|
|
token_count=self.token_count,
|
|||
|
|
message_count=len(self.messages),
|
|||
|
|
tool_call_count=len(self.tool_calls),
|
|||
|
|
duration_seconds=(datetime.now() - self.start_time).total_seconds(),
|
|||
|
|
state=self.state.value
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
async def persist(self):
|
|||
|
|
"""持久化会话"""
|
|||
|
|
await self.session_service.save(SessionRecord(
|
|||
|
|
session_id=self.config.session_id,
|
|||
|
|
user_id=self.config.user_id,
|
|||
|
|
state=self.state.value,
|
|||
|
|
round_count=self.round_count,
|
|||
|
|
token_count=self.token_count,
|
|||
|
|
messages=self.messages,
|
|||
|
|
tool_calls=self.tool_calls,
|
|||
|
|
events=self.events
|
|||
|
|
))
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 后台任务系统
|
|||
|
|
|
|||
|
|
### 5.1 BackgroundTaskManager
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# backend/app/agents/background/manager.py
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class BackgroundTask:
|
|||
|
|
"""后台任务"""
|
|||
|
|
task_id: str
|
|||
|
|
description: str
|
|||
|
|
agent_config: dict
|
|||
|
|
schedule: str | None = None # cron expression
|
|||
|
|
|
|||
|
|
status: BackgroundTaskStatus
|
|||
|
|
created_at: datetime
|
|||
|
|
started_at: datetime | None = None
|
|||
|
|
completed_at: datetime | None = None
|
|||
|
|
|
|||
|
|
result: Any = None
|
|||
|
|
error: str | None = None
|
|||
|
|
|
|||
|
|
class BackgroundTaskManager:
|
|||
|
|
"""
|
|||
|
|
后台任务管理器
|
|||
|
|
|
|||
|
|
管理长期运行的 Agent 任务
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def __init__(
|
|||
|
|
self,
|
|||
|
|
task_store: TaskStore,
|
|||
|
|
agent_factory: AgentFactory
|
|||
|
|
):
|
|||
|
|
self.task_store = task_store
|
|||
|
|
self.agent_factory = agent_factory
|
|||
|
|
|
|||
|
|
self._running_tasks: dict[str, asyncio.Task] = {}
|
|||
|
|
self._scheduler = AsyncIOScheduler()
|
|||
|
|
|
|||
|
|
async def submit_task(
|
|||
|
|
self,
|
|||
|
|
task: BackgroundTask
|
|||
|
|
) -> str:
|
|||
|
|
"""提交后台任务"""
|
|||
|
|
# 保存任务记录
|
|||
|
|
await self.task_store.save(task)
|
|||
|
|
|
|||
|
|
# 如果有定时计划,调度任务
|
|||
|
|
if task.schedule:
|
|||
|
|
self._scheduler.add_job(
|
|||
|
|
self._execute_task,
|
|||
|
|
CronTrigger.from_crontab(task.schedule),
|
|||
|
|
args=[task.task_id]
|
|||
|
|
)
|
|||
|
|
else:
|
|||
|
|
# 立即执行
|
|||
|
|
asyncio.create_task(self._execute_task(task.task_id))
|
|||
|
|
|
|||
|
|
return task.task_id
|
|||
|
|
|
|||
|
|
async def _execute_task(self, task_id: str):
|
|||
|
|
"""执行任务"""
|
|||
|
|
task = await self.task_store.get(task_id)
|
|||
|
|
if not task:
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
self._running_tasks[task_id] = asyncio.current_task()
|
|||
|
|
|
|||
|
|
task.status = BackgroundTaskStatus.RUNNING
|
|||
|
|
task.started_at = datetime.now()
|
|||
|
|
await self.task_store.save(task)
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
# 创建 Agent
|
|||
|
|
agent = await self.agent_factory.create(task.agent_config)
|
|||
|
|
|
|||
|
|
# 执行
|
|||
|
|
result = await agent.run()
|
|||
|
|
|
|||
|
|
task.status = BackgroundTaskStatus.COMPLETED
|
|||
|
|
task.result = result
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
task.status = BackgroundTaskStatus.FAILED
|
|||
|
|
task.error = str(e)
|
|||
|
|
|
|||
|
|
finally:
|
|||
|
|
task.completed_at = datetime.now()
|
|||
|
|
await self.task_store.save(task)
|
|||
|
|
|
|||
|
|
if task_id in self._running_tasks:
|
|||
|
|
del self._running_tasks[task_id]
|
|||
|
|
|
|||
|
|
async def cancel_task(self, task_id: str) -> bool:
|
|||
|
|
"""取消任务"""
|
|||
|
|
if task_id in self._running_tasks:
|
|||
|
|
self._running_tasks[task_id].cancel()
|
|||
|
|
del self._running_tasks[task_id]
|
|||
|
|
|
|||
|
|
task = await self.task_store.get(task_id)
|
|||
|
|
if task:
|
|||
|
|
task.status = BackgroundTaskStatus.CANCELLED
|
|||
|
|
await self.task_store.save(task)
|
|||
|
|
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
async def get_task_status(self, task_id: str) -> BackgroundTask | None:
|
|||
|
|
"""获取任务状态"""
|
|||
|
|
return await self.task_store.get(task_id)
|
|||
|
|
|
|||
|
|
async def list_tasks(
|
|||
|
|
self,
|
|||
|
|
user_id: str,
|
|||
|
|
status: BackgroundTaskStatus | None = None
|
|||
|
|
) -> list[BackgroundTask]:
|
|||
|
|
"""列出任务"""
|
|||
|
|
return await self.task_store.list(user_id, status)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. 文件结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
backend/app/agents/
|
|||
|
|
├── team/ # Team 协作
|
|||
|
|
│ ├── __init__.py
|
|||
|
|
│ ├── leader.py # 团队领导
|
|||
|
|
│ ├── member.py # 团队成员
|
|||
|
|
│ └── task.py # 团队任务
|
|||
|
|
│
|
|||
|
|
├── transport/ # 传输层
|
|||
|
|
│ ├── __init__.py
|
|||
|
|
│ ├── structured_io.py # 结构化 IO
|
|||
|
|
│ ├── remote.py # 远程传输
|
|||
|
|
│ └── websocket.py # WebSocket 传输
|
|||
|
|
│
|
|||
|
|
├── session/ # 会话管理
|
|||
|
|
│ ├── __init__.py
|
|||
|
|
│ ├── manager.py # 会话管理器
|
|||
|
|
│ ├── context.py # 会话上下文
|
|||
|
|
│ └── persistence.py # 会话持久化
|
|||
|
|
│
|
|||
|
|
├── background/ # 后台任务
|
|||
|
|
│ ├── __init__.py
|
|||
|
|
│ ├── manager.py # 后台任务管理器
|
|||
|
|
│ ├── scheduler.py # 任务调度
|
|||
|
|
│ └── executor.py # 任务执行器
|
|||
|
|
│
|
|||
|
|
└── coordinator.py # 协调整合(现有)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. 验收标准
|
|||
|
|
|
|||
|
|
| 检查点 | 标准 |
|
|||
|
|
|--------|------|
|
|||
|
|
| Team 创建 | 可以创建和管理 Agent 团队 |
|
|||
|
|
| Team 任务分配 | 任务能正确分配给合适的成员 |
|
|||
|
|
| Team 结果收集 | 能收集和聚合多成员的结果 |
|
|||
|
|
| 结构化 IO | 支持结构化的输入输出格式 |
|
|||
|
|
| 远程传输 | 支持远程 Agent 通信 |
|
|||
|
|
| 会话管理 | 支持复杂的会话层级和状态管理 |
|
|||
|
|
| 后台任务 | 支持定时和异步后台任务 |
|
|||
|
|
| 子会话 | 支持从父会话创建子会话 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. Demo 借鉴
|
|||
|
|
|
|||
|
|
| claw-code | Jarvis 对应 |
|
|||
|
|
|-----------|------------|
|
|||
|
|
| `src/assistant/sessionHistory.ts` | `session/manager.py` |
|
|||
|
|
| `src/cli/structuredIO.ts` | `transport/structured_io.py` |
|
|||
|
|
| `src/cli/remoteIO.ts` | `transport/remote.py` |
|
|||
|
|
| `src/cli/transports/*` | `transport/` |
|
|||
|
|
| Team/* tools | `team/leader.py` |
|
|||
|
|
| Background tasks | `background/manager.py` |
|