Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/memory/query_rewriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn format_history(messages: &[ChatMessage]) -> String {
.iter()
.filter_map(|m| {
m.content.as_ref().map(|c| {
let snippet = crate::utils::str::truncate_chars(c, 200);
let snippet = crate::utils::strings::truncate_chars(c, 200);
format!("{}: {}", m.role, snippet)
})
})
Expand Down
8 changes: 4 additions & 4 deletions src/memory/rag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub async fn auto_retrieve_context(
for msg in &results {
if let Some(content) = &msg.content {
let role = &msg.role;
let snippet = crate::utils::str::truncate_chars(content, 300);
let snippet = crate::utils::strings::truncate_chars(content, 300);
block.push_str(&format!("[{}] {}\n", role, snippet));
}
}
Expand Down Expand Up @@ -136,8 +136,8 @@ mod tests {
async fn test_auto_retrieve_truncates_long_snippets() {
// Verify the 300-char truncation logic via truncate_chars
let content = "x".repeat(500);
let snippet = crate::utils::str::truncate_chars(&content, 300);
assert_eq!(snippet.len(), 303); // 300 + "..."
let snippet = crate::utils::strings::truncate_chars(&content, 300);
assert_eq!(snippet.chars().count(), 303); // 300 chars + "..."
assert!(snippet.ends_with("..."));
}

Expand All @@ -147,7 +147,7 @@ mod tests {
// content longer than 300 bytes with Chinese characters.
// Old &content[..300] would panic here.
let long_chinese = "每日論文摘要(香港時間)人工智能".repeat(25); // ~400 chars, >1200 bytes
let result = crate::utils::str::truncate_chars(&long_chinese, 300);
let result = crate::utils::strings::truncate_chars(&long_chinese, 300);
assert!(result.ends_with("..."), "should be truncated");
assert!(
std::str::from_utf8(result.as_bytes()).is_ok(),
Expand Down
4 changes: 2 additions & 2 deletions src/platform/tool_notifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ pub fn format_args_preview(args_json: &str) -> String {
serde_json::Value::String(s) => s.clone(),
other => other.to_string(),
};
let truncated = crate::utils::str::truncate_chars(&s, 60);
let truncated = crate::utils::strings::truncate_chars(&s, 60);
return format!("\"{}\"", truncated);
}
}
}
}
// Fallback: truncate raw JSON
crate::utils::str::truncate_chars(args_json, 60)
crate::utils::strings::truncate_chars(args_json, 60)
}

/// Manages the live-edited Telegram status message during agent tool execution.
Expand Down
2 changes: 1 addition & 1 deletion src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod str;
pub mod strings;
8 changes: 8 additions & 0 deletions src/utils/str.rs → src/utils/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,12 @@ mod tests {
assert!(result.ends_with("..."));
assert!(std::str::from_utf8(result.as_bytes()).is_ok());
}

#[test]
fn test_truncate_chars_zero_max() {
// max_chars=0: every non-empty string is truncated immediately to "..."
assert_eq!(truncate_chars("hello", 0), "...");
// Empty string is never truncated (loop body never entered)
assert_eq!(truncate_chars("", 0), "");
}
}
Loading