Skip to content

feat(feishu): add interactive card, file upload/send, and message tools - #27163

Open
jajabong wants to merge 5 commits into
NousResearch:mainfrom
jajabong:feat/feishu-card-tool
Open

feat(feishu): add interactive card, file upload/send, and message tools#27163
jajabong wants to merge 5 commits into
NousResearch:mainfrom
jajabong:feat/feishu-card-tool

Conversation

@jajabong

Copy link
Copy Markdown

Summary

Add four new Feishu IM tools that were missing from the main codebase:

New Tools

Tool Description
feishu_send_card Send interactive Message Cards with buttons, fields, and rich layouts
feishu_send_message Plain text messages (simpler than card)
feishu_upload_file Upload file to Feishu, return file_key
feishu_send_file Two-step: upload + send file message to user/chat

Card Template Helpers

For building card JSON programmatically:

  • task_card(title, status, due_date, assignee_name, task_url) — task notification with status emoji, field rows, action button
  • calendar_card(title, start_time, end_time, location, attendees, organizer, description) — event info card
  • generic_card(title, body_lines, description, status, actions) — generic info card with field pairs
  • _card_text(), _card_div(), _card_hr(), _card_button() — base element builders

Changes

  • tools/feishu_card_tool.py — new file (558 lines)
  • tests/tools/test_feishu_card_tool.py — 20 tests (all pass)

Note: feishu_messages_tool.py (session history reader) is a different tool and was intentionally left unchanged.

ClawOS Mini added 5 commits May 17, 2026 05:30
The _list_recent_sessions() call now passes user_id=None (from contextvars)
to list_sessions_rich() for multi-user session isolation.
Multi-user routing improvements:
- SessionState now carries platform/chat_id/user_id fields for per-user routing
- ACP set_config_option now handles chat_id/platform/user_id as first-class config
- send_message_tool: session chat_id takes priority over home_channel (CLI/cron fallback preserved)
- session_search: user_id passed through to list_sessions_rich/search_messages for scoped results
- hermes_state: user_id parameter added to list_sessions_rich, search_messages, FTS methods

HermesOS gateway integration:
- gateway/run.py: _resolve_model_tier_config() reads HERMES_OS_MODEL_TIER env var and maps to config.yaml providers (local/kilo/minimax/blend/opus/baosi)
- Auto-injects hermes-os gateway patch from ~/hermes-os/src/hermes_os/gateway_patch.py

Feishu improvements:
- WS reconnect: ws_thread_done callback detects fatal errors and triggers gateway reconnect
- Heartbeat interval config (90s default, matches lark WS ping)
- Swallow RuntimeError from lark-oapi reconnect cleanup

cmux bypass:
- local.py subprocess env: remove cmux.app bin from PATH, unset CMUX_* env vars to prevent claude -p hanging in non-cmux contexts

Bug fix:
- feishu_task_tool: add missing PatchTaskRequestBodyBuilder import for reopen handler

Feishu tools (new):
- feishu_task_tool: create/list/complete/reopen/delete/search tasks via lark-oapi
- hermes_cli/auth.py: add MINIMAX_CN_API_KEY_2 as second MiniMax key env var
…ls + chief_agent

New tools:
- feishu_bitable_tool: list/create/search records in Feishu Bitable
- feishu_calendar_tool: CRUD events, attendees, calendars via lark-oapi
- feishu_messages_tool: send/get messages with text/post/media support
- feishu_oauth: PKCE OAuth flow for user access tokens + disk token storage
- chief_agent_tool: Hermes OS chief agent intent routing tool

All tools include full unit tests with mock lark-oapi client.
…smatch

- Remove sys.modules patching in tests (conflicts with xdist module cache)
- Replace nonexistent SearchTaskRequestBuilder with ListTaskRequestBuilder
- Add explicit error for unsupported due_start/due_end params
- 41 tests pass consistently
- feishu_send_card: send rich interactive Message Cards
- feishu_send_message: plain text messages
- feishu_upload_file: upload to Feishu, return file_key
- feishu_send_file: two-step upload + send

Card template helpers (for building card JSON):
- task_card(pending/completed/overdue with fields + action button)
- calendar_card(event info with time/location/attendees)
- generic_card(field rows + markdown description + action buttons)
- _card_text/_card_div/_card_hr/_card_button base builders

20 tests pass.
@cardtest15-coder

This comment was marked as spam.

@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists platform/feishu Feishu / Lark adapter comp/tools Tool registry, model_tools, toolsets comp/gateway Gateway runner, session dispatch, delivery comp/acp Agent Communication Protocol adapter labels May 16, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Scope concern: This PR bundles multiple unrelated features beyond the stated Feishu card tools -- includes HermesOS ChiefAgent tool (tools/chief_agent_tool.py with hardcoded developer paths), HermesOS model tier routing (gateway/run.py), multi-user session isolation plumbing (acp_adapter/, hermes_state.py, session_search_tool.py), cmux PATH workaround (tools/environments/local.py), and MiniMax API key addition (hermes_cli/auth.py). These should ideally be separate PRs.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the Feishu tooling contribution. Current main still lacks the four IM tools named in the PR, so the feature premise is real, but this branch needs narrowing and a few correctness fixes.

Problems

  • tools/feishu_card_tool.py:551 registers the new tools under toolset="feishu", while current toolsets.py:603-607 only auto-merges registry tools whose toolset name matches the requested toolset. The gateway enables hermes-feishu, so these tools may not be exposed in Feishu gateway sessions.
  • toolsets.py:57 adds chief_agent to _HERMES_CORE_TOOLS, and tools/chief_agent_tool.py:19-23 hardcodes developer-specific HermesOS paths. That is unrelated to the Feishu card/message/file feature and expands the core tool footprint.
  • gateway/run.py:1806-1823 adds HERMES_OS_MODEL_TIER routing before normal session override resolution, and gateway/run.py:16505-16509 imports ~/hermes-os/src/hermes_os/gateway_patch.py during gateway startup. These HermesOS changes should not be bundled with Feishu IM tools.
  • gateway/platforms/feishu.py:1339-1346 catches and swallows BaseException; then the future callback at gateway/platforms/feishu.py:4437-4456 cannot observe that exception.

Suggested changes

  • Split HermesOS, ACP/session isolation, cmux, and MiniMax changes into separate PRs.
  • Wire the Feishu IM tools into hermes-feishu explicitly or via the registry alias path.
  • Keep HermesOS orchestration behind a plugin/service-gated toolset rather than _HERMES_CORE_TOOLS.

Automated hermes-sweeper review.

@alt-glitch alt-glitch added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint and removed P2 Medium — degraded but workaround exists labels Jun 27, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Scope note for reviewers: the stated change is "4 Feishu IM tools (~558 lines)", but the actual diff is +7760 lines across 23 files and bundles unrelated core tooling that does not belong to the Feishu card feature — most notably a new tools/chief_agent_tool.py (a "Hermes OS ChiefAgent" delegate with hardcoded local search paths), plus changes to acp_adapter/server.py, gateway/run.py, hermes_cli/auth.py, hermes_state.py, tools/environments/local.py, toolsets.py, and tools/send_message_tool.py. The maintainer sweeper verdict is keep_open (salvageability=medium): main still lacks the four Feishu IM tools (feishu_send_card, feishu_send_message, feishu_upload_file, feishu_send_file), so they are wanted — but the unrelated ChiefAgent/HermesOS bundling should be stripped into the Feishu-only surface before review. Labeled for the real (multi-component) content; not a duplicate of the send_message-integration Feishu-card PRs (#37830, #47697) — different mechanism (dedicated tools).

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the Feishu tooling contribution. The dedicated-tool premise remains real: current main has adapter-level card/file transport but no feishu_send_card, feishu_send_message, feishu_upload_file, or feishu_send_file tools.

Problems

  • tools/feishu_card_tool.py:553 registers under feishu, but current hermes-feishu does not include that toolset (toolsets.py:516-525), and registry merging is exact-name only (toolsets.py:626-631).
  • tools/feishu_card_tool.py:556 uses lambda _: True; registry availability probes call fn() (tools/registry.py:145-167), so these tools are filtered out.
  • tools/feishu_card_tool.py:524-535 regex-parses a JSON tool_result() payload. The \S+ capture includes JSON punctuation after the file key, yielding an invalid outbound file_key.
  • The added HermesOS core tool is unrelated. It adds developer-specific paths (tools/chief_agent_tool.py:19-23) and is inserted into the core bundle (toolsets.py:57).

Suggested changes

  • Salvage the Feishu-only work onto the current bundled-plugin layout introduced by 552adbe08.
  • Wire it to the selected Feishu toolset with a zero-argument availability check.
  • Use structured upload results, not regexes over serialized tool output, and add toolset-exposure plus exact-file-key tests.

Automated hermes-sweeper review.

Comment thread tools/feishu_card_tool.py
upload_resp = _handle_feishu_upload_file({"file_path": file_path}, **kw)
import re

m = re.search(r"file_key=(\S+)", upload_resp)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tool_result() returns JSON, so this regex captures the closing JSON quote/brace with the key (file_123"}), then sends that malformed value. Return structured upload data and parse it with json.loads() instead.

Comment thread tools/feishu_card_tool.py
]:
registry.register(
name=_name,
toolset="feishu",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feishu gateway sessions resolve hermes-feishu, whose static bundle does not include toolset feishu; registry merging only includes exact toolset-name matches. These tools will not be exposed unless this is wired through the selected Feishu bundle/alias path.

Comment thread tools/feishu_card_tool.py
toolset="feishu",
schema=_schema,
handler=_handler,
check_fn=lambda _: True,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registry availability checks invoke check_fn() with no arguments. This one-argument lambda raises TypeError, which the registry treats as unavailable, hiding all four tools.

Comment thread tools/chief_agent_tool.py

# --- Robust path setup ---
# Try multiple possible Hermes OS locations
_HERMES_OS_SEARCH_PATHS = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These developer-specific filesystem paths are unrelated to Feishu delivery and cannot be shipped as a portable core integration. Please remove this HermesOS code from the Feishu salvage.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit labels Jul 13, 2026
@alt-glitch alt-glitch removed sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/gateway Gateway runner, session dispatch, delivery comp/acp Agent Communication Protocol adapter sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 13, 2026
@alt-glitch alt-glitch added comp/gateway Gateway runner, session dispatch, delivery comp/acp Agent Communication Protocol adapter needs-decision Awaiting maintainer decision before any implementation and removed sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades comp/acp Agent Communication Protocol adapter labels Jul 13, 2026
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 comp/tools Tool registry, model_tools, toolsets needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have platform/feishu Feishu / Lark adapter sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants