fix(sandbox): npm 步骤加重试,抗境内 mirror 断流(bump 0.52.3)
腾讯 npm 源拉 cytoscape 偶发 ECONNRESET 崩整个镜像 build(部署实测)。 fetch-retries 2->5 + fetch-retry-maxtimeout 120s;RUN 故障兜底补该行, 并写明部署不涉及镜像变化时用 update_bluegreen.sh --skip-build 跳过重建。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
2ca210dbad
commit
386a9ee048
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
### 2026-07
|
### 2026-07
|
||||||
|
|
||||||
|
- **07-08 / 0.52.3**:sandbox 镜像 npm 步骤加重试——腾讯 npm 源拉 cytoscape 偶发 ECONNRESET 崩整个 build(部署实测),fetch-retries 2→5 + retry-maxtimeout 120s;RUN 故障兜底补该行,并写明"部署不涉及镜像变化时用 `--skip-build` 跳过重建"。
|
||||||
- **07-08 / 0.52.2**:sandbox 镜像 build 剔除 host-only 依赖——pilk 进 requirements 后镜像 build 也去装它,slim 基底无 gcc 整个 build 编崩(部署实测)。容器内 run_python 用不到语音解码,方案:requirements 行尾标 `# [host-only]`,Dockerfile 装包前 `grep -v '\[host-only\]'` 过滤(通用机制,后续 host-only 依赖复用);不往镜像塞 build-essential(+~250MB 没收益)。
|
- **07-08 / 0.52.2**:sandbox 镜像 build 剔除 host-only 依赖——pilk 进 requirements 后镜像 build 也去装它,slim 基底无 gcc 整个 build 编崩(部署实测)。容器内 run_python 用不到语音解码,方案:requirements 行尾标 `# [host-only]`,Dockerfile 装包前 `grep -v '\[host-only\]'` 过滤(通用机制,后续 host-only 依赖复用);不往镜像塞 build-essential(+~250MB 没收益)。
|
||||||
- **07-08 / 0.52.1**:RUN 故障兜底补 pilk 源码编译坑——服务器 py3.12 无 pilk 预编译 wheel,pip 退源码编译撞缺 gcc(`x86_64-linux-gnu-gcc ... No such file or directory`),处理:`apt install build-essential python3-dev` 后重跑 update(用户部署实测踩到)。
|
- **07-08 / 0.52.1**:RUN 故障兜底补 pilk 源码编译坑——服务器 py3.12 无 pilk 预编译 wheel,pip 退源码编译撞缺 gcc(`x86_64-linux-gnu-gcc ... No such file or directory`),处理:`apt install build-essential python3-dev` 后重跑 update(用户部署实测踩到)。
|
||||||
- **07-08 / 0.52.0**:个人微信 ClawBot 语音接入(0.51.0 留的第二步)——用户真机发语音,0.51.0 加的 unhandled item 日志拿到结构:`voice_item`(type=3),media 与图片/文件同款 `{encrypt_query_param, aes_key}`,音频 SILK v3(`\x02#!SILK_V3` 头,ffmpeg 解不了)。实现:① `ilink.get_updates` 解析 voice_item → `InboundAttachment(kind="voice")`,CDN 下载/AES 解密全复用;② `core/audio.py` 重构出统一入口 `transcribe_voice(bytes)`(按字节头分流:SILK → pilk 解码 24k PCM + ffmpeg 重采样 16k,其余 AMR 等 → ffmpeg 直解),两渠道(wecom `_transcribe_wecom_voice` / ClawBot inbound)共用;③ `inbound._poll_binding` 语音附件就地转写:回执「🎤 已识别:…」→ 转写文本并入 m.text 进对话,不当文件落盘;失败回可读提示。**新依赖 pilk**(requirements,有 manylinux/win wheels)。已实测:pilk encode(tencent=True) 造微信同款 silk → 全链转写逐字正确,AMR 路径回归通过。另:**企微语音"无声失败"补日志**——用户报企微发语音无反应但日志无线索:voice 入站打 MediaId/Format 行、transcribe 异常打错误行、`push_wecom` 失败原样打 reason(原先返回值被忽略纯静默)、未处理 msgtype 也留行;待用户重测后按日志定位。企业微信语音消息转写进对话(0.47.0 留的二期)——回调新增 `msgtype=voice` 分支:media/get 下 AMR → 新模块 `core/audio.py`(ffmpeg 子进程 stdin/stdout 解成 16k/16bit/mono PCM,不落临时文件,格式自动探测)→ 复用 `asr_xfyun.transcribe()` → 转写文本当用户消息走同一条 `_run_channel_conversation` 链路。要点:① 下载/解码/转写全放后台任务(长语音数秒,inline 会踩企微 5s 回调窗口触发重推),回调只登记 MediaId 即回 success;② 识别结果先推「🎤 已识别:…」回显(微信端看不到识别成什么,识别错不回显用户一头雾水);③ 兜底分层:ffmpeg 缺失(AudioNotConfigured)/讯飞未配置(XfyunASRNotConfigured)/识别为空各回对应可读提示,不静默;④ 超 60s 截前 60s(讯飞上限,企微语音本身也限 60s);⑤ 未绑定成员发语音也回绑定指引(msgtype 白名单加 voice)。**服务器新增系统依赖 ffmpeg**(apt install ffmpeg / env FFMPEG_PATH,RUN.md env 段);个人微信 ClawBot 语音待真机探协议(getupdates 未识别 item 已加结构日志,预计 SILK v3 需 pilk 解码)。ppt 验收改纯代码几何质检,撤除 0.36.0 渲图 vision 验收闭环(DESIGN §8.10)——真实会话复盘:沙箱 chromium "找到了但渲染崩"无回退,硬门+死路逼模型 pip install cairosvg 手写渲染,look_at_image 逐页 26-42s 纯烧 token。删 accept_pages.py / acceptance.json 登记 / 导出验收门 / `--allow-unreviewed`;正确性由质检器 check13/14 几何检测保底(越界/压字/错位,导出边界自动复跑);svg_preview.py 保留为手动工具并修回退(chromium 渲染失败按页自动落 cairosvg),但 SKILL/SKILL_LIST **零提及渲图**(提示面不给渲染入口,模型不再主动渲);SKILL.md 阶段五简化为 finalize 单步 + 强调导出唯一入口 svg_to_pptx,Geometry warning 改"回源核对坐标"。放弃逐页美学验收,观感靠用户反馈迭代。
|
- **07-08 / 0.52.0**:个人微信 ClawBot 语音接入(0.51.0 留的第二步)——用户真机发语音,0.51.0 加的 unhandled item 日志拿到结构:`voice_item`(type=3),media 与图片/文件同款 `{encrypt_query_param, aes_key}`,音频 SILK v3(`\x02#!SILK_V3` 头,ffmpeg 解不了)。实现:① `ilink.get_updates` 解析 voice_item → `InboundAttachment(kind="voice")`,CDN 下载/AES 解密全复用;② `core/audio.py` 重构出统一入口 `transcribe_voice(bytes)`(按字节头分流:SILK → pilk 解码 24k PCM + ffmpeg 重采样 16k,其余 AMR 等 → ffmpeg 直解),两渠道(wecom `_transcribe_wecom_voice` / ClawBot inbound)共用;③ `inbound._poll_binding` 语音附件就地转写:回执「🎤 已识别:…」→ 转写文本并入 m.text 进对话,不当文件落盘;失败回可读提示。**新依赖 pilk**(requirements,有 manylinux/win wheels)。已实测:pilk encode(tencent=True) 造微信同款 silk → 全链转写逐字正确,AMR 路径回归通过。另:**企微语音"无声失败"补日志**——用户报企微发语音无反应但日志无线索:voice 入站打 MediaId/Format 行、transcribe 异常打错误行、`push_wecom` 失败原样打 reason(原先返回值被忽略纯静默)、未处理 msgtype 也留行;待用户重测后按日志定位。企业微信语音消息转写进对话(0.47.0 留的二期)——回调新增 `msgtype=voice` 分支:media/get 下 AMR → 新模块 `core/audio.py`(ffmpeg 子进程 stdin/stdout 解成 16k/16bit/mono PCM,不落临时文件,格式自动探测)→ 复用 `asr_xfyun.transcribe()` → 转写文本当用户消息走同一条 `_run_channel_conversation` 链路。要点:① 下载/解码/转写全放后台任务(长语音数秒,inline 会踩企微 5s 回调窗口触发重推),回调只登记 MediaId 即回 success;② 识别结果先推「🎤 已识别:…」回显(微信端看不到识别成什么,识别错不回显用户一头雾水);③ 兜底分层:ffmpeg 缺失(AudioNotConfigured)/讯飞未配置(XfyunASRNotConfigured)/识别为空各回对应可读提示,不静默;④ 超 60s 截前 60s(讯飞上限,企微语音本身也限 60s);⑤ 未绑定成员发语音也回绑定指引(msgtype 白名单加 voice)。**服务器新增系统依赖 ffmpeg**(apt install ffmpeg / env FFMPEG_PATH,RUN.md env 段);个人微信 ClawBot 语音待真机探协议(getupdates 未识别 item 已加结构日志,预计 SILK v3 需 pilk 解码)。ppt 验收改纯代码几何质检,撤除 0.36.0 渲图 vision 验收闭环(DESIGN §8.10)——真实会话复盘:沙箱 chromium "找到了但渲染崩"无回退,硬门+死路逼模型 pip install cairosvg 手写渲染,look_at_image 逐页 26-42s 纯烧 token。删 accept_pages.py / acceptance.json 登记 / 导出验收门 / `--allow-unreviewed`;正确性由质检器 check13/14 几何检测保底(越界/压字/错位,导出边界自动复跑);svg_preview.py 保留为手动工具并修回退(chromium 渲染失败按页自动落 cairosvg),但 SKILL/SKILL_LIST **零提及渲图**(提示面不给渲染入口,模型不再主动渲);SKILL.md 阶段五简化为 finalize 单步 + 强调导出唯一入口 svg_to_pptx,Geometry warning 改"回源核对坐标"。放弃逐页美学验收,观感靠用户反馈迭代。
|
||||||
|
|
|
||||||
1
RUN.md
1
RUN.md
|
|
@ -820,6 +820,7 @@ sudo xfs_quota -x -c "limit -p bhard=10g zcbot_<user_uuid>" /opt
|
||||||
| 镜像 build pip 报 `ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', ...)` | 境内访问 PyPI 抖动。加 `--build-arg PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple/`(清华,现默认)或腾讯 / 阿里源,详 RUN.md「镜像构建」段。Dockerfile 已把 pip timeout 拉到 60s,主因仍是源不通而非超时 |
|
| 镜像 build pip 报 `ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', ...)` | 境内访问 PyPI 抖动。加 `--build-arg PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple/`(清华,现默认)或腾讯 / 阿里源,详 RUN.md「镜像构建」段。Dockerfile 已把 pip timeout 拉到 60s,主因仍是源不通而非超时 |
|
||||||
| pip 报 `Could not find a version that satisfies the requirement litellm>=1.83.0`(伴随一串 `Ignored ... yanked versions: 0.1.xxxx`) | 用的镜像源同步滞后,没有该新版本。**阿里 PyPI 一度只到 litellm 1.82.6** —— update.sh 默认已是清华源(同步及时)。若手动 build 撞到:换 `PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple/` 或腾讯源。那串 `0.1.xxxx` 是 litellm 远古版本,纯干扰信息 |
|
| pip 报 `Could not find a version that satisfies the requirement litellm>=1.83.0`(伴随一串 `Ignored ... yanked versions: 0.1.xxxx`) | 用的镜像源同步滞后,没有该新版本。**阿里 PyPI 一度只到 litellm 1.82.6** —— update.sh 默认已是清华源(同步及时)。若手动 build 撞到:换 `PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple/` 或腾讯源。那串 `0.1.xxxx` 是 litellm 远古版本,纯干扰信息 |
|
||||||
| 镜像 build npm 装 mermaid-cli 慢 / fail | npm 源境内慢。默认已用腾讯 `https://mirrors.cloud.tencent.com/npm/`(清华无 npm 源;npmmirror 访问不稳被弃)。备选:华为 `https://repo.huaweicloud.com/repository/npm/` / USTC `https://npmreg.mirrors.ustc.edu.cn/`,手动 build 加 `--build-arg NPM_REGISTRY=...` |
|
| 镜像 build npm 装 mermaid-cli 慢 / fail | npm 源境内慢。默认已用腾讯 `https://mirrors.cloud.tencent.com/npm/`(清华无 npm 源;npmmirror 访问不稳被弃)。备选:华为 `https://repo.huaweicloud.com/repository/npm/` / USTC `https://npmreg.mirrors.ustc.edu.cn/`,手动 build 加 `--build-arg NPM_REGISTRY=...` |
|
||||||
|
| 镜像 build npm 报 `ECONNRESET ... Invalid response body while trying to fetch` | mirror 偶发断流(腾讯源实测),非配置问题。0.52.3 起 Dockerfile 已把 npm fetch-retries 拉到 5,一般重跑即过;**若本次部署不涉及镜像内容变化,直接 `update_bluegreen.sh --skip-build` 跳过重建**,镜像留到下次更新再建 |
|
||||||
| 镜像 build apt 报 `OpenSSL error: ... unexpected eof while reading` | 某些 mirror HTTPS 端偶发 close_notify 缺失,OpenSSL 3 严格 fail(腾讯 / 阿里见过;清华一般不犯)。改用 http 形式:`--build-arg APT_MIRROR=http://mirrors.tuna.tsinghua.edu.cn`(apt 包 GPG 签名校验,无 HTTPS 安全收益)。Dockerfile 已配 apt retry=5 + 关 pipeline,重 build 一般直接过 |
|
| 镜像 build apt 报 `OpenSSL error: ... unexpected eof while reading` | 某些 mirror HTTPS 端偶发 close_notify 缺失,OpenSSL 3 严格 fail(腾讯 / 阿里见过;清华一般不犯)。改用 http 形式:`--build-arg APT_MIRROR=http://mirrors.tuna.tsinghua.edu.cn`(apt 包 GPG 签名校验,无 HTTPS 安全收益)。Dockerfile 已配 apt retry=5 + 关 pipeline,重 build 一般直接过 |
|
||||||
| 容器内 shell 写工作目录报 `Permission denied`(but `sandbox check` ⑤ HOST_UID aligned ok) | DockerExecutor 写死了 `--user 1000:1000` 不会自动跟 build 的 HOST_UID 同步(改 `--user zcbot` 后已修)。仍报错检查镜像内 `docker run --rm --entrypoint id zcbot-sandbox:latest zcbot` 输出 uid 是否 = `id -u $(whoami)` |
|
| 容器内 shell 写工作目录报 `Permission denied`(but `sandbox check` ⑤ HOST_UID aligned ok) | DockerExecutor 写死了 `--user 1000:1000` 不会自动跟 build 的 HOST_UID 同步(改 `--user zcbot` 后已修)。仍报错检查镜像内 `docker run --rm --entrypoint id zcbot-sandbox:latest zcbot` 输出 uid 是否 = `id -u $(whoami)` |
|
||||||
| 容器内 mmdc 渲 mermaid 报 `Failed to launch chromium` / `No usable sandbox` | chromium 在 `--cap-drop=ALL` 下自家 setuid sandbox 起不来,要 `--no-sandbox`。镜像已落 `/sandbox/puppeteer-config.json` + 给 mmdc 套了 wrapper 自动 `-p` 注入 ── **裸调 `mmdc -i x -o y` 就该成**。仍跪:`docker exec ... cat /usr/local/bin/mmdc` 看 wrapper 在不在(老镜像没 rebuild 则没有);或显式 `mmdc -p /sandbox/puppeteer-config.json -i x -o y` |
|
| 容器内 mmdc 渲 mermaid 报 `Failed to launch chromium` / `No usable sandbox` | chromium 在 `--cap-drop=ALL` 下自家 setuid sandbox 起不来,要 `--no-sandbox`。镜像已落 `/sandbox/puppeteer-config.json` + 给 mmdc 套了 wrapper 自动 `-p` 注入 ── **裸调 `mmdc -i x -o y` 就该成**。仍跪:`docker exec ... cat /usr/local/bin/mmdc` 看 wrapper 在不在(老镜像没 rebuild 则没有);或显式 `mmdc -p /sandbox/puppeteer-config.json -i x -o y` |
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
||||||
# 改版本只动这一行。
|
# 改版本只动这一行。
|
||||||
__version__ = "0.52.2"
|
__version__ = "0.52.3"
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,11 @@ ARG NPM_REGISTRY=https://registry.npmjs.org/
|
||||||
ENV PUPPETEER_SKIP_DOWNLOAD=true
|
ENV PUPPETEER_SKIP_DOWNLOAD=true
|
||||||
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
|
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
|
||||||
|
|
||||||
|
# fetch-retries 默认只有 2,境内 mirror 偶发 ECONNRESET(2026-07-08 腾讯源拉 cytoscape
|
||||||
|
# 断流实测)→ 拉到 5 次 + 放宽重试窗口,单次抖动不再崩整个 build
|
||||||
RUN npm config set registry ${NPM_REGISTRY} \
|
RUN npm config set registry ${NPM_REGISTRY} \
|
||||||
|
&& npm config set fetch-retries 5 \
|
||||||
|
&& npm config set fetch-retry-maxtimeout 120000 \
|
||||||
&& npm install -g @mermaid-js/mermaid-cli@latest \
|
&& npm install -g @mermaid-js/mermaid-cli@latest \
|
||||||
&& npm cache clean --force
|
&& npm cache clean --force
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue