import json
import logging
from typing import Any
from rllm.parser.tool_parser.tool_parser_base import ToolParser
from rllm.tools.tool_base import ToolCall
logger = logging.getLogger(__name__)
class QwenToolParser(ToolParser):
def __init__(self):
"""Initialize the parser with specified type and model.
Args:
model (str): Model name for tokenizer (optional)
parser_type (str): Type of parser to use ('qwen' or other parsers you might add)
"""
self.tool_call_begin = "<tool_call>"
self.tool_call_end = "</tool_call>"
self.tool_output_begin = "<tool_response>"
self.tool_output_end = "</tool_response>"
def parse(self, model_response: str) -> list[ToolCall]:
"""Parse tool calls from model output.
Args:
model_output (str): Text containing tool calls
Returns:
ToolInputs: Parsed tool calls
"""
tool_calls_dicts = self.parse_qwen_tool_calls(model_response)
tool_calls = [ToolCall(name=tc["name"], arguments=tc["arguments"]) for tc in tool_calls_dicts]
return tool_calls
def parse_qwen_tool_calls(self, text: str) -> list[dict[str, Any]]:
"""Parse tool calls from text using a simple token format.
Format:
<tool_call>{"name": "function_name", "arguments": {...}}</tool_call>
Returns:
list[dict]: List of parsed tool calls, each containing 'name' and 'parameters'
"""
tool_calls: list[dict[str, Any]] = []
if self.tool_call_begin not in text:
return tool_calls
while self.tool_call_begin in text:
start = text.find(self.tool_call_begin) + len(self.tool_call_begin)
end = text.find(self.tool_call_end)
if end == -1:
break
json_content = text[start:end].strip()
try:
call_data = json.loads(json_content)
tool_calls.append({"name": call_data["name"], "arguments": call_data["arguments"]})
except json.JSONDecodeError:
logger.warning(f"Error parsing tool call: {json_content}")
text = text[end + len(self.tool_call_end) :]
continue
text = text[end + len(self.tool_call_end) :]
return tool_calls
def get_tool_prompt(self, tools_schema: str) -> str:
return f"""
You are provided with function signatures within <tools></tools> XML tags:
<tools>
{tools_schema}
</tools>
For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:
<tool_call>
{{"name": <function-name>, "arguments": <args-json-object>}}
</tool_call><|im_end|>
"""