@@ -194,8 +194,7 @@ impl OpenAIClient {
194194
195195 if let Some ( tool_calls) = item. tool_calls {
196196 for call in tool_calls {
197- let input = serde_json:: from_str :: < serde_json:: Value > ( & call. arguments )
198- . unwrap_or_else ( |_| json ! ( { "raw_arguments" : call. arguments} ) ) ;
197+ let input = parse_tool_arguments ( & call. arguments ) ;
199198 content_blocks. push ( ContentBlock :: ToolUse {
200199 id : call. id ,
201200 name : call. name ,
@@ -208,8 +207,7 @@ impl OpenAIClient {
208207 if let ( Some ( name) , Some ( arguments) , Some ( call_id) ) =
209208 ( item. name , item. arguments , item. call_id )
210209 {
211- let input = serde_json:: from_str :: < serde_json:: Value > ( & arguments)
212- . unwrap_or_else ( |_| json ! ( { "raw_arguments" : arguments} ) ) ;
210+ let input = parse_tool_arguments ( & arguments) ;
213211 content_blocks. push ( ContentBlock :: ToolUse {
214212 id : call_id,
215213 name,
@@ -259,6 +257,44 @@ impl OpenAIClient {
259257 }
260258}
261259
260+ /// Try to parse tool call arguments as JSON, with recovery for common issues.
261+ fn parse_tool_arguments ( args : & str ) -> serde_json:: Value {
262+ // Try normal parsing first
263+ if let Ok ( v) = serde_json:: from_str :: < serde_json:: Value > ( args) {
264+ return v;
265+ }
266+
267+ // Try trimming whitespace
268+ let trimmed = args. trim ( ) ;
269+ if trimmed != args {
270+ if let Ok ( v) = serde_json:: from_str :: < serde_json:: Value > ( trimmed) {
271+ return v;
272+ }
273+ }
274+
275+ // Try removing trailing commas before } or ]
276+ let fixed = trimmed. replace ( ",}" , "}" ) . replace ( ",]" , "]" ) ;
277+ if fixed != trimmed {
278+ if let Ok ( v) = serde_json:: from_str :: < serde_json:: Value > ( & fixed) {
279+ return v;
280+ }
281+ }
282+
283+ // Try adding missing closing brace
284+ if trimmed. starts_with ( '{' ) && !trimmed. ends_with ( '}' ) {
285+ let braced = format ! ( "{}}}" , trimmed. trim_end_matches( ',' ) ) ;
286+ if let Ok ( v) = serde_json:: from_str :: < serde_json:: Value > ( & braced) {
287+ return v;
288+ }
289+ }
290+
291+ eprintln ! (
292+ " \x1b [33m⚠\x1b [0m Failed to parse tool arguments as JSON: {}" ,
293+ & args[ ..args. len( ) . min( 200 ) ]
294+ ) ;
295+ json ! ( { "raw_arguments" : args} )
296+ }
297+
262298fn build_response_input ( request : & CreateMessageRequest ) -> Vec < serde_json:: Value > {
263299 let mut input = Vec :: new ( ) ;
264300
0 commit comments