feat(sub_agent): 交付目录改为可选,未指定时自动创建
deliverables_dir 移出必填:留空时自动在 .astrion/sub_agent_results/ 下创建(撞名自动加后缀),最终路径作为工具结果返回;显式传入已存在目录仍报错。 Co-authored-by: Astrion powered by DeepSeek-V4-Flash <astrion-agent@users.noreply.github.com>
This commit is contained in:
parent
04770e0af9
commit
10a2763f00
@ -133,7 +133,7 @@ class ToolsDefinitionAgentToolsMixin:
|
|||||||
},
|
},
|
||||||
"deliverables_dir": {
|
"deliverables_dir": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "交付文件夹的相对路径(相对于项目根目录)。子智能体会将所有结果文件放在此目录。\n\n要求:必须是不存在的新目录;若目录不存在会自动创建;若目录已存在(无论是否为空)将报错。\n\n留空则使用默认路径:sub_agent_results/agent_{agent_id}\n\n示例:'docs/api'、'reports/performance'、'tests/generated'"
|
"description": "交付文件夹的相对路径(相对于项目根目录)。子智能体会将所有结果文件放在此目录。\n\n显式传入时:必须是不存在的新目录,若已存在(无论是否为空)将报错。\n\n留空时:自动在 .astrion/sub_agent_results/ 下创建(如 agent_{agent_id}),最终路径会作为工具结果返回。\n\n示例:'docs/api'、'reports/performance'、'tests/generated'"
|
||||||
},
|
},
|
||||||
"run_in_background": {
|
"run_in_background": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@ -149,7 +149,7 @@ class ToolsDefinitionAgentToolsMixin:
|
|||||||
"description": "子智能体思考模式,根据任务复杂度选择:\n\nfast(快速模式)- 适合简单明确的任务:\n- 网络信息搜集和整理\n- 批量文件读取和简单处理\n- 执行已知的命令序列\n- 生成简单的文档或报告\n- 数据格式转换\n\nthinking(思考模式)- 适合复杂任务:\n- 代码架构分析和重构设计\n- 复杂算法实现和优化\n- 多步骤问题诊断和调试\n- 技术方案选型和对比\n- 需要深度推理的代码审查\n\n不填则使用默认模式。"
|
"description": "子智能体思考模式,根据任务复杂度选择:\n\nfast(快速模式)- 适合简单明确的任务:\n- 网络信息搜集和整理\n- 批量文件读取和简单处理\n- 执行已知的命令序列\n- 生成简单的文档或报告\n- 数据格式转换\n\nthinking(思考模式)- 适合复杂任务:\n- 代码架构分析和重构设计\n- 复杂算法实现和优化\n- 多步骤问题诊断和调试\n- 技术方案选型和对比\n- 需要深度推理的代码审查\n\n不填则使用默认模式。"
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
"required": ["agent_id", "summary", "task", "deliverables_dir", "thinking_mode"]
|
"required": ["agent_id", "summary", "task", "thinking_mode"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -103,22 +103,22 @@ class SubAgentCreationMixin:
|
|||||||
return "任务摘要不能为空"
|
return "任务摘要不能为空"
|
||||||
if not task or not task.strip():
|
if not task or not task.strip():
|
||||||
return "任务详情不能为空"
|
return "任务详情不能为空"
|
||||||
# 多智能体模式不需要交付目录
|
# 交付目录不再必填:传统模式未指定时自动创建(见 _resolve_deliverables_dir)
|
||||||
if not multi_agent_mode and target_dir is None:
|
|
||||||
return "指定文件夹不能为空"
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _generate_task_id(self, agent_id: int) -> str:
|
def _generate_task_id(self, agent_id: int) -> str:
|
||||||
suffix = uuid.uuid4().hex[:6]
|
suffix = uuid.uuid4().hex[:6]
|
||||||
return f"sub_{agent_id}_{int(time.time())}_{suffix}"
|
return f"sub_{agent_id}_{int(time.time())}_{suffix}"
|
||||||
|
|
||||||
def _resolve_deliverables_dir(self, relative_dir: Optional[str], *, multi_agent_mode: bool = False) -> Path:
|
def _resolve_deliverables_dir(self, relative_dir: Optional[str], *, agent_id: int = 0, multi_agent_mode: bool = False) -> Path:
|
||||||
relative_dir = (relative_dir or "").strip()
|
relative_dir = (relative_dir or "").strip()
|
||||||
# 多智能体模式:没有交付目录概念,直接使用项目根目录
|
# 多智能体模式:没有交付目录概念,直接使用项目根目录
|
||||||
if multi_agent_mode and not relative_dir:
|
if multi_agent_mode and not relative_dir:
|
||||||
return self.project_path.resolve()
|
return self.project_path.resolve()
|
||||||
if not relative_dir:
|
if not relative_dir:
|
||||||
raise ValueError(tr("sub_agent_creation.deliverables_dir_required"))
|
# 未显式指定交付目录:在运行时目录 .astrion/sub_agent_results/ 下自动创建
|
||||||
|
#(撞名自动加后缀,保证总能建成),实际路径由 create_sub_agent 结果返回
|
||||||
|
return self._auto_deliverables_dir(agent_id)
|
||||||
deliverables_path = (self.project_path / relative_dir).resolve()
|
deliverables_path = (self.project_path / relative_dir).resolve()
|
||||||
if not str(deliverables_path).startswith(str(self.project_path)):
|
if not str(deliverables_path).startswith(str(self.project_path)):
|
||||||
raise ValueError(tr("sub_agent_creation.deliverables_dir_outside"))
|
raise ValueError(tr("sub_agent_creation.deliverables_dir_outside"))
|
||||||
@ -126,3 +126,15 @@ class SubAgentCreationMixin:
|
|||||||
raise ValueError(tr("sub_agent_creation.deliverables_dir_not_new"))
|
raise ValueError(tr("sub_agent_creation.deliverables_dir_not_new"))
|
||||||
deliverables_path.mkdir(parents=True, exist_ok=True)
|
deliverables_path.mkdir(parents=True, exist_ok=True)
|
||||||
return deliverables_path
|
return deliverables_path
|
||||||
|
|
||||||
|
def _auto_deliverables_dir(self, agent_id: int) -> Path:
|
||||||
|
"""未指定交付目录时自动创建:.astrion/sub_agent_results/agent_{id}(撞名追加后缀)。"""
|
||||||
|
base = (self.project_path / ".astrion" / "sub_agent_results").resolve()
|
||||||
|
base.mkdir(parents=True, exist_ok=True)
|
||||||
|
candidate = base / f"agent_{agent_id}"
|
||||||
|
suffix = 2
|
||||||
|
while candidate.exists():
|
||||||
|
candidate = base / f"agent_{agent_id}_{suffix}"
|
||||||
|
suffix += 1
|
||||||
|
candidate.mkdir(parents=True, exist_ok=True)
|
||||||
|
return candidate
|
||||||
|
|||||||
@ -284,7 +284,7 @@ class SubAgentManager(SubAgentStateMixin, SubAgentStatsMixin, SubAgentCreationMi
|
|||||||
task_root.mkdir(parents=True, exist_ok=True)
|
task_root.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
deliverables_path = self._resolve_deliverables_dir(deliverables_dir, multi_agent_mode=multi_agent_mode)
|
deliverables_path = self._resolve_deliverables_dir(deliverables_dir, agent_id=agent_id, multi_agent_mode=multi_agent_mode)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
# 回滚已创建的任务目录,避免残留状态(交付目录校验失败时 deliverables 不会创建)
|
# 回滚已创建的任务目录,避免残留状态(交付目录校验失败时 deliverables 不会创建)
|
||||||
shutil.rmtree(task_root, ignore_errors=True)
|
shutil.rmtree(task_root, ignore_errors=True)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user