@dsh-enhanced/lark-channel
飞书/Lark 的薄协议适配器:把 WebSocket 长连接消息写入 assistant-delivery 的 typed Inbox,并把已经落盘的 Outbox intent 转成飞书发送或回复 API。本包不拥有配对、会话、重试或授权真源。
Delivery 的 typed presentation 还可把审批实际生效终态,以及拥有稳定 owner route 的 Host
Automation incident open / recovering / resolved 原位渲染到同一条飞书卡片。本包只渲染 Delivery
已经持久化、授权并取得 provider message id 的 projection,不能创建领域终态、伪造 applied 或 incident
revision,也不能绕过 Delivery/Policy。Agent Automation 只持有 exact conversation binding,因此每个持久
revision 投递一条内容无关的状态更新;两种路径的重试、fence 与 generation 都由 Automations/Delivery
账本负责。
插件默认 enabled: false,安装后不会立即读取凭据或联网。启用后,合法新消息落盘时可添加 Get,最终答复发送成功后可添加 DONE;reaction 与原生执行进度都是 best-effort 展示,最终答复仍由 Delivery Outbox 保证。
模型回答被输出上限截断、返回空正文或超过 Delivery 的 maxTextBytes 时,Delivery 默认会在后台自动续写、重新生成或压缩,并在恢复完成后只向飞书发送一条完整答复;正常情况不需要用户再回复“继续”。模型恢复次数耗尽或安全调度边界不可用时才展示明确的未完成提示,也不再要求用户发送“继续”这类协议词;持久化无法确认时则不投递结果,任何情况都不会把半句标成“任务已完成”。Delivery 与本插件的 maxTextBytes 默认都为 65536,手工覆盖时应保持一致。
默认进度策略为 progressDetails: direct:经 Delivery 授权的私聊可显示限长、常见凭据已脱敏的工具参数和结果;默认向导只授权 owner。群聊只显示工具名、状态、步骤与待办。progressDetails: off 可在所有会话隐藏参数和结果。任何 reasoning/thinking 内容都不外发;飞书 message_cot 不可用时只降级展示,不影响任务或最终回复。
已创建的进度消息句柄由 Delivery 私有 SQLite 账本保存;终态在飞书更新前落盘。连接重建或进程重启后,只有原 Inbox 已确认结束、原绑定代次与应用凭证仍一致时才更新同一条进度消息;活动任务不会被误关。终态更新失败按间隔重试,最多八次,不会因此重新运行任务或再建进度消息。创建请求的网络结果未知时保留无句柄状态,不盲目重建;升级前没有保存句柄的历史气泡无法原位恢复。账本只保存句柄、绑定与目标摘要、终态及重试状态,不保存工具参数或思考正文。
文档
Linux supervised 新安装在模型、TraeX、飞书配置与 doctor 后自动取得当前 owner、生成有限授权与 manifest,并部署目标和独立协调器两个 systemd Host。新 owner 安装接通有界新工具创建、任务派生独立验收与动态采用;旧安装重试保留原授权,不自动增加创建通道。未就绪会以非零状态停止安装完成提示;重试不续期授权。当前尚未完成真实普通任务驱动的修复、采用和观察验收,见上述配置指南。
兼容性
- DeepSeek Harness:
0.2.0-rc.2 基线语义(通过 assistant-delivery)。
@dsh-enhanced/assistant-delivery:>0.1.7 <0.2.0;本包的 supervised setup 使用当前发布切片的私有 capability。
@deepseek-ai/dsh-user-questions:由 DSH 0.1.2-rc.1 定义 Agent-scoped user-questions/request answerer waterfall。Web Host 通过 Remote Events 提供 scoped answerer;飞书通道要承接 ask_user_question 时也必须直接注册同一 scope 的 answerer。
@dsh-enhanced/credentials-keychain:handle 模式为 >=0.1.0 <0.2.0;env fallback 不要求其激活。
- 普通个人助理场景同时安装
@dsh-enhanced/preference-learning。向导会只为完成 owner 对话产生有界偏好证据及读取 active snapshot 的两项能力;它们不依赖广义 Agent 工具开关,也不要求 Health/Heartbeat/Recovery。
- 分级自治成长激活器要求有效 profile 同时启用
@dsh-enhanced/personal-assistant、@dsh-enhanced/assistant-automations、@dsh-enhanced/assistant-heartbeat、@dsh-enhanced/assistant-evaluation、@dsh-enhanced/preference-learning、@dsh-enhanced/assistant-evolution、@dsh-enhanced/assistant-growth-experiments、@dsh-enhanced/assistant-health 与 @dsh-enhanced/assistant-recovery。Policy、Memory 与 Wiki 由 personal-assistant 这一 profile row 提供。Recovery 仍是无模型 Host runbook;独立的 supervised-growth-analyst 每天最多一次,只能 review/propose adoption,preview 强制 paused,active 前逐项证明定义和私有 scratch,且只有审批路由、没有普通结果投递。workflow lane 使用 Delivery 私有、可撤销的 content-free trace sink,以及独立预算、owner-bound approval、prefix-bounded dynamic Automation identity 和 exact binding delivery;Lark 文本、卡片或回调本身不能制造 trace 或 learned workflow。默认不授予 learned workflow 任意工具。旧 supervised-growth Heartbeat 只在升级时被安全暂停。
- 官方
@larksuiteoapi/node-sdk:固定 1.76.0。该版在握手超时和关闭 socket 时保留错误监听,避免异步错误终止 Host;type=card 回调仍由本包的 CardKit 桥处理。
- Node.js:
^22.19.0 || >=24.0.0。
仓库级基线见兼容性说明。
安装
先配置 @dsh-enhanced/assistant-policy、@dsh-enhanced/assistant-delivery 与 @dsh-enhanced/preference-learning,再安装本包:
dsh plugin --profile web add @dsh-enhanced/lark-channel
dsh --profile web --dump-config
推荐使用跨平台向导完成飞书应用授权、凭据保存、owner 绑定、owner 工具策略 和用户级常驻服务:
~/.dsh/profiles/web/node_modules/.bin/dsh-lark-setup \
--profile web \
--create-app
源码工作区也可运行:
pnpm --filter @dsh-enhanced/lark-channel build
pnpm --filter @dsh-enhanced/lark-channel run onboard --profile web --create-app
向导不会把 App Secret 放进 argv、profile 或日志。macOS 使用 Keychain,Linux 优先 Secret Service、无桌面环境降级为严格权限的 protected-file,Windows 使用 best-effort DPAPI。完整流程、已有应用接入和平台排障见安装文档。
向导默认还安装或复用官方 lark-cli,使用同一应用为绑定的 owner 申请 --domain all 用户授权,并生成原生 DSH 业务技能。Agent 按需读取 CLI 内嵌的最新技能说明,通过原生工具操作文档、表格、日历、任务、邮件等;已授权任务无需反复批准。重复安装验证并复用有效用户授权;明确的部分授权也可接入已获批能力,同时显示未获批权限。有完整授权结果的中断收尾可恢复,不把普通错误当作授权成功。只需消息通道时,可用 --no-business-tools 跳过该步骤。
业务 CLI 使用 DSH 专用配置目录、显式 profile 和净化后的环境;Linux 另用专用数据目录保存 CLI 加密凭据,macOS/Windows 的系统钥匙环仍可能按应用/用户共享凭据。自动安装只下载并校验官方 npm 包与匹配的 GitHub release(失败时尝试官方安装器镜像,使用相同校验值),不运行 npm lifecycle 或全局安装脚本。此安装步骤需要网络和子进程权限,生成的技能位于 $DSH_HOME/skills;具体平台权限仍以飞书实际批准结果为准。
最小配置
不使用向导时,可在 profile patch 中配置:
config:
enabled: true
account: personal-bot
tenant: personal
appId: cli_0123456789abcdef
credentialHandle: lark-app-secret
credentialPurpose: connect
credentialLeaseMs: 86400000
# Calendar API stays unavailable unless every ID is explicitly listed.
allowedCalendarIds: []
domain: feishu
requireMentionInGroups: true
showProgress: true
progressDetails: direct
statusReactions: true
imageDownloadTimeoutMs: 30000
userQuestionTtlMs: 86400000
credentialHandle 应由 @dsh-enhanced/credentials-keychain 提供,并只允许 consumer dsh-enhanced-lark-channel、purpose connect。兼容部署可改用 appSecretEnv,两者只能选一个;配置不接受 appSecret 等明文字段。
Calendar v4 读取默认关闭;每页响应上限为 1 MiB,超限请求失败且不推进事件游标。只有同时满足以下条件时,连接器才会读取一个页面:该 ID 位于 allowedCalendarIds、应用已被授予并发布 calendar:calendar:readonly、调用方已通过自身的 owner/Policy 授权。event-triggers 使用此窄桥观察一个预先选定的日历;它不能列出日历,不能取得 app secret 或 tenant token,也不能凭 credentialPurpose: connect 自动取得 Calendar 范围。使用官方向导更新应用范围时运行 dsh-lark-setup --create-app --calendar-readonly,然后由操作员把实际授权的 exact Calendar ID 填入 allowedCalendarIds。
userQuestionTtlMs 默认 24 小时,范围为 1 分钟至 7 天;它限制当前进程内等待飞书回答的时长。过期、取消、Host 已在其他端结算或 adapter 注销都会撤销这次即时等待,不会把后到消息变成新的问题回答;短暂 WebSocket 重连不会主动丢弃仍有效的卡片。
飞书应用至少需要机器人身份读取、单聊/群内 @ 消息接收、机器人发消息、im.message.receive_v1;Get/DONE 需要 im:message.reactions:write_only,图片需要 im:resource,审批、模型选择和用户问题卡片需要 card.action.trigger。事件与回调使用 WebSocket 长连接,不需要公网 callback URL。
ask_user_question 交互
ask_user_question 由 Host 的 ctx.userQuestions.ask() 在 exact live root Agent scope 派发。飞书兼容层必须直接为这个 scope 注册 answerer,只接受仍属于 exact active owner binding、且 adapter 仍具备问题交互能力的请求,再把问题送到原飞书会话;按钮或自由输入的答案直接作为 waterfall 结果返回。Web Remote Events answerer 与飞书 answerer 是同一 scoped waterfall 的组合参与者,按 composition 顺序串联;迟到、撤销和重复交互仍必须由各 answerer 自己拒绝,且不得制造新的 Agent turn。
飞书使用不可转发的 CardKit 2.0 卡片呈现选项。推荐项只显示“推荐”标识,不会自动选择;多选必须点击“提交已选答案”;无选项或需要输入其他答案时会明确要求回复对应问题卡片。未引用卡片的新文字始终作为普通消息处理,即使原会话只有这一条 pending question 也不会被当成答案吞掉。按钮和卡片回调使用签名 capability,且回调或自由文本都必须匹配 exact owner、account/tenant/chat、原会话路由、当前 binding version/generation 与请求 fence。群聊中的普通文字命令仍遵循 @ 机器人门槛,不想输入答案时可直接点击卡片“取消”。问题会发送到原 binding 会话而非强制转为私聊,因此在群聊中问题正文、详情和选项对群成员可见;不要把秘密、凭据或只应由私聊接收的内容放进问题。
整体目标结果反馈
外部 event-wait scheduled whole-goal 结果(当前 producer 为 goal-event-wake-*;普通 goal_schedule 不外发结果)沿用普通 Markdown Outbox 和现有飞书 reply identity;本 adapter 无需新增目标专用卡片、callback 或信任逻辑。结果正文由 Delivery 附加固定反馈说明,owner 必须直接回复那一条已发送消息,再使用 /feedback status、correct 或 withdraw。首次 status 已显示 Verifier baseline 的 revision 1;裸 achieved|partial|not-achieved 只有与 baseline 相同才幂等,不同判断必须按当前 version/status 使用 correct。Lark 只把 replyToProviderMessageId 连同 actor/conversation 写入 typed Inbox;Delivery、Goals、Verifier 与 Evaluation 负责核对 schema 20 sidecar、当前 owner/route/binding 和 exact assessment proof。复制正文、回复其它消息、错人或 /new 后失效 binding 都不能修订目标。
已发送的历史结果即使原 Verifier freshness 到期仍可由同一 owner 纠正,但不可变 Goal/assessment/receipt identity 仍须由当前 Goals 与 Verifier 重验。发送前过期则失败关闭且不会调用飞书。当前测试是本地 transport/Host fixture,不是一次真实飞书云端、真实模型或生产 cohort 验收。Web native-session 没有飞书 provider reply identity,不属于本路径。
常用命令
在飞书会话中使用:
/status # 当前 session 代次与上下文统计;/session 同义
/stop # 停止当前任务,保留 session
/new # 停止旧任务并切换到空白 session;/clear 同义
/compact # 宿主支持时压缩当前上下文
/model # 打开 provider/model/effort 选择卡片
/model use <route> # 文字方式切换模型
/model reset # 恢复部署默认模型
/permissions # 查看并选择权限档位
/permission ask
/permission auto
/permission full confirm
/feedback # 查看固定偏好反馈语法
/learning status # 查看偏好学习状态
/learning explain # 查看无历史正文的 key/value、版本与证据计数
/learning export # 导出无正文、无内部标识的稳定 T1 JSON
/learning pause # 暂停收集、激活与注入
/learning resume # 恢复,仅接收此后的新证据
/learning rollback response.language confirm # 撤回当前 lineage 的一个 exact active T1 key
/learning forget confirm # 物理删除当前 scope 的学习记录
未知 slash 命令不会进入模型。模型卡片、权限卡片和会话 lane 语义见操作文档。
运维常用:
# 重新安装或重启用户级常驻服务
dsh-lark-setup --profile web --install-service
# 刷新 setup 托管的 Agent Policy,不重走 onboarding
dsh-lark-setup --profile web --refresh-agent-policy --allow-agent-tools
权限与数据边界
- 首次绑定 owner 默认为本地
foreground 与精确 owner Delivery 主体建立已安装 capability/工具可达性,配合默认 Full access 无需逐工具确认。重复配置保留现有规则;可显式 --allow-agent-tools 开启、--disable-agent-tools 关闭向导规则,或 --preserve-agent-tools 连首次配置也保留现状;不授权 background,也不绕过显式 deny、紧急停止、身份、预算及插件业务硬门。
ask 和 auto 中真正需要人工确认的工具调用只向 active owner 私聊发送一次性 CardKit 2.0 审批卡;卡片包含“允许一次 / 拒绝”按钮。若租户拒绝该卡片格式,只对 format_error 降级成同一私聊的明确文字审批;恰好一个匹配请求时,owner 回复“允许”“允许一次”或“拒绝”可恢复原调用。多请求并存不猜测,网络/连接失败也不自动放行。允许或拒绝后,原卡片立即显示终态并移除按钮;允许只表示本次授权已生效,执行结果由后续任务消息提供。取消、超时或连接结束也尝试替换原卡,更新失败不改变审批结果。异步终态更新最多等待 30 秒,关闭时最多等待 1 秒后取消。full 关闭逐次审批并放开 sandbox,应保持 owner 与应用可用范围最小。
ask_user_question 的卡片是另一条即时交互路径:本包有向原飞书会话发送/原位更新 CardKit 2.0 卡片、并接收 card.action.trigger callback 的网络权限。选项仅以签名 callback capability 提交;自由文本只接受 exact owner 对原卡的明确回复。它不把卡片点击或匹配回复写成普通 Inbox/新 turn,且问题内容会在原会话显示,群聊并不保密。
- 记忆、Wiki 和行为学习提案使用 Card 2.0 审批按钮,签名绑定会话、提案版本与有效期;回调操作人另按 owner 授权校验。行为学习卡会把 scope、情境、guidance、版本、证据和回滚原因逐字段以纯文本展示;提案内容不会作为 Markdown 或卡片组件解释。点击后卡片只确认 Policy 决策已写入持久账本,明确不把“批准”误报成“变更已生效”。投递失败且已经过期的提案需要重新提交,升级不会自动批准或补发旧卡。
- 消息通道运行时网络仅访问所选飞书/Lark OpenAPI、token 与 WebSocket endpoint;图片读取使用固定消息资源端点,不接受消息或模型提供的 URL,并关闭重定向。
- 安装阶段的
dsh-rsi-setup --prepare-source 执行 Git,在 $DSH_HOME/rsi-sources/<profile> 写入私有源码与 bare 发布仓库;npm 来源访问固定官方 GitHub 仓库的精确版本 tag,本地来源只复制已提交内容。支持常用代理与 CA 环境变量,不执行安装脚本;此命令不使用飞书凭据或浏览器,详见 RSI 配置。
dsh-rsi-setup --prepare-local-update 在 Home 外准备本地上游与现有修复分支合并后的源码和 tarball,使用固定的镜像准备器及离线 bubblewrap 构建,保留原包、源码 refs 与授权。它可联网准备依赖镜像,但候选 build/pack 不带网络、凭据或原 Home;不会停服或激活更新。pre-owner 安装可使用 checkout 维护事务,已有 owner 的完整迁移仍未交付,详见 RSI 配置。
- checkout 的
local-service-upgrade 使用固定 pnpm,在停服前以无 registry 凭据的私有配置联网验证旧锁文件并预取依赖,失败保留原服务。停服副本的原生安装无网络且禁用安装脚本;新 Node 子进程沿用隔离边界,完整核验安装包文件和依赖闭包。事务会写入独立缓存及 Home 副本、切换 systemd 服务;它不启用 owner scheduler 或扩大授权。用法与恢复见安装器指南。
- macOS 安装使用系统 Perl 的内核
flock 串行化同一用户、同名 profile 的 LaunchAgent 操作,使用 plutil/launchctl 核对服务归属并管理当前用户服务;运行检查核对状态与 PID。同名目标属于另一 DSH_HOME 时拒绝修改,替换失败时尝试恢复旧定义与注册状态。原生学习另串行化 Home 配置,写入私有计划、有限授权、恢复日志和 HMAC observer 密钥。新安装从冻结源码清单和锁文件准备私有 Node、pnpm 及依赖,候选构建和行为检查使用本机 Seatbelt;Host 也是原生 Node。支持范围与失败恢复见原生 macOS 学习。
完整的文件系统、子进程、浏览器、审批签名和 Policy 说明见进度与安全文档。
当前限制
- v0.1 支持文本、受限图片描述符、文本/Markdown-card 出站、durable proposal、owner-DM 一次性工具审批、模型/权限卡片、reaction 和原生进度;模型不能提交任意 card JSON,也不能直接控制 reaction 或进度载荷。
- 只有图片资源具备受限下载能力,且依赖 AttachmentStore 与模型图片能力;文件、音频、视频和 sticker 只进入 metadata quarantine。没有病毒扫描、附件上传或消息编辑。
- 单应用长连接是集群竞争消费,不提供广播、多节点 exactly-once 或断线历史补拉;目标部署是受 supervisor 管理的单机进程。
- setup wizard 正式支持 macOS 与 Linux;Windows 为 best-effort。企业管理员审批和应用可用范围仍由飞书控制。
message_cot 与 reaction 都可能因租户、应用类型或接口能力而降级;它们失败不会重跑任务,也不会阻断最终回复。
更细的传输可靠性和故障处理见操作文档。
License
MIT