Commit cd6a8aea authored by Your Name's avatar Your Name

Add short format tool parsing: <tool>TOOL_NAME>JSON</tool>

- Add pattern for <tool>financial_data_fetcher>{JSON}</tool>
- Add pattern for <tool_call><tool>financial_data_fetcher>{JSON}</tool></tool_call>
- Added to both coder CLI and ToolCallParser
parent 8988356b
......@@ -1112,6 +1112,50 @@ class ToolCallParser:
}
})
# NEW: Pattern for short format <tool>TOOL_NAME>JSON</tool>
# Example: <tool>financial_data_fetcher>{"ticker": "AAPL", "period": "Q4"}</tool>
pattern_short = r'<tool>(\w+)>(\{.*?\})</tool>'
matches_short = re.findall(pattern_short, text, re.DOTALL)
for name, args_str in matches_short:
name = name.strip()
if not name:
continue
try:
args = json.loads(args_str.strip()) if args_str.strip() else {}
except json.JSONDecodeError:
args = {}
tool_calls.append({
"id": f"call_{uuid.uuid4().hex[:16]}",
"type": "function",
"function": {
"name": name,
"arguments": json.dumps(args)
}
})
# NEW: Pattern for <tool_call><tool>TOOL_NAME>JSON</tool></tool_call>
# Example: <tool_call><tool>financial_data_fetcher>{"ticker": "MSFT"}</tool></tool_call>
pattern_short2 = r'<tool_call>\s*<tool>(\w+)>\s*(\{.*?\})\s*</tool>\s*</tool_call>'
matches_short2 = re.findall(pattern_short2, text, re.DOTALL)
for name, args_str in matches_short2:
name = name.strip()
if not name:
continue
try:
args = json.loads(args_str.strip()) if args_str.strip() else {}
except json.JSONDecodeError:
args = {}
tool_calls.append({
"id": f"call_{uuid.uuid4().hex[:16]}",
"type": "function",
"function": {
"name": name,
"arguments": json.dumps(args)
}
})
# NEW: Pattern for nested tool_call with multiple tool blocks inside
# Example: <tool_call><tool><name>search</name><arguments>{...}</arguments></tool><tool><name>search</name><arguments>{...}</arguments></tool></tool_call>
# Also handles case where there's a nested <tool_call> before second tool
......
......@@ -806,6 +806,47 @@ class CoderClient:
}
})
# Format 4: Short format <tool>TOOL_NAME>JSON</tool>
# Example: <tool>financial_data_fetcher>{"ticker": "AAPL"}</tool>
pattern_short = r'<tool>(\w+)>(\{.*?\})</tool>'
for match in re.finditer(pattern_short, text, re.DOTALL):
name = match.group(1).strip()
args_str = match.group(2).strip()
if not name:
continue
try:
args = json.loads(args_str) if args_str else {}
except json.JSONDecodeError:
args = {}
parsed.append({
'id': f'call_{len(parsed)}',
'type': 'function',
'function': {
'name': name,
'arguments': json.dumps(args)
}
})
# Format 5: <tool_call><tool>TOOL_NAME>JSON</tool></tool_call>
pattern_short2 = r'<tool_call>\s*<tool>(\w+)>\s*(\{.*?\})\s*</tool>\s*</tool_call>'
for match in re.finditer(pattern_short2, text, re.DOTALL):
name = match.group(1).strip()
args_str = match.group(2).strip()
if not name:
continue
try:
args = json.loads(args_str) if args_str else {}
except json.JSONDecodeError:
args = {}
parsed.append({
'id': f'call_{len(parsed)}',
'type': 'function',
'function': {
'name': name,
'arguments': json.dumps(args)
}
})
return parsed
# Process streaming response line by line
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment