feat: message aggregator (#1985)

* feat: aggregator

* fix: resolve deadlock, mutation, and safety issues in message aggregator

- Fix deadlock: don't await cancelled timer tasks inside the lock;
  _flush_buffer acquires the same lock, causing a deadlock cycle
- Fix message_event mutation: keep original message_event unmodified
  to preserve message_id/metadata for reply/quote; only pass merged
  message_chain separately
- Fix Plain positional arg: Plain('\n') → Plain(text='\n')
- Fix float() ValueError: wrap delay cast in try/except
- Add MAX_BUFFER_MESSAGES (10) cap to prevent unbounded buffer growth
- Default enabled to false to avoid surprising latency on upgrade
- Fix flush_all: cancel all timers under one lock acquisition, then
  flush outside the lock to avoid deadlock

---------

Co-authored-by: RockChinQ <rockchinq@gmail.com>
This commit is contained in:
Guanchao Wang
2026-02-25 14:20:34 +08:00
committed by GitHub
parent 298437f352
commit b8df0dbd7f
6 changed files with 331 additions and 2 deletions
@@ -17,6 +17,10 @@
"prefix": [],
"regexp": []
},
"message-aggregation": {
"enabled": false,
"delay": 1.5
},
"misc": {
"combine-quote-message": true
}
@@ -123,6 +123,34 @@ stages:
type: array[string]
required: true
default: []
- name: message-aggregation
label:
en_US: Message Aggregation
zh_Hans: 消息聚合
description:
en_US: When a user sends multiple messages consecutively, wait for a period and merge them into one before processing
zh_Hans: 当用户连续发送多条消息时,等待一段时间后合并为一条消息再处理(防抖)
config:
- name: enabled
label:
en_US: Enable Message Aggregation
zh_Hans: 启用消息聚合
description:
en_US: If enabled, consecutive messages from the same user will be merged after a delay
zh_Hans: 如果启用,同一用户连续发送的消息将在延迟后合并处理
type: boolean
required: true
default: false
- name: delay
label:
en_US: Aggregation Delay (seconds)
zh_Hans: 聚合延迟(秒)
description:
en_US: 'Wait time before merging messages. Range: 1.0-10.0 seconds.'
zh_Hans: '合并消息前的等待时间。范围:1.0-10.0 秒。'
type: float
required: true
default: 1.5
- name: misc
label:
en_US: Misc