f068311cac
- backend/api/server.py:训练 step-detail / pipeline 卡片排序逻辑 - frontend:thread-list / thread / training-pipeline-panel / step-detail-sheet 配套调整,新增 metrics-chart-panel - src/agent_*:tool spec / runtime / prompting 配套 - .gitignore 加 .logs/ Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
150 lines
6.8 KiB
Python
150 lines
6.8 KiB
Python
from __future__ import annotations
|
||
|
||
from collections.abc import Mapping
|
||
|
||
from ..agent_tool_core import AgentTool, ToolHandler
|
||
from ._builder import resolve_handler
|
||
|
||
|
||
def build_execution_tools(handlers: Mapping[str, ToolHandler]) -> list[AgentTool]:
|
||
"""构建本地命令、Python 执行与短等待工具声明。"""
|
||
|
||
return [
|
||
AgentTool(
|
||
name='python_package',
|
||
description=(
|
||
'在当前用户独立 Python venv 中检查或安装 Python 包。'
|
||
'用于 python_exec 缺少 pandas、pyarrow、openpyxl 等分析依赖时;'
|
||
'不要通过 bash 执行 pip,也不要安装到项目 .venv。'
|
||
),
|
||
parameters={
|
||
'type': 'object',
|
||
'properties': {
|
||
'action': {
|
||
'type': 'string',
|
||
'enum': ['show', 'install'],
|
||
'description': 'show 查看当前 Python 环境和 pip;install 安装 packages。',
|
||
},
|
||
'packages': {
|
||
'type': 'array',
|
||
'items': {'type': 'string'},
|
||
'description': '要安装的包名或 pip requirement spec,例如 pandas、pyarrow==15.0.0。',
|
||
},
|
||
'timeout_seconds': {
|
||
'type': 'number',
|
||
'minimum': 1,
|
||
'maximum': 600,
|
||
'description': '安装超时时间,默认 120 秒。',
|
||
},
|
||
'max_output_chars': {
|
||
'type': 'integer',
|
||
'minimum': 1000,
|
||
'maximum': 50000,
|
||
},
|
||
},
|
||
'required': ['action'],
|
||
},
|
||
handler=resolve_handler(handlers, 'python_package', 'execution'),
|
||
),
|
||
AgentTool(
|
||
name='bash',
|
||
description=(
|
||
'运行真实 shell 命令,包括系统命令、进程控制、git 只读检查、用户已确认的依赖安装,'
|
||
'以及所有 Python 脚本执行。'
|
||
'执行 Python 时,把代码先写到 scratchpad 下的 .py 文件,'
|
||
'再用本工具跑 `python3 -u <script> 2>&1 | tee <log>`;'
|
||
'`-u` 关掉 stdout 缓冲,`tee` 让进度行实时落盘,超时被 kill 时仍能 `tail` 日志看到死在哪个 phase。'
|
||
'不要把多行 Python 代码以 `-c` 字符串方式塞进 command。'
|
||
'Python 包安装必须优先使用 python_package;不要通过 bash 执行 pip。'
|
||
'需要等待远端长任务(>30s 的训练、文件落盘、外部 API 回调)时,'
|
||
'设置 run_in_background=true 让命令在后台 detach 跑、立刻返回 task_id;'
|
||
'默认 wait_for_completion=true 时进程结束后会自动起新一轮把结果送回。'
|
||
'后台任务输出落在 <remote_workspace>/.bg_tasks/<task_id>/output。'
|
||
),
|
||
parameters={
|
||
'type': 'object',
|
||
'properties': {
|
||
'command': {'type': 'string'},
|
||
'run_in_background': {
|
||
'type': 'boolean',
|
||
'description': (
|
||
'后台 detach 跑。立刻返回 task_id,不等命令结束。'
|
||
'适合 >30s 的远端任务、需要等异步事件的场景。'
|
||
),
|
||
},
|
||
'wait_for_completion': {
|
||
'type': 'boolean',
|
||
'description': (
|
||
'仅在 run_in_background=true 时生效。'
|
||
'true(默认):进程结束后由后端自动起新一轮把结果作为 system 消息送回;'
|
||
'false:不自动续,agent 需自行调 bash_status 取结果。'
|
||
),
|
||
},
|
||
},
|
||
'required': ['command'],
|
||
},
|
||
handler=resolve_handler(handlers, 'bash', 'execution'),
|
||
),
|
||
AgentTool(
|
||
name='bash_status',
|
||
description=(
|
||
'查询通过 bash(run_in_background=true) 启动的后台任务状态。'
|
||
'block=true 会阻塞到任务终止或 timeout_seconds 到期再返回;'
|
||
'block=false(默认)立刻返回当前快照。'
|
||
'返回 status (running/completed/failed/cancelled)、exit_code 和最近输出预览。'
|
||
),
|
||
parameters={
|
||
'type': 'object',
|
||
'properties': {
|
||
'task_id': {
|
||
'type': 'string',
|
||
'description': 'bash run_in_background 启动时返回的 task_id。',
|
||
},
|
||
'block': {
|
||
'type': 'boolean',
|
||
'description': '是否等到任务终止再返回;默认 false。',
|
||
},
|
||
'timeout_seconds': {
|
||
'type': 'number',
|
||
'minimum': 0,
|
||
'maximum': 600,
|
||
'description': 'block=true 时最长等待秒数,默认 30,上限 600。',
|
||
},
|
||
},
|
||
'required': ['task_id'],
|
||
},
|
||
handler=resolve_handler(handlers, 'bash_status', 'execution'),
|
||
),
|
||
AgentTool(
|
||
name='bash_kill',
|
||
description=(
|
||
'主动终止通过 bash(run_in_background=true) 启动的后台任务。'
|
||
'注意:用户在前端按 stop 取消当前 run 不会自动杀后台进程(detach 的本意),'
|
||
'需要明确调用本工具才能终止远端进程。'
|
||
),
|
||
parameters={
|
||
'type': 'object',
|
||
'properties': {
|
||
'task_id': {
|
||
'type': 'string',
|
||
'description': 'bash run_in_background 启动时返回的 task_id。',
|
||
},
|
||
},
|
||
'required': ['task_id'],
|
||
},
|
||
handler=resolve_handler(handlers, 'bash_kill', 'execution'),
|
||
),
|
||
AgentTool(
|
||
name='sleep',
|
||
description='Pause execution briefly for bounded local wait flows.',
|
||
parameters={
|
||
'type': 'object',
|
||
'properties': {
|
||
'seconds': {'type': 'number', 'minimum': 0.0, 'maximum': 5.0},
|
||
},
|
||
'required': ['seconds'],
|
||
},
|
||
handler=resolve_handler(handlers, 'sleep', 'execution'),
|
||
),
|
||
]
|