feat: integrate sub agent workflow
This commit is contained in:
parent
a58d695f13
commit
0ac246c22b
@ -128,6 +128,13 @@
|
||||
```
|
||||
启动时可选择“快速模式”或“思考模式”,并指定项目路径(默认为 `./project`)。
|
||||
|
||||
4. **子智能体测试服务(可选)**
|
||||
```bash
|
||||
python sub_agent/server.py
|
||||
# 默认监听 8092 端口,供 create_sub_agent/wait_sub_agent 工具调用
|
||||
```
|
||||
当前实现为占位服务,会在 `sub_agent/tasks/` 下生成交付文件,并立即返回测试结果,便于主智能体打通基础流程。
|
||||
|
||||
---
|
||||
|
||||
## 主要工具与能力
|
||||
|
||||
@ -10,6 +10,7 @@ from . import ui as _ui
|
||||
from . import memory as _memory
|
||||
from . import todo as _todo
|
||||
from . import auth as _auth
|
||||
from . import sub_agent as _sub_agent
|
||||
|
||||
from .api import *
|
||||
from .paths import *
|
||||
@ -21,9 +22,10 @@ from .ui import *
|
||||
from .memory import *
|
||||
from .todo import *
|
||||
from .auth import *
|
||||
from .sub_agent import *
|
||||
|
||||
__all__ = []
|
||||
for module in (_api, _paths, _limits, _terminal, _conversation, _security, _ui, _memory, _todo, _auth):
|
||||
for module in (_api, _paths, _limits, _terminal, _conversation, _security, _ui, _memory, _todo, _auth, _sub_agent):
|
||||
__all__ += getattr(module, "__all__", [])
|
||||
|
||||
del _api, _paths, _limits, _terminal, _conversation, _security, _ui, _memory, _todo, _auth
|
||||
del _api, _paths, _limits, _terminal, _conversation, _security, _ui, _memory, _todo, _auth, _sub_agent
|
||||
|
||||
24
config/sub_agent.py
Normal file
24
config/sub_agent.py
Normal file
@ -0,0 +1,24 @@
|
||||
"""子智能体相关配置。"""
|
||||
|
||||
import os
|
||||
|
||||
# 子智能体服务
|
||||
SUB_AGENT_SERVICE_BASE_URL = os.environ.get("SUB_AGENT_SERVICE_URL", "http://127.0.0.1:8092")
|
||||
SUB_AGENT_DEFAULT_TIMEOUT = int(os.environ.get("SUB_AGENT_DEFAULT_TIMEOUT", "180")) # 秒
|
||||
SUB_AGENT_STATUS_POLL_INTERVAL = float(os.environ.get("SUB_AGENT_STATUS_POLL_INTERVAL", "2.0"))
|
||||
|
||||
# 存储与并发限制
|
||||
SUB_AGENT_TASKS_BASE_DIR = os.environ.get("SUB_AGENT_TASKS_BASE_DIR", "./sub_agent/tasks")
|
||||
SUB_AGENT_PROJECT_RESULTS_DIR = os.environ.get("SUB_AGENT_PROJECT_RESULTS_DIR", "./project/sub_agent_results")
|
||||
SUB_AGENT_STATE_FILE = os.environ.get("SUB_AGENT_STATE_FILE", "./data/sub_agents.json")
|
||||
SUB_AGENT_MAX_ACTIVE = int(os.environ.get("SUB_AGENT_MAX_ACTIVE", "5"))
|
||||
|
||||
__all__ = [
|
||||
"SUB_AGENT_SERVICE_BASE_URL",
|
||||
"SUB_AGENT_DEFAULT_TIMEOUT",
|
||||
"SUB_AGENT_STATUS_POLL_INTERVAL",
|
||||
"SUB_AGENT_TASKS_BASE_DIR",
|
||||
"SUB_AGENT_PROJECT_RESULTS_DIR",
|
||||
"SUB_AGENT_STATE_FILE",
|
||||
"SUB_AGENT_MAX_ACTIVE",
|
||||
]
|
||||
@ -38,6 +38,7 @@ from modules.terminal_ops import TerminalOperator
|
||||
from modules.memory_manager import MemoryManager
|
||||
from modules.terminal_manager import TerminalManager
|
||||
from modules.todo_manager import TodoManager
|
||||
from modules.sub_agent_manager import SubAgentManager
|
||||
from modules.webpage_extractor import extract_webpage_content, tavily_extract
|
||||
from core.tool_config import TOOL_CATEGORIES
|
||||
from utils.api_client import DeepSeekClient
|
||||
@ -77,6 +78,11 @@ class MainTerminal:
|
||||
)
|
||||
|
||||
self.todo_manager = TodoManager(self.context_manager)
|
||||
self.sub_agent_manager = SubAgentManager(
|
||||
project_path=self.project_path,
|
||||
data_dir=str(self.data_dir)
|
||||
)
|
||||
self._announced_sub_agent_tasks = set()
|
||||
|
||||
# 聚焦文件管理
|
||||
self.focused_files = {} # {path: content} 存储聚焦的文件内容
|
||||
@ -207,6 +213,27 @@ class MainTerminal:
|
||||
|
||||
return limited_chunks, truncated, consumed
|
||||
|
||||
def _record_sub_agent_message(self, message: Optional[str], task_id: Optional[str] = None, inline: bool = False):
|
||||
"""以 system 消息记录子智能体状态。"""
|
||||
if not message:
|
||||
return
|
||||
if task_id and task_id in self._announced_sub_agent_tasks:
|
||||
return
|
||||
if task_id:
|
||||
self._announced_sub_agent_tasks.add(task_id)
|
||||
logger.info(
|
||||
"[SubAgent] record message | task=%s | inline=%s | content=%s",
|
||||
task_id,
|
||||
inline,
|
||||
message.replace("\n", "\\n")[:200],
|
||||
)
|
||||
metadata = {"sub_agent_notice": True, "inline": inline}
|
||||
if task_id:
|
||||
metadata["task_id"] = task_id
|
||||
self.context_manager.add_conversation("system", message, metadata=metadata)
|
||||
print(f"{OUTPUT_FORMATS['info']} {message}")
|
||||
|
||||
|
||||
def _handle_read_tool(self, arguments: Dict) -> Dict:
|
||||
"""集中处理 read_file 工具的三种模式。"""
|
||||
file_path = arguments.get("path")
|
||||
@ -1341,6 +1368,46 @@ class MainTerminal:
|
||||
"required": ["confirm"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "create_sub_agent",
|
||||
"description": "创建新的子智能体任务。需要提供任务摘要、详细要求、交付目录以及可供参考的文件列表。注意:同一时间最多运行5个子智能体。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"agent_id": {"type": "integer", "description": "子智能体代号(1~5)"},
|
||||
"summary": {"type": "string", "description": "任务摘要,简要说明目标"},
|
||||
"task": {"type": "string", "description": "任务详细要求"},
|
||||
"target_dir": {"type": "string", "description": "项目下用于接收交付的相对目录"},
|
||||
"reference_files": {
|
||||
"type": "array",
|
||||
"description": "提供给子智能体的参考文件列表(相对路径)",
|
||||
"items": {"type": "string"},
|
||||
"maxItems": 10
|
||||
},
|
||||
"timeout_seconds": {"type": "integer", "description": "子智能体最大运行秒数(默认180秒)"}
|
||||
},
|
||||
"required": ["agent_id", "summary", "task", "target_dir"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "wait_sub_agent",
|
||||
"description": "等待指定子智能体任务结束(或超时)。任务完成后会返回交付目录,并将结果复制到指定的项目文件夹。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task_id": {"type": "string", "description": "子智能体任务ID"},
|
||||
"agent_id": {"type": "integer", "description": "子智能体代号(可选,用于缺省 task_id 的情况)"},
|
||||
"timeout_seconds": {"type": "integer", "description": "本次等待的超时时长(秒)"}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
if self.disabled_tools:
|
||||
@ -1725,7 +1792,7 @@ class MainTerminal:
|
||||
if char_count > MAX_EXTRACT_WEBPAGE_CHARS:
|
||||
result = {
|
||||
"success": False,
|
||||
"error": f"网页提取返回了过长的{char_count}字符,请不要提取这个网页,可以使用网页保存功能,然后使用终端命令查找或查看网页",
|
||||
"error": f"网页提取返回了过长的{char_count}字符,请不要提取这个网页,可以使用网页保存功能,然后使用read工具查找或查看网页",
|
||||
"char_count": char_count,
|
||||
"limit": MAX_EXTRACT_WEBPAGE_CHARS,
|
||||
"url": url
|
||||
@ -1897,6 +1964,24 @@ class MainTerminal:
|
||||
reason=arguments.get("reason")
|
||||
)
|
||||
|
||||
elif tool_name == "create_sub_agent":
|
||||
result = self.sub_agent_manager.create_sub_agent(
|
||||
agent_id=arguments.get("agent_id"),
|
||||
summary=arguments.get("summary", ""),
|
||||
task=arguments.get("task", ""),
|
||||
target_dir=arguments.get("target_dir", ""),
|
||||
reference_files=arguments.get("reference_files", []),
|
||||
timeout_seconds=arguments.get("timeout_seconds")
|
||||
)
|
||||
|
||||
elif tool_name == "wait_sub_agent":
|
||||
result = self.sub_agent_manager.wait_for_completion(
|
||||
task_id=arguments.get("task_id"),
|
||||
agent_id=arguments.get("agent_id"),
|
||||
timeout_seconds=arguments.get("timeout_seconds")
|
||||
)
|
||||
self._record_sub_agent_message(result.get("system_message"), result.get("task_id"), inline=False)
|
||||
|
||||
else:
|
||||
result = {"success": False, "error": f"未知工具: {tool_name}"}
|
||||
|
||||
@ -1947,6 +2032,7 @@ class MainTerminal:
|
||||
|
||||
# 添加对话历史(保留完整结构,包括tool_calls和tool消息)
|
||||
for conv in context["conversation"]:
|
||||
metadata = conv.get("metadata") or {}
|
||||
if conv["role"] == "assistant":
|
||||
# Assistant消息可能包含工具调用
|
||||
message = {
|
||||
@ -1968,8 +2054,14 @@ class MainTerminal:
|
||||
}
|
||||
messages.append(message)
|
||||
|
||||
elif conv["role"] == "system" and metadata.get("sub_agent_notice"):
|
||||
# 转换为用户消息,让模型能及时响应
|
||||
messages.append({
|
||||
"role": "user",
|
||||
"content": conv["content"]
|
||||
})
|
||||
else:
|
||||
# User消息
|
||||
# User 或普通 System 消息
|
||||
messages.append({
|
||||
"role": conv["role"],
|
||||
"content": conv["content"]
|
||||
|
||||
@ -56,4 +56,8 @@ TOOL_CATEGORIES: Dict[str, ToolCategory] = {
|
||||
label="待办事项",
|
||||
tools=["todo_create", "todo_update_task", "todo_finish", "todo_finish_confirm"],
|
||||
),
|
||||
"sub_agent": ToolCategory(
|
||||
label="子智能体",
|
||||
tools=["create_sub_agent", "wait_sub_agent"],
|
||||
),
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
import json
|
||||
from typing import Dict, List, Optional, Callable
|
||||
from core.main_terminal import MainTerminal
|
||||
from utils.logger import setup_logger
|
||||
try:
|
||||
from config import MAX_TERMINALS, TERMINAL_BUFFER_SIZE, TERMINAL_DISPLAY_SIZE
|
||||
except ImportError:
|
||||
@ -14,6 +15,8 @@ except ImportError:
|
||||
from config import MAX_TERMINALS, TERMINAL_BUFFER_SIZE, TERMINAL_DISPLAY_SIZE
|
||||
from modules.terminal_manager import TerminalManager
|
||||
|
||||
logger = setup_logger(__name__)
|
||||
|
||||
class WebTerminal(MainTerminal):
|
||||
"""Web版本的终端,继承自MainTerminal,包含对话持久化功能"""
|
||||
|
||||
@ -436,6 +439,11 @@ class WebTerminal(MainTerminal):
|
||||
|
||||
# 调用父类的工具处理(包含我们的新逻辑)
|
||||
result = await super().handle_tool_call(tool_name, arguments)
|
||||
logger.debug(
|
||||
"[SubAgent][WebTerminal] tool=%s 执行完成,result前200=%s",
|
||||
tool_name,
|
||||
result[:200] if isinstance(result, str) else result,
|
||||
)
|
||||
|
||||
# 解析结果并广播工具结束事件
|
||||
try:
|
||||
|
||||
443
modules/sub_agent_manager.py
Normal file
443
modules/sub_agent_manager.py
Normal file
@ -0,0 +1,443 @@
|
||||
"""子智能体任务管理。"""
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import time
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
import httpx
|
||||
|
||||
from config import (
|
||||
OUTPUT_FORMATS,
|
||||
SUB_AGENT_DEFAULT_TIMEOUT,
|
||||
SUB_AGENT_MAX_ACTIVE,
|
||||
SUB_AGENT_PROJECT_RESULTS_DIR,
|
||||
SUB_AGENT_SERVICE_BASE_URL,
|
||||
SUB_AGENT_STATE_FILE,
|
||||
SUB_AGENT_STATUS_POLL_INTERVAL,
|
||||
SUB_AGENT_TASKS_BASE_DIR,
|
||||
)
|
||||
from utils.logger import setup_logger
|
||||
|
||||
logger = setup_logger(__name__)
|
||||
TERMINAL_STATUSES = {"completed", "failed", "timeout"}
|
||||
|
||||
|
||||
class SubAgentManager:
|
||||
"""负责主智能体与子智能体服务之间的任务调度。"""
|
||||
|
||||
def __init__(self, project_path: str, data_dir: str):
|
||||
self.project_path = Path(project_path).resolve()
|
||||
self.data_dir = Path(data_dir).resolve()
|
||||
self.base_dir = Path(SUB_AGENT_TASKS_BASE_DIR).resolve()
|
||||
self.results_dir = Path(SUB_AGENT_PROJECT_RESULTS_DIR).resolve()
|
||||
self.state_file = Path(SUB_AGENT_STATE_FILE).resolve()
|
||||
|
||||
self.base_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.results_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.state_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
self.tasks: Dict[str, Dict] = {}
|
||||
self._load_state()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 公共方法
|
||||
# ------------------------------------------------------------------
|
||||
def create_sub_agent(
|
||||
self,
|
||||
*,
|
||||
agent_id: int,
|
||||
summary: str,
|
||||
task: str,
|
||||
target_dir: str,
|
||||
reference_files: Optional[List[str]] = None,
|
||||
timeout_seconds: Optional[int] = None,
|
||||
) -> Dict:
|
||||
"""创建子智能体任务并启动远端服务。"""
|
||||
reference_files = reference_files or []
|
||||
validation_error = self._validate_create_params(agent_id, summary, task, target_dir)
|
||||
if validation_error:
|
||||
return {"success": False, "error": validation_error}
|
||||
|
||||
if self._active_task_count() >= SUB_AGENT_MAX_ACTIVE:
|
||||
return {
|
||||
"success": False,
|
||||
"error": f"已有 {SUB_AGENT_MAX_ACTIVE} 个子智能体在运行,请稍后再试。",
|
||||
}
|
||||
|
||||
task_id = self._generate_task_id(agent_id)
|
||||
task_root = self.base_dir / task_id
|
||||
references_dir = task_root / "references"
|
||||
deliverables_dir = task_root / "deliverables"
|
||||
workspace_dir = task_root / "workspace"
|
||||
|
||||
for path in (task_root, references_dir, deliverables_dir, workspace_dir):
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
copied_refs, copy_errors = self._copy_reference_files(reference_files, references_dir)
|
||||
if copy_errors:
|
||||
return {"success": False, "error": "; ".join(copy_errors)}
|
||||
|
||||
try:
|
||||
target_project_dir = self._ensure_project_subdir(target_dir)
|
||||
except ValueError as exc:
|
||||
return {"success": False, "error": str(exc)}
|
||||
|
||||
timeout_seconds = timeout_seconds or SUB_AGENT_DEFAULT_TIMEOUT
|
||||
payload = {
|
||||
"task_id": task_id,
|
||||
"agent_id": agent_id,
|
||||
"summary": summary,
|
||||
"task": task,
|
||||
"target_project_dir": str(target_project_dir),
|
||||
"workspace_dir": str(workspace_dir),
|
||||
"references_dir": str(references_dir),
|
||||
"deliverables_dir": str(deliverables_dir),
|
||||
"timeout_seconds": timeout_seconds,
|
||||
}
|
||||
|
||||
service_response = self._call_service("POST", "/tasks", payload, timeout_seconds + 5)
|
||||
if not service_response.get("success"):
|
||||
self._cleanup_task_folder(task_root)
|
||||
return {
|
||||
"success": False,
|
||||
"error": service_response.get("error", "子智能体服务调用失败"),
|
||||
"details": service_response,
|
||||
}
|
||||
|
||||
status = service_response.get("status", "pending")
|
||||
task_record = {
|
||||
"task_id": task_id,
|
||||
"agent_id": agent_id,
|
||||
"summary": summary,
|
||||
"task": task,
|
||||
"status": status,
|
||||
"target_project_dir": str(target_project_dir),
|
||||
"references_dir": str(references_dir),
|
||||
"deliverables_dir": str(deliverables_dir),
|
||||
"workspace_dir": str(workspace_dir),
|
||||
"copied_references": copied_refs,
|
||||
"timeout_seconds": timeout_seconds,
|
||||
"service_payload": payload,
|
||||
"created_at": time.time(),
|
||||
}
|
||||
self.tasks[task_id] = task_record
|
||||
self._save_state()
|
||||
|
||||
message = f"子智能体{agent_id} 已创建,任务ID: {task_id},当前状态:{status}"
|
||||
print(f"{OUTPUT_FORMATS['info']} {message}")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"task_id": task_id,
|
||||
"agent_id": agent_id,
|
||||
"status": status,
|
||||
"message": message,
|
||||
"deliverables_dir": str(deliverables_dir),
|
||||
"copied_references": copied_refs,
|
||||
}
|
||||
|
||||
def wait_for_completion(
|
||||
self,
|
||||
*,
|
||||
task_id: Optional[str] = None,
|
||||
agent_id: Optional[int] = None,
|
||||
timeout_seconds: Optional[int] = None,
|
||||
) -> Dict:
|
||||
"""阻塞等待子智能体完成或超时。"""
|
||||
task = self._select_task(task_id, agent_id)
|
||||
if not task:
|
||||
return {"success": False, "error": "未找到对应的子智能体任务"}
|
||||
|
||||
if task.get("status") in TERMINAL_STATUSES and task.get("final_result"):
|
||||
return task["final_result"]
|
||||
|
||||
timeout_seconds = timeout_seconds or task.get("timeout_seconds") or SUB_AGENT_DEFAULT_TIMEOUT
|
||||
deadline = time.time() + timeout_seconds
|
||||
last_payload: Optional[Dict] = None
|
||||
|
||||
while time.time() < deadline:
|
||||
last_payload = self._call_service("GET", f"/tasks/{task['task_id']}", timeout=15)
|
||||
status = last_payload.get("status")
|
||||
if not last_payload.get("success") and status not in TERMINAL_STATUSES:
|
||||
time.sleep(SUB_AGENT_STATUS_POLL_INTERVAL)
|
||||
continue
|
||||
|
||||
if status in {"completed", "failed", "timeout"}:
|
||||
break
|
||||
|
||||
time.sleep(SUB_AGENT_STATUS_POLL_INTERVAL)
|
||||
else:
|
||||
status = "timeout"
|
||||
last_payload = {"success": False, "status": status, "message": "等待超时"}
|
||||
|
||||
if not last_payload:
|
||||
last_payload = {"success": False, "status": "unknown", "message": "无法获取子智能体状态"}
|
||||
status = "unknown"
|
||||
else:
|
||||
status = last_payload.get("status", status)
|
||||
|
||||
finalize_result = self._finalize_task(task, last_payload or {}, status)
|
||||
self._save_state()
|
||||
return finalize_result
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 内部工具方法
|
||||
# ------------------------------------------------------------------
|
||||
def _load_state(self):
|
||||
if self.state_file.exists():
|
||||
try:
|
||||
data = json.loads(self.state_file.read_text(encoding="utf-8"))
|
||||
self.tasks = data.get("tasks", {})
|
||||
except json.JSONDecodeError:
|
||||
logger.warning("子智能体状态文件损坏,已忽略。")
|
||||
self.tasks = {}
|
||||
else:
|
||||
self.tasks = {}
|
||||
|
||||
def _save_state(self):
|
||||
payload = {"tasks": self.tasks}
|
||||
self.state_file.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
|
||||
def _generate_task_id(self, agent_id: int) -> str:
|
||||
suffix = uuid.uuid4().hex[:6]
|
||||
return f"sub_{agent_id}_{int(time.time())}_{suffix}"
|
||||
|
||||
def _active_task_count(self) -> int:
|
||||
return len([t for t in self.tasks.values() if t.get("status") in {"pending", "running"}])
|
||||
|
||||
def _copy_reference_files(self, references: List[str], dest_dir: Path) -> Tuple[List[str], List[str]]:
|
||||
copied = []
|
||||
errors = []
|
||||
for rel_path in references:
|
||||
rel_path = rel_path.strip()
|
||||
if not rel_path:
|
||||
continue
|
||||
try:
|
||||
source = self._resolve_project_file(rel_path)
|
||||
except ValueError as exc:
|
||||
errors.append(str(exc))
|
||||
continue
|
||||
|
||||
if not source.exists():
|
||||
errors.append(f"参考文件不存在: {rel_path}")
|
||||
continue
|
||||
|
||||
target_path = dest_dir / rel_path
|
||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
shutil.copy2(source, target_path)
|
||||
copied.append(rel_path)
|
||||
except Exception as exc:
|
||||
errors.append(f"复制 {rel_path} 失败: {exc}")
|
||||
return copied, errors
|
||||
|
||||
def _ensure_project_subdir(self, relative_dir: str) -> Path:
|
||||
relative_dir = relative_dir.strip() if relative_dir else ""
|
||||
if not relative_dir:
|
||||
relative_dir = "sub_agent_results"
|
||||
target = (self.project_path / relative_dir).resolve()
|
||||
if not str(target).startswith(str(self.project_path)):
|
||||
raise ValueError("指定文件夹必须位于项目目录内")
|
||||
target.mkdir(parents=True, exist_ok=True)
|
||||
return target
|
||||
|
||||
def _resolve_project_file(self, relative_path: str) -> Path:
|
||||
relative_path = relative_path.strip()
|
||||
candidate = (self.project_path / relative_path).resolve()
|
||||
if not str(candidate).startswith(str(self.project_path)):
|
||||
raise ValueError(f"非法的参考文件路径: {relative_path}")
|
||||
return candidate
|
||||
|
||||
def _select_task(self, task_id: Optional[str], agent_id: Optional[int]) -> Optional[Dict]:
|
||||
if task_id:
|
||||
return self.tasks.get(task_id)
|
||||
|
||||
if agent_id is None:
|
||||
return None
|
||||
|
||||
# 返回最新的匹配任务
|
||||
candidates = [
|
||||
task for task in self.tasks.values()
|
||||
if task.get("agent_id") == agent_id and task.get("status") in {"pending", "running"}
|
||||
]
|
||||
if candidates:
|
||||
candidates.sort(key=lambda item: item.get("created_at", 0), reverse=True)
|
||||
return candidates[0]
|
||||
return None
|
||||
|
||||
def poll_updates(self) -> List[Dict]:
|
||||
"""检查运行中的子智能体任务,返回新完成的结果。"""
|
||||
updates: List[Dict] = []
|
||||
pending_tasks = [
|
||||
task for task in self.tasks.values()
|
||||
if task.get("status") not in TERMINAL_STATUSES
|
||||
]
|
||||
logger.debug(f"[SubAgentManager] 待检查任务: {len(pending_tasks)}")
|
||||
if not pending_tasks:
|
||||
return updates
|
||||
|
||||
state_changed = False
|
||||
for task in pending_tasks:
|
||||
payload = self._call_service("GET", f"/tasks/{task['task_id']}", timeout=10)
|
||||
status = payload.get("status")
|
||||
logger.debug(f"[SubAgentManager] 任务 {task['task_id']} 服务状态: {status}")
|
||||
if status not in TERMINAL_STATUSES:
|
||||
continue
|
||||
result = self._finalize_task(task, payload, status)
|
||||
updates.append(result)
|
||||
state_changed = True
|
||||
|
||||
if state_changed:
|
||||
self._save_state()
|
||||
return updates
|
||||
|
||||
def _call_service(self, method: str, path: str, payload: Optional[Dict] = None, timeout: Optional[int] = None) -> Dict:
|
||||
url = f"{SUB_AGENT_SERVICE_BASE_URL.rstrip('/')}{path}"
|
||||
try:
|
||||
with httpx.Client(timeout=timeout or 10) as client:
|
||||
if method.upper() == "POST":
|
||||
response = client.post(url, json=payload or {})
|
||||
else:
|
||||
response = client.get(url)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except httpx.RequestError as exc:
|
||||
logger.error(f"子智能体服务请求失败: {exc}")
|
||||
return {"success": False, "error": f"无法连接子智能体服务: {exc}"}
|
||||
except httpx.HTTPStatusError as exc:
|
||||
logger.error(f"子智能体服务返回错误: {exc}")
|
||||
try:
|
||||
return exc.response.json()
|
||||
except Exception:
|
||||
return {"success": False, "error": f"服务端错误: {exc.response.text}"}
|
||||
except json.JSONDecodeError:
|
||||
return {"success": False, "error": "子智能体服务返回格式错误"}
|
||||
|
||||
def _finalize_task(self, task: Dict, service_payload: Dict, status: str) -> Dict:
|
||||
existing_result = task.get("final_result")
|
||||
if existing_result and task.get("status") in TERMINAL_STATUSES:
|
||||
return existing_result
|
||||
|
||||
task["status"] = status
|
||||
task["updated_at"] = time.time()
|
||||
message = service_payload.get("message") or service_payload.get("error") or ""
|
||||
deliverables_dir = Path(service_payload.get("deliverables_dir") or task.get("deliverables_dir", ""))
|
||||
logger.debug(f"[SubAgentManager] finalize task={task['task_id']} status={status}")
|
||||
|
||||
if status != "completed":
|
||||
result = {
|
||||
"success": False,
|
||||
"task_id": task["task_id"],
|
||||
"agent_id": task["agent_id"],
|
||||
"status": status,
|
||||
"message": message or f"子智能体状态:{status}",
|
||||
"details": service_payload,
|
||||
"system_message": self._build_system_message(task, status, None, message),
|
||||
}
|
||||
task["final_result"] = result
|
||||
return result
|
||||
|
||||
if not deliverables_dir.exists():
|
||||
result = {
|
||||
"success": False,
|
||||
"task_id": task["task_id"],
|
||||
"agent_id": task["agent_id"],
|
||||
"status": "failed",
|
||||
"error": f"未找到交付目录: {deliverables_dir}",
|
||||
"system_message": self._build_system_message(task, "failed", None, f"未找到交付目录: {deliverables_dir}"),
|
||||
}
|
||||
task["status"] = "failed"
|
||||
task["final_result"] = result
|
||||
return result
|
||||
|
||||
result_md = deliverables_dir / "result.md"
|
||||
if not result_md.exists():
|
||||
result = {
|
||||
"success": False,
|
||||
"task_id": task["task_id"],
|
||||
"agent_id": task["agent_id"],
|
||||
"status": "failed",
|
||||
"error": "交付目录缺少 result.md,无法完成任务。",
|
||||
"system_message": self._build_system_message(task, "failed", None, "交付目录缺少 result.md"),
|
||||
}
|
||||
task["status"] = "failed"
|
||||
task["final_result"] = result
|
||||
return result
|
||||
|
||||
copied_path = self._copy_deliverables_to_project(task, deliverables_dir)
|
||||
task["copied_path"] = str(copied_path)
|
||||
|
||||
system_message = self._build_system_message(task, status, copied_path, message)
|
||||
result = {
|
||||
"success": True,
|
||||
"task_id": task["task_id"],
|
||||
"agent_id": task["agent_id"],
|
||||
"status": status,
|
||||
"message": message or "子智能体已完成任务。",
|
||||
"deliverables_path": str(deliverables_dir),
|
||||
"copied_path": str(copied_path),
|
||||
"system_message": system_message,
|
||||
"details": service_payload,
|
||||
}
|
||||
task["final_result"] = result
|
||||
return result
|
||||
|
||||
def _copy_deliverables_to_project(self, task: Dict, source_dir: Path) -> Path:
|
||||
"""将交付文件复制到项目目录下的指定文件夹。"""
|
||||
target_dir = Path(task["target_project_dir"])
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
dest_dir = target_dir / f"{task['task_id']}_deliverables"
|
||||
|
||||
if dest_dir.exists():
|
||||
shutil.rmtree(dest_dir)
|
||||
shutil.copytree(source_dir, dest_dir)
|
||||
|
||||
return dest_dir
|
||||
|
||||
def _cleanup_task_folder(self, task_root: Path):
|
||||
if task_root.exists():
|
||||
shutil.rmtree(task_root, ignore_errors=True)
|
||||
|
||||
def _validate_create_params(self, agent_id: Optional[int], summary: str, task: str, target_dir: str) -> Optional[str]:
|
||||
if agent_id is None:
|
||||
return "子智能体代号不能为空"
|
||||
try:
|
||||
agent_id = int(agent_id)
|
||||
except ValueError:
|
||||
return "子智能体代号必须是整数"
|
||||
if not (1 <= agent_id <= SUB_AGENT_MAX_ACTIVE):
|
||||
return f"子智能体代号必须在 1~{SUB_AGENT_MAX_ACTIVE} 范围内"
|
||||
if not summary or not summary.strip():
|
||||
return "任务摘要不能为空"
|
||||
if not task or not task.strip():
|
||||
return "任务详情不能为空"
|
||||
if target_dir is None:
|
||||
return "指定文件夹不能为空"
|
||||
return None
|
||||
|
||||
def _build_system_message(
|
||||
self,
|
||||
task: Dict,
|
||||
status: str,
|
||||
copied_path: Optional[Path],
|
||||
extra_message: Optional[str] = None,
|
||||
) -> str:
|
||||
prefix = f"子智能体{task['agent_id']} 任务摘要:{task['summary']}"
|
||||
extra = (extra_message or "").strip()
|
||||
|
||||
if status == "completed" and copied_path:
|
||||
msg = f"{prefix} 已完成,成果已复制到 {copied_path}。"
|
||||
if extra:
|
||||
msg += f" ({extra})"
|
||||
return msg
|
||||
|
||||
if status == "timeout":
|
||||
return f"{prefix} 超时未完成。" + (f" {extra}" if extra else "")
|
||||
|
||||
if status == "failed":
|
||||
return f"{prefix} 执行失败:" + (extra if extra else "请检查交付目录或任务状态。")
|
||||
|
||||
return f"{prefix} 状态:{status}。" + (extra if extra else "")
|
||||
@ -302,6 +302,21 @@ async function bootstrapApp() {
|
||||
window.open('/file-manager', '_blank');
|
||||
},
|
||||
|
||||
findMessageByAction(action) {
|
||||
if (!action) {
|
||||
return null;
|
||||
}
|
||||
for (const message of this.messages) {
|
||||
if (!message.actions) {
|
||||
continue;
|
||||
}
|
||||
if (message.actions.includes(action)) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
async bootstrapRoute() {
|
||||
const path = window.location.pathname.replace(/^\/+/, '');
|
||||
if (!path || path === 'new') {
|
||||
@ -1045,20 +1060,10 @@ async function bootstrapApp() {
|
||||
|
||||
// 系统消息
|
||||
this.socket.on('system_message', (data) => {
|
||||
if (this.currentMessageIndex >= 0) {
|
||||
const msg = this.messages[this.currentMessageIndex];
|
||||
const action = {
|
||||
id: `system-${Date.now()}-${Math.random()}`,
|
||||
type: 'system',
|
||||
content: data.content,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
msg.actions.push(action);
|
||||
this.$forceUpdate();
|
||||
this.conditionalScrollToBottom();
|
||||
} else {
|
||||
this.addSystemMessage(data.content);
|
||||
if (!data || !data.content) {
|
||||
return;
|
||||
}
|
||||
this.appendSystemAction(data.content);
|
||||
});
|
||||
|
||||
// 错误处理
|
||||
@ -2382,10 +2387,18 @@ async function bootstrapApp() {
|
||||
},
|
||||
|
||||
addSystemMessage(content) {
|
||||
this.messages.push({
|
||||
role: 'system',
|
||||
content: content
|
||||
this.appendSystemAction(content);
|
||||
},
|
||||
|
||||
appendSystemAction(content) {
|
||||
const msg = this.ensureAssistantMessage();
|
||||
msg.actions.push({
|
||||
id: `system-${Date.now()}-${Math.random()}`,
|
||||
type: 'system',
|
||||
content: content,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
this.$forceUpdate();
|
||||
this.conditionalScrollToBottom();
|
||||
},
|
||||
|
||||
|
||||
@ -272,6 +272,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统提示块 -->
|
||||
<div v-else-if="action.type === 'system'" class="system-action">
|
||||
<div class="system-action-content">
|
||||
{{ action.content }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 追加内容占位 -->
|
||||
<div v-else-if="action.type === 'append_payload'"
|
||||
class="append-placeholder"
|
||||
|
||||
@ -868,6 +868,23 @@ body {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.system-action {
|
||||
margin: 12px 0;
|
||||
padding: 10px 14px;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(59, 130, 246, 0.08));
|
||||
border-left: 4px solid rgba(79, 70, 229, 0.6);
|
||||
color: var(--claude-text);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.system-action-content {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.append-block {
|
||||
margin: 12px 0;
|
||||
padding: 12px 16px;
|
||||
|
||||
1
sub_agent/__init__.py
Normal file
1
sub_agent/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
"""子智能体独立服务与工具集合。"""
|
||||
127
sub_agent/server.py
Normal file
127
sub_agent/server.py
Normal file
@ -0,0 +1,127 @@
|
||||
"""子智能体测试服务。
|
||||
|
||||
该服务与主智能体完全隔离,监听 8092 端口,模拟 20 秒后完成任务的过程。
|
||||
后续可替换为真实的多轮子智能体推理逻辑。
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from flask import Flask, jsonify, request
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
TASKS_ROOT = BASE_DIR / "tasks"
|
||||
STATE_FILE = TASKS_ROOT / "tasks_state.json"
|
||||
STUB_DELAY_SECONDS = int(os.environ.get("SUB_AGENT_STUB_DELAY", "20"))
|
||||
|
||||
TASKS_ROOT.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
app = Flask(__name__)
|
||||
TASK_CACHE = {}
|
||||
|
||||
|
||||
def load_state():
|
||||
if STATE_FILE.exists():
|
||||
try:
|
||||
data = json.loads(STATE_FILE.read_text(encoding="utf-8"))
|
||||
TASK_CACHE.update(data)
|
||||
except json.JSONDecodeError:
|
||||
STATE_FILE.unlink(missing_ok=True)
|
||||
|
||||
|
||||
def save_state():
|
||||
STATE_FILE.write_text(json.dumps(TASK_CACHE, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
|
||||
|
||||
def _touch_result_files(deliverables_dir: Path, summary: str, task_description: str) -> str:
|
||||
deliverables_dir.mkdir(parents=True, exist_ok=True)
|
||||
result_md = deliverables_dir / "result.md"
|
||||
if not result_md.exists():
|
||||
result_md.write_text(
|
||||
f"# 子智能体测试结果\n\n"
|
||||
f"- 摘要:{summary}\n"
|
||||
f"- 任务:{task_description}\n"
|
||||
f"- 说明:当前为测试服务,已自动生成占位结果。\n",
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
payload = {
|
||||
"summary": summary,
|
||||
"task": task_description,
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": time.time(),
|
||||
}
|
||||
result_json = deliverables_dir / "result.json"
|
||||
result_json.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
return str(result_json)
|
||||
|
||||
|
||||
def _finalize_if_ready(task_id: str) -> dict:
|
||||
record = TASK_CACHE.get(task_id)
|
||||
if not record:
|
||||
return {}
|
||||
|
||||
if record.get("status") == "completed":
|
||||
return record
|
||||
|
||||
if time.time() >= record.get("ready_at", 0):
|
||||
deliverables_dir = Path(record["deliverables_dir"])
|
||||
result_file = _touch_result_files(deliverables_dir, record["summary"], record["task_description"])
|
||||
record.update(
|
||||
{
|
||||
"success": True,
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"result_file": result_file,
|
||||
"updated_at": time.time(),
|
||||
}
|
||||
)
|
||||
TASK_CACHE[task_id] = record
|
||||
save_state()
|
||||
|
||||
return record
|
||||
|
||||
|
||||
@app.post("/tasks")
|
||||
def create_task():
|
||||
data = request.get_json(silent=True) or {}
|
||||
task_id = data.get("task_id") or f"sub_stub_{int(time.time())}"
|
||||
summary = data.get("summary", "未提供摘要")
|
||||
description = data.get("task", "未提供任务说明")
|
||||
deliverables_dir = Path(data.get("deliverables_dir") or (TASKS_ROOT / task_id / "deliverables"))
|
||||
deliverables_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
record = {
|
||||
"success": True,
|
||||
"task_id": task_id,
|
||||
"status": "running",
|
||||
"message": f"子智能体任务已提交,预计 {STUB_DELAY_SECONDS} 秒后完成。",
|
||||
"deliverables_dir": str(deliverables_dir),
|
||||
"result_file": None,
|
||||
"updated_at": time.time(),
|
||||
"ready_at": time.time() + STUB_DELAY_SECONDS,
|
||||
"summary": summary,
|
||||
"task_description": description,
|
||||
}
|
||||
TASK_CACHE[task_id] = record
|
||||
save_state()
|
||||
return jsonify(record)
|
||||
|
||||
|
||||
@app.get("/tasks/<task_id>")
|
||||
def get_task(task_id: str):
|
||||
record = _finalize_if_ready(task_id)
|
||||
if not record:
|
||||
return jsonify({"success": False, "status": "unknown", "message": "task not found"}), 404
|
||||
return jsonify(record)
|
||||
|
||||
|
||||
def main():
|
||||
load_state()
|
||||
app.run(host="0.0.0.0", port=8092)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1
sub_agent/tasks/.gitkeep
Normal file
1
sub_agent/tasks/.gitkeep
Normal file
@ -0,0 +1 @@
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "搜索特斯拉最新股价信息",
|
||||
"task": "请搜索特斯拉(Tesla)的最新股价信息,包括当前股价、今日涨跌幅度、成交量等关键数据。搜索最新的财经新闻和股价数据,整理成简洁的报告格式。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763136273.262679
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:搜索特斯拉最新股价信息
|
||||
- 任务:请搜索特斯拉(Tesla)的最新股价信息,包括当前股价、今日涨跌幅度、成交量等关键数据。搜索最新的财经新闻和股价数据,整理成简洁的报告格式。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,包含一些基础内容,证明任务能够正常执行和交付。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763137676.5623722
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,包含一些基础内容,证明任务能够正常执行和交付。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明任务能够正常执行。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763137994.669416
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明任务能够正常执行。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试AI发展趋势研究",
|
||||
"task": "请搜索2025年AI发展的最新趋势,重点关注技术突破、应用场景和商业价值。整理成结构化的报告,包含主要趋势、关键数据和未来发展预测。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763138553.300131
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试AI发展趋势研究
|
||||
- 任务:请搜索2025年AI发展的最新趋势,重点关注技术突破、应用场景和商业价值。整理成结构化的报告,包含主要趋势、关键数据和未来发展预测。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "请创建一个简单的测试文件,包含一些基础文本内容,用于验证子智能体功能是否正常工作。文件应该包含当前时间戳和测试说明。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763138869.392883
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:请创建一个简单的测试文件,包含一些基础文本内容,用于验证子智能体功能是否正常工作。文件应该包含当前时间戳和测试说明。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,请创建一个简单的测试文件,证明子智能体功能正常运行。创建一个名为test_result.txt的文件,内容为\"子智能体测试成功\",然后保存到指定的交付目录中。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763139191.900894
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,请创建一个简单的测试文件,证明子智能体功能正常运行。创建一个名为test_result.txt的文件,内容为"子智能体测试成功",然后保存到指定的交付目录中。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的文件操作和基础任务。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763139811.727322
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的文件操作和基础任务。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明子智能体可以正常执行任务。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763139963.9868438
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明子智能体可以正常执行任务。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明子智能体功能可用。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763139984.730519
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明子智能体功能可用。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明子智能体可以正常执行任务。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763140327.6530402
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明子智能体可以正常执行任务。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763140992.09611
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763141417.687732
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763141437.721546
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的文件操作,比如创建一个测试文件并写入一些内容。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763141513.724341
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的文件操作,比如创建一个测试文件并写入一些内容。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请返回一个简单的测试响应。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763141648.8687701
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请返回一个简单的测试响应。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763141745.7180889
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请创建一个简单的文本文件,内容为\"子智能体测试成功\",文件名为test_result.txt",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763141987.713505
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请创建一个简单的文本文件,内容为"子智能体测试成功",文件名为test_result.txt
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请创建一个简单的文本文件,内容为\"子智能体测试成功\",保存为test_result.txt",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763142848.306821
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请创建一个简单的文本文件,内容为"子智能体测试成功",保存为test_result.txt
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763143066.173541
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763143169.6625862
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些基础操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763143471.6208158
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些基础操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763143780.888017
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763143944.4543931
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些基础操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763144242.230876
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些基础操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体功能是否正常工作",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763144337.501353
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体功能是否正常工作
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763144765.529836
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task": "这是一个测试任务,用于验证子智能体的基础功能是否正常工作。请执行一些简单的操作并返回结果。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763145263.387938
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试子智能体基础功能
|
||||
- 任务:这是一个测试任务,用于验证子智能体的基础功能是否正常工作。请执行一些简单的操作并返回结果。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试20秒延迟完成的任务",
|
||||
"task": "这是一个测试任务,用于验证子智能体的延迟完成功能。任务将在20秒后自动完成,请耐心等待并监控任务状态变化。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763136504.791338
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试20秒延迟完成的任务
|
||||
- 任务:这是一个测试任务,用于验证子智能体的延迟完成功能。任务将在20秒后自动完成,请耐心等待并监控任务状态变化。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试30秒等待流程",
|
||||
"task": "这是一个测试任务,用于验证30秒等待流程。任务将在20秒后自动完成,请观察等待过程中的状态变化。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763136599.648795
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试30秒等待流程
|
||||
- 任务:这是一个测试任务,用于验证30秒等待流程。任务将在20秒后自动完成,请观察等待过程中的状态变化。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试被动通知机制",
|
||||
"task": "这是一个测试任务,专门用于验证系统的被动通知机制。任务将在20秒后自动完成,请观察系统是否会主动发送完成通知,而不需要主动查询。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763137514.195047
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试被动通知机制
|
||||
- 任务:这是一个测试任务,专门用于验证系统的被动通知机制。任务将在20秒后自动完成,请观察系统是否会主动发送完成通知,而不需要主动查询。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"summary": "测试被动通知机制-重启后测试",
|
||||
"task": "这是一个测试任务,专门用于验证系统的被动通知机制。任务将在20秒后自动完成,请观察系统是否会主动发送完成通知,而不需要主动查询。这是重启后的测试。",
|
||||
"note": "stub result generated by sub_agent server",
|
||||
"timestamp": 1763137553.357258
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
# 子智能体测试结果
|
||||
|
||||
- 摘要:测试被动通知机制-重启后测试
|
||||
- 任务:这是一个测试任务,专门用于验证系统的被动通知机制。任务将在20秒后自动完成,请观察系统是否会主动发送完成通知,而不需要主动查询。这是重启后的测试。
|
||||
- 说明:当前为测试服务,已自动生成占位结果。
|
||||
371
sub_agent/tasks/tasks_state.json
Normal file
371
sub_agent/tasks/tasks_state.json
Normal file
@ -0,0 +1,371 @@
|
||||
{
|
||||
"sub_1_1763136273_b5c2e6": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763136273_b5c2e6",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763136273_b5c2e6/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763136273_b5c2e6/deliverables/result.json",
|
||||
"updated_at": 1763136273.262999
|
||||
},
|
||||
"sub_2_1763136484_918182": {
|
||||
"success": true,
|
||||
"task_id": "sub_2_1763136484_918182",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_2_1763136484_918182/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_2_1763136484_918182/deliverables/result.json",
|
||||
"updated_at": 1763136504.792568,
|
||||
"ready_at": 1763136504.118033,
|
||||
"summary": "测试20秒延迟完成的任务",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体的延迟完成功能。任务将在20秒后自动完成,请耐心等待并监控任务状态变化。"
|
||||
},
|
||||
"sub_3_1763136563_d5fd0b": {
|
||||
"success": true,
|
||||
"task_id": "sub_3_1763136563_d5fd0b",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_3_1763136563_d5fd0b/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_3_1763136563_d5fd0b/deliverables/result.json",
|
||||
"updated_at": 1763136599.649166,
|
||||
"ready_at": 1763136583.069194,
|
||||
"summary": "测试30秒等待流程",
|
||||
"task_description": "这是一个测试任务,用于验证30秒等待流程。任务将在20秒后自动完成,请观察等待过程中的状态变化。"
|
||||
},
|
||||
"sub_4_1763136763_c6507f": {
|
||||
"success": true,
|
||||
"task_id": "sub_4_1763136763_c6507f",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_4_1763136763_c6507f/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_4_1763136763_c6507f/deliverables/result.json",
|
||||
"updated_at": 1763137514.195194,
|
||||
"ready_at": 1763136783.612108,
|
||||
"summary": "测试被动通知机制",
|
||||
"task_description": "这是一个测试任务,专门用于验证系统的被动通知机制。任务将在20秒后自动完成,请观察系统是否会主动发送完成通知,而不需要主动查询。"
|
||||
},
|
||||
"sub_5_1763137514_d8ad3f": {
|
||||
"success": true,
|
||||
"task_id": "sub_5_1763137514_d8ad3f",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_5_1763137514_d8ad3f/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_5_1763137514_d8ad3f/deliverables/result.json",
|
||||
"updated_at": 1763137553.357632,
|
||||
"ready_at": 1763137534.186771,
|
||||
"summary": "测试被动通知机制-重启后测试",
|
||||
"task_description": "这是一个测试任务,专门用于验证系统的被动通知机制。任务将在20秒后自动完成,请观察系统是否会主动发送完成通知,而不需要主动查询。这是重启后的测试。"
|
||||
},
|
||||
"sub_1_1763137647_0cbccf": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763137647_0cbccf",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763137647_0cbccf/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763137647_0cbccf/deliverables/result.json",
|
||||
"updated_at": 1763137676.562777,
|
||||
"ready_at": 1763137667.353677,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,包含一些基础内容,证明任务能够正常执行和交付。"
|
||||
},
|
||||
"sub_1_1763137973_55bdfa": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763137973_55bdfa",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763137973_55bdfa/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763137973_55bdfa/deliverables/result.json",
|
||||
"updated_at": 1763137994.669676,
|
||||
"ready_at": 1763137993.252982,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明任务能够正常执行。"
|
||||
},
|
||||
"sub_1_1763138525_f3c26a": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763138525_f3c26a",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763138525_f3c26a/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763138525_f3c26a/deliverables/result.json",
|
||||
"updated_at": 1763138553.3004239,
|
||||
"ready_at": 1763138545.089707,
|
||||
"summary": "测试AI发展趋势研究",
|
||||
"task_description": "请搜索2025年AI发展的最新趋势,重点关注技术突破、应用场景和商业价值。整理成结构化的报告,包含主要趋势、关键数据和未来发展预测。"
|
||||
},
|
||||
"sub_1_1763138848_a510e7": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763138848_a510e7",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763138848_a510e7/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763138848_a510e7/deliverables/result.json",
|
||||
"updated_at": 1763138869.393047,
|
||||
"ready_at": 1763138868.7424152,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "请创建一个简单的测试文件,包含一些基础文本内容,用于验证子智能体功能是否正常工作。文件应该包含当前时间戳和测试说明。"
|
||||
},
|
||||
"sub_1_1763139150_3c9d67": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763139150_3c9d67",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763139150_3c9d67/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763139150_3c9d67/deliverables/result.json",
|
||||
"updated_at": 1763139191.906615,
|
||||
"ready_at": 1763139170.9200552,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,请创建一个简单的测试文件,证明子智能体功能正常运行。创建一个名为test_result.txt的文件,内容为\"子智能体测试成功\",然后保存到指定的交付目录中。"
|
||||
},
|
||||
"sub_1_1763139777_e3bb89": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763139777_e3bb89",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763139777_e3bb89/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763139777_e3bb89/deliverables/result.json",
|
||||
"updated_at": 1763139811.727471,
|
||||
"ready_at": 1763139797.230397,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的文件操作和基础任务。"
|
||||
},
|
||||
"sub_1_1763139812_a31421": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763139812_a31421",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763139812_a31421/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763139812_a31421/deliverables/result.json",
|
||||
"updated_at": 1763139963.9870741,
|
||||
"ready_at": 1763139832.061038,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明子智能体可以正常执行任务。"
|
||||
},
|
||||
"sub_1_1763139964_f7096d": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763139964_f7096d",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763139964_f7096d/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763139964_f7096d/deliverables/result.json",
|
||||
"updated_at": 1763139984.730966,
|
||||
"ready_at": 1763139984.328714,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明子智能体功能可用。"
|
||||
},
|
||||
"sub_1_1763140306_2e963d": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763140306_2e963d",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763140306_2e963d/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763140306_2e963d/deliverables/result.json",
|
||||
"updated_at": 1763140327.653261,
|
||||
"ready_at": 1763140326.7281852,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请创建一个简单的测试文件,证明子智能体可以正常执行任务。"
|
||||
},
|
||||
"sub_1_1763140968_fcc7e8": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763140968_fcc7e8",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763140968_fcc7e8/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763140968_fcc7e8/deliverables/result.json",
|
||||
"updated_at": 1763140992.096374,
|
||||
"ready_at": 1763140988.710644,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763141298_73fecb": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763141298_73fecb",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141298_73fecb/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141298_73fecb/deliverables/result.json",
|
||||
"updated_at": 1763141417.687985,
|
||||
"ready_at": 1763141318.212076,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763141416_b3f4af": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763141416_b3f4af",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141416_b3f4af/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141416_b3f4af/deliverables/result.json",
|
||||
"updated_at": 1763141437.721798,
|
||||
"ready_at": 1763141436.1827981,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763141493_04306c": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763141493_04306c",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141493_04306c/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141493_04306c/deliverables/result.json",
|
||||
"updated_at": 1763141513.724571,
|
||||
"ready_at": 1763141513.175173,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的文件操作,比如创建一个测试文件并写入一些内容。"
|
||||
},
|
||||
"sub_1_1763141627_2a3caa": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763141627_2a3caa",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141627_2a3caa/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141627_2a3caa/deliverables/result.json",
|
||||
"updated_at": 1763141648.869268,
|
||||
"ready_at": 1763141647.23754,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请返回一个简单的测试响应。"
|
||||
},
|
||||
"sub_1_1763141724_e8356f": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763141724_e8356f",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141724_e8356f/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141724_e8356f/deliverables/result.json",
|
||||
"updated_at": 1763141745.718327,
|
||||
"ready_at": 1763141744.739198,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763141965_68ed0f": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763141965_68ed0f",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141965_68ed0f/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763141965_68ed0f/deliverables/result.json",
|
||||
"updated_at": 1763141987.71402,
|
||||
"ready_at": 1763141985.7928262,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请创建一个简单的文本文件,内容为\"子智能体测试成功\",文件名为test_result.txt"
|
||||
},
|
||||
"sub_1_1763142827_cf8333": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763142827_cf8333",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763142827_cf8333/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763142827_cf8333/deliverables/result.json",
|
||||
"updated_at": 1763142848.307034,
|
||||
"ready_at": 1763142847.8183172,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请创建一个简单的文本文件,内容为\"子智能体测试成功\",保存为test_result.txt"
|
||||
},
|
||||
"sub_1_1763143045_674f80": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763143045_674f80",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143045_674f80/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143045_674f80/deliverables/result.json",
|
||||
"updated_at": 1763143066.173978,
|
||||
"ready_at": 1763143065.1142159,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763143148_5b7d12": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763143148_5b7d12",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143148_5b7d12/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143148_5b7d12/deliverables/result.json",
|
||||
"updated_at": 1763143169.6628668,
|
||||
"ready_at": 1763143168.05108,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763143449_52810c": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763143449_52810c",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143449_52810c/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143449_52810c/deliverables/result.json",
|
||||
"updated_at": 1763143471.621085,
|
||||
"ready_at": 1763143469.180256,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些基础操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763143759_a861ea": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763143759_a861ea",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143759_a861ea/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143759_a861ea/deliverables/result.json",
|
||||
"updated_at": 1763143780.888281,
|
||||
"ready_at": 1763143779.9134731,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763143923_588633": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763143923_588633",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143923_588633/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763143923_588633/deliverables/result.json",
|
||||
"updated_at": 1763143944.4546719,
|
||||
"ready_at": 1763143943.580575,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763144220_abb092": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763144220_abb092",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763144220_abb092/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763144220_abb092/deliverables/result.json",
|
||||
"updated_at": 1763144242.2311318,
|
||||
"ready_at": 1763144240.835765,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作。请执行一些基础操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763144317_eabeba": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763144317_eabeba",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763144317_eabeba/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763144317_eabeba/deliverables/result.json",
|
||||
"updated_at": 1763144337.5016708,
|
||||
"ready_at": 1763144337.132025,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体功能是否正常工作"
|
||||
},
|
||||
"sub_1_1763144744_81368a": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763144744_81368a",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763144744_81368a/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763144744_81368a/deliverables/result.json",
|
||||
"updated_at": 1763144765.530027,
|
||||
"ready_at": 1763144764.7613509,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体系统的基础功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
},
|
||||
"sub_1_1763145242_d44a87": {
|
||||
"success": true,
|
||||
"task_id": "sub_1_1763145242_d44a87",
|
||||
"status": "completed",
|
||||
"message": "测试子智能体已生成占位结果。",
|
||||
"deliverables_dir": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763145242_d44a87/deliverables",
|
||||
"result_file": "/Users/jojo/Desktop/agents/正在修复中/agents/sub_agent/tasks/sub_1_1763145242_d44a87/deliverables/result.json",
|
||||
"updated_at": 1763145263.388503,
|
||||
"ready_at": 1763145262.3055072,
|
||||
"summary": "测试子智能体基础功能",
|
||||
"task_description": "这是一个测试任务,用于验证子智能体的基础功能是否正常工作。请执行一些简单的操作并返回结果。"
|
||||
}
|
||||
}
|
||||
@ -2363,6 +2363,48 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
|
||||
web_terminal.pending_modify_request = None
|
||||
return result
|
||||
|
||||
async def process_sub_agent_updates(
|
||||
messages: List[Dict],
|
||||
inline: bool = False,
|
||||
after_tool_call_id: Optional[str] = None
|
||||
):
|
||||
"""轮询子智能体任务并通知前端,并把结果插入当前对话上下文。"""
|
||||
manager = getattr(web_terminal, "sub_agent_manager", None)
|
||||
if not manager:
|
||||
return
|
||||
try:
|
||||
updates = manager.poll_updates()
|
||||
debug_log(f"[SubAgent] poll inline={inline} updates={len(updates)}")
|
||||
except Exception as exc:
|
||||
debug_log(f"子智能体状态检查失败: {exc}")
|
||||
return
|
||||
for update in updates:
|
||||
message = update.get("system_message")
|
||||
if not message:
|
||||
continue
|
||||
task_id = update.get("task_id")
|
||||
debug_log(f"[SubAgent] update task={task_id} inline={inline} msg={message}")
|
||||
web_terminal._record_sub_agent_message(message, task_id, inline=inline)
|
||||
debug_log(f"[SubAgent] recorded task={task_id}, 计算插入位置")
|
||||
|
||||
insert_index = len(messages)
|
||||
if after_tool_call_id:
|
||||
for idx, msg in enumerate(messages):
|
||||
if msg.get("role") == "tool" and msg.get("tool_call_id") == after_tool_call_id:
|
||||
insert_index = idx + 1
|
||||
break
|
||||
|
||||
messages.insert(insert_index, {
|
||||
"role": "system",
|
||||
"content": message,
|
||||
"metadata": {"sub_agent_notice": True, "inline": inline, "task_id": task_id}
|
||||
})
|
||||
debug_log(f"[SubAgent] 插入系统消息位置: {insert_index}")
|
||||
sender('system_message', {
|
||||
'content': message,
|
||||
'inline': inline
|
||||
})
|
||||
|
||||
for iteration in range(max_iterations):
|
||||
total_iterations += 1
|
||||
debug_log(f"\n--- 迭代 {iteration + 1}/{max_iterations} 开始 ---")
|
||||
@ -2919,7 +2961,7 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
|
||||
web_terminal.context_manager.add_conversation("system", follow_prompt)
|
||||
debug_log("已注入追加任务提示")
|
||||
|
||||
if not append_result.get("success"):
|
||||
if append_result["handled"] and not append_result.get("success"):
|
||||
sender('system_message', {
|
||||
'content': f'⚠️ 追加写入失败:{append_result.get("error")}'
|
||||
})
|
||||
@ -2995,7 +3037,7 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
|
||||
web_terminal.context_manager.add_conversation("system", follow_prompt)
|
||||
debug_log("已注入修改任务提示")
|
||||
|
||||
if not modify_result.get("success"):
|
||||
if modify_result["handled"] and not modify_result.get("success"):
|
||||
error_message = modify_result.get("summary_message") or modify_result.get("error") or "修改操作未成功,请根据提示重新执行。"
|
||||
sender('system_message', {
|
||||
'content': f'⚠️ 修改操作存在未完成的内容:{error_message}'
|
||||
@ -3006,6 +3048,7 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
|
||||
text_has_content = False
|
||||
full_response = ""
|
||||
|
||||
|
||||
# 保存思考内容(如果这是第一次迭代且有思考)
|
||||
if web_terminal.thinking_mode and web_terminal.api_client.current_task_first_call and current_thinking:
|
||||
web_terminal.api_client.current_task_thinking = current_thinking
|
||||
@ -3294,6 +3337,18 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
|
||||
else:
|
||||
debug_log("modify_file 返回完成状态")
|
||||
|
||||
if function_name == "wait_sub_agent":
|
||||
system_msg = result_data.get("system_message")
|
||||
if system_msg:
|
||||
messages.append({
|
||||
"role": "system",
|
||||
"content": system_msg
|
||||
})
|
||||
sender('system_message', {
|
||||
'content': system_msg,
|
||||
'inline': False
|
||||
})
|
||||
|
||||
update_payload = {
|
||||
'id': tool_display_id,
|
||||
'status': action_status,
|
||||
@ -3342,6 +3397,9 @@ async def handle_task_with_sender(terminal: WebTerminal, message, sender, client
|
||||
"content": tool_result_content
|
||||
})
|
||||
|
||||
if function_name not in ['append_to_file', 'modify_file']:
|
||||
await process_sub_agent_updates(messages, inline=True, after_tool_call_id=tool_call_id)
|
||||
|
||||
await asyncio.sleep(0.2)
|
||||
|
||||
# 标记不再是第一次迭代
|
||||
|
||||
Loading…
Reference in New Issue
Block a user