feat(feishu): show processing state via reactions on user messages

Replaces the permanent "OK" receipt reaction with a 3-phase visual
lifecycle:

- Typing animation appears when the agent starts processing.
- Cleared when processing succeeds — the reply message is the signal.
- Replaced with CrossMark when processing fails.
- Cleared when processing is cancelled or interrupted.

When Feishu rejects the reaction-delete call, we keep the Typing in
place and skip adding CrossMark. Showing both at once would leave the
user seeing both "still working" and "done/failed" simultaneously,
which is worse than a stuck Typing.

A FEISHU_REACTIONS env var (default on) disables the whole lifecycle.
User-added reactions with the same emoji still route through to the
agent; only bot-origin reactions are filtered to break the feedback
loop.

Change-Id: I527081da31f0f9d59b451f45de59df4ddab522ba
This commit is contained in:
Roy-oss1 2026-04-18 12:56:06 +08:00 committed by Teknium
parent 60236862ee
commit 520edd3499
3 changed files with 395 additions and 90 deletions

View file

@ -335,13 +335,22 @@ If the Feishu API rejects the post payload (e.g., due to unsupported markdown co
Plain text messages (no markdown detected) are sent as the simple `text` message type.
## ACK Emoji Reactions
## Processing Status Reactions
When the adapter receives an inbound message, it immediately adds an ✅ (OK) emoji reaction to signal that the message was received and is being processed. This provides visual feedback before the agent completes its response.
The adapter cycles a reaction on the user's message to signal what the agent is doing:
The reaction is persistent — it remains on the message after the response is sent, serving as a receipt marker.
| Phase | Reaction |
|-------|----------|
| Agent begins processing | `Typing` added |
| Processing succeeds | `Typing` removed (the reply message itself is the success signal) |
| Processing fails | `Typing` removed, `CrossMark` added |
| Processing is cancelled or interrupted | `Typing` removed (task aborted; no replacement badge) |
User reactions on bot messages are also tracked. If a user adds or removes an emoji reaction on a message sent by the bot, it is routed as a synthetic text event (`reaction:added:EMOJI_TYPE` or `reaction:removed:EMOJI_TYPE`) so the agent can respond to feedback.
Unlike Discord/Matrix, no positive badge is added on success — Feishu reactions render as prominent timeline badges and a per-message success marker would create visual noise. The absence of a badge, together with the reply message, is the success signal.
Set `FEISHU_REACTIONS=false` to disable this entirely (e.g., for tenants where the bot lacks reaction permission, or where the noise is unwanted).
User reactions on bot messages are routed back to the agent as synthetic text events (`reaction:added:EMOJI_TYPE` or `reaction:removed:EMOJI_TYPE`). Only real user reactions are routed — bot/app-origin reactions (including the adapter's own `Typing`/`CrossMark`) are dropped to avoid feedback loops.
## Burst Protection and Batching