@@ -366,80 +366,134 @@ def _fix_tool_arguments(self, raw_args: str) -> str:
366366
367367 logger .debug (f"🔧 开始修复参数: { raw_args [:1000 ]} { '...' if len (raw_args ) > 1000 else '' } " )
368368
369- # 尝试直接解析
369+ # 统一的修复流程:预处理 -> json-repair -> 后处理
370370 try :
371- args_obj = json .loads (raw_args )
372- result = json .dumps (args_obj , ensure_ascii = False )
373- logger .debug (f"✅ 参数无需修复: { result } " )
374- return result
375- except json .JSONDecodeError :
376- pass
371+ # 1. 预处理:只处理 json-repair 无法处理的问题
372+ processed_args = self ._preprocess_json_string (raw_args .strip ())
377373
378- # 预处理:提取纯 JSON 部分和修复转义引号
379- processed_args = self ._preprocess_json_string (raw_args .strip ())
380-
381- # 使用 json-repair 库进行修复
382- from json_repair import repair_json
383-
384- try :
374+ # 2. 使用 json-repair 进行主要修复
375+ from json_repair import repair_json
385376 repaired_json = repair_json (processed_args )
386377 logger .debug (f"🔧 json-repair 修复结果: { repaired_json } " )
387378
388- # 验证修复结果
379+ # 3. 解析并后处理
389380 args_obj = json .loads (repaired_json )
390- fixed_result = json . dumps (args_obj , ensure_ascii = False )
381+ args_obj = self . _post_process_args (args_obj )
391382
392- # 记录修复前后对比
393- logger .info (f"✅ JSON 修复成功:" )
394- logger .info (f" 修复前: { raw_args [:1000 ]} { '...' if len (raw_args ) > 1000 else '' } " )
395- logger .info (f" 修复后: { fixed_result } " )
383+ # 4. 生成最终结果
384+ fixed_result = json .dumps (args_obj , ensure_ascii = False )
396385
397386 return fixed_result
398387
399388 except Exception as e :
400389 logger .error (f"❌ JSON 修复失败: { e } , 原始参数: { raw_args [:1000 ]} ..., 使用空参数" )
401390 return "{}"
402391
392+ def _post_process_args (self , args_obj : Dict [str , Any ]) -> Dict [str , Any ]:
393+ """统一的后处理方法"""
394+ # 修复路径中的过度转义
395+ args_obj = self ._fix_path_escaping_in_args (args_obj )
396+
397+ # 修复命令中的多余引号
398+ args_obj = self ._fix_command_quotes (args_obj )
399+
400+ return args_obj
401+
403402 def _preprocess_json_string (self , text : str ) -> str :
404- """预处理 JSON 字符串,修复转义引号和提取纯 JSON 部分 """
403+ """预处理 JSON 字符串,只处理 json-repair 无法处理的问题 """
405404 import re
406405
407- # 1. 如果包含额外内容(如 "result" 字段),提取纯 JSON 部分
408- if '"result"' in text :
409- brace_count = 0
410- json_end = - 1
411- for i , char in enumerate (text ):
412- if char == '{' :
413- brace_count += 1
414- elif char == '}' :
415- brace_count -= 1
416- if brace_count == 0 :
417- json_end = i + 1
418- break
419-
420- if json_end > 0 :
421- text = text [:json_end ]
422- logger .debug (f"🔧 提取纯 JSON 部分: { text [:1000 ]} ..." )
423-
424- # 2. 修复缺少开始括号的情况
406+ # 只保留 json-repair 无法处理的预处理步骤
407+
408+ # 1. 修复缺少开始括号的情况(json-repair 无法处理)
425409 if not text .startswith ('{' ) and text .endswith ('}' ):
426410 text = '{' + text
427411 logger .debug (f"🔧 补全开始括号" )
428412
429- # 3. 修复转义引号问题
430- # 处理 "key:\"value\"," 模式 -> "key":"value",
431- pattern = r'(["\w]+):\\"([^"\\]*)\\"'
413+ # 2. 修复末尾多余的反斜杠和引号(json-repair 可能处理不当)
414+ # 匹配模式:字符串值末尾的 \" 后面跟着 } 或 ,
415+ # 例如:{"url":"https://www.bilibili.com\"} -> {"url":"https://www.bilibili.com"}
416+ # 例如:{"url":"https://www.bilibili.com\",} -> {"url":"https://www.bilibili.com",}
417+ pattern = r'([^\\])\\"([}\s,])'
432418 if re .search (pattern , text ):
433- text = re .sub (pattern , r'\1:"\2"' , text )
434- logger .debug (f"🔧 修复字段转义引号模式" )
435-
436- # 处理剩余的转义引号 \" -> "
437- if '\\ "' in text :
438- text = text .replace ('\\ "' , '"' )
439- logger .debug (f"🔧 替换剩余转义引号" )
419+ text = re .sub (pattern , r'\1"\2' , text )
420+ logger .debug (f"🔧 修复末尾多余的反斜杠" )
440421
441422 return text
442423
424+ def _fix_path_escaping_in_args (self , args_obj : Dict [str , Any ]) -> Dict [str , Any ]:
425+ """修复参数对象中路径的过度转义问题"""
426+ import re
427+
428+ # 需要检查的路径字段
429+ path_fields = ['file_path' , 'path' , 'directory' , 'folder' ]
430+
431+ for field in path_fields :
432+ if field in args_obj and isinstance (args_obj [field ], str ):
433+ path_value = args_obj [field ]
434+
435+ # 检查是否是Windows路径且包含过度转义
436+ if path_value .startswith ('C:' ) and '\\ \\ ' in path_value :
437+ logger .debug (f"🔍 检查路径字段 { field } : { repr (path_value )} " )
438+
439+ # 分析路径结构:正常路径应该是 C:\Users\...
440+ # 但过度转义的路径可能是 C:\Users\\Documents(多了一个反斜杠)
441+ # 我们需要找到不正常的双反斜杠模式并修复
442+
443+ # 先检查是否有不正常的双反斜杠(不在路径开头)
444+ # 正常:C:\Users\Documents
445+ # 异常:C:\Users\\Documents 或 C:\Users\\\\Documents
446+
447+ # 使用更精确的模式:匹配路径分隔符后的额外反斜杠
448+ # 但要保留正常的路径分隔符
449+ fixed_path = path_value
450+
451+ # 检查是否有连续的多个反斜杠(超过正常的路径分隔符)
452+ if '\\ \\ ' in path_value :
453+ # 计算反斜杠的数量,如果超过正常数量就修复
454+ parts = path_value .split ('\\ ' )
455+ # 重新组装路径,去除空的部分(由多余的反斜杠造成)
456+ clean_parts = [part for part in parts if part ]
457+ if len (clean_parts ) > 1 :
458+ fixed_path = '\\ ' .join (clean_parts )
459+
460+ logger .debug (f"🔍 修复后路径: { repr (fixed_path )} " )
461+
462+ if fixed_path != path_value :
463+ args_obj [field ] = fixed_path
464+ logger .debug (f"🔧 修复字段 { field } 的路径转义: { path_value } -> { fixed_path } " )
465+ else :
466+ logger .debug (f"🔍 路径无需修复: { path_value } " )
467+
468+ return args_obj
469+
470+ def _fix_command_quotes (self , args_obj : Dict [str , Any ]) -> Dict [str , Any ]:
471+ """修复命令中的多余引号问题"""
472+ import re
473+
474+ # 检查命令字段
475+ if 'command' in args_obj and isinstance (args_obj ['command' ], str ):
476+ command = args_obj ['command' ]
477+
478+ # 检查是否以双引号结尾(多余的引号)
479+ if command .endswith ('""' ):
480+ logger .debug (f"🔧 发现命令末尾多余引号: { command } " )
481+ # 移除最后一个多余的引号
482+ fixed_command = command [:- 1 ]
483+ args_obj ['command' ] = fixed_command
484+ logger .debug (f"🔧 修复命令引号: { command } -> { fixed_command } " )
485+
486+ # 检查其他可能的引号问题
487+ # 例如:路径末尾的 \"" 模式
488+ elif re .search (r'\\""+$' , command ):
489+ logger .debug (f"🔧 发现命令末尾引号模式问题: { command } " )
490+ # 修复路径末尾的引号问题
491+ fixed_command = re .sub (r'\\""+$' , '\\ "' , command )
492+ args_obj ['command' ] = fixed_command
493+ logger .debug (f"🔧 修复命令引号模式: { command } -> { fixed_command } " )
494+
495+ return args_obj
496+
443497 def _create_content_chunk (self , content : str ) -> Dict [str , Any ]:
444498 """创建内容块"""
445499 return {
0 commit comments