feat: add close_sub_agent tool

This commit is contained in:
JOJO 2025-11-15 16:51:13 +08:00
parent 1f105e7497
commit 3100643534
3 changed files with 78 additions and 0 deletions

View File

@ -1369,6 +1369,20 @@ class MainTerminal:
}
}
},
{
"type": "function",
"function": {
"name": "close_sub_agent",
"description": "强制关闭指定子智能体,适用于长时间无响应、超时或卡死的任务。使用前请确认必要的日志/文件已保留,操作会立即终止该任务。",
"parameters": {
"type": "object",
"properties": {
"task_id": {"type": "string", "description": "子智能体任务ID"},
"agent_id": {"type": "integer", "description": "子智能体编号1~5若缺少 task_id 可用"}
}
}
}
},
{
"type": "function",
"function": {
@ -1991,6 +2005,12 @@ class MainTerminal:
)
self._record_sub_agent_message(result.get("system_message"), result.get("task_id"), inline=False)
elif tool_name == "close_sub_agent":
result = self.sub_agent_manager.terminate_sub_agent(
task_id=arguments.get("task_id"),
agent_id=arguments.get("agent_id")
)
else:
result = {"success": False, "error": f"未知工具: {tool_name}"}

View File

@ -206,6 +206,31 @@ class SubAgentManager:
self._save_state()
return finalize_result
def terminate_sub_agent(
self,
*,
task_id: Optional[str] = None,
agent_id: Optional[int] = None,
) -> Dict:
"""强制关闭指定子智能体。"""
task = self._select_task(task_id, agent_id)
if not task:
return {"success": False, "error": "未找到对应的子智能体任务"}
task_id = task["task_id"]
response = self._call_service("POST", f"/tasks/{task_id}/terminate", timeout=10)
if response.get("success"):
task["status"] = "terminated"
task["final_result"] = {
"success": False,
"status": "terminated",
"task_id": task_id,
"agent_id": task.get("agent_id"),
"message": response.get("message") or "子智能体已被强制关闭。",
}
self._save_state()
return response
# ------------------------------------------------------------------
# 内部工具方法
# ------------------------------------------------------------------

View File

@ -2132,6 +2132,32 @@ def stop_sub_agent_task(task_id: str) -> Dict[str, Any]:
return {"success": True, "message": "已发送停止指令"}
def force_terminate_sub_agent(task_id: str) -> Dict[str, Any]:
cleanup_inactive_sub_agent_tasks()
task = sub_agent_tasks.get(task_id)
if not task:
return {"success": False, "error": "任务不存在"}
client_sid = task.get("last_client_sid")
if client_sid and client_sid in stop_flags:
stop_flags[client_sid]["stop"] = True
terminal = sub_agent_terminals.get(task_id)
if terminal:
try:
reset_system_state(terminal)
except Exception:
pass
update_sub_agent_task(task_id, status="terminated")
broadcast_sub_agent_event(task_id, "sub_agent_status", {
"status": "terminated",
"message": "子智能体已强制关闭"
})
_purge_sub_agent_task(task_id)
return {"success": True, "message": "子智能体已强制关闭"}
# ==========================================
# 子智能体任务API主智能体调用免登录
# ==========================================
@ -2189,6 +2215,13 @@ def api_stop_sub_agent(task_id: str):
return jsonify(result), status_code
@app.route('/tasks/<task_id>/terminate', methods=['POST'])
def api_terminate_sub_agent(task_id: str):
result = force_terminate_sub_agent(task_id)
status_code = 200 if result.get("success") else 400
return jsonify(result), status_code
@app.route('/tasks/<task_id>/conversation', methods=['GET'])
def api_get_sub_agent_conversation(task_id: str):
info = get_task_record(task_id)