zcbot/scripts
caoqianming 1685004f96 feat(loop): 空响应防御——provider 吐空自动重试 + warn 自停不静默 done + 面板留痕(bump 0.58.32)
task 2a1bc25d 复盘:unifyllm 网关对某档 Claude 偶发把 tool_use 漏成正文/直接吐空,回来的轮
tool_calls=[] 且正文空,loop 当"模型答完"静默 done(run_status=idle、无报错、无终态失败),
表现为"自己中断",只能人肉挖 DB 才发现。复测该 bug 现已消失/瞬态,但"空 tool_calls 直接
done"这个失败模式本身太隐蔽,任何 provider 未来吐一次空都会静默卡死,故加防御(对称既有畸形
salvage 链)。

- _is_empty_response(tc 空且 content 去空白为空;纯 tool_call 轮不误判)挂进 _stream_llm 的
  attempt 循环:空-空丢弃本轮走非流式重试(多数瞬态重发一次即恢复,用户无感)
- run() 收尾点分空-空分支:重试耗尽仍空不发静默 done,改发可见 warn「模型返回空响应,已停止,
  回复继续可重试」+ done(复用 stall 熔断自停话术,run_status 落 idle 可续),不引入终态 error
- _log_empty_response stdout + usage_events(kind=empty_response,cost 0)双写留痕;core/toolfail
  加第四段扫描聚成 tool=(empty)/kind=empty cluster(sample=model_profile 看哪个网关档在吐空),
  admin 面板 + 巡检邮件零改动自动带上(单次瞬态 <阈值不触发,跨 task 系统性吐空才冒头)
- 刻意不做内容嗅探式"narrated tool_call 特征→重试":marker 每次变且与正常正文高度重叠,假阳性
  (合法回答判坏反复重试)比罕见静默停更糟,那类只靠面板留痕兜、不改热路径行为
- tests: test_loop_empty_response.py 新增 7 件 + test_toolfail_malformed.py +2;顺手补回
  test_loop_malformed_retry.py 因 salvage(0.58.24)落地后失修的 loop.executor 桩。全 247 测试绿

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 15:29:49 +08:00
..
_smoke_proposal_diagrams.py skill(proposal): mermaid 管线 + render_docx 图片插入 + 图题自动编号 2026-05-18 21:37:16 +08:00
backfill_chat_cost_cache_discount.py fix(usage): 缓存命中率同源(修 822% 怪值)+ 列表花费改 hover + backfill 加 --assume-cache-hit-rate 2026-06-05 08:41:51 +08:00
backfill_tool_message_name.py fix(loop): tool message append 补 name 字段 + backfill 历史 — 修历史 task 重开后 seedream banner/chip 不展示 2026-05-21 08:14:23 +08:00
diag_asr.py feat(web): 语音输入(讯飞语音听写 IAT)(bump 0.47.0) 2026-07-07 14:16:58 +08:00
diag_dump_task.py fix(sandbox): docker run 加 --shm-size 修 mmdc 渲 mermaid 挂超时 + bump 0.12.5 2026-06-14 10:40:45 +08:00
diag_error_retry.py feat(tools+loop): 批量抓取 + 重复调用守卫 —— 治高轮数烧 token 2026-06-08 16:47:56 +08:00
diag_lfasr.py feat(asr): 录音文件转写工具 transcribe_audio(讯飞 LFASR,bump 0.53.0) 2026-07-08 15:33:14 +08:00
diag_mmdc_history2.py fix(sandbox): pids-limit 256→1024 修容器内 mermaid 渲染必崩(bump 0.58.2) 2026-07-11 09:02:45 +08:00
diag_mmdc_ok_case.py fix(sandbox): pids-limit 256→1024 修容器内 mermaid 渲染必崩(bump 0.58.2) 2026-07-11 09:02:45 +08:00
diag_narrated_toolcall_2a1bc25d.py feat(loop): 空响应防御——provider 吐空自动重试 + warn 自停不静默 done + 面板留痕(bump 0.58.32) 2026-07-15 15:29:49 +08:00
diag_progress_d1285247.py fix(web): 进度条自愈——回放层强制单调完成(d1285247 复盘,bump 0.36.2) 2026-07-03 11:16:34 +08:00
diag_run_python_empty.py fix(context): 不压 assistant tool_call 参数,断 run_python 投毒空转 2026-06-12 10:41:54 +08:00
diag_run_python_noent.py fix(exec): run_python script_path 宿主预检+前缀容错+code 落盘回退(bump 0.58.22) 2026-07-13 16:41:43 +08:00
diag_run_python_noent2.py fix(exec): run_python script_path 宿主预检+前缀容错+code 落盘回退(bump 0.58.22) 2026-07-13 16:41:43 +08:00
diag_run_python_trace.py fix(context): 不压 assistant tool_call 参数,断 run_python 投毒空转 2026-06-12 10:41:54 +08:00
diag_sched_e621.py fix(scheduler): 定时任务超时被掐断时记 error 而非误吞成 ok(bump 0.32.2) 2026-06-29 14:35:40 +08:00
diag_search_args.py feat(tools+loop): 批量抓取 + 重复调用守卫 —— 治高轮数烧 token 2026-06-08 16:47:56 +08:00
diag_task_2a1bc25d.py feat(loop): 空响应防御——provider 吐空自动重试 + warn 自停不静默 done + 面板留痕(bump 0.58.32) 2026-07-15 15:29:49 +08:00
diag_task_9dcae061.py fix(sandbox): pids-limit 256→1024 修容器内 mermaid 渲染必崩(bump 0.58.2) 2026-07-11 09:02:45 +08:00
diag_tool_repeat.py feat(tools+loop): 批量抓取 + 重复调用守卫 —— 治高轮数烧 token 2026-06-08 16:47:56 +08:00
diag_unifyllm.py feat(models): unifyllm 再加 gpt-5.5 / gpt-5.4-mini 进 pro 档(bump 0.58.1) 2026-07-10 21:06:37 +08:00
diag_wechat_push.py fix(wechat,email): host-side 文件工具翻译容器路径,修复附件发不出 + bump 0.24.1 2026-06-24 14:02:48 +08:00
diag_wecom.py fix(wecom): diag_wecom 加 sys.path 仓库根 + 手动 .env 兜底(直跑不再 ModuleNotFoundError)+ bump 0.26.5 2026-06-25 10:16:17 +08:00
optimize_arch_ppt.py docs: 用户操作说明书(详+精简)+ 文献库口径 21W→100W + bump 0.16.2 2026-06-17 10:34:08 +08:00
probe_clawbot.py feat(wechat): ClawBot 个人微信接入第一期(后端 + 绑定页)+ 双渠道设计 §8.7 + bump 0.22.0 2026-06-24 08:59:56 +08:00
probe_clawbot_chat.py feat(wechat): ClawBot 个人微信接入第一期(后端 + 绑定页)+ 双渠道设计 §8.7 + bump 0.22.0 2026-06-24 08:59:56 +08:00
probe_clawbot_clientid.py feat(wechat): ClawBot 个人微信接入第一期(后端 + 绑定页)+ 双渠道设计 §8.7 + bump 0.22.0 2026-06-24 08:59:56 +08:00
probe_clawbot_file.py feat(wechat): ClawBot 个人微信接入第一期(后端 + 绑定页)+ 双渠道设计 §8.7 + bump 0.22.0 2026-06-24 08:59:56 +08:00
probe_clawbot_stream.py feat(wechat): ClawBot 个人微信接入第一期(后端 + 绑定页)+ 双渠道设计 §8.7 + bump 0.22.0 2026-06-24 08:59:56 +08:00
probe_clawbot_token.py feat(wechat): ClawBot 个人微信接入第一期(后端 + 绑定页)+ 双渠道设计 §8.7 + bump 0.22.0 2026-06-24 08:59:56 +08:00
probe_seedream_i2i.py design: 加 §8.1 seedream i2i + vision 后续步骤 + probe 实测 base64 通 2026-05-29 12:47:04 +08:00
smoke_files_rename.py api+ui(files): POST /v1/files/delete 加 recursive 字段 — 顶层目录被 task 引用闸 + dev SPA 二次确认显示条目数 2026-05-20 14:38:58 +08:00
smoke_look_at_image.py feat(media): look_at_image 图像理解(豆包 Seed 2.0 Lite vision)+ bump 0.16.0 2026-06-16 16:20:05 +08:00
smoke_paper_skill.py feat(research): paper_server 接口对接 API Key(bump 0.39.2) 2026-07-06 11:15:51 +08:00
smoke_scheduler.py test(scheduler): 定时任务端到端 smoke + tick 默认 30s→10s + bump 0.20.1 2026-06-18 15:48:44 +08:00
smoke_scientific_skills.py feat(tools): documents/pymatgen secret-bearing 能力改 host-side tools,key 不进 sandbox 2026-06-01 09:35:10 +08:00
smoke_seedance.py feat(seedance): 加 seedance_2_pro variant + smoke 支持 --variant 参数 2026-05-22 10:11:31 +08:00
smoke_seedream.py feat(media): 接入豆包 Seedream 5.0 图像生成 tool + 0007 cost_usd→cost_cny 全表统一币种 2026-05-20 15:20:34 +08:00
smoke_transcribe_audio.py feat(asr): 录音文件转写工具 transcribe_audio(讯飞 LFASR,bump 0.53.0) 2026-07-08 15:33:14 +08:00
test_bgproc_manual.py feat(procs): 后台进程 bg proc + 对话锁/完成通知 + seedance 续查(bump 0.56.0) 2026-07-10 16:47:11 +08:00
test_gpt_image_manual.py feat(media): 第二图像后端 gpt_image(unifyllm 网关,pro 档)(bump 0.58.0) 2026-07-10 20:47:06 +08:00