diff --git a/src-tauri/src/services/acp/manager/dispatcher.rs b/src-tauri/src/services/acp/manager/dispatcher.rs
index db0bd9d..0e6155f 100644
--- a/src-tauri/src/services/acp/manager/dispatcher.rs
+++ b/src-tauri/src/services/acp/manager/dispatcher.rs
@@ -19,6 +19,17 @@ use crate::services::acp::payloads::{
ToolResultPayload, ToolTitlePayload,
};
+fn extract_user_message(raw: &str) -> &str {
+ const OPEN: &str = "\n";
+ const CLOSE: &str = "\n";
+ if let Some(start) = raw.find(OPEN) {
+ let inner = start + OPEN.len();
+ if raw[inner..].ends_with(CLOSE) {
+ return &raw[inner..raw.len() - CLOSE.len()];
+ }
+ }
+ raw
+}
fn model_options_from_select_options(options: &SessionConfigSelectOptions) -> Vec {
match options {
SessionConfigSelectOptions::Ungrouped(values) => values
@@ -386,13 +397,14 @@ impl Client for SessionEventDispatcher {
}
}
+ let display_text = extract_user_message(&text.text);
let message_id = uuid::Uuid::new_v4().to_string();
let _ = self.app_handle.emit(
"acp:replay_user_message",
serde_json::json!({
"sessionId": local_session_id,
"messageId": message_id,
- "text": text.text,
+ "text": display_text,
}),
);
}
@@ -502,3 +514,6 @@ impl Client for SessionEventDispatcher {
Ok(())
}
}
+#[cfg(test)]
+#[path = "dispatcher_tests.rs"]
+mod tests;
diff --git a/src-tauri/src/services/acp/manager/dispatcher_tests.rs b/src-tauri/src/services/acp/manager/dispatcher_tests.rs
new file mode 100644
index 0000000..7b68478
--- /dev/null
+++ b/src-tauri/src/services/acp/manager/dispatcher_tests.rs
@@ -0,0 +1,28 @@
+use super::*;
+
+#[test]
+fn extract_user_message_strips_xml_wrapper() {
+ let wrapped = "\nYou are a helpful assistant.\n\n\n\nhello\n";
+ assert_eq!(extract_user_message(wrapped), "hello");
+}
+
+#[test]
+fn extract_user_message_multiline() {
+ let wrapped = "\nstuff\n\n\n\nline one\nline two\n";
+ assert_eq!(extract_user_message(wrapped), "line one\nline two");
+}
+
+#[test]
+fn extract_user_message_no_wrapper() {
+ assert_eq!(extract_user_message("plain text"), "plain text");
+}
+
+#[test]
+fn extract_user_message_preserves_inner_delimiter() {
+ // User literally typed "" in their message — must not truncate.
+ let wrapped = "\nstuff\n\n\n\ncheck this tag: cool right?\n";
+ assert_eq!(
+ extract_user_message(wrapped),
+ "check this tag: cool right?"
+ );
+}