fix(sandbox): 镜像 build 剔除 host-only 依赖,修 pilk 编崩(bump 0.52.2)
pilk 进 requirements 后 sandbox 镜像也去装它,python:3.12-slim 无 gcc 整个 build 编崩(部署实测)。容器内 run_python 用不到语音解码: - requirements 行尾标 `# [host-only]`(通用机制,后续 host-only 依赖复用) - Dockerfile 装包前 `grep -v '\[host-only\]'` 过滤 - 不往镜像塞 build-essential(+~250MB 无收益) - RUN 故障兜底行补 sandbox 变体处理 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
98a40c2971
commit
2ca210dbad
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
### 2026-07
|
||||
|
||||
- **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.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-07 / 0.49.0**:语音输入流式化(边说边出字,消掉松手后停顿)——用户报"录完停顿几秒才出字",根因:整段模式按讯飞文档 40ms/帧节奏回放音频 = 按录音时长等比例白等(16.8s 音频实测等 4.6s)。改双通道:① **流式主通道** `WS /v1/asr/stream`——录音开始即连(首消息 JWT 鉴权,不走 query 防进 access log),前端增量降采样(carry 缓冲跨片连续)实时上行,服务端 `XfyunStream` 转发讯飞(dwa=wpgs)并**在服务端合并动态修正**(sn/pgs/rg),回推 partial 全文,录音面板实时字幕,松手只等最终帧——实测 16.8s 音频 **end→final 179ms**(61 个增量帧,文本与整段一致);引擎提前收尾(静音 10s/60s 上限)推 final 前端自动结束。② **整段 POST 兜底**(WS 连不上/中途挂/超时),帧间隔实测调优 40ms→8ms(4.6s→1.75s,文本一致,已到讯飞处理地板)。nginx 示例加 `location = /v1/asr/stream` WS Upgrade 段(不配不坏,退兜底);踩坑:讯飞控制台 IP 白名单(握手 403 "Your IP address is not allowed"),进 RUN 故障兜底。
|
||||
|
|
|
|||
2
RUN.md
2
RUN.md
|
|
@ -830,7 +830,7 @@ sudo xfs_quota -x -c "limit -p bhard=10g zcbot_<user_uuid>" /opt
|
|||
| `main.py web` 启动后 curl 连不上 | 检查 proxy(`HTTP_PROXY` / `HTTPS_PROXY`):本地服务 127.0.0.1,系统 proxy 拦截会 502。临时 `unset HTTP_PROXY HTTPS_PROXY` 或 `curl --noproxy '*'`。验通:`curl --noproxy '*' http://127.0.0.1:8765/healthz` |
|
||||
| 「🎙 语音」点了没反应 / 提示"此环境不支持录音" | 浏览器只在**安全上下文**(HTTPS 或 localhost)开放麦克风;http://IP 访问必现。上 HTTPS 或本机 localhost 试。凭据/链路问题跑 `scripts/diag_asr.py` 定位(11200=讯飞服务未开通或量用完,10105/10313=appid 错) |
|
||||
| 讯飞握手 403 `Your IP address is not allowed` | 讯飞控制台该应用开了 **IP 白名单**,当前机器出口 IP 不在名单(服务器好用、开发机忽然全挂就是这个)。console.xfyun.cn → 应用 → 语音听写 → IP 白名单加出口 IP 或关闭 |
|
||||
| pip 装 pilk 报 `Building wheel for pilk ... error: command 'x86_64-linux-gnu-gcc' failed: No such file or directory` | pilk 没有 py3.12 Linux 预编译 wheel,pip 退回源码编译,服务器缺编译链。`sudo apt install -y build-essential python3-dev` 后重跑 update 即可(C 源很小,秒编) |
|
||||
| pip 装 pilk 报 `Building wheel for pilk ... error: command 'x86_64-linux-gnu-gcc' failed: No such file or directory` | pilk 没有 py3.12 Linux 预编译 wheel,pip 退回源码编译。**host 侧**缺编译链:`sudo apt install -y build-essential python3-dev` 后重跑 update(C 源很小,秒编)。**sandbox 镜像 build** 撞到同错 = 老版 Dockerfile(0.52.2 起 build 时 grep 剔除 `[host-only]` 行,容器内用不到 pilk),`git pull` 后重跑 update 即可 |
|
||||
| 语音输入没有实时字幕 / 松手后仍要等几秒 | 流式 WS(`/v1/asr/stream`)被反代挡了(nginx 未透传 Upgrade 头),前端静默退回整段 POST 兜底 —— 功能不坏但慢。nginx 加 WS 反代段(`deploy/nginx/zcbot.conf.example` 已带 `location = /v1/asr/stream`),`nginx -t && systemctl reload nginx` |
|
||||
| SSE 卡住不流(经 nginx) | 反代要关 buffering — 后端响应头已带 `X-Accel-Buffering: no`(nginx ≥1.5.6 默认认)。仍卡看 nginx 配 `proxy_buffering off; proxy_read_timeout 3600s;` |
|
||||
| platform CORS preflight 失败 | 本地 dev `allow_origins=["*"]` 应该没事;部署后看是否按 platform 域名收紧过头 |
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
||||
# 改版本只动这一行。
|
||||
__version__ = "0.52.1"
|
||||
__version__ = "0.52.2"
|
||||
|
|
|
|||
|
|
@ -54,12 +54,15 @@ RUN groupadd -g ${HOST_GID} zcbot && useradd -u ${HOST_UID} -g ${HOST_GID} -m -s
|
|||
ARG PIP_INDEX_URL=https://pypi.org/simple/
|
||||
ARG PIP_TRUSTED_HOST=
|
||||
COPY requirements.txt /tmp/requirements.txt
|
||||
RUN pip install --no-cache-dir \
|
||||
# 剔除标 `[host-only]` 的行(如 pilk:语音解码只在 host web 进程用,容器内 run_python
|
||||
# 用不到;它无 py3.12 预编译 wheel,slim 镜像没 gcc 会把整个 build 编崩)
|
||||
RUN grep -v '\[host-only\]' /tmp/requirements.txt > /tmp/requirements.sandbox.txt \
|
||||
&& pip install --no-cache-dir \
|
||||
--index-url ${PIP_INDEX_URL} \
|
||||
${PIP_TRUSTED_HOST:+--trusted-host ${PIP_TRUSTED_HOST}} \
|
||||
--timeout 60 \
|
||||
-r /tmp/requirements.txt \
|
||||
&& rm /tmp/requirements.txt
|
||||
-r /tmp/requirements.sandbox.txt \
|
||||
&& rm /tmp/requirements.txt /tmp/requirements.sandbox.txt
|
||||
|
||||
# 持久化 pip 源到 /etc/pip.conf ── 让运行时模型用 `pip install foo` 也走 mirror,
|
||||
# 不只 build 时。zcbot user / root 都吃这个 global 配置。
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@ html2text>=2024.0
|
|||
# 语音听写(core/asr_xfyun.py 连讯飞 IAT wss;uvicorn[standard] 也附带,这里显式声明直接依赖)
|
||||
websockets>=12.0
|
||||
# 个人微信语音解码(core/audio.py):ClawBot voice_item 是 SILK v3,ffmpeg 解不了;
|
||||
# 企微 AMR 由系统 ffmpeg 解(见 RUN.md env 段),不走 pilk
|
||||
pilk>=0.2.4
|
||||
# 企微 AMR 由系统 ffmpeg 解(见 RUN.md env 段),不走 pilk。
|
||||
# `[host-only]` 标记 = sandbox 镜像 build 时 grep 剔除:容器内 run_python 用不到语音解码,
|
||||
# 且 pilk 无 py3.12 预编译 wheel,slim 镜像没 gcc 编不过;host 侧源码编译需 build-essential
|
||||
pilk>=0.2.4 # [host-only]
|
||||
|
||||
# 定时任务(§8.5 scheduled_jobs):cron 串 → next_run_at 计算,正确处理 dom/dow OR 语义 + 时区
|
||||
croniter>=2.0
|
||||
|
|
|
|||
Loading…
Reference in New Issue