d2283397a4
* feat(feishu): scan-to-create QR onboarding flow
Add a device-code flow against accounts.feishu.cn/oauth/v1/app/registration
that lets users scan a terminal QR code with Feishu / Lark mobile to
auto-create a PersonalAgent bot app with the required IM permissions
pre-attached. The poll endpoint returns app_id + app_secret, which the
onboarding wizard then writes into the channel config — no manual app
creation on open.feishu.cn required.
- channels/feishu/onboard.py: qr_register() public entry, init/begin/poll
helpers, QR rendering via the soft qrcode dep, automatic feishu↔lark
domain switch based on the scanning user's tenant_brand, and a
best-effort bot probe to surface the bot name in the wizard
- channels/feishu/__init__.py: re-export qr_register (mirrors qq)
- config/onboard.py: offer "Scan QR code (recommended) / Enter manually"
in the Feishu branch, ask for region (feishu vs lark), then call
qr_register and populate feishu_app_id / feishu_app_secret /
feishu_domain; add qrcode>=7.4 to the feishu pip extras
* fix(feishu): silently absorb unsubscribed WebSocket events
Feishu auto-subscribes PersonalAgent apps to many event types
(im.message.reaction.created_v1, message.read_v1, message.recalled_v1,
chat.member.*, ...) that EvoScientist doesn't register handlers for.
Without intervention, lark-oapi's dispatcher raises EventException
("processor not found, type: ..."), the WS client logs it at ERROR and
replies HTTP 500 on the frame, and Feishu marks the event as failed
and retries it.
The problem is amplified by _send_ack_reaction: every inbound message
triggers our own reaction, which Feishu echoes back as
reaction.created_v1, creating a continuous ERROR-log feedback loop and
pointless retries.
Wrap EventDispatcherHandler._do_without_validation after build() to
swallow "processor not found" EventExceptions (debug log + return None)
while letting all other errors propagate. Failure-safe: if lark-oapi's
internal API changes the wrapper degrades to the prior behavior rather
than breaking the channel.
---------
Co-authored-by: Xi Zhang <106144707+X-iZhang@users.noreply.github.com>