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:
@@ -162,8 +162,8 @@ def get_doing_tasks_section() -> str:
|
||||
'不要为了单次操作创建 helper 或抽象。优先使用能完整解决问题的最简单实现。',
|
||||
'除非确实需要新文件,否则优先编辑现有文件。',
|
||||
'对于文件解析、表格转换、JSON 或 JSONL 处理、日志分析、批量校验、数据抽样等任务,如果小型 Python 脚本比手工文本处理更可靠,可以编写小型 Python 脚本。',
|
||||
'小脚本应短小、可读,并明确输入和输出。需要执行 Python 代码或 Python 脚本时,使用 python_exec;不要通过 bash 执行 python、python3 或 .venv/bin/python。',
|
||||
'一次性 Python 分析优先直接传给 python_exec.code,不要为了临时分析创建项目文件。',
|
||||
'小脚本应短小、可读,并明确输入和输出。需要执行 Python 时,把代码写到 session/scratchpad 下的 .py 文件,再用 bash 跑 `python3 -u <script> 2>&1 | tee <log>`;`-u` 关 stdout 缓冲、`tee` 让进度行实时落盘,超时被 kill 时仍能 tail 日志看到死在哪。不要把多行 Python 代码以 `-c` 字符串方式塞进 bash command。',
|
||||
'一次性 Python 分析也走脚本文件 + bash,不要为了临时分析在项目根目录创建脚本,scratchpad 是默认临时区。',
|
||||
'如果确实需要临时脚本、缓存或中间产物,必须写入当前 session/scratchpad;交付产物必须优先写入当前 session/output。',
|
||||
'只有用户明确要求长期复用或该脚本属于产品代码时,才把 Python 脚本加入项目源码目录。',
|
||||
'当事情失败时,先诊断原因再改变方向。不要对同一个失败动作反复循环。',
|
||||
|
||||
@@ -1620,9 +1620,9 @@ class LocalCodingAgent:
|
||||
'请回复“继续”,我会要求模型重新生成合法 JSON 参数;'
|
||||
'如果是 write_file 写短文本/Markdown,应改用 content_lines;'
|
||||
'如果是很小的 JSON/JSONL/CSV,可用 json_content、jsonl_records 或 csv_rows;'
|
||||
'如果是脚本、长文本、大 JSON、JSONL、CSV 或生成数据,应直接改用 python_exec 写文件;'
|
||||
'如果是生成/转换结构化数据,应优先调用对应 skill 脚本或 python_exec,'
|
||||
'不要把大段内容直接塞进工具参数;bash 仅作为最后兜底。'
|
||||
'如果是脚本、长文本、大 JSON、JSONL、CSV 或生成数据,应改用 bash 配合 quoted heredoc 写文件,'
|
||||
'或先 write_file 落地一个小 .py 再用 bash 跑;'
|
||||
'不要把大段内容直接塞进工具参数。'
|
||||
) from exc
|
||||
if not isinstance(arguments, dict):
|
||||
raise OpenAICompatError(
|
||||
|
||||
@@ -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 时进程结束后会自动起新一轮把结果送回。'
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -117,7 +117,6 @@ def default_tool_registry() -> dict[str, AgentTool]:
|
||||
'grep_search': _grep_search,
|
||||
}),
|
||||
*build_execution_tools({
|
||||
'python_exec': _run_python_exec,
|
||||
'python_package': _run_python_package,
|
||||
'bash': _run_bash,
|
||||
'bash_status': _run_bash_status,
|
||||
|
||||
Reference in New Issue
Block a user