You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When table_mode = "code", render_table_code pads every cell to the widest cell in that column. For tables with one very long cell (e.g. a Finding description of 80-100+ chars), every row gets padded to the same width regardless of its own content length.
On Discord (message_limit = 2000), this padding quickly exhausts the char budget, causing split_message to split the table mid-way between rows — resulting in two separate code blocks across two Discord messages.
Additionally, when a split occurs and the original message contains bot mentions (<@BotB>) or uses reply_to, only the first chunk carries the mention/reference. Under allow_bot_messages = "mentions", the receiving bot only processes the first chunk — the rest of the content is silently dropped.
Detect both mention sources: explicit <@UID> / <@&RoleID> AND reply_to targets (reply_to only applies to first message in Discord — subsequent chunks lose that context entirely)
Reserve char budget: split_message limit should account for appended mentions (e.g. 2000 - len(mentions))
Deduplicate: only append mentions not already present in that chunk
Works with per-thread batching: all chunks pass the gate → dispatcher batches them into one ACP turn → agent sees full content
Secondary Improvement: Table Rendering
The padding waste is a separate (visual) issue. If a single rendered table exceeds message_limit, consider:
Column width cap (e.g. max 40 chars per column, truncate with …)
Auto-fallback to bullets mode when rendered table would exceed limit
This reduces the frequency of splits but does not eliminate them — mention propagation is still needed as the safety net
Description
When
table_mode = "code",render_table_codepads every cell to the widest cell in that column. For tables with one very long cell (e.g. a Finding description of 80-100+ chars), every row gets padded to the same width regardless of its own content length.On Discord (
message_limit = 2000), this padding quickly exhausts the char budget, causingsplit_messageto split the table mid-way between rows — resulting in two separate code blocks across two Discord messages.Additionally, when a split occurs and the original message contains bot mentions (
<@BotB>) or usesreply_to, only the first chunk carries the mention/reference. Underallow_bot_messages = "mentions", the receiving bot only processes the first chunk — the rest of the content is silently dropped.Reproduction
A table like the PR review findings table:
#,Severity,Finding,LocationFindingcolumn has one cell ~90 chars longRoot Cause
split_messagehas no table-awareness — it splits at line boundaries within code fencesmessage_limit = 11,900(Block Kit cap, PR fix(slack): dedupe native-stream finalize + render final as Block Kit markdown #1056), but Discord API hard-limits at 2000reply_to(message_reference) only applies to the first Discord message; subsequent chunks have no reply contextallow_bot_messages) is per-message with no thread context awarenessExpected Behavior
When a bot reply is split into multiple Discord messages:
per-threadbatching on the receiver side should reassemble all chunks into one complete ACP turnSolution: Mention Propagation on Split Chunks
After
split_message, append all detected mentions to each subsequent chunk so every piece passes the receiving bot's gate.Flow (current — broken)
Flow (proposed fix)
Key Design Points
<@UID>/<@&RoleID>ANDreply_totargets (reply_to only applies to first message in Discord — subsequent chunks lose that context entirely)split_messagelimit should account for appended mentions (e.g.2000 - len(mentions))Secondary Improvement: Table Rendering
The padding waste is a separate (visual) issue. If a single rendered table exceeds
message_limit, consider:…)bulletsmode when rendered table would exceed limitReferences
message_limitto 11,900 (not possible on Discord)src/format.rs:split_message()— line-boundary splitting with fence awarenesssrc/adapter.rs~L921: where split + send happenssrc/discord.rs~L464-490: bot message gating (per-message, no thread context)