@@ -135,6 +135,18 @@ pub async fn run_agent_loop(
135135 tool_call_id : None ,
136136 } ) ;
137137
138+ let needs_tool_name_sanitization = model. contains ( "kimi" ) ;
139+ let sanitized_tools: Vec < ToolDefinition > = if needs_tool_name_sanitization {
140+ tools. iter ( ) . map ( |t| {
141+ let mut t = t. clone ( ) ;
142+ t. function . name = t. function . name . replace ( '.' , "_" ) ;
143+ t
144+ } ) . collect ( )
145+ } else {
146+ tools. to_vec ( )
147+ } ;
148+ let api_tools = if needs_tool_name_sanitization { & sanitized_tools } else { tools } ;
149+
138150 for turn in 0 ..max_turns {
139151 if cancel_token. is_cancelled ( ) {
140152 eprintln ! ( "[oai-runner] Cancelled by signal" ) ;
@@ -161,7 +173,7 @@ pub async fn run_agent_loop(
161173 model : model. to_string ( ) ,
162174 messages : messages. clone ( ) ,
163175 stream : true ,
164- tools : Some ( tools . to_vec ( ) ) ,
176+ tools : Some ( api_tools . to_vec ( ) ) ,
165177 max_tokens : Some ( max_tokens as u32 ) ,
166178 response_format : format,
167179 stream_options : Some ( StreamOptions { include_usage : true } ) ,
@@ -237,32 +249,38 @@ pub async fn run_agent_loop(
237249 break ;
238250 }
239251
252+ let tool_name = if needs_tool_name_sanitization {
253+ tc. function . name . replace ( '_' , "." )
254+ } else {
255+ tc. function . name . clone ( )
256+ } ;
257+
240258 let args: serde_json:: Value =
241259 serde_json:: from_str ( & tc. function . arguments ) . unwrap_or ( serde_json:: Value :: Null ) ;
242260
243- output. tool_call ( & tc . function . name , & args) ;
261+ output. tool_call ( & tool_name , & args) ;
244262
245- let result = if let Some ( mcp) = mcp_client:: find_client_for_tool ( mcp_clients, & tc . function . name ) {
246- match mcp_client:: call_tool ( mcp, & tc . function . name , & tc. function . arguments ) . await {
263+ let result = if let Some ( mcp) = mcp_client:: find_client_for_tool ( mcp_clients, & tool_name ) {
264+ match mcp_client:: call_tool ( mcp, & tool_name , & tc. function . arguments ) . await {
247265 Ok ( r) => {
248- output. tool_result ( & tc . function . name , & r) ;
266+ output. tool_result ( & tool_name , & r) ;
249267 r
250268 }
251269 Err ( e) => {
252270 let err_msg = e. to_string ( ) ;
253- output. tool_error ( & tc . function . name , & err_msg) ;
271+ output. tool_error ( & tool_name , & err_msg) ;
254272 format ! ( "Error: {}" , err_msg)
255273 }
256274 }
257275 } else {
258- match executor:: execute_tool ( & tc . function . name , & tc. function . arguments , working_dir) . await {
276+ match executor:: execute_tool ( & tool_name , & tc. function . arguments , working_dir) . await {
259277 Ok ( r) => {
260- output. tool_result ( & tc . function . name , & r) ;
278+ output. tool_result ( & tool_name , & r) ;
261279 r
262280 }
263281 Err ( e) => {
264282 let err_msg = e. to_string ( ) ;
265- output. tool_error ( & tc . function . name , & err_msg) ;
283+ output. tool_error ( & tool_name , & err_msg) ;
266284 format ! ( "Error: {}" , err_msg)
267285 }
268286 }
0 commit comments