Summary
When an agent reply exceeds ~1900 characters, the message chunks are sent to Discord twice, resulting in duplicate messages visible to users.
Root Cause
In src/discord.rs → stream_prompt, there are two independent code paths that both call channel.say() for overflow chunks:
1. Edit-streaming task (live updates every 1.5s)
if content.len() > 1900 {
let chunks = format::split_message(&content, 1900);
// ...
for chunk in chunks.iter().skip(1) {
if let Ok(new_msg) = channel.say(&ctx.http, chunk).await { // ← sends chunks
current_edit_msg = new_msg.id;
}
}
}
2. Final edit (after streaming completes)
let chunks = format::split_message(&final_content, 2000);
for (i, chunk) in chunks.iter().enumerate() {
if i == 0 {
let _ = edit(&ctx, channel, current_msg_id, chunk).await;
} else {
let _ = channel.say(&ctx.http, chunk).await; // ← sends chunks again
}
}
Both paths send new messages for chunks beyond the first, with no coordination between them.
Steps to Reproduce
- Ask the agent a question that produces a long reply (>1900 chars)
- Observe duplicate message chunks in the Discord thread
Suggested Fix (pick one)
Option A: Edit-streaming task should only edit() the first message, never say() new chunks. Leave all chunking to the final edit.
Option B: Track message IDs created by the edit-streaming task and pass them to the final edit, so it edits existing messages instead of creating new ones.
Option A is simpler — during streaming, just truncate to 1900 chars with a ... indicator, then let the final edit handle the full multi-chunk output.
Summary
When an agent reply exceeds ~1900 characters, the message chunks are sent to Discord twice, resulting in duplicate messages visible to users.
Root Cause
In
src/discord.rs→stream_prompt, there are two independent code paths that both callchannel.say()for overflow chunks:1. Edit-streaming task (live updates every 1.5s)
2. Final edit (after streaming completes)
Both paths send new messages for chunks beyond the first, with no coordination between them.
Steps to Reproduce
Suggested Fix (pick one)
Option A: Edit-streaming task should only
edit()the first message, neversay()new chunks. Leave all chunking to the final edit.Option B: Track message IDs created by the edit-streaming task and pass them to the final edit, so it edits existing messages instead of creating new ones.
Option A is simpler — during streaming, just truncate to 1900 chars with a
...indicator, then let the final edit handle the full multi-chunk output.