Skip to content

feat(feishu): interactive model picker card with two-level drill-down#10301

Open
yanen-bohoon wants to merge 1 commit into
NousResearch:mainfrom
yanen-bohoon:feishu-model-picker
Open

feat(feishu): interactive model picker card with two-level drill-down#10301
yanen-bohoon wants to merge 1 commit into
NousResearch:mainfrom
yanen-bohoon:feishu-model-picker

Conversation

@yanen-bohoon

Copy link
Copy Markdown

Summary

Add a full-featured interactive model picker card for the Feishu (Lark) platform. Users can now switch models through a visual card UI instead of typing commands.

Features

  • Two-level drill-down: First select a provider, then pick a model from that provider
  • Pagination: 4 models per page with prev/next navigation
  • In-place card updates: Uses P2CardActionTriggerResponse + CallBackCard for instant UI feedback without sending new messages
  • Status feedback: Shows "switching..." state, then success/failure with color-coded header

Additional changes bundled

  • Fix: Change approval card action intercept from wildcard (if hermes_action:) to exact set match (if hermes_action in approval_actions). This prevents model picker buttons from being incorrectly routed to the approval handler.
  • Add qwen3.6-plus to the Alibaba provider model list

Demo flow

  1. User clicks /model or equivalent trigger
  2. Bot sends a card listing all configured providers with model counts
  3. User taps a provider → card updates inline to show models (paginated)
  4. User taps a model → card shows "switching..." → updates to success/failure
  5. Bot sends a confirmation message with the new model name

…down and pagination

Add a full-featured model selection card for the Feishu platform that
supports provider -> model drill-down, pagination (4 models per page),
and in-place card updates via CallBackCard immediate responses.

Also includes:
- Fix: change approval card action intercept from wildcard to exact
  match (approval_actions set) to avoid catching model picker buttons
- Add qwen3.6-plus to Alibaba provider model list
@zycaskevin

Copy link
Copy Markdown

Thanks for building this! We independently wrote a similar implementation before discovering this PR. Since yours is already in-flight, I'd like to contribute our 12 passing unit tests and some review feedback to help this land.


✅ What looks good

  • Clean two-layer drill-down (provider → model) matching Telegram/Discord UX
  • P2CardActionTriggerResponse for synchronous card updates on navigation — correct approach
  • Separate _build_* card builders keep things readable
  • Approval vs picker routing is well-isolated with approval_actions set
  • Async switch via _submit_on_loop for the heavy on_model_selected callback

📦 Tests we can contribute

We wrote 12 pytest unit tests (all passing ✅) covering:

  • Provider card structure and current-provider marking
  • Model card: pagination, back/cancel buttons, multi-page navigation
  • Sync dispatch: provider→model, page nav, back, cancel, expired state
  • Model selection schedules async work + returns processing card

Test file: tests/gateway/test_feishu_model_picker.py

Happy to open a PR against your branch, or you can pull from zycaskevin/hermes-agent:feat/feishu-model-picker (tests in tests/gateway/test_feishu_model_picker.py). Let me know which you prefer!


🔍 Review observations (non-blocking)

1. No cancel button — Telegrams picker has ✗ Cancel alongside Back. Without it, the only way to dismiss is switching models or waiting for expiry. A model_pick_cancel action that shows a "Cancelled" card + cleans up state would improve UX. We used mx for this.

2. Feishu 4-button-per-action limit — The provider list puts ALL buttons in one "action" element (line ~1489). If there are >4 providers, Feishu will reject the card. We split into groups of 4 across multiple action elements. The 4-model-per-page design means model buttons never hit this limit, but provider buttons could.

3. Double notification on switch_execute_model_switch both updates the existing card AND sends a separate send() message. This means the user sees the card update + a second message "✅ 模型已切换为...". Intentional or leftover from debugging? Telegram just edits the original message.

4. Unrelated qwen3.6-plus entry — The hermes_cli/models.py diff adds a new model entry that looks unrelated to the picker feature. Consider splitting into separate PRs for cleaner review.

5. State key = picker_id vs chat_id — Using mp_{chat_id} as key means stale state is never cleaned up (just accumulates in _model_picker_state dict). Using chat_id directly (like Telegram) means a new /model naturally overwrites old state. Minor, but worth considering.


Again, great work — happy to help push this over the finish line! Let me know how you'd like me to contribute the tests.

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

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/feishu Feishu / Lark adapter type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants