☰
OpenAlice file-delivery:在 Connector 会话回复中通过 `[[relative/path.ext]]` 附件交付 Workspace 文件
2026/9/29 7:46:56 网站建设 项目流程

【免费下载链接】OpenAlice

Your one-person Wall Street. An AI trading agent covering equities, crypto, commodities, forex, and macro — from research through position entry, ongoing management, to exit.

项目地址:https://gitcode.com/gh_mirrors/op/OpenAlice
点击查看免费下载

本指南讲解 OpenAlice 的file-delivery技能(default/skills/file-delivery/SKILL.md):如何在 Connector 会话(Telegram、Discord、Slack、飞书)的最终回复中,用双括号引用把 Workspace 内的文件作为附件直接发送给人类用户,并阐明它何时应该使用 Inbox 通知(alice inbox push)而非普通回复。读完本文,你将掌握附件引用的完整语法与约束、Connector 服务端的解析与上传链路、附件的媒体类型推断规则,以及"回复附件"与"Inbox 报告"两种交付方式的准确取舍。

核心机制:在最终回复中用[[relative/path.ext]]引用文件

file-delivery技能的核心是一条极简约定:在 Connector 对话的最终回复中,把文件相对当前 Workspace 的路径用双括号包裹,Connector 服务即会在回复的对应位置把解析成功的文件作为附件上传。文件必须先创建或先验证存在,再在回复中引用。示例:

Here is the report. [[reports/summary.pdf]] The chart shows the comparison. [[reports/chart.png]]

这条语法有四个必须遵守的要点:

  1. 引用必须写在代码区之外。把[[...]]放进行内代码(backtick)或代码围栏(fenced code block)后,它会被解析器视为"讨论语法"而不触发上传——这正是"只想说明语法、不实际发文件"时的标准做法。
  2. 保持文本与附件的相对顺序。Connector 会在回复中引用所在的位置上传解析成功的文件,文本段落与附件的先后关系被原样保留(服务端实现见下文"文本与附件按位置分片")。
  3. 不产生 Inbox 条目。通过回复发送文件不会在 Inbox 中留下任何通知记录;Inbox 是独立于对话的另一个交付面。
  4. 路径指向"回复该会话"所属的 Workspace。若要发送**对等工作区(peer Workspace)**的文件,必须先把它复制进当前 Workspace 再引用,不允许跨界直接引用。

路径书写格式是严格的白名单式约束:直接用相对路径和扩展名即可,禁止使用file:前缀、绝对路径、..上级目录跳转、以及|label标签后缀。任何缺失、不可读或不支持的引用都会原样保留为字面文本,Connector 不会把未能解析的引用替换成占位符;因此"写了引用"本身不等于"文件已送达",交付结果需要以实际收到的附件为准。

交付限额(当前版本)

限额项数值说明
每次回复唯一文件数最多5个相同路径重复引用只上传一次(去重)
单个文件大小最多1 MiB超过则引用无法解析为附件
字节完整性文件字节原样保留不重编码、不缩放(但编码归一化的报告例外,见下)

服务端的硬性约束与这两条完全一致:MAX_CONNECTOR_ATTACHMENT_BYTES = 1024 * 1024、MAX_CONNECTOR_ATTACHMENTS = 5定义在 packages/connector-protocol/src/types.ts,且connectorAttachmentSchema用sizeBytes: z.number().int().min(0).max(MAX_CONNECTOR_ATTACHMENT_BYTES)在协议层就拒绝超限附件。连接器在回复里实际解析时也按"最多 5 个"截断:resolved.size >= 5即停止解析后续引用(services/connector/src/core/delivery-manager.ts)。

各平台的呈现方式

  • Telegram:PNG / JPEG / WebP 以**图片(photo)形式发送,其余受支持的文件类型以文档(document)**形式发送。
  • GUI 聊天界面(OpenAlice 的 web 会话界面):渲染预览,并在右侧面板打开文档;点击图片时弹出预览对话框。
  • 终端(Terminal):只显示文本、不执行上传——终端会话没有附件通道,引用只会以字面文本展示。

注意:Telegram 发送图片还是文档,取决于 reply-directives.ts 中的媒体类型推断,而非 Telegram 侧的魔数判断(见下文"媒体类型推断")。

贴纸(Sticker)交付

sticker/*.png与sticker/*.webp路径走贴纸交付通道(在支持贴纸的平台上按贴纸发送,而非普通图片)。可用的贴纸包及其用法以**已安装的贴纸技能(sticker Skill)**为准——OpenAlice 仓库内置了alice-color与alice-ink两套贴纸包(default/stickers),每套含 20 张 PNG 与一张 JSON 清单;引用的路径要与已安装贴纸包中的实际文件名匹配。

解析与交付的源码级链路

回复附件的完整链路在Connector Service的DeliveryManager.deliverOwnerChat中实现(services/connector/src/core/delivery-manager.ts),核心步骤:

  1. 解析引用:parseReplyDirectives(message.text)扫出文本中所有合法的[[path]]引用(来自 packages/connector-protocol/src/content-references.ts 的parseContentReferences,Connector 侧重导出为parseReplyDirectives)。
  2. 解析文件:对每个去重后的路径,优先尝试readWorkspaceFile(workspaceId, path)从回复会话所属的 Workspace读取;若路径命中市场图表引用(market/...),则走renderMarket渲染(见 reply-directives.ts 对parseMarketReference的优先判断)。任何解析失败(如文件不存在、不可读)都被静默吞掉,引用保持字面文本。
  3. 文本与附件按位置分片:把回复按引用位置切分为{text}与{path, attachment}交替的片段序列,先发送首段文本(transport 的"实时回复"),再按顺序依次sendOwnerText/sendOwnerFile——这就是"回复中文本与附件顺序被保留"的实现来源(delivery-manager.ts)。
  4. 媒体类型推断:replyMedia(path)决定附件以file/image/sticker哪种呈现方式上传,规则见下文。
  5. 字节与哈希校验:附件携带contentSha256与sizeBytes;reply-media.spec.ts明确测试了"损坏媒体(哈希不符)在上传前被拒绝"(services/connector/src/adapters/reply-media.spec.ts),避免把坏字节发给用户。

媒体类型推断规则

来自 services/connector/src/core/reply-directives.ts,判断顺序是:

优先级条件呈现类型
1命中市场引用(parseMarketReference(path),如market/okx|BTC/USDT:USDT/4h)image(渲染图表)
2sticker/目录下且扩展名为.png/.webp(大小写不敏感)sticker
3扩展名为.png/.jpg/.jpeg/.webp(大小写不敏感)image
4其余一切路径file

这套规则与测试完全一致:report/chart.PNG→ image、report/weekly.pdf→ file、sticker/notes.txt→ file(因为不满足贴纸扩展名条件)(services/connector/src/core/reply-directives.spec.ts)。

平台适配:sendOwnerFile 的实现差异

各 Connector 适配器都实现了sendOwnerFile(attachment, presentation),但对presentation的利用程度不同:

  • Telegram最完整地利用ReplyMedia:image按 photo、sticker按贴纸发送;
  • Discord / Slack在 discord.ts 与 slack.ts 中把_presentation参数忽略(_前缀表明未使用),一律按普通文件上传——它们的消息体系本身就把图片作为附件展示;
  • 飞书在 feishu.ts 中接收presentation参数参与上传分发。

三个平台的通用约束(reply-media.spec.ts):只向已关联的 owner发送(未关联 owner 时先抛错、不产生上传);上传失败会记录delivery.failed并把适配器健康状态降级为degraded,同时向用户回发Could not send file: <path>. Upload failed; please try again.(delivery-manager.ts)。

解析器的语法豁免(escape 与代码区)

parseContentReferences的正则扫描(content-references.ts)会对以下形式整体跳过:代码围栏(``` 与~~~)、行内代码(`...`)、反斜杠转义(\[[...]])。content-references.spec.ts用一整段样例验证了这些豁免:

`[[inline.md]]` ```md [[fenced.md]]

[[escaped.md]] [[NVDA]] [[../private.md]] [[/absolute.pdf]] [[https://example.com/a.pdf]] [[./README]]

其中 `[[../private.md]]`、`[[/absolute.pdf]]`、`[[https://example.com/a.pdf]]` 都不会被当作文件引用(`isFileReference` 拒绝以 `/` 开头、含 `..` 段、以协议前缀开头的路径,见 [content-references.ts](https://link.gitcode.com/i/23a14d45cc4719806f0f034af035fa25))——这正是 SKILL.md 中"禁止绝对路径、`..`"约束的底层实现。行内代码与围栏内的引用则被解析器跳过、永远保持字面文本。 ## 什么时候该用 Inbox:回复附件 vs 通知报告 **Inbox 是 OpenAlice 面向人类的外部通知与报告面**:警报、发现、报告、或需要人类关注并**应有独立交付记录**的内容,才使用 Inbox。而"当前对话中用户索要的文件"直接在回复里发送即可——**它不会仅仅因为是一个文件就需要一条 Inbox 记录**。 三条职责边界(与 [default/skills/alice/references/collaboration.md](https://link.gitcode.com/i/e30269a1d35e219c2a9e9e932504e998) 的"命令模型"表一致): | 交付面 | 职责 | 不负责 | |---|---|---| | 回复(`[[...]]`) | 当前会话内给人类的即时回复附件 | 独立通知、报告记录 | | Inbox(`alice inbox push`) | 面向人类的通知、报告、后续跟进 | 通用对等聊天、文件存储 | | 对等会话(`alice conversation`) | Agent 到 Agent 的手递手 | 人类通知 | **避免重复投递**:除非确实需要一条独立的通知或报告交接,不要把回复内容再复制进 Inbox。文件与 Git 承载工作产物,Inbox 负责把结果告知人类,对等会话负责 Agent 间交接——三者各司其职。 ### 用 Inbox 推送带附件的报告 需要给人类发一条**独立通知**(例如无人值守任务的结果、需要专门关注度的报告)时,用 `alice inbox push`: ```bash # 方式一:body 内联引用——Markdown 正文 + 活文件引用 alice inbox push --body 'See [[report/summary.pdf]]' # 方式二:--body-file 把 Markdown 文件本身发布为通知正文 alice inbox push --body-file report/summary.md

两处的语义细节(来自 default/skills/alice/references/collaboration.md 与 src/tool/inbox-push.ts 的实现):

  • --body-file发布的是该 Markdown 文件本身,而--body中内联的[[relative/path.ext]]引用是活引用:它们相对发布方 Workspace 根目录解析,且保持"活着"——读者之后仍能跟随引用打开对应文件。
  • 发布时正文被冻结(frozen):正文文本在发布那一刻定稿,但文件引用保持动态解析;每个被引用的文件会计算sha256:前缀的发布哈希作为该文件版本的标识,写入fileRevisions(inbox-push.ts)。若希望 Git 保存发布内容,请先提交文件再发布。
  • 代码示例中的引用与缺失路径在 Inbox 正文中同样保持字面文本。
  • 每条附件在alice inbox read的files[]中返回:可直接使用的absolutePath、原始relativePath、以及可用时的发布revision;若absolutePath为 null(Workspace 不可用或路径不安全),不要猜测补全,可用alice peer path --id <workspaceId>解析对等 Workspace 根目录后用 Agent 原生的 Read/Search/Glob/Git 能力检查。

查看近期投递:

alice inbox read --limit 5 # 最近 5 条 alice inbox read --self # 只看本 Workspace 自己的推送

inbox push/inbox read/inbox ask在aliceCLI 中是顶层inbox组的动词(src/server/cli-commands.ts);inbox_push同时以 Workspace 工具(tool)的形式暴露给 Agent,其工具描述明确写着:"body 是 Markdown,用[[report/file.pdf]]指向相对此 Workspace 根的活文件;CLI--body-file把 Markdown 文件读作发布正文;普通回复用于会话内响应;Inbox 不是文件存储,也不是 Agent 间通道;来源(origin)自动记录。"(src/tool/inbox-push.ts)——工具会自动为推送条目盖上来源(run / session)戳,供alice provenance show --kind inbox追溯。

常用协作命令速查(与 file-delivery 直接相关)

alice --help # 发现研究/协作命令组 alice inbox push --body 'Finished — see [[research/report.md]] for evidence.' alice inbox push --body-file research/report.md alice inbox read --limit 5 alice inbox read --self alice inbox ask --id <entryId> --prompt 'Why did you send this result?' --await alice conversation create --ws-id <workspaceId> --prompt '...' # Agent 间会话(非 Inbox) alice peer path --id <workspaceId> # 解析对等 Workspace 根目录

注意:Inbox 只通知人类;Agent 到 Agent 的完成通知没有"主动推送总线",普通对等交流必须走alice conversation,配合--await/await/read/collect拉取回复。

常见误区与排错清单

结合 SKILL.md 的约束与解析器实现,最容易踩的坑如下:

  1. 引用写在代码区里→ 被解析器豁免,永远不触发上传。想发送文件,引用必须位于正文;想讨论语法,引用放进行内代码或代码围栏。
  2. 路径写错格式:file:前缀、绝对路径(/开头)、..段、|label后缀都会被isFileReference拒绝 → 引用保持字面文本,不会交付。
  3. 文件不在回复会话的 Workspace:peer Workspace 的文件必须先复制进当前 Workspace再引用。
  4. 超限:超过 5 个唯一文件、或单个文件超过 1 MiB → 超出的引用无法解析(协议层connectorAttachmentSchema直接拒绝超限附件)。
  5. 写了引用 ≠ 已送达:缺失/不可读/不支持的引用保持字面文本,Connector 不会提示你失败(仅在上传阶段失败时才回发Could not send file提示)。交付后应通过收到的附件确认,而不是看回复文本。
  6. 混淆交付面:会话内索要的文件直接用回复发送,不要机械地再复制一条 Inbox;需要独立通知/报告记录时才用alice inbox push,避免重复投递。
  7. 贴纸路径:只有sticker/*.png、sticker/*.webp且与已安装贴纸包实际文件名匹配时才走贴纸通道(reply-directives.ts);用错扩展名或路径会退化为file或保持字面。

延伸阅读

  • 技能原文:default/skills/file-delivery/SKILL.md
  • alice协作命令全貌(peer / conversation / inbox / issue / provenance 等):default/skills/alice/references/collaboration.md
  • 共享引用解析器与文件引用白名单:packages/connector-protocol/src/content-references.ts
  • Connector 回复解析与附件限额:packages/connector-protocol/src/types.ts
  • 回复分片、上传与媒体推断:services/connector/src/core/delivery-manager.ts、services/connector/src/core/reply-directives.ts
  • 多平台附件上传行为测试:services/connector/src/adapters/reply-media.spec.ts
  • Inbox 推送工具实现:src/tool/inbox-push.ts
  • Inbox 数据与文件语义:docs/inbox-content.md、docs/connector-service.md

【免费下载链接】OpenAlice

Your one-person Wall Street. An AI trading agent covering equities, crypto, commodities, forex, and macro — from research through position entry, ongoing management, to exit.

项目地址:https://gitcode.com/gh_mirrors/op/OpenAlice
点击查看免费下载

相关推荐

上一篇:Raspberry Pi 常驻自托管 Runner 搭建指南:让 Opencode Triage 与 AI 工具免重复认证(opencode-antigravity-auth 实战)
下一篇:Capistrano 服务器过滤(Filtering)机制完全指南:On-Filters 与 Property-Filters 实战解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询