Skip to content

refactor(platform): 建立平台运行时边界并接入 Lark#442

Draft
LucasIcarus wants to merge 2 commits into
deepcoldy:masterfrom
LucasIcarus:refactor/platform-runtime-boundary
Draft

refactor(platform): 建立平台运行时边界并接入 Lark#442
LucasIcarus wants to merge 2 commits into
deepcoldy:masterfrom
LucasIcarus:refactor/platform-runtime-boundary

Conversation

@LucasIcarus

@LucasIcarus LucasIcarus commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

背景与目标

botmux 当前的生产执行路径以 Lark/飞书为中心,daemon、会话编排、消息发送和持久化身份之间仍有较强的直接耦合。如果继续沿现有路径叠加新 IM,平台差异会进一步渗入 core,也难以可靠约束“一个 session 属于哪个平台实例”。

本 PR 先建立真实可运行的平台边界,并让现有 Lark 路径通过该边界运行:

  • 一个部署可以管理多个平台实例,但一个 daemon 进程只运行一个平台实例;
  • 一个 session 始终归属一个平台实例,A2A / relay 只在同平台内闭环;
  • 核心模型和已迁移的通用调用只依赖平台中立接口;
  • Lark runtime 由 daemon composition root 组装和注入;
  • 本阶段不引入 Discord SDK、配置或可启动的 Discord runtime;
  • 不改变现有配置格式、磁盘数据、dashboard wire shape 和用户可见行为。

改了什么

平台领域模型与小型 ports

  • 新增 PlatformIdPlatformInstanceRefPlatformConversationRef,以及统一的 message、sender、mention、attachment 模型;
  • 按职责拆分 messaging、cards、reactions、attachments、identity、conversation、DM 等 ports;
  • PlatformCapabilities 显式声明 cards、stream updates、threads、mentions 等能力;
  • 能力缺失或声明与 port 不一致时明确报错,不使用空实现伪装支持;
  • 收敛此前未落地的巨型 ImAdapter 草案,避免两套竞争性抽象;
  • 增加架构依赖测试,禁止平台专属类型继续渗入平台中立层。

Lark runtime 与 composition root

  • 新增 LarkPlatformRuntime,组合现有 Lark event dispatcher、client、cards、reactions、attachments、identity 和 conversation routing;
  • runtime façade 以薄委托方式复用成熟实现,保留原有参数、返回值、异常、调用顺序和重试语义;
  • daemon 负责选择 bot 配置、构造单个 runtime,并把所需能力注入会话编排;
  • 文档评论、VC、群管理等 Lark 特有能力继续留在 extension/raw event callback 层,不为它们设计虚假的跨平台 parity。

会话归属、恢复与兼容层

  • DaemonSession 拆分为平台中立状态和类型安全的 Lark compatibility context;
  • session key 增加基于 PlatformInstanceRef 的入口;Lark 仍生成与旧版本相同的 key;
  • session store、adopt / restore / resume、A2A / relay 和 dashboard IPC 增加平台实例校验;
  • 跨平台路径在进入转发前明确返回 unsupported;
  • registry、daemon descriptor 和 dashboard discovery 增加 (platform, instanceId) 视图,同时保留 larkAppId 及旧字段语义;
  • 旧配置、旧 session JSON 和缺少新字段的 descriptor 在读取时默认推导为 Lark,不触发批量迁移或历史文件回写;
  • daemon descriptor 增量加入 platforminstanceIdcapabilities,旧字段与文件名保持不变。

此外补全了 sandbox 新建目录的元数据测试夹具;该项不修改生产行为,可以独立审阅或回退。

基本设计

daemon(composition root)
├─ core 会话编排 ──> PlatformRuntime + 按职责拆分的 ports
│  └─ 尚未迁移的专属路径 -. 精确 legacy allowlist .-> 既有 Lark 模块
└─ LarkPlatformRuntime ──> 现有 Lark client / dispatcher / 能力委托

这里没有设计一个覆盖所有平台细节的万能 adapter。稳定的跨平台语义进入小型 ports;平台是否支持某项能力由 capability 声明;尚未抽象的 Lark 特有能力继续留在 extension 层。

迁移采用 strangler 方式:已迁移的生产调用先穿过 runtime façade,再委托到原有 Lark 实现。这是第一段迁移,不是一次性清空所有 Lark 耦合;架构测试会冻结既有例外,后续应逐项缩小 allowlist,而不是扩大它。

影响面与兼容性

维度 结论
平台 当前仍只有 Lark runtime;未加入 Discord。Lark 可以是能力超集。
配置与磁盘数据 larkAppId/larkAppSecret/brandsessions-<larkAppId>.json、旧 descriptor 字段和文件名保持不变。
Dashboard discovery/registry 内部开始使用平台实例身份;UI、路由、筛选、会话控制和 wire shape 不变。
会话类型 覆盖话题、普通群、chat/thread scope、queued/pending、冷恢复、adopt/restore;旧 Lark session key 与恢复语义保持不变。
CLI / backend worker/CLI 协议未改;平台改造不改变具体 CLI 的输入输出协议。
A2A / relay 同平台路径保持原样;跨平台请求明确拒绝。
Lark 专属能力 保持在 extension 层,不塞入通用 ports。

验证方式

通用自动化验证:

pnpm build
pnpm test

pnpm vitest run --project unit \
  test/platform-runtime.test.ts \
  test/lark-platform-runtime.test.ts \
  test/platform-session-key.test.ts \
  test/platform-architecture.test.ts \
  test/daemon-discovery.test.ts \
  test/dashboard-registry.test.ts

pnpm vitest run --project e2e \
  test/tmux-backend.e2e.ts \
  test/multi-bot-session.e2e.ts \
  test/multi-bot-group-flow.e2e.ts \
  test/web-terminal-scrollback.e2e.ts \
  test/card-toggle.e2e.ts

重点断言包括:

  • 平台身份、capability 声明与 runtime 生命周期;
  • Lark façade 对旧实现的参数、返回值、异常和调用顺序兼容;
  • 旧配置、旧 session、旧 descriptor 的读取兼容;
  • session key、恢复、adopt、chat/thread scope 与 dashboard discovery;
  • cards、reactions、attachments、mentions、A2A / relay;
  • 平台中立层不能新增 im/lark 依赖。

Live E2E

真实 Lark 环境的 live E2E 是 opt-in 测试,不进入默认 pnpm test,也不要求每位开发者使用个人飞书环境。具备独立测试租户或可接受的临时测试环境时,建议使用每轮新建的隔离群覆盖:

  • 同一条消息触发两个 bot,验证平台实例和 session 不串;
  • 非流式模式下的 reaction、最终答案和无 streaming status card;
  • chat/thread scope、type-ahead、daemon restart recovery;
  • 同平台 relay;
  • 附件、AskUser / approval,以及至少一项 Lark extension。

所有 live case 应只操作本轮随机命名的临时资源,并在结束后精确清理;不得复用已有工作群或私聊。

Computer Use 仅作为 best-effort 的原生客户端渲染观察:没有合适桌面环境、登录态或测试意愿时可以直接跳过,不影响自动化测试结论,也不作为 PR 合并门槛。

当前状态

本 PR 保持 Draft。自动化边界与兼容性验证可继续审阅;真实 Lark live E2E 在具备合适的隔离环境后再补充结果。

@LucasIcarus
LucasIcarus force-pushed the refactor/platform-runtime-boundary branch 4 times, most recently from 64a3c0b to 8804921 Compare July 14, 2026 11:00
@LucasIcarus
LucasIcarus force-pushed the refactor/platform-runtime-boundary branch from 8804921 to 5ddcf16 Compare July 15, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant