@@ -203,6 +203,35 @@ impl SandcastleHandler {
203203 . to_string ( )
204204 }
205205
206+ /// Returns a sanitized copy of an arguments map for logging.
207+ /// Fields that may contain user content are truncated to avoid emitting large blobs or
208+ /// sensitive values into logs.
209+ fn sanitize_args (
210+ args : & serde_json:: Map < String , serde_json:: Value > ,
211+ ) -> serde_json:: Map < String , serde_json:: Value > {
212+ const OPEN_TEXT : & [ & str ] = & [ "content" , "command" , "old_string" , "new_string" ] ;
213+ const TRIM_LEN : usize = 8 ;
214+
215+ args. iter ( )
216+ . map ( |( k, v) | {
217+ let sanitized = if OPEN_TEXT . contains ( & k. as_str ( ) ) {
218+ if let Some ( s) = v. as_str ( ) {
219+ let mut trimmed: String = s. chars ( ) . take ( TRIM_LEN ) . collect ( ) ;
220+ if s. chars ( ) . count ( ) > TRIM_LEN {
221+ trimmed. push ( '…' ) ;
222+ }
223+ serde_json:: Value :: String ( trimmed)
224+ } else {
225+ v. clone ( )
226+ }
227+ } else {
228+ v. clone ( )
229+ } ;
230+ ( k. clone ( ) , sanitized)
231+ } )
232+ . collect ( )
233+ }
234+
206235 async fn resume_known_sandbox ( & self , sandbox_id : & str ) -> Result < SandboxHandle , String > {
207236 for p in & self . providers {
208237 if let Ok ( handle) = p. resume ( sandbox_id) . await {
@@ -707,6 +736,8 @@ impl ServerHandler for SandcastleHandler {
707736 request : CallToolRequestParams ,
708737 context : RequestContext < RoleServer > ,
709738 ) -> Result < CallToolResult , ErrorData > {
739+ let sanitized = request. arguments . as_ref ( ) . map ( Self :: sanitize_args) ;
740+ tracing:: info!( tool = %request. name, args = ?sanitized, "tool call" ) ;
710741 let tcc = ToolCallContext :: new ( self , request, context) ;
711742 self . tool_router . call ( tcc) . await
712743 }
0 commit comments