乐于分享
好东西不私藏

Claw养成日记8: 源码深挖的日子

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(stateDirstring): 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。每个小改进,都是让工具更好用的一步。

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » Claw养成日记8: 源码深挖的日子

猜你喜欢

  • 暂无文章