From fc5b2a359f6085ba5ad6a9f9028d6083c6e4c327 Mon Sep 17 00:00:00 2001 From: ooodc <549496103@qq.com> Date: Fri, 1 May 2026 16:07:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E6=88=AA=E6=96=AD=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=A4=9A=E5=AD=97=E8=8A=82=E5=AD=97=E7=AC=A6=E8=BE=B9=E7=95=8C?= =?UTF-8?q?=E5=A4=84=E7=90=86=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tools/http_request.rs | 16 ++++++++++++++-- src/tools/web_fetch.rs | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) 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] ..." + ); + } }