backend/frontend/runtime: 训练面板 / session 隔离 / agent runtime 调整

- 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>
This commit is contained in:
hupenglong1
2026-05-25 11:43:10 +08:00
parent 57f5b60a3e
commit f068311cac
17 changed files with 1571 additions and 270 deletions
+7 -49
View File
@@ -10,51 +10,6 @@ def build_execution_tools(handlers: Mapping[str, ToolHandler]) -> list[AgentTool
"""构建本地命令、Python 执行与短等待工具声明。"""
return [
AgentTool(
name='python_exec',
description=(
'优先用本工具执行小型 Python 代码或项目内 Python 脚本,用于结构化文件分析、'
'JSON/JSONL 处理、批量校验、数据抽样和快速计算。默认使用当前用户独立 Python venv'
'不要用 bash 运行 python/python3/.venv/bin/python。不要用本工具安装依赖。'
'缺包时应向用户确认后再处理依赖。一次性分析优先传 code;项目或 skill 内已有脚本优先传 script_path'
'不要在 code 里用 subprocess 二次调用 Python 脚本。如需写临时文件,'
'必须写入环境变量 PYTHON_EXEC_SCRATCHPAD 指向的会话隔离目录,'
'不要在项目根目录创建临时 .py 脚本。'
),
parameters={
'type': 'object',
'properties': {
'code': {
'type': 'string',
'description': '要通过 python -c 执行的 Python 代码。code 和 script_path 必须二选一;一次性分析优先使用 code。',
},
'script_path': {
'type': 'string',
'description': '工作区内已有、需要长期复用的 Python 脚本路径。code 和 script_path 必须二选一;不要为一次性分析在项目根目录新建脚本。',
},
'args': {
'type': 'array',
'items': {'type': 'string'},
'description': '传给脚本的命令行参数。仅在 script_path 模式下使用。',
},
'stdin': {
'type': 'string',
'description': '可选标准输入内容。',
},
'timeout_seconds': {
'type': 'number',
'minimum': 1,
'description': '可选超时时间,默认 30 秒。读大 CSV/JSONL、pandas 分析、批量校验、训练评测脚本等可能 >30s 的任务必须显式传值(常规 120-300、训练/长跑 600+)。',
},
'max_output_chars': {
'type': 'integer',
'minimum': 100,
'description': '可选输出截断长度,默认使用当前会话输出限制。',
},
},
},
handler=resolve_handler(handlers, 'python_exec', 'execution'),
),
AgentTool(
name='python_package',
description=(
@@ -94,10 +49,13 @@ def build_execution_tools(handlers: Mapping[str, ToolHandler]) -> list[AgentTool
AgentTool(
name='bash',
description=(
'运行真实 shell 命令,例如系统命令、进程控制、git 只读检查用户已确认的依赖安装'
'不要用 bash 执行 python、python3、pip 或 .venv/bin/python;结构化文件分析、'
'JSON/JSONL 处理、批量校验、数据抽样和快速计算必须优先使用 python_exec。'
'Python 包安装必须优先使用 python_package。'
'运行真实 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 时进程结束后会自动起新一轮把结果送回。'
+5 -5
View File
@@ -41,8 +41,8 @@ def build_file_tools(handlers: Mapping[str, ToolHandler]) -> list[AgentTool]:
description=(
'Write or append a SMALL UTF-8 file inside the workspace. Creates parent directories when needed. '
'Use this for short notes, lightweight markdown, and small config files. '
'For Python scripts, JSONL, large JSON/CSV, generated datasets, or quote-heavy/multi-line content, prefer python_exec '
'to write the file with pathlib/json/csv; do not pack large content into tool arguments.'
'For Python scripts, JSONL, large JSON/CSV, generated datasets, or quote-heavy/multi-line content, prefer bash with a quoted heredoc '
"(e.g. `cat > scratchpad/foo.py <<'EOF' ... EOF`); do not pack large content into tool arguments."
),
parameters={
'type': 'object',
@@ -51,7 +51,7 @@ def build_file_tools(handlers: Mapping[str, ToolHandler]) -> list[AgentTool]:
'content_lines': {
'type': 'array',
'items': {'type': 'string'},
'description': 'Lines to join with "\\n"; use only for short text/markdown or small scripts. For long scripts use python_exec to create the file.',
'description': 'Lines to join with "\\n"; use only for short text/markdown or small scripts. For long scripts use bash with a quoted heredoc to create the file.',
},
'content': {
'type': 'string',
@@ -63,12 +63,12 @@ def build_file_tools(handlers: Mapping[str, ToolHandler]) -> list[AgentTool]:
},
'json_content': {
'type': 'object',
'description': 'Small JSON value to serialize with ensure_ascii=false and indent=2. For large JSON use python_exec streaming write.',
'description': 'Small JSON value to serialize with ensure_ascii=false and indent=2. For large JSON write a small Python script to scratchpad and run it via bash.',
},
'jsonl_records': {
'type': 'array',
'items': {'type': 'object'},
'description': 'Small list of objects to serialize as compact JSONL. For more than a few dozen records or generated datasets use python_exec.',
'description': 'Small list of objects to serialize as compact JSONL. For more than a few dozen records or generated datasets, write a Python script to scratchpad and run it via bash.',
},
'csv_headers': {
'type': 'array',