fix(send_message): use markdown for DingTalk standalone webhook delivery#34400
Closed
WenhuaXia wants to merge 2 commits into
Closed
fix(send_message): use markdown for DingTalk standalone webhook delivery#34400WenhuaXia wants to merge 2 commits into
WenhuaXia wants to merge 2 commits into
Conversation
…er concurrent writes Root cause: multiple kanban worker processes (hermes -p <profile>) open independent sqlite3 connections to the same kanban.db. SQLite WAL + BEGIN _IMMEDIATE only protects within-process threads — concurrent writers from different processes can still corrupt the WAL under heavy write pressure (task_events + task_runs + status transitions within the same tick). Fix: acquire an fcntl.LOCK_EX on a per-DB .db.lock file around every write_txn(). The lock fd is stored in a module-level dict keyed by id(conn) (sqlite3.Connection is a C-extension type that rejects both attribute assignment and weakref). On platforms without fcntl (Windows) or when the lock file can't be opened, the lock is a graceful no-op. This preserves the existing WAL + BEGIN IMMEDIATE strategy while serialising cross-process writes, which is the common pattern for SQLite-based multi-process workloads.
Standalone fallback sends msgtype: "text" which doesn't render markdown tables. The live DingTalk adapter sends msgtype: "markdown" which works. Align the two paths so cron job delivery renders tables correctly. Also adds 20K character truncation (matching live adapter limit) and fallback to plain text if the API rejects the markdown payload. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
3 tasks
Author
|
Closing — will be reopened as a bilingual PR on a clean branch. |
WenhuaXia
added a commit
to WenhuaXia/hermes-agent
that referenced
this pull request
Jun 2, 2026
…+ DingTalk markdown webhook 看板 SQLite 跨进程写锁(inter-process flock): Kanban SQLite cross-process write lock (inter-process flock): 问题:多个 kanban worker 进程并发写入同一 SQLite 数据库导致 WAL 损坏。SQLite WAL + busy_timeout 只能保护同一进程内的 并发线程,跨进程仍会竞争 BEGIN IMMEDIATE 导致页面损坏。 Problem: Multiple kanban worker processes writing concurrently to the same SQLite database caused frequent WAL corruption. SQLite WAL + busy_timeout only protects concurrent threads within the same process; cross-process races through BEGIN IMMEDIATE can corrupt WAL pages. 修复: Fix: 1. connect() 后打开 .db.lock 文件,write_txn() 用 fcntl.flock(LOCK_EX) 包裹整个事务,确保同一时间只有一个进程在写。 2. schema init 也获取 .db.lock(不只是 .init.lock),防止 DDL/DML 竞争。 3. Windows 或 fcntl 不可用时优雅降级为 no-op。 1. After connect(), open a .db.lock file. Every write_txn() acquires fcntl.flock(LOCK_EX) around the entire transaction, ensuring only one process writes at a time. 2. Schema init also acquires .db.lock (not just .init.lock) to prevent DDL/DML races. 3. Graceful fallback on Windows or when fcntl is unavailable. 钉钉 webhook Markdown 渲染: DingTalk webhook Markdown rendering: 问题:standalone cron delivery 用 msgtype:"text" 发钉钉消息,markdown 表格中的管道符显示为文字。live adapter 用 msgtype:"markdown" 正确渲染。 Problem: Standalone cron delivery sent msgtype:"text" for DingTalk, which does not render markdown tables — pipes show as literal characters. The live DingTalk adapter sends msgtype:"markdown" which renders tables correctly. 修复:统一使用 msgtype:"markdown",被拒绝时 fallback 到纯文本。 Fix: Use msgtype:"markdown" consistently with fallback to plain text if the API rejects the markdown payload. Changes: - hermes_cli/kanban_db.py: fcntl flock for inter-process write safety - tools/send_message_tool.py: markdown msgtype for DingTalk standalone delivery Related: NousResearch#35787 (closed), NousResearch#34400 (closed)
This was referenced Jun 2, 2026
WenhuaXia
added a commit
to WenhuaXia/hermes-agent
that referenced
this pull request
Jun 6, 2026
…alk standalone webhook 问题 / Problem: standalone cron delivery 用 msgtype:"text" 发钉钉消息,markdown 表格中的管道符显示为文字。live adapter 用 msgtype:"markdown" 正确渲染。 Problem: Standalone cron delivery sent msgtype:"text" for DingTalk, which does not render markdown tables — pipes show as literal characters. The live DingTalk adapter sends msgtype:"markdown" which renders tables correctly. 修复 / Fix: 统一使用 msgtype:"markdown",被拒绝时 fallback 到纯文本。 Fix: Use msgtype:"markdown" consistently with fallback to plain text if the API rejects the markdown payload. Changes: - tools/send_message_tool.py: markdown msgtype for DingTalk standalone delivery Related: NousResearch#34400 (closed), NousResearch#37292 (closed, split)
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
msgtype: "text"for DingTalk, which doesn't render markdown tables — pipes show as literal charactersmsgtype: "markdown"which renders tables correctlyMAX_MESSAGE_LENGTH)Test plan
DINGTALK_WEBHOOK_URLand verify cron job delivery renders markdown tables🤖 Generated with Claude Code