diff --git a/src/tools/http_request.rs b/src/tools/http_request.rs index 0c05dd0..be6f9ce 100644 --- a/src/tools/http_request.rs +++ b/src/tools/http_request.rs @@ -4,6 +4,7 @@ use async_trait::async_trait; use reqwest::header::HeaderMap; use serde_json::json; +use crate::text::take_prefix_chars; use crate::tools::traits::{Tool, ToolResult}; pub struct HttpRequestTool { @@ -93,10 +94,10 @@ impl HttpRequestTool { return text.to_string(); } - if text.len() > self.max_response_size { + if text.chars().count() > self.max_response_size { format!( "{}\n\n... [Response truncated due to size limit] ...", - &text[..self.max_response_size] + take_prefix_chars(text, self.max_response_size) ) } else { text.to_string() @@ -437,4 +438,15 @@ mod tests { async fn test_blocks_local_tld() { assert!(is_private_host("service.local")); } + + #[tokio::test] + async fn test_truncate_response_handles_multibyte_boundary() { + let tool = HttpRequestTool::new(vec!["*".to_string()], 3, 30, false); + let text = "a\u{1F642}bc"; + let truncated = tool.truncate_response(text); + assert_eq!( + truncated, + "a\u{1F642}b\n\n... [Response truncated due to size limit] ..." + ); + } } diff --git a/src/tools/web_fetch.rs b/src/tools/web_fetch.rs index 16adb87..113b62d 100644 --- a/src/tools/web_fetch.rs +++ b/src/tools/web_fetch.rs @@ -4,6 +4,7 @@ use async_trait::async_trait; use reqwest::header::HeaderMap; use serde_json::json; +use crate::text::take_prefix_chars; use crate::tools::traits::{Tool, ToolResult}; pub struct WebFetchTool { @@ -50,10 +51,10 @@ impl WebFetchTool { return text.to_string(); } - if text.len() > self.max_response_size { + if text.chars().count() > self.max_response_size { format!( "{}\n\n... [Response truncated due to size limit] ...", - &text[..self.max_response_size] + take_prefix_chars(text, self.max_response_size) ) } else { text.to_string() @@ -383,4 +384,15 @@ mod tests { assert!(text.contains("Content")); assert!(!text.contains("color")); } + + #[tokio::test] + async fn test_truncate_response_handles_multibyte_boundary() { + let tool = WebFetchTool::new(3, 30); + let text = "a\u{1F642}bc"; + let truncated = tool.truncate_response(text); + assert_eq!( + truncated, + "a\u{1F642}b\n\n... [Response truncated due to size limit] ..." + ); + } }