feat(feishu): add IM platform adapter - #46
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a staged Feishu/Lark IM adapter layer (background service + session manager + controller bridge + reply rendering) and wires a generic “platform background services” lifecycle into the core platform manager/orchestrator, while keeping the legacy Feishu websocket entrypoint unchanged.
Changes:
- Extend
@nine1bot/platform-protocolandPlatformAdapterManagerto support per-platform background services (start/stop + status reporting). - Add Feishu IM skeleton: config normalization/validation, gateway/parse/dedup/gating, route keys + bindings, session manager (buffering/busy/abort/control commands), HTTP controller bridge, and reply sink with cards + streaming CardKit support + telemetry.
- Add/extend tests for Feishu IM components and platform manager background service lifecycle.
Reviewed changes
Copilot reviewed 38 out of 38 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/platform-protocol/src/index.ts | Adds background service + controller bridge types to the platform protocol. |
| packages/platform-feishu/test/feishu-platform.test.ts | Asserts Feishu descriptor exposes IM reply-related settings. |
| packages/platform-feishu/test/feishu-im.test.ts | Tests IM config normalization/validation, parsing, gating, dedup, routing, bindings, and legacy-staging status. |
| packages/platform-feishu/test/feishu-im-session-manager.test.ts | Tests session routing, buffering/flush, abort, busy behavior, thread parallelism, and control commands. |
| packages/platform-feishu/test/feishu-im-reply.test.ts | Tests reply sink behaviors (text/card/streaming-card), CardKit streaming, fallbacks, interactions, and telemetry. |
| packages/platform-feishu/test/feishu-im-controller-bridge.test.ts | Tests the HTTP controller bridge mapping to public controller APIs, including 409 busy responses. |
| packages/platform-feishu/src/runtime.ts | Registers IM config fields/actions; merges IM runtime status into overall Feishu status. |
| packages/platform-feishu/src/node.ts | Exports Feishu IM node helpers (controller bridge + reply client). |
| packages/platform-feishu/src/index.ts | Re-exports IM module from the package entrypoint. |
| packages/platform-feishu/src/im/types.ts | Defines Feishu IM domain types (config, routing, control results, runtime snapshots). |
| packages/platform-feishu/src/im/streaming-card-controller.ts | Implements streaming card transport (CardKit → patch → text) with throttling and sanitization. |
| packages/platform-feishu/src/im/store/binding-store.ts | Adds an in-memory binding store for route→session bindings. |
| packages/platform-feishu/src/im/session-manager.ts | Implements message buffering, session reuse/reset, abort, control commands, and busy semantics. |
| packages/platform-feishu/src/im/runtime.ts | Implements staged Feishu IM background service + runtime status snapshotting/cards. |
| packages/platform-feishu/src/im/route.ts | Implements route-key construction/serialization/parsing for DM/group/thread. |
| packages/platform-feishu/src/im/reply-telemetry.ts | Tracks IM reply runtime counters and last-error metadata for status display. |
| packages/platform-feishu/src/im/reply-sink.ts | Bridges controller runtime events to Feishu replies (text/cards/streaming + interactions). |
| packages/platform-feishu/src/im/reply-coordinator.ts | Provides factories for reply sinks and immediate replies from session-manager results. |
| packages/platform-feishu/src/im/reply-client.ts | Defines reply client interface and an in-memory implementation for tests. |
| packages/platform-feishu/src/im/node/reply-client.ts | Implements a Node reply client using Lark/Feishu SDK APIs (message + CardKit). |
| packages/platform-feishu/src/im/node/http-controller-bridge.ts | Implements controller bridge over HTTP + SSE event subscription. |
| packages/platform-feishu/src/im/interactions.ts | Implements card action payloads, parsing/validation, and interaction answering. |
| packages/platform-feishu/src/im/index.ts | Public export surface for the Feishu IM module. |
| packages/platform-feishu/src/im/inbound/parse.ts | Parses incoming Feishu IM events into normalized message objects. |
| packages/platform-feishu/src/im/inbound/gate.ts | Implements gating policy (allowlist, DM/group policy, mention-only). |
| packages/platform-feishu/src/im/history.ts | Implements in-memory group history store (TTL + limit). |
| packages/platform-feishu/src/im/gateway.ts | Adds a minimal gateway handle abstraction (start/stop/inject). |
| packages/platform-feishu/src/im/dedup.ts | Adds an event deduplicator with TTL and max-size pruning. |
| packages/platform-feishu/src/im/controller-bridge.ts | Defines the controller bridge interface + capabilities and helper utilities. |
| packages/platform-feishu/src/im/config.ts | Adds IM config normalization, validation, defaults, and secret-ref enforcement. |
| packages/platform-feishu/src/im/cards.ts | Renders Feishu cards (turn/control/permission/question/streaming + CardKit v2). |
| packages/platform-feishu/src/im/buffer/message-buffer.ts | Adds per-route message buffering with flush/max timers and snapshots. |
| packages/platform-feishu/src/im/abort.ts | Defines abort keywords and normalization helpers. |
| packages/platform-feishu/package.json | Adds @larksuiteoapi/node-sdk dependency. |
| packages/nine1bot/src/platform/manager.ts | Adds background service start/stop lifecycle and runtime status application. |
| packages/nine1bot/src/platform/manager.test.ts | Adds tests for starting/stopping/restarting background services. |
| packages/nine1bot/src/platform/builtin.ts | Exposes helpers to start/stop background services for built-in platforms. |
| packages/nine1bot/src/launcher/orchestrator.ts | Starts/stops platform background services during app launch/shutdown. |
Comments suppressed due to low confidence (1)
packages/nine1bot/src/platform/manager.ts:221
configure()triggersstopBackgroundServices()without awaiting it. BecausestopBackgroundServices()clears the registry before awaiting the individualhandle.stop()calls, a subsequentstartBackgroundServices()(or another reconfigure) can start new services while old ones are still stopping, leaving overlapping background services running briefly. Consider making the stop operation serialized (e.g. track an in-flight stop promise thatstartBackgroundServices()/configure()await) or makingconfigureasync so it can await a full stop.
configure(config: PlatformManagerConfig) {
void this.stopBackgroundServices()
this.unregisterRuntimeAdapters()
this.config = normalizeConfig(config)
this.rebuildRecords()
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
描述 / Summary
本 PR 为
platform-feishu增加 Feishu IM 平台接入层的可测试基础闭环,使飞书 IM 能力进入 Nine1Bot 多平台适配架构,而不是继续扩展旧的packages/nine1bot/src/feishu临时实现。本阶段重点完成平台级 IM 架构、会话管理、Controller Bridge、Reply Sink、卡片交互、buffer / abort / thread 并行和 streaming card 能力。当前 PR 不切换生产 websocket,不删除旧 Feishu 主实现;旧
feishu.enabled场景下新 IM background service 保持 staged/degraded,避免双连接。类型 / Type of change
关联的 issue(如果有)/ Related issues
暂无。
变更点 / What changed
platform-feishucontribution 声明后台服务。packages/platform-feishu/src/imIM 子模块,包含 config normalize、gateway 抽象、parse、dedup、gate、route key、binding store、history、message buffer 等基础逻辑。FeishuIMSessionManager,支持 DM / group / thread route 隔离、session binding 复用、/new、/cwd、/project、消息缓冲、busy reject、abort 和 thread 并行。FeishuControllerBridge,通过公开 HTTP Controller API 创建 session、发送消息、读取 project/session、abort turn,不反向 import Nine1Bot 产品层或 opencode server 内部实现。/control、项目切换、当前 cwd/session 展示等交互。packages/nine1bot/src/feishu生产入口不变,本 PR 只提供新 IM 能力的 staged 可测试实现。如何测试 / How to test
bun test packages/platform-feishu/testcd packages/platform-feishu && bun run typecheckcd packages/platform-protocol && bun run typecheckcd packages/nine1bot && bun run typecheckfeishu.enabled场景下保持 staged/degraded,不抢占 websocket。截图(UI 变更时提供)/ Screenshots for UI changed
暂无。本 PR 主要是平台 descriptor 驱动的配置项与状态卡片接入,没有新增定制 UI 页面。
Checklist(合并前请确认) / Checklist
imAccounts中接受明文appSecretfeishu.enabled场景下抢占 websocketplatform-feishu不反向依赖 Nine1Bot 产品层或 opencode server 内部实现备注 / Notes for reviewers
packages/platform-feishu/src/im/session-manager.ts、reply-sink.ts、streaming-card-controller.ts和node/reply-client.ts。turn.abort卡片 action 要求 account / route / session / turn 完整匹配,避免旧卡片误操作当前 turn。