Skills Plugins MCP Prompt Model 博客 我的中心

hermes-feishu-streaming-card

Stream Hermes Gateway agent responses to Feishu/Lark as live-updating interactive cards with thinking process, tool calls, and in-card interactions

DeepseekModel Curated skill Quality Good · 64 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=aradotso-hermes-skills-skills-hermes-feishu-streaming-card-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name hermes-feishu-streaming-card description Stream Hermes Gateway agent responses to Feishu/Lark as live-updating interactive cards with thinking process, tool calls, and in-card interactions triggers ["install hermes feishu streaming card plugin","configure feishu streaming cards for hermes","set up lark cards for hermes gateway","stream hermes responses to feishu cards","add interactive feishu cards to hermes agent","troubleshoot hermes feishu card not updating","debug hermes feishu streaming card sidecar","configure feishu card interactions for hermes"] Hermes Feishu Streaming Card Skill by ara.so — Hermes Skills collection. The Hermes Feishu Streaming Card plugin transforms Hermes Agent Gateway's Feishu/Lark responses into continuously-updating interactive cards. Instead of fragmented gray text messages, you get a single card showing thinking process, tool calls, final answers, authorization requests, option selections, and execution stats — all in one place. What It Does This plugin solves key pain points when connecting Hermes to Feishu: Unified streaming experience : thinking.delta , answer.delta , tool.updated , and message.completed all update the same Feishu card In-card interactions : Hermes approval/clarify choices render as Feishu buttons (callback mode) or numbered options (localhost/private sidecar) Long content stability : Markdown tables and code blocks split at structure boundaries to avoid raw markdown rendering Multi-bot/profile support : Multiple Feishu bots, multiple Hermes profiles, group chat bindings, routing diagnostics Sidecar-only architecture : Independent process handles Feishu API calls, state machine, retries, health checks Fail-open design : Hermes hook failures don't break your gateway; original text messages serve as fallback Installation Prerequisites Python 3.9+ Hermes Gateway v0.13.0+ (or date-based version v2026.4.23+ ) Active Feishu/Lark bot with app credentials Quick Install # Install plugin pip install hermes-feishu-streaming-card # Verify installation and Hermes compatibility hermes-feishu-card doctor --hermes-dir ~/.hermes/hermes-agent # Install hooks into Hermes hermes-feishu-card install --hermes-dir ~/.hermes/hermes-agent -- yes # Restart Hermes Gateway # (kill existing process and start again) From Release Package # Download latest release wget https://github.com/baileyh8/hermes-feishu-streaming-card/releases/latest/download/hermes-feishu-streaming-card.tar.gz tar -xzf hermes-feishu-streaming-card.tar.gz cd hermes-feishu-streaming-card # Install pip install . hermes-feishu-card install --hermes-dir ~/.hermes/hermes-agent -- yes Installation State Management The installer creates manifest and backup files in ~/.hermes-feishu-card/ : # Check installation state hermes-feishu-card doctor --explain # Repair corrupted state (safe, validates before overwriting) hermes-feishu-card repair --hermes-dir ~/.hermes/hermes-agent -- yes # Restore original Hermes files hermes-feishu-card restore --hermes-dir ~/.hermes/hermes-agent -- yes # Complete uninstall hermes-feishu-card uninstall --hermes-dir ~/.hermes/hermes-agent -- yes Configuration Basic Setup Create or update ~/.hermes-feishu-card/config.yaml : # Feishu bot credentials feishu: - app_id: cli_a1b2c3d4e5f6g7h8 app_secret: ${FEISHU_APP_SECRET_1} # Use environment variable verification_token: v1a2b3c4d5e6f7g8h9i0 encrypt_key: ${FEISHU_ENCRYPT_KEY_1} bot_name: "Production Bot" # Sidecar server sidecar: host: 127.0 .0 .1 port: 8765 log_level: INFO # DEBUG for troubleshooting # Card appearance and behavior card: title: "🤖 Hermes Agent" thinking_emoji: "💭" answer_emoji: "💬" tool_emoji: "🔧" show_footer_stats: true thinking_mode: append_block # or replace interaction_mode: auto # auto, callback, or text # Content handling content: main_content_chunk_chars: 3500 code_fence_preserve: true table_header_repeat: true feishu_table_row_limit: 50 Multi-Bot Configuration feishu: - app_id: cli_prod_bot app_secret: ${FEISHU_PROD_SECRET} verification_token: ${FEISHU_PROD_TOKEN} encrypt_key: ${FEISHU_PROD_ENCRYPT} bot_name: "Production Bot" - app_id: cli_test_bot app_secret: ${FEISHU_TEST_SECRET} verification_token: ${FEISHU_TEST_TOKEN} encrypt_key: ${FEISHU_TEST_ENCRYPT} bot_name: "Test Bot" # Bind specific group chats to profiles bindings: chats: oc_a1b2c3d4e5f6g7h8: profile_id: thinking bot_name: "Production Bot" oc_x9y8z7w6v5u4t3s2: profile_id: research bot_name: "Test Bot" Interaction Modes card: # auto: localhost/private sidecar uses text mode, public uses callback interaction_mode: auto # callback: render real Feishu buttons (requires public callback URL) # interaction_mode: callback # callback_base_url: https://your-domain.com # text: always use numbered options in card, return to Hermes text flow # interaction_mode: text Key Commands Sidecar Management # Start sidecar (runs in background) hermes-feishu-card start # Check sidecar status hermes-feishu-card status # Stop sidecar hermes-feishu-card stop # View logs hermes-feishu-card logs # Follow logs in real-time hermes-feishu-card logs -- tail 50 --follow Diagnostics # Human-readable diagnostic summary hermes-feishu-card doctor --explain --hermes-dir ~/.hermes/hermes-agent # Machine-readable JSON output hermes-feishu-card doctor --json --hermes-dir ~/.hermes/hermes-agent # Check runtime import (does Hermes venv have the plugin?) hermes-feishu-card doctor --explain # Look for runtime_import section Bot Testing # Test single bot (default config) hermes-feishu-card bots test # Test specific bot by app_id hermes-feishu-card bots test --app-id cli_a1b2c3d4e5f6g7h8 # Test all configured bots hermes-feishu-card bots test --all # Test with specific profile hermes-feishu-card bots test --profile-id thinking Smoke Testing # Send test card to Feishu chat hermes-feishu-card smoke-feishu-card \ --chat-id oc_a1b2c3d4e5f6g7h8 \ --bot-name "Production Bot" \ --profile-id thinking # Test with custom message hermes-feishu-card smoke-feishu-card \ --chat-id oc_a1b2c3d4e5f6g7h8 \ --test-message "Complex query with\n**markdown** and `code`" Working with the Sidecar Health Check Endpoints The sidecar exposes health check endpoints: # Basic health curl http://localhost:8765/health # Detailed routing info curl http://localhost:8765/health.routing # Profile-specific routing curl http://localhost:8765/health.routing.profiles Example response: { "status" : "healthy" , "sidecar_version" : "3.6.5" , "uptime_seconds" : 3600 , "bots_configured" : 2 , "chats_bound" : 5 , "profiles" : { "thinking" : { "bot_name" : "Production Bot" , "bound_chats" : 3 , "last_route" : "2026-06-24T10:30:00Z" , "last_route_error" : null } } } Event Flow The sidecar receives events from Hermes hooks and manages card lifecycle: # Hook emits events to sidecar import requests def emit_event ( event: dict ): """Send event from Hermes hook to sidecar""" try : response = requests.post( "http://localhost:8765/events" , json=event, timeout= 1.0 ) return response.status_code == 200 except Exception as e: # Fail-open: hook errors don't break Hermes print ( f"[hermes-feishu-card] hook failed: {e} " ) return False Event types: message.started : Create new card thinking.delta : Update thinking section answer.delta : Update answer section tool.updated : Show tool call progress message.completed : Finalize card interaction.requested : Add approval/clarify buttons interaction.selected : Record user choice Real Code Examples Custom Card Template from hermes_feishu_card.card_builder import CardBuilder def create_custom_card (): """Build a custom Feishu card""" builder = CardBuilder( title= "Custom Agent" , thinking_emoji= "🧠" , answer_emoji= "✨" , tool_emoji= "⚙️" ) # Add thinking section builder.update_thinking( "Analyzing user request..." , mode= "append_block" ) # Add tool call builder.update_tool( tool_name= "web_search" , status= "running" , input_data={ "query" : "latest news" } ) # Add answer builder.update_answer( "Based on the search results, here's what I found..." ) # Add footer stats builder.update_footer( elapsed_sec= 2.5 , tokens_used= 1234 , model_name= "gpt-4" ) return builder.build() Handling Long Content from hermes_feishu_card.content_splitter import split_markdown_aware def send_long_content ( content: str , max_chunk: int = 3500 ): """Split long content intelligently""" chunks = split_markdown_aware( content, max_chunk_chars=max_chunk, preserve_code_fence= True , repeat_table_header= True ) for i, chunk in enumerate (chunks): print ( f"Chunk {i+ 1 } / { len (chunks)} : { len (chunk)} chars" ) # Each chunk is valid markdown with complete structures Custom Interaction Handler from hermes_feishu_card.interaction import InteractionManager async def handle_custom_approval ( interaction_id: str , choices: list ): """Custom approval flow""" manager = InteractionManager( sidecar_url= "http://localhost:8765" ) # Request interaction await manager.request_interaction( interaction_id=interaction_id, interaction_type= "approval" , choices=choices, message_id= "msg_123" , user_id= "ou_456" ) # Poll for user selection while True : result = await manager.get_interaction(interaction_id) if result and result.get( "selected_choice" ) is not None : return result[ "selected_choice" ] await asyncio.sleep( 0.5 ) Profile-Specific Bot Routing from hermes_feishu_card.routing import resolve_bot_for_profile def get_bot_for_message ( profile_id: str , chat_id: str ): """Determine which bot to use""" config = load_config() # Your config loader # Check chat binding first chat_binding = config.get( "bindings" , {}).get( "chats" , {}).get(chat_id) if chat_binding and chat_binding.get( "profile_id" ) == profile_id: bot_name = chat_binding[ "bot_name" ] return next ( bot for bot in config[ "feishu" ] if bot[ "bot_name" ] == bot_name ) # Fall back to first bot return config[ "feishu" ][ 0 ] Common Patterns Streaming Delta Aggregation # Hermes hook pattern for delta events class StreamingCardHook : def __init__ ( self ): self .answer_buffer = {} self .thinking_buffer = {} def on_answer_delta ( self, message_id: str , delta: str ): """Aggregate answer deltas""" if message_id not in self .answer_buffer: self .answer_buffer[message_id] = "" # Preserve boundary spaces self .answer_buffer[message_id] += delta # Send to sidecar emit_event({ "type" : "answer.delta" , "message_id" : message_id, "delta" : delta, "accumulated" : self .answer_buffer[message_id] }) Fail-Open Error Handling def safe_emit_event ( event: dict ) -> bool : """Emit event with fail-open behavior""" try : response = requests.post( "http://localhost:8765/events" , json=event, timeout= 1.0 ) if response.status_code != 200 : print ( f"[hermes-feishu-card] sidecar returned {response.status_code} " ) return False return True except requests.exceptions.Timeout: print ( "[hermes-feishu-card] sidecar timeout (continuing)" ) return False except Exception as e: # Don't break Hermes flow print ( f"[hermes-feishu-card] hook failed: {e} " ) return False Media/Attachment Handling def format_attachments ( message_locals: dict ) -> str : """Format media/file attachments for card""" attachments = [] # Check various attachment structures if "attachments" in message_locals: attachments.extend(message_locals[ "attachments" ]) if "media_files" in message_locals: attachments.extend(message_locals[ "media_files" ]) if "files" in message_locals: attachments.extend(message_locals[ "files" ]) # Format summary summary_parts = [] for att in attachments: if isinstance (att, dict ):
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。