Skip to content

Commit e338461

Browse files
committed
fix reply_target chain to use String instead of u64, fix UTF-8 boundary panic in attachment truncation, improve Telegram/webhook channel_name metadata
1 parent fe6fb8b commit e338461

File tree

8 files changed

+33
-10
lines changed

8 files changed

+33
-10
lines changed

src/agent/channel.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub struct ChannelState {
7070
pub conversation_logger: ConversationLogger,
7171
pub process_run_logger: ProcessRunLogger,
7272
/// Discord message ID to reply to for work spawned in the current turn.
73-
pub reply_target_message_id: Arc<RwLock<Option<u64>>>,
73+
pub reply_target_message_id: Arc<RwLock<Option<String>>>,
7474
pub channel_store: ChannelStore,
7575
pub screenshot_dir: std::path::PathBuf,
7676
pub logs_dir: std::path::PathBuf,
@@ -155,7 +155,7 @@ pub struct Channel {
155155
/// Branch IDs for silent memory persistence branches (results not injected into history).
156156
memory_persistence_branches: HashSet<BranchId>,
157157
/// Optional Discord reply target captured when each branch was started.
158-
branch_reply_targets: HashMap<BranchId, u64>,
158+
branch_reply_targets: HashMap<BranchId, String>,
159159
/// Buffer for coalescing rapid-fire messages.
160160
coalesce_buffer: Vec<InboundMessage>,
161161
/// Deadline for flushing the coalesce buffer.
@@ -1437,7 +1437,8 @@ impl Channel {
14371437
} => {
14381438
run_logger.log_branch_started(channel_id, *branch_id, description);
14391439
if let Some(message_id) = reply_to_message_id {
1440-
self.branch_reply_targets.insert(*branch_id, *message_id);
1440+
self.branch_reply_targets
1441+
.insert(*branch_id, message_id.clone());
14411442
}
14421443
}
14431444
ProcessEvent::BranchResult {

src/agent/channel_attachments.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,10 @@ async fn download_text_attachment(
417417

418418
// Truncate very large files to avoid blowing up context
419419
let truncated = if content.len() > 50_000 {
420+
let end = content.floor_char_boundary(50_000);
420421
format!(
421422
"{}...\n[truncated — {} bytes total]",
422-
&content[..50_000],
423+
&content[..end],
423424
content.len()
424425
)
425426
} else {

src/agent/channel_dispatch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ async fn spawn_branch(
199199
branch_id,
200200
channel_id: state.channel_id.clone(),
201201
description: status_label.to_string(),
202-
reply_to_message_id: *state.reply_target_message_id.read().await,
202+
reply_to_message_id: state.reply_target_message_id.read().await.clone(),
203203
})
204204
.ok();
205205

src/agent/channel_history.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,15 @@ pub(crate) fn format_batched_user_message(
334334
format!("[{display_name}] ({absolute_timestamp}; {relative_text}): {text_content}")
335335
}
336336

337-
pub(crate) fn extract_message_id(message: &InboundMessage) -> Option<u64> {
337+
pub(crate) fn extract_message_id(message: &InboundMessage) -> Option<String> {
338338
message
339339
.metadata
340340
.get(crate::metadata_keys::MESSAGE_ID)
341-
.and_then(|value| value.as_u64())
341+
.and_then(|value| match value {
342+
serde_json::Value::String(s) => Some(s.clone()),
343+
serde_json::Value::Number(n) => Some(n.to_string()),
344+
_ => None,
345+
})
342346
}
343347

344348
/// Check if a ProcessEvent is targeted at a specific channel.

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub enum ProcessEvent {
104104
branch_id: BranchId,
105105
channel_id: ChannelId,
106106
description: String,
107-
reply_to_message_id: Option<u64>,
107+
reply_to_message_id: Option<String>,
108108
},
109109
BranchResult {
110110
agent_id: AgentId,

src/messaging/discord.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@ impl DiscordAdapter {
8989
message
9090
.metadata
9191
.get(crate::metadata_keys::REPLY_TO_MESSAGE_ID)
92-
.and_then(|value| value.as_u64())
92+
.and_then(|value| match value {
93+
serde_json::Value::String(s) => s.parse::<u64>().ok(),
94+
serde_json::Value::Number(n) => n.as_u64(),
95+
_ => None,
96+
})
9397
.map(MessageId::new)
9498
}
9599
}

src/messaging/telegram.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,16 @@ fn build_metadata(
818818
metadata.insert("telegram_chat_title".into(), (*title).into());
819819
metadata.insert(crate::metadata_keys::SERVER_NAME.into(), (*title).into());
820820
}
821-
metadata.insert(crate::metadata_keys::CHANNEL_NAME.into(), chat_type.into());
821+
let channel_name = message
822+
.chat
823+
.title()
824+
.map(|title| title.to_string())
825+
.or_else(|| message.from.as_ref().map(build_display_name))
826+
.unwrap_or_else(|| chat_type.to_string());
827+
metadata.insert(
828+
crate::metadata_keys::CHANNEL_NAME.into(),
829+
channel_name.into(),
830+
);
822831

823832
let formatted_author = if let Some(from) = &message.from {
824833
metadata.insert(

src/messaging/webhook.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ async fn handle_send(
268268
"sender_display_name".into(),
269269
serde_json::Value::String(request.sender_id.clone()),
270270
);
271+
metadata.insert(
272+
crate::metadata_keys::CHANNEL_NAME.into(),
273+
serde_json::Value::String(request.conversation_id.clone()),
274+
);
271275

272276
let conversation_id = format!("webhook:{}", request.conversation_id);
273277

0 commit comments

Comments
 (0)