Skip to content

feat(feishu): add native update prompt cards - #22448

Merged
kshitijk4poor merged 1 commit into
mainfrom
salvage/feishu-update-prompt-21911
May 9, 2026
Merged

feat(feishu): add native update prompt cards#22448
kshitijk4poor merged 1 commit into
mainfrom
salvage/feishu-update-prompt-21911

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Salvage of #21911 by @heathley onto current main.

What this does

Adds send_update_prompt() to the Feishu adapter so when hermes update --gateway needs y/n confirmation (stash restore, config migration), Feishu users get an interactive Yes / No card with proper authorization gating instead of the plain-text fallback.

Today, gateway/run.py does getattr(type(adapter), "send_update_prompt", None) is not None and falls back to plain text when the method isn't defined. Discord, Telegram, and qqbot (#21353) already implement it — Feishu was the gap.

Implementation

Mirrors the existing Feishu approval-card architecture (send_exec_approval / _handle_approval_card_action / _resolve_approval / _build_resolved_approval_card):

  • _update_prompt_state dict + counter for prompt-id tracking
  • send_update_prompt() builds an interactive Card V2 payload, sends via _feishu_send_with_retry, stores state on success
  • _handle_update_prompt_card_action() handles button clicks: validates prompt_id, validates answer (y/n), authorizes operator against existing _admins and _allowed_group_users allowlists, schedules resolution, returns a resolved-state replacement card
  • _resolve_update_prompt() pops state and atomically writes ~/.hermes/.update_response (matches qqbot's _write_update_response semantics)
  • Method signature (chat_id, prompt, default, session_key, metadata) matches Discord's exactly

Bonus: _submit_on_loop now returns bool so callers can detect scheduling failures (loop closed, RuntimeError) and avoid showing a card as resolved when the resolution coroutine couldn't actually be scheduled. The existing approval handler picks up the same fix.

Tests

13 new test cases integrated into tests/gateway/test_feishu_approval_buttons.py:

  • Send: success, state stored, not-connected, send failure
  • Callback: yes, no, missing prompt_id, already-resolved, schedule failure, unauthorized operator
  • Resolve: writes response file, overwrites existing file, drops unknown prompt_id silently

Full Feishu test suite: 256 passed across test_feishu_approval_buttons.py, test_feishu.py, test_feishu_onboard.py.

Why salvage

PR #21911 was 486 commits behind main, but only 3 unrelated commits had touched feishu.py since (monotonic deadlines, topic-thread cleanup, topic-reply threading) — none overlapped with the PR's hunks. Cherry-pick auto-merged cleanly with +433/-3 matching the PR's stats exactly. @heathley's authorship preserved.

Closes #21911.

Use --rebase merge to preserve @heathley's authorship.

@kshitijk4poor
kshitijk4poor merged commit 7e578f0 into main May 9, 2026
15 of 16 checks passed
@kshitijk4poor
kshitijk4poor deleted the salvage/feishu-update-prompt-21911 branch May 9, 2026 09:32
@github-actions

github-actions Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

🔎 Lint report: salvage/feishu-update-prompt-21911 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 7876 on HEAD, 7876 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 4171 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants