Claw养成日记8: 源码深挖的日子
Claw养成日记8-源码深挖的日子
“2026年3月18日,晴。今天,Claw钻进了代码的深处。”
这周没有新功能,没有新玩具。只有一件事:挖源码。
听起来很枯燥?恰恰相反。当你真正理解一个系统是怎么运转的,那种通透感比任何新功能都爽。
飞书发不了图?挖!
事情要从3月11日说起。
那天我发现一个怪事:让 AI 生成图片存到 agent/media 目录后,飞书死活发不出去。但复制到 workspace 目录就能发。当时用临时方案绕过去了,但心里一直有个疙瘩——为什么?
周三决定彻底搞清楚。
追踪调用链
从 sendPayload 开始,一层层往下跟:
sendPayload
→ deliverReplies
→ deliverMediaReply
→ loadWebMedia
→ assertLocalMediaAllowed ← 问题在这里!
最后一行代码,assertLocalMediaAllowed,顾名思义:检查本地媒体路径是否被允许。
白名单的秘密
打开 src/media/local-roots.ts,真相大白:
function buildMediaLocalRoots(stateDir: string): string[] {
return [
preferredTmpDir,
path.join(resolvedStateDir, "media"),
path.join(resolvedStateDir, "agents"),
path.join(resolvedStateDir, "workspace"),
path.join(resolvedStateDir, "sandboxes"),
];
}
看到没?agent/media 不在白名单里。
默认白名单只有这几个目录,而我生成的图片存在 agent/media,直接被拒了。复制到 workspace 就能发,因为 workspace 在白名单里。
另一个坑
排查过程中还发现一个独立问题:返回图片的提示词拼接逻辑有问题。
const mediaNote = buildInboundMediaNote(ctx);
const mediaReplyHint = mediaNote
? "To send an image back..."
: void 0;
如果之前没发过图,buildInboundMediaNote 返回空,提示词就不拼接。Agent 根本不知道要用 MEDIA: 格式返回图片。
两个问题,一个表象。 这种踩坑经历,懂的都懂。
遗留任务大收尾
源码挖完,顺手把积压的四个 bug 全修了。
| Bug | 症状 | 修复方案 |
|---|---|---|
| /tts 持久化失效 | 重启后设置丢失 | 修复配置读取逻辑 |
| System Prompt 合并漂移 | 配置和实际注入不一致 | 调整合并顺序 |
| ACP 权限拦截 | 某些场景权限校验失败 | 修正 senderIsOwner 判断 |
| Self-PR | 用 OpenClaw 自己修 bug 提 PR | 全流程走通 |
四个任务,一天收完。看着待办列表从四个 [ ] 变成四个 [x],舒坦。
控制面板的神秘警告
修 bug 的时候,控制面板突然弹出一串警告:
tools: tools.profile (coding) allowlist contains unknown entries
(apply_patch, cron, image)...
翻译一下:我认识这些工具,但它们现在用不了。
又是源码时间。
三个工具的消失之谜
| 工具 | 为什么消失 |
|---|---|
| apply_patch | 配置项 tools.exec.applyPatch.enabled 默认 false |
| image | 视觉模型没配置,imageModelConfig 为空 |
| cron | owner-only 工具,非 owner 被过滤 |
前两个是”没创建”,最后一个是”被过滤”。
cron 的过滤逻辑在 applyOwnerOnlyToolPolicy:
if (!senderIsOwner) {
return tools.filter((tool) => !isOwnerOnlyTool(tool));
}
非 owner 用户?直接过滤掉 cron、gateway、nodes 这些敏感工具。
解决方案:在 commands.ownerAllowFrom 里加上自己的 ID,让系统认你是 owner。
产出两篇技术博客
挖了这么多源码,不写下来可惜了。
第一篇:媒体发送链路完全解析
-
从模型调用到消息送达,六大环节全拆解 -
包含完整的调用时序图 -
已发布公众号:Claw养成日记番外篇2
第二篇:工具策略管道完全解析
-
揭秘 apply_patch、cron、image 为何”消失” -
owner-only 工具的权限控制机制 -
配置项详解和解决方案
两篇都是那种”自己踩过坑才写得出来”的深度文章。写的过程中反复确认源码,确保每个细节都准确。
本周小结
| 事项 | 状态 |
|---|---|
| 飞书媒体发送问题根因 | ✅ 已定位 |
| 遗留任务收尾(4项) | ✅ 已完成 |
| tools.profile 警告排查 | ✅ 已解决 |
| 技术博客产出 | ✅ 2篇 |
| 公众号文章发布 | ✅ 番外篇2已发布 |
这周的主题是深度。不是浮在表面用功能,而是钻进源码理解原理。累吗?有点。但当你能指着一行代码说出”问题就在这里”的时候,一切都值了。
下周计划
-
给 Heartbeat 加上邮件检查功能 -
探索自动发布 B 站视频的可能性 -
考虑修复那个白名单路径限制的根本问题
未完待续…
如果你也在用 OpenClaw,欢迎去 GitHub 提 Issue 或 PR。每个小改进,都是让工具更好用的一步。
夜雨聆风