【免费下载链接】octo-server The Go backend powering OCTO — an open workplace built for humans × AI agents. REST WebSocket APIs, Lobster (AI agent) orchestration, and WuKongIM real-time messaging control plane.项目地址https://gitcode.com/gh_mirrors/oc/octo-server点击查看免费下载octo-server是 OCTO 开源工作区的 Go 后端提供 REST WebSocket API、LobsterAI Agent编排和 WuKongIM 实时消息控制面。它的交互式卡片协议InteractiveCard消息类型type: 17用一份 JSON同时解决了两件事消息的渲染长什么样和交互点了按钮会发生什么。这篇文章面向新手带你从一条消息信封讲起看懂卡片如何渲染、如何降级、如何点击回调。一、为什么需要卡片消息普通文本消息只能被看而卡片消息可以被操作文档审批卡上点一下同意AI 推理卡上折叠/展开思考过程——这些都是一份 JSON 描述出来的 UI。在 octo-server 里卡片消息是独立的消息类型类型编号ContentType 17InteractiveCard与7名片 Card无关协议文档特别强调别把新逻辑接到 7 上卡体使用标准 Adaptive Cards 1.5 JSON微软的开放卡片规范不是私有 DSL意味着渲染器可互换协议文档docs/card-protocol.md服务端强制权威在 pkg/cardmsg/ 包白名单、大小上限、plain 派生规则以代码为准。二、先看信封一条卡片消息长什么样所有 type-17 消息共用同一个信封wire envelope核心就 4 个字段{ type: 17, card: { …: 标准 Adaptive Cards 1.5 JSONocto/v1 白名单子集 }, plain: 服务端权威纯文本客户端提交值一律被服务端重算覆盖, card_version: 1.5, profile: octo/v1 }逐字段拆解字段含义关键点card卡片 UI 本体标准 AC 1.5 JSON服务端从不改写卡体树plain纯文本兜底服务端按固定规则派生、永不为空离线推送、搜索、会话摘要、引用、降级显示全以它为准card_versionAC 规范版本当前固定1.5profile能力分档octo/v1展示档 /octo/v2交互档决定客户端能用哪些元素三、plain 与降级链老客户端永远看得到内容 ️新手最容易担心的问题老版本客户端不认识卡片消息会不会变成乱码——协议用一条降级链回答了它客户端认识该profile→ 渲染card不认识profile客户端太旧→ 渲染服务端算好的plain纯文本连type: 17都不认识存量客户端→ 显示兜底文案。plain的派生规则完全由服务端说了算按文档序遍历卡体TextBlock剥掉 markdown、FactSet转成title: value行、Image显示为[图片]、按钮不参与按钮是操作面不是内容客户端提交的plain一律被覆盖。结果为空时兜底为[卡片]。四、白名单与尺寸限制能放什么、不能放什么服务端对入站卡片做write-strict 校验白名单外一律返回 400类别允许的内容展示元素TextBlockmarkdown 子集、RichTextBlock、Image、ImageSet、Container、ColumnSet、FactSet、Table、ActionSet本地动作不回调服务端Action.OpenUrl、Action.ToggleVisibility折叠/展开、Action.CopyToClipboard交互元素octo/v2起Action.Submit、Input.Text/Input.Toggle/Input.ChoiceSet/Input.Number/Input.Date/Input.Time硬性预算所有入口一致完整 payload 序列化 ≤512 KiB递归节点数 ≤200嵌套深度 ≤16URL 正向白名单仅允许绝对http/httpsdata:、javascript:、相对路径一律拒绝markdown 里的链接/图片目标也走同一套校验校验面 ≥ 渲染面服务端不解引用卡内任何 URL无图片代理/预取。隐藏内容isVisible: false的子树也不豁免校验隐藏节点不能成为绕过通道。五、三层信任模型谁能发卡、谁能信卡这是协议里防伪造的核心设计三层各自独立必要服务端入口只有 bot/v1/bot/sendMessage、robot API与 incoming webhookmsg_type:card能发卡普通用户/v1/message/send发 type-17 直接 403客户端渲染门禁只有当消息的from_uid是 bot / webhook 身份时才渲染card否则降级为plain展示——from_uid由 IM 连接鉴权绑定不可伪造动作端点复验POST /v1/message/card/action处理点击时服务端再次校验目标消息的 sender 身份与存储 provenance。部署侧还有两道开关总闸OCTO_CARD_MESSAGE_ENABLED默认关闭和 bot 侧子开关OCTO_BOT_CARD_ENABLED。能力发现走GET /v1/bot/card/profile生产者可以按元素/动作粒度探测服务端支持哪些能力而不是赌一把。六、从点按钮到全端刷新交互闭环 ⚡交互是卡片协议的灵魂。以文档审批卡为例完整链路是这样的客户端点按钮 → POST /v1/message/card/action鉴权/防伪造/幂等即时 ack → 服务端按 stored sender data.owner/action_type 分支 - 一方注册路由内部可靠队列 → HMAC callback → 写终态卡 - 普通 Bot事件队列 event_typecard_action/v1/bot/events 轮询 → Bot 调 /v1/bot/message/edit 重写卡片 → message_extra CMD 同步 → 三端实时重渲染新帧几个值得记住的设计决策状态在卡片内容里没有独立状态 API消息列表/sync 响应就是卡片状态的权威。防重复操作 服务端幂等业务身份键message_id action_id operator_uid bot 重写卡片让按钮消失/置灰 客户端 10 秒瞬时 loading每帧都是完整信封连续帧结构可任意不同可在octo/v1/octo/v2之间迁移存储只留最新帧变更历史入侧表GET /v1/message/card/revisions可查乱序防护可选card_seq单调递增旧帧直接 409输入信任边界提交的键必须命中当前生效帧声明过的Input.*id未声明则 fail-closed。交互契约的细节在 docs/card-protocol.md 第 7 节一方回调的传输与运维合同见 docs/card-action-callback-dispatch.md。七、不用手写 JSON模板基座让业务传字段就行真正落业务时开发者不需要手搓 AC JSON。octo-server 提供了平台级基座octo-card1.0分层如下L0 平台基座协议版本 · profile · 白名单 · Registry · Render 唯一入口 L1 单卡契约manifest.json data.schema.json interaction.json samples纯 JSON 制品版本化 L2a 平台内置卡片文档 / 智能总结 / 审批 / Git 通知等 L2b 业务自定义卡片业务方自实现 Template 独立 callback route开放中以首个样板卡docs.access-request0.3.0文档访问申请为例它的所有契约都是机读 JSON元数据与视图声明manifest.json ——pending视图走octo/v2带审批按钮approved/rejected终态走octo/v1纯展示调用方入参示例samples/pending.json —— 业务方只传requestId、文档信息、申请人等结构化字段交互面声明reports/pending.interaction.json —— 机读声明了docs-access-approve/docs-access-deny两个Action.Submit和deny_reason输入CI 会断言渲染产物与声明完全相等漂移即失败。模板的核心接口只有 3 个方法Meta/Build/FallbackTextmetadata 注入、cardmsg.Validate校验、视图切换更新全部由基座Registry.Render强制完成。完整契约见 docs/platform-card-base.md。八、安全设计速览这些纪律你绕不开纪律说明server-authoritative布局、文案、交互 id 归服务端调用方只传业务字段版本化冻结同一templateIdversion一经发布永不修改历史消息永远按当时版本渲染显式降级每张模板必须声明 fallback 文本总开关关闭时降级为纯文本URL 白名单所有图片/链接/深链必须绝对 httpsdeep-link 域名来自服务端配置输入校验失败不降级schema 不通过直接 400 零投递禁止把错误请求伪装成成功的文本九、延伸阅读文件地图 想继续深入按这个顺序看效率最高资料路径看什么卡片消息协议全文docs/card-protocol.md信封、白名单、信任模型、plain 派生、P2 交互契约平台基座契约docs/platform-card-base.mdL0/L1/L2 分层、Template 接口、Registry、回调契约服务端强制权威pkg/cardmsg/cardmsg.goContentType17常量、512 KiB 上限、profile 协商模板注册与渲染pkg/cardtmpl/Registry.Render唯一入口、各张 L2a 卡的 handoff 制品动作回调分发internal/cardactiondispatch/路由、HMAC 签名、finalizer、DLQ写在最后octo-server 的交互式卡片协议本质是一条标准 JSON 打穿全链路渲染靠 Adaptive Cards 1.5降级靠服务端权威plain交互靠Action.Submit 幂等回调安全靠白名单 三层信任模型。对新手来说最值得关注的是它的两个承诺老客户端永远看得到内容新客户端永远只信任服务端。想动手验证建议先从docs.access-request这张样板卡的 handoff JSON 制品读起——它把一份 JSON 实现消息渲染与交互这件事诠释得最完整。赞分享【免费下载链接】octo-server The Go backend powering OCTO — an open workplace built for humans × AI agents. REST WebSocket APIs, Lobster (AI agent) orchestration, and WuKongIM real-time messaging control plane.项目地址https://gitcode.com/gh_mirrors/oc/octo-server点击查看免费下载相关推荐3分钟搞懂Electron渲染流程从HTML到交互全解析3分钟搞懂Electron渲染流程从HTML到交互全解析 你是否好奇桌面应用如何像网页一样运行Electron用前端技术解决了这个问题但它的渲染流程远比普桌面应用示例工程LiteLoaderQQNT与QQNT协议交互深入理解通信机制LiteLoaderQQNT与QQNT协议交互深入理解通信机制 引言插件加载器的核心通信挑战 你是否曾好奇LiteLoaderQQNT插件加载器如何与QQ插件系统即时通讯如何用RabbitMQ STOMP协议5分钟搞定跨语言消息通信如何用RabbitMQ STOMP协议5分钟搞定跨语言消息通信 还在为不同编程语言之间的消息传递而头疼吗复杂的协议配置、繁琐的客户端集成是否让你望而却步Ra后端消息队列消息路由创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考