hermes - ✅(Solved) Fix [Weixin] WeChat client clips right-side content when scrolling Markdown tables [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#16951Fetched 2026-04-29 06:38:07
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Author
Participants
Timeline (top)
labeled ×3cross-referenced ×2

Fix Action

Workaround

Generate table images using table-image-generator skill and send as native images via MEDIA::

node ~/.hermes/skills/creative/table-image-generator/scripts/table.mjs \
  --data '[{"Col A":"val","Col B":"val","Col C":"val"}]' \
  --output table.png --dark --scale 2

Then include MEDIA:/path/to/table.png in the agent response.

PR fix notes

PR #2: fix: resolve 7 identified issues [automated]

Description (problem / solution / changelog)

Summary

This PR resolves 7 identified issues in the Hermes Agent codebase.

Issues Fixed

1. #17076 - kimi-coding vision broken (HTTP 404)

File: agent/auxiliary_client.py Problem: The kimi-coding provider was missing from _PROVIDER_VISION_MODELS, causing the vision auto-detect to fail with HTTP 404 when using image inputs. Fix: Added kimi-coding and kimi-coding-cn to _PROVIDER_VISION_MODELS dict. Commit: 82b920ff

2. #16970 - Model Picker ignores model_catalog.enabled=false

File: hermes_cli/model_switch.py Problem: The list_authenticated_providers() function ignored model_catalog.enabled=false config, showing built-in providers even when the catalog was disabled. Fix: Added catalog_enabled check that skips sections 1-3 (built-in provider enumeration) when model_catalog.enabled=false. Commit: b6b6fbbe

3. #16830 - Credential pool rotation counts toward api_max_retries

File: run_agent.py Problem: When a credential pool rotation occurred, retry_count was not reset, causing premature exhaustion of retries. Fix: Reset retry_count = 0 when _recover_with_credential_pool() succeeds. Commit: 366582d4

4. #16979 - QQ Bot file attachments silently dropped on download failure

File: gateway/platforms/qqbot/adapter.py Problem: When CDN download failed for file attachments, they were silently discarded with no indication to the agent. Fix: Added fallback text (download failed) to attachment_info when download fails. Commit: f956da73

5. #16875 - kimi-k2.6 HTTP 400 via OpenCode Go

Files: hermes_cli/setup.py, hermes_cli/models.py Problem: kimi-k2.6 was listed as an available model for opencode-go provider but returns HTTP 400 on all requests. Fix: Removed kimi-k2.6 from the opencode-go model list in both files. Commit: 5a77400d

6. #16951 - WeChat clips right-side content when scrolling Markdown tables

File: gateway/platforms/weixin.py Problem: WeChat's WebView CSS clips tables with many columns, making rightmost columns invisible. Fix: Added _truncate_wide_table_row() helper that limits table rows to 6 columns and appends ... for overflow indication. Commit: d3e43e10

7. #17009 - Termux hermes update fails with "Failed to determine Android API level"

File: hermes_cli/main.py Problem: Native extension builds (maturin) fail in Termux because ANDROID_API_LEVEL is not set. Fix: In _install_python_dependencies_with_optional_fallback(), detect Termux environment and set ANDROID_API_LEVEL=29 as a safe default. Commit: 096a80b9

Files Modified

  • agent/auxiliary_client.py (1 change)
  • hermes_cli/model_switch.py (1 change)
  • run_agent.py (1 change)
  • gateway/platforms/qqbot/adapter.py (1 change)
  • hermes_cli/setup.py (1 change)
  • hermes_cli/models.py (1 change)
  • gateway/platforms/weixin.py (2 changes)
  • hermes_cli/main.py (1 change)

Testing

All changes were validated with python3 -m py_compile to ensure no syntax errors.

Changed files

  • .gitignore (modified, +1/-0)
  • AGENTS.md (modified, +1/-1)
  • Dockerfile (modified, +6/-2)
  • acp_adapter/entry.py (modified, +11/-0)
  • acp_adapter/server.py (modified, +28/-1)
  • agent/anthropic_adapter.py (modified, +155/-78)
  • agent/auxiliary_client.py (modified, +342/-55)
  • agent/bedrock_adapter.py (modified, +41/-3)
  • agent/context_compressor.py (modified, +113/-5)
  • agent/credential_pool.py (modified, +82/-4)
  • agent/credential_sources.py (modified, +0/-1)
  • agent/error_classifier.py (modified, +32/-0)
  • agent/gemini_cloudcode_adapter.py (modified, +0/-2)
  • agent/gemini_schema.py (modified, +1/-1)
  • agent/google_code_assist.py (modified, +0/-1)
  • agent/google_oauth.py (modified, +3/-3)
  • agent/image_routing.py (added, +236/-0)
  • agent/memory_manager.py (modified, +113/-5)
  • agent/model_metadata.py (modified, +56/-21)
  • agent/nous_rate_guard.py (modified, +144/-1)
  • agent/onboarding.py (added, +191/-0)
  • agent/prompt_builder.py (modified, +38/-0)
  • agent/redact.py (modified, +7/-3)
  • agent/shell_hooks.py (modified, +7/-2)
  • agent/skill_commands.py (modified, +2/-2)
  • agent/title_generator.py (modified, +39/-5)
  • agent/transports/anthropic.py (modified, +1/-7)
  • agent/transports/chat_completions.py (modified, +74/-0)
  • agent/transports/codex.py (modified, +1/-3)
  • cli-config.yaml.example (modified, +28/-8)
  • cli.py (modified, +527/-196)
  • cron/jobs.py (modified, +34/-5)
  • cron/scheduler.py (modified, +39/-5)
  • docker/entrypoint.sh (modified, +9/-7)
  • flake.nix (modified, +1/-0)
  • gateway/builtin_hooks/boot_md.py (removed, +0/-85)
  • gateway/channel_directory.py (modified, +67/-14)
  • gateway/config.py (modified, +84/-3)
  • gateway/display_config.py (modified, +3/-1)
  • gateway/hooks.py (modified, +7/-13)
  • gateway/mirror.py (modified, +57/-11)
  • gateway/pairing.py (modified, +2/-1)
  • gateway/platforms/__init__.py (modified, +2/-0)
  • gateway/platforms/base.py (modified, +233/-16)
  • gateway/platforms/discord.py (modified, +18/-24)
  • gateway/platforms/email.py (modified, +3/-0)
  • gateway/platforms/feishu_comment.py (modified, +0/-1)
  • gateway/platforms/helpers.py (modified, +11/-2)
  • gateway/platforms/matrix.py (modified, +493/-47)
  • gateway/platforms/mattermost.py (modified, +0/-1)
  • gateway/platforms/qqbot/adapter.py (modified, +7/-7)
  • gateway/platforms/slack.py (modified, +753/-70)
  • gateway/platforms/telegram.py (modified, +138/-14)
  • gateway/platforms/weixin.py (modified, +47/-3)
  • gateway/platforms/yuanbao.py (added, +4754/-0)
  • gateway/platforms/yuanbao_media.py (added, +645/-0)
  • gateway/platforms/yuanbao_proto.py (added, +1209/-0)
  • gateway/platforms/yuanbao_sticker.py (added, +558/-0)
  • gateway/run.py (modified, +1139/-279)
  • gateway/runtime_footer.py (added, +150/-0)
  • gateway/session.py (modified, +16/-21)
  • gateway/stream_consumer.py (modified, +110/-0)
  • gateway/whatsapp_identity.py (modified, +21/-1)
  • hermes_cli/auth.py (modified, +40/-4)
  • hermes_cli/azure_detect.py (modified, +1/-1)
  • hermes_cli/backup.py (modified, +272/-1)
  • hermes_cli/banner.py (modified, +0/-1)
  • hermes_cli/claw.py (modified, +67/-6)
  • hermes_cli/commands.py (modified, +116/-5)
  • hermes_cli/config.py (modified, +322/-29)
  • hermes_cli/debug.py (modified, +13/-7)
  • hermes_cli/dingtalk_auth.py (modified, +0/-1)
  • hermes_cli/doctor.py (modified, +11/-1)
  • hermes_cli/env_loader.py (modified, +2/-1)
  • hermes_cli/fallback_cmd.py (added, +361/-0)
  • hermes_cli/gateway.py (modified, +25/-4)
  • hermes_cli/hooks.py (modified, +1/-2)
  • hermes_cli/main.py (modified, +689/-58)
  • hermes_cli/model_catalog.py (added, +329/-0)
  • hermes_cli/model_switch.py (modified, +366/-306)
  • hermes_cli/models.py (modified, +251/-44)
  • hermes_cli/nous_subscription.py (modified, +16/-8)
  • hermes_cli/oneshot.py (modified, +28/-11)
  • hermes_cli/platforms.py (modified, +1/-0)
  • hermes_cli/plugins.py (modified, +14/-0)
  • hermes_cli/plugins_cmd.py (modified, +0/-1)
  • hermes_cli/profiles.py (modified, +58/-2)
  • hermes_cli/providers.py (modified, +26/-0)
  • hermes_cli/runtime_provider.py (modified, +100/-14)
  • hermes_cli/setup.py (modified, +70/-17)
  • hermes_cli/skills_hub.py (modified, +230/-20)
  • hermes_cli/slack_cli.py (added, +152/-0)
  • hermes_cli/status.py (modified, +3/-2)
  • hermes_cli/timeouts.py (modified, +4/-4)
  • hermes_cli/tips.py (modified, +2/-4)
  • hermes_cli/tools_config.py (modified, +173/-4)
  • hermes_cli/web_server.py (modified, +11/-14)
  • hermes_cli/webhook.py (modified, +2/-2)
  • hermes_logging.py (modified, +3/-4)
  • hermes_state.py (modified, +578/-164)

PR #17108: fix: resolve 7 identified issues [automated]

Description (problem / solution / changelog)

Summary

This PR resolves 7 identified issues in the Hermes Agent codebase. All issues were identified from open GitHub issues in NousResearch/hermes-agent.

Issues Fixed

1. #17076 - kimi-coding vision broken (HTTP 404)

File: agent/auxiliary_client.py Problem: The kimi-coding provider was missing from _PROVIDER_VISION_MODELS, causing the vision auto-detect to fail with HTTP 404 when using image inputs. Fix: Added kimi-coding and kimi-coding-cn to _PROVIDER_VISION_MODELS dict. Commit: 82b920ff

2. #16970 - Model Picker ignores model_catalog.enabled=false

File: hermes_cli/model_switch.py Problem: The list_authenticated_providers() function ignored model_catalog.enabled=false config, showing built-in providers even when the catalog was disabled. Fix: Added catalog_enabled check that skips sections 1-3 (built-in provider enumeration) when model_catalog.enabled=false. Commit: b6b6fbbe

3. #16830 - Credential pool rotation counts toward api_max_retries

File: run_agent.py Problem: When a credential pool rotation occurred, retry_count was not reset, causing premature exhaustion of retries. Fix: Reset retry_count = 0 when _recover_with_credential_pool() succeeds. Commit: 366582d4

4. #16979 - QQ Bot file attachments silently dropped on download failure

File: gateway/platforms/qqbot/adapter.py Problem: When CDN download failed for file attachments, they were silently discarded with no indication to the agent. Fix: Added fallback text (download failed) to attachment_info when download fails. Commit: f956da73

5. #16875 - kimi-k2.6 HTTP 400 via OpenCode Go

Files: hermes_cli/setup.py, hermes_cli/models.py Problem: kimi-k2.6 was listed as an available model for opencode-go provider but returns HTTP 400 on all requests. Fix: Removed kimi-k2.6 from the opencode-go model list in both files. Commit: 5a77400d

6. #16951 - WeChat clips right-side content when scrolling Markdown tables

File: gateway/platforms/weixin.py Problem: WeChat's WebView CSS clips tables with many columns, making rightmost columns invisible. Fix: Added _truncate_wide_table_row() helper that limits table rows to 6 columns and appends ... for overflow indication. Commit: d3e43e10

7. #17009 - Termux hermes update fails with "Failed to determine Android API level"

File: hermes_cli/main.py Problem: Native extension builds (maturin) fail in Termux because ANDROID_API_LEVEL is not set. Fix: In _install_python_dependencies_with_optional_fallback(), detect Termux environment and set ANDROID_API_LEVEL=29 as a safe default. Commit: 096a80b9

Files Modified

  • agent/auxiliary_client.py
  • hermes_cli/model_switch.py
  • run_agent.py
  • gateway/platforms/qqbot/adapter.py
  • hermes_cli/setup.py
  • hermes_cli/models.py
  • gateway/platforms/weixin.py
  • hermes_cli/main.py

Commits (7 total)

  • 82b920ff - fix(vision): add kimi-coding provider to _PROVIDER_VISION_MODELS
  • b6b6fbbe - fix(model_picker): respect model_catalog.enabled=false config
  • 366582d4 - fix(credential_pool): reset retry_count on credential rotation
  • f956da73 - fix(qqbot): add fallback text when attachment download fails
  • 5a77400d - fix(setup): remove kimi-k2.6 from opencode-go model list
  • d3e43e10 - fix(weixin): truncate wide tables to prevent viewport clipping
  • 096a80b9 - fix(termux): set ANDROID_API_LEVEL default during update

Changed files

  • agent/auxiliary_client.py (modified, +4/-0)
  • gateway/platforms/qqbot/adapter.py (modified, +5/-0)
  • gateway/platforms/weixin.py (modified, +21/-0)
  • hermes_cli/main.py (modified, +9/-0)
  • hermes_cli/model_switch.py (modified, +355/-344)
  • hermes_cli/models.py (modified, +0/-1)
  • hermes_cli/setup.py (modified, +1/-1)
  • run_agent.py (modified, +1/-0)

Code Example

node ~/.hermes/skills/creative/table-image-generator/scripts/table.mjs \
  --data '[{"Col A":"val","Col B":"val","Col C":"val"}]' \
  --output table.png --dark --scale 2
RAW_BUFFERClick to expand / collapse

Bug Description

The WeChat personal client (connected via iLink Bot API) renders Markdown tables as scrollable containers, but clips/hides content beyond the visible viewport on the right side. Users can scroll horizontally within the table, but the rightmost columns are cut off and invisible.

This is a WeChat client-side rendering bug in its Markdown/CSS Webview engine, not a Hermes transport issue.

Hermes Transport Layer Status

Hermes is correctly preserving Markdown tables as-is since v2026.4.23 (PR #11571, commit 6ee65b4d):

  1. format_message() -> _normalize_markdown_blocks() -> preserves Markdown tables
  2. _send_message() -> sends raw Markdown text to iLink API
  3. _rewrite_table_block_for_weixin() exists but is dead code (never called)

The Markdown arrives intact at the WeChat client. The clipping happens during rendering.

Steps to Reproduce

  1. Send a Markdown table with 3+ columns to a WeChat contact via the Weixin adapter
  2. Open the message in WeChat personal client (Windows / macOS / mobile)
  3. The table renders as a scrollable container
  4. Scroll right -> right-side columns are clipped/invisible

Expected Behavior

All table columns should be visible when scrolling, or the table should expand to fit content.

Actual Behavior

Columns beyond the initial visible width are clipped. The scrollable container exists but does not reveal all content.

Environment

ComponentValue
OSRaspberry Pi 4B (agent host)
Python3.11.x
Hermes Versionv2026.4.23+232 (post PR #11571)
WeChat ClientWindows / macOS / mobile (all affected)
ConnectioniLink Bot API

Workaround

Generate table images using table-image-generator skill and send as native images via MEDIA::

node ~/.hermes/skills/creative/table-image-generator/scripts/table.mjs \
  --data '[{"Col A":"val","Col B":"val","Col C":"val"}]' \
  --output table.png --dark --scale 2

Then include MEDIA:/path/to/table.png in the agent response.

Proposed Mitigation (Hermes-side)

Since this is a client-side bug outside Hermes' control, the recommended mitigation is to update the Weixin platform hint in prompt_builder.py to instruct the agent to:

  1. Use table images (via table-image-generator skill) for tables with 3+ columns or wide content
  2. Use list format (key: value) for simple 2-column tables
  3. Avoid pipe tables in Weixin responses until the WeChat client fixes its rendering

Related Issues / PRs

  • Closes (transport): #10308 - Weixin adapter still rewrites Markdown tables
  • PR #11571 - fix(weixin): preserve native markdown rendering (v2026.4.23)
  • PR #10338 - Original fix PR (merged via #11571)
  • #7468 - Regression: tables fragmented into bubbles (fixed in earlier release)
  • #9612 - Proposal: simplify Weixin message delivery logic

extent analysis

TL;DR

Use table images generated by the table-image-generator skill for tables with 3+ columns to workaround the WeChat client-side rendering bug.

Guidance

  • Verify that the issue is indeed caused by the WeChat client-side rendering bug by checking if the Markdown tables are preserved correctly by the Hermes transport layer.
  • Use the proposed mitigation strategy to update the Weixin platform hint in prompt_builder.py to instruct the agent to use table images for tables with 3+ columns.
  • Consider using the table-image-generator skill to generate table images and send them as native images via MEDIA: as a temporary workaround.
  • Review the related issues and PRs to ensure that the Hermes transport layer is correctly preserving Markdown tables.

Example

node ~/.hermes/skills/creative/table-image-generator/scripts/table.mjs \
  --data '[{"Col A":"val","Col B":"val","Col C":"val"}]' \
  --output table.png --dark --scale 2

Then include MEDIA:/path/to/table.png in the agent response.

Notes

This workaround may not be suitable for all use cases, and the WeChat client-side rendering bug should be fixed by the WeChat team for a permanent solution.

Recommendation

Apply the workaround by using table images generated by the table-image-generator skill, as this is the most straightforward way to mitigate the issue until the WeChat client-side rendering bug is fixed.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING