fix(feishu): proactively update approval card via API to avoid 220340 callback failure#13929
Open
HiddenPuppy wants to merge 7 commits into
Open
fix(feishu): proactively update approval card via API to avoid 220340 callback failure#13929HiddenPuppy wants to merge 7 commits into
HiddenPuppy wants to merge 7 commits into
Conversation
added 7 commits
April 22, 2026 15:18
…call messages for Kimi /coding Fixes NousResearch#13848 Kimi's /coding endpoint speaks the Anthropic Messages protocol but has its own thinking semantics: when thinking is enabled, Kimi validates message history and requires every prior assistant tool-call message to carry OpenAI-style reasoning_content. The Anthropic path never populated that field, and convert_messages_to_anthropic strips all Anthropic thinking blocks on third-party endpoints — so the request failed with HTTP 400: "thinking is enabled but reasoning_content is missing in assistant tool call message at index N" Now, when an assistant message contains tool_calls and a reasoning_content string, we append a {"type": "thinking", ...} block to the Anthropic content so Kimi can validate the history. This only affects assistant messages with tool_calls + reasoning_content; plain text assistant messages are unchanged.
Map tsuijinglei@gmail.com → hiddenpuppy.
…t exhaustion for fallback Fixes NousResearch#13887 OpenRouter returns HTTP 403 (not 402) for key-limit and spend-limit errors. The existing _is_payment_error() only checked 402/429/None, so these 403s were not classified as payment exhaustion and auxiliary calls would fail immediately instead of falling back to the next provider. Now _is_payment_error() also checks status == 403 and looks for OpenRouter-specific keywords: key limit, spending limit, spend limit, total limit, credit limit, quota exceeded. This keeps the fix scoped: only 403s with these specific phrases are treated as payment errors. Other 403s (auth, forbidden, etc.) still raise normally. The fallback path already skips the failed provider via _try_payment_fallback(), so no changes are needed there.
Map jerome@clawwork.ai → HiddenPuppy.
…H/tunnels Fixes NousResearch#13870 prompt_toolkit sends \x1b[6n (Device Status Report) to query cursor position; the terminal replies with \x1b[row;colR. Over SSH/cloudflared tunnels these CPR responses leak as raw text (e.g. 20
…sections Fixes NousResearch#13396 PUT /api/config was calling save_config() with only the payload from the client, which replaced the entire ~/.hermes/config.yaml file. If a dashboard UI sent only the sections it manages (agent, display), everything else (model, custom_providers, compression, auxiliary, fallback_model, etc.) was silently deleted. Now update_config() loads the existing config, deep-merges the incoming payload into it, and saves the merged result. Keys present in the payload overwrite existing values; keys absent from the payload are preserved. This matches the behavior third-party clients already assume and prevents accidental data loss.
… callback failure Fixes NousResearch#13924 When a user clicks an approval button on a Feishu interactive card, the synchronous callback response (P2CardActionTriggerResponse with CallBackCard) sometimes fails with error 220340, leaving the card unchanged and the user confused about whether the action worked. Root cause: Feishu's card-action callback response path is unreliable over some transports. The card update in the callback response may be rejected while the approval resolution (scheduled asynchronously) succeeds. Fix: In _resolve_approval(), proactively call im.v1.message.update with the resolved card BEFORE calling resolve_gateway_approval(). This uses the stored message_id from _approval_state, so it doesn't depend on the callback response path at all. - Card is updated even if approval resolution fails - If the API update also fails, we log a warning but still resolve the approval so the agent isn't blocked - The callback response is still returned for clients where it works
建议合并改进方案我在 #35090 中实现了更完善的修复方案(已关闭,本 PR 更早),核心改进: 1. 主动 API 更新回退2. 通用卡片更新模板新增 方法,将蓝色⏳卡片自动更新为绿色✅状态。 3. 自然语言审批命令别名在 中添加别名映射,支持 等自然语言输入。 4. 完整测试覆盖
建议:将这些改进合并到 PR 中,可以更全面地解决飞书卡片交互问题。 仓库:https://github.com/xxzzzEkko/hermes-agent/tree/fix/feishu-approval-card-update |
建议合并改进方案我在 #35090 中实现了更完善的修复方案(已关闭,本 PR 更早),核心改进: 1. 主动 API 更新回退在
2. 通用卡片更新模板新增 3. 自然语言审批命令别名在
4. 完整测试覆盖
建议:将这些改进合并到 PR 中,可以更全面地解决飞书卡片交互问题。 仓库:https://github.com/xxzzzEkko/hermes-agent/tree/fix/feishu-approval-card-update |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #13924
Problem
When a user clicks an approval button (Allow Once, Session, Always, Deny) on a Feishu interactive card, the action returns error:
The approval is never processed — the agent remains blocked.
Root Cause
The
_handle_approval_card_action()method returns aP2CardActionTriggerResponsewith aCallBackCardcontaining the resolved card. Feishu is supposed to update the card inline using this response, but over some transports this callback response path fails with error 220340.Meanwhile,
_resolve_approval()is scheduled asynchronously and correctly callsresolve_gateway_approval(), but the card is never updated to show the resolution.Fix
In
_resolve_approval(), proactively callim.v1.message.updatewith the resolved card BEFORE callingresolve_gateway_approval(). This uses the storedmessage_idfrom_approval_state, so it doesn't depend on the callback response path at all.Changes
gateway/platforms/feishu.py:_resolve_approval()— added proactive card update viaim.v1.message.updateVerification
Checklist