feat(feishu): sync community contributions from clawdbot-feishu#12662
feat(feishu): sync community contributions from clawdbot-feishu#12662cpojer merged 1 commit intoopenclaw:mainfrom
Conversation
Sync community contributions from the independent feishu plugin repo (clawdbot-feishu 0171c12..ee8312a): - Card format upgrade to schema 2.0 for proper markdown rendering - Message dedup mechanism to prevent duplicate processing on WS reconnect - Dynamic agent creation for DM users - Topic-based session isolation for group chats - Webhook connection mode support for Lark Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| let route = core.channel.routing.resolveAgentRoute({ | ||
| cfg, | ||
| channel: "feishu", | ||
| accountId: account.accountId, | ||
| peer: { | ||
| kind: isGroup ? "group" : "direct", | ||
| id: isGroup ? ctx.chatId : ctx.senderOpenId, | ||
| id: peerId, | ||
| }, | ||
| }); |
There was a problem hiding this comment.
Inconsistent peer kind
resolveAgentRoute is first called with peer.kind set to "direct" for DMs, but if dynamic agent creation triggers you re-resolve using peer.kind: "dm" (and dynamic-agent.ts also creates bindings with peer.kind: "dm"). If the routing/binding system only recognizes "direct" (as used elsewhere in the codebase) this will prevent the new binding from ever matching, leaving DMs stuck on the default route.
This should use the same peer kind consistently (typically "direct") for both binding creation and route resolution.
Also appears in: extensions/feishu/src/dynamic-agent.ts:29-33, 67-71, 109-112.
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/feishu/src/bot.ts
Line: 688:696
Comment:
**Inconsistent peer kind**
`resolveAgentRoute` is first called with `peer.kind` set to `"direct"` for DMs, but if dynamic agent creation triggers you re-resolve using `peer.kind: "dm"` (and `dynamic-agent.ts` also creates bindings with `peer.kind: "dm"`). If the routing/binding system only recognizes `"direct"` (as used elsewhere in the codebase) this will prevent the new binding from ever matching, leaving DMs stuck on the default route.
This should use the same peer kind consistently (typically `"direct"`) for both binding creation and route resolution.
Also appears in: `extensions/feishu/src/dynamic-agent.ts:29-33, 67-71, 109-112`.
How can I resolve this? If you propose a fix, please make it concise.| const port = account.config.webhookPort ?? 3000; | ||
| const path = account.config.webhookPath ?? "/feishu/events"; | ||
|
|
||
| log(`feishu[${accountId}]: starting Webhook server on port ${port}, path ${path}...`); | ||
|
|
||
| const server = http.createServer(); | ||
| server.on("request", Lark.adaptDefault(path, eventDispatcher, { autoChallenge: true })); |
There was a problem hiding this comment.
Port collision across accounts
In webhook mode, monitorWebhook defaults to webhookPort ?? 3000 for every account. If multiple Feishu accounts are enabled with connectionMode: "webhook" and don’t explicitly set distinct ports, the second server will fail to listen() (EADDRINUSE) and monitoring for that account will never start.
Consider requiring an explicit port in webhook mode, or deriving unique defaults per account / running a single shared server with per-account routing.
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/feishu/src/monitor.ts
Line: 194:200
Comment:
**Port collision across accounts**
In webhook mode, `monitorWebhook` defaults to `webhookPort ?? 3000` for every account. If multiple Feishu accounts are enabled with `connectionMode: "webhook"` and don’t explicitly set distinct ports, the second server will fail to `listen()` (EADDRINUSE) and monitoring for that account will never start.
Consider requiring an explicit port in webhook mode, or deriving unique defaults per account / running a single shared server with per-account routing.
How can I resolve this? If you propose a fix, please make it concise.| let effectiveCfg = cfg; | ||
| if (!isGroup && route.matchedBy === "default") { | ||
| const dynamicCfg = feishuCfg?.dynamicAgentCreation as DynamicAgentCreationConfig | undefined; | ||
| if (dynamicCfg?.enabled) { | ||
| const runtime = getFeishuRuntime(); | ||
| const result = await maybeCreateDynamicAgent({ | ||
| cfg, | ||
| runtime, |
There was a problem hiding this comment.
Config writes ignored
maybeCreateDynamicAgent writes the updated config file via runtime.config.writeConfigFile(updatedCfg), but handleFeishuMessage continues dispatching using the original cfg (e.g. dispatchReplyFromConfig({ ctx, cfg, ... })). Since routing and agent selection are config-driven, the newly-created agent/binding may not take effect for the current message (and possibly subsequent messages depending on how cfg is sourced).
If dynamic agent creation is intended to apply immediately, the dispatch path should use effectiveCfg (or otherwise reload config after the write) consistently for routing + dispatch.
Also appears in: extensions/feishu/src/bot.ts:712-726 where effectiveCfg is set but not used later.
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/feishu/src/bot.ts
Line: 700:707
Comment:
**Config writes ignored**
`maybeCreateDynamicAgent` writes the updated config file via `runtime.config.writeConfigFile(updatedCfg)`, but `handleFeishuMessage` continues dispatching using the original `cfg` (e.g. `dispatchReplyFromConfig({ ctx, cfg, ... })`). Since routing and agent selection are config-driven, the newly-created agent/binding may not take effect for the current message (and possibly subsequent messages depending on how `cfg` is sourced).
If dynamic agent creation is intended to apply immediately, the dispatch path should use `effectiveCfg` (or otherwise reload config after the write) consistently for routing + dispatch.
Also appears in: `extensions/feishu/src/bot.ts:712-726` where `effectiveCfg` is set but not used later.
How can I resolve this? If you propose a fix, please make it concise.…claw#12662) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…claw#12662) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…claw#12662) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…claw#12662) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…claw#12662) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Sync community contributions from the independent feishu plugin repo (clawdbot-feishu
0171c12..ee8312a):chatId:topic:rootIdas peer IDCloses
Test plan
dynamicAgentCreation.enabled: true🤖 Generated with Claude Code
Greptile Overview
Greptile Summary
This PR syncs Feishu plugin changes from an upstream community repo, adding (1) in-memory message deduplication to reduce duplicate handling on reconnect/redelivery, (2) a webhook-based connection mode (HTTP server + Lark adapter) for environments without WS subscriptions, (3) optional topic/thread session isolation in group chats via a derived peer id, (4) dynamic DM agent creation by writing new agents/bindings into the config file, and (5) interactive card schema 2.0 formatting for improved markdown rendering.
Key touch points are
extensions/feishu/src/bot.ts(inbound parsing/routing/dedup + dynamic agent creation),extensions/feishu/src/monitor.ts(WS vs webhook listener), andextensions/feishu/src/config-schema.ts/types.ts(new config knobs).Confidence Score: 3/5
(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!