[fix] Handle escaped characters in GLM tool call parser to prevent double serialization (#12456)
This commit is contained in:
@@ -24,13 +24,23 @@ def get_argument_type(func_name: str, arg_key: str, defined_tools: list):
|
||||
|
||||
def parse_arguments(json_value):
|
||||
try:
|
||||
try:
|
||||
parsed_value = json.loads(json_value)
|
||||
except:
|
||||
parsed_value = ast.literal_eval(json_value)
|
||||
parsed_value = json.loads(json_value)
|
||||
return parsed_value, True
|
||||
except:
|
||||
return json_value, False
|
||||
# If that fails, try wrapping it to unescape JSON characters
|
||||
try:
|
||||
# Wrap the value as a JSON string field
|
||||
wrapped = json.loads('{"tmp": "' + json_value + '"}')
|
||||
# parse the unescaped value
|
||||
parsed_value = json.loads(wrapped["tmp"])
|
||||
return parsed_value, True
|
||||
except:
|
||||
# Final fallback to ast.literal_eval
|
||||
try:
|
||||
parsed_value = ast.literal_eval(json_value)
|
||||
return parsed_value, True
|
||||
except:
|
||||
return json_value, False
|
||||
|
||||
|
||||
class Glm4MoeDetector(BaseFormatDetector):
|
||||
@@ -45,8 +55,13 @@ class Glm4MoeDetector(BaseFormatDetector):
|
||||
self.bot_token = "<tool_call>"
|
||||
self.eot_token = "</tool_call>"
|
||||
self.func_call_regex = r"<tool_call>.*?</tool_call>"
|
||||
self.func_detail_regex = r"<tool_call>([^\n]*)\n(.*)</tool_call>"
|
||||
self.func_arg_regex = r"<arg_key>(.*?)</arg_key>\s*<arg_value>(.*?)</arg_value>"
|
||||
self.func_detail_regex = re.compile(
|
||||
r"<tool_call>(.*?)(?:\\n|\n)(.*)</tool_call>", re.DOTALL
|
||||
)
|
||||
self.func_arg_regex = re.compile(
|
||||
r"<arg_key>(.*?)</arg_key>(?:\\n|\s)*<arg_value>(.*?)</arg_value>",
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
def has_tool_call(self, text: str) -> bool:
|
||||
"""Check if the text contains a glm-4.5 / glm-4.6 format tool call."""
|
||||
@@ -69,14 +84,10 @@ class Glm4MoeDetector(BaseFormatDetector):
|
||||
try:
|
||||
for match_result in match_result_list:
|
||||
# Get function name
|
||||
func_detail = re.search(self.func_detail_regex, match_result, re.DOTALL)
|
||||
func_detail = self.func_detail_regex.search(match_result)
|
||||
func_name = func_detail.group(1)
|
||||
func_args = func_detail.group(2)
|
||||
pairs = re.findall(
|
||||
r"<arg_key>(.*?)</arg_key>\s*<arg_value>(.*?)</arg_value>",
|
||||
func_args,
|
||||
re.DOTALL,
|
||||
)
|
||||
pairs = self.func_arg_regex.findall(func_args)
|
||||
arguments = {}
|
||||
for arg_key, arg_value in pairs:
|
||||
arg_key = arg_key.strip()
|
||||
|
||||
Reference in New Issue
Block a user