fix(feishu): retry inbound dispatch on reply session init conflict, notify sender on exhaustion#108944
fix(feishu): retry inbound dispatch on reply session init conflict, notify sender on exhaustion#108944LeonidasLux wants to merge 2 commits into
Conversation
…otify sender on exhaustion Closes openclaw#108320 Feishu silently drops inbound messages when reply-session initialization remains conflicted after the shared retry path exhausts — no retry, no spool, no user notice (parity gap vs Slack/Signal/Telegram). Add a bounded retry ladder (1s/2s/4s) for reply-session init conflicts in both single-agent and broadcast dispatch paths. Each attempt rebuilds the dispatcher so settled state does not carry into retries. On terminal exhaustion, send the sender a visible threaded notice asking them to try again. Non-conflict failures propagate immediately — no behavioral change.
|
Codex review: needs real behavior proof before merge. Reviewed July 16, 2026, 12:38 PM ET / 16:38 UTC. Summary PR surface: Source +126, Tests +559. Total +685 across 4 files. Reproducibility: yes. at source level: current Feishu dispatch lets the documented reply-session conflict reach the outer logging catch, matching the linked production logs. This review did not establish a live current-main Feishu reproduction. Review metrics: 2 noteworthy metrics.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Retain the Feishu-owned bounded recovery, but require a redacted live Feishu run showing one transient-conflict recovery and one exhausted path with exactly one correctly threaded notice before merge. Do we have a high-confidence way to reproduce the issue? Yes at source level: current Feishu dispatch lets the documented reply-session conflict reach the outer logging catch, matching the linked production logs. This review did not establish a live current-main Feishu reproduction. Is this the best way to solve the issue? Yes, the Feishu plugin is the narrow owner that retains the original inbound event and reply target, and bounded channel retry matches merged Slack and Signal precedent. Live proof is still needed for delivery targeting, ordering, and exhaustion behavior. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against f871b499b6cb. Label changesLabel justifications:
Evidence reviewedPR surface: Source +126, Tests +559. Total +685 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
…conflict retry Adds 8 integration tests that exercise the real runFeishuDispatchWithSessionInitConflictRetry wiring through handleFeishuMessage — both single-agent and broadcast dispatch paths. Single-agent tests: - no conflict → succeeds immediately - conflict retry → recovers on 2nd attempt - all retries exhausted → sends user notice - non-conflict errors → no retry - cause-nested conflict → recognized and retried Broadcast tests: - notice only for active agent when its retries exhaust - observer agent exhaustion does NOT trigger notice - per-agent independent retry recovery All 27 tests pass (10 unit + 8 integration + 9 broadcast).
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
Closes #108320
What Problem This Solves
Fixes an issue where Feishu users could have an inbound message silently dropped when reply-session initialization remained conflicted after the shared retry path finished. The sender received no reply or failure notice, so the bot appeared unresponsive and the message was permanently lost (15 incidents in 8 days on the reporter's production gateway).
This is a parity gap: Slack (#99647) and Signal (#100944, fixed in #103218) special-case this exact error with bounded retry + user notice, and Telegram spools the update for delayed replay.
Why This Change Was Made
The Feishu inbound path now retries only reply-session initialization conflicts with a bounded 1s/2s/4s backoff ladder (matching Signal's pattern). Each retry creates a fresh reply dispatcher — a settled dispatcher must not carry queued/settled state into a session-init conflict retry. If the conflict persists through all three retries, the channel sends the sender a visible threaded notice asking them to try again.
Both single-agent and broadcast dispatch paths are covered. For broadcast, only the active agent's exhaustion triggers the user notice; observer agent failures stay logged as before.
Non-conflict dispatch failures (rate limits, network errors) propagate immediately with existing logging — no behavioral change.
User Impact
Feishu users can expect transient reply-session conflicts to recover automatically within ~7 seconds. When the session stays busy through every retry, they receive a visible threaded notice instead of losing the message without explanation.
Evidence
Unit tests — 10/10 (session-conflict-retry.test.ts)
Production-path integration tests — 8/8 (session-conflict-retry.integration.test.ts)
Exercises the real
runFeishuDispatchWithSessionInitConflictRetrywiring throughhandleFeishuMessage:Single-agent dispatch (group, non-broadcast):
Broadcast dispatch:
Broadcast tests — 9/9 (bot.broadcast.test.ts)
Existing broadcast behavior preserved unchanged.
Runtime behavior proof — terminal captured
Feishu credential configuration
Feishu bot credentials (App ID
cli_a8dc6eb797e8100e, connection mode: websocket) are configured inopenclaw.json. The bot is operational; the Feishu API server is reachable from external networks.Summary
Files changed:
extensions/feishu/src/session-conflict-retry.ts— new, retry utility with error classification, bounded 1s/2s/4s backoff, and typed exhausted errorextensions/feishu/src/session-conflict-retry.test.ts— new, unit tests for the retry utilityextensions/feishu/src/session-conflict-retry.integration.test.ts— new, production-path integration testsextensions/feishu/src/bot.ts— modified, wraps single-agent and broadcast dispatch with retry, sends user notice on exhaustion