SRHarness / src /sr_harness /parser /openai_parser.py
yuzihan@SIM1
Deploy SRHarness Docker Space
d06fa57
Raw History Blame Contribute Delete
3.07 kB
# Copyright (c) 2026-present, Yumeow. Licensed under the MIT License.
from __future__ import annotations
import json
from logging import getLogger
from typing import List, Dict, Any
from .base_parser import BaseParser
from ..core import ToolCall, ToolCallResult
_logger = getLogger(f'sr_harness.{__name__}')
@BaseParser.register('openai')
class OpenAIParser(BaseParser):
"""Parser for native OpenAI-compatible tool calls."""
native_tool_calls = True
def format_tools(self) -> List[Dict[str, Any]]:
"""Return OpenAI-compatible native function descriptions."""
return [
{
"type": "function",
"function": {
"name": tool.metadata.name,
"description": tool.metadata.description,
"parameters": tool.metadata.parameters,
},
}
for tool in self.tools
]
def parse_response(self, response: Any) -> List[ToolCall]:
"""Normalize provider-native function calls already extracted by BaseAPI."""
normalized = []
for tool_call in response or []:
if isinstance(tool_call, dict):
raw = tool_call
elif hasattr(tool_call, "to_dict"):
raw = tool_call.to_dict()
elif hasattr(tool_call, "model_dump"):
raw = tool_call.model_dump()
else:
raise ValueError(f"Unrecognized tool call format: {tool_call}")
function = raw.get("function") or {}
name = function.get("name") or raw.get("name") or None
params = (
function.get("arguments")
or raw.get("arguments")
or raw.get("arguments_json")
or raw.get("args")
or {}
)
try:
if isinstance(params, str):
params = json.loads(params) if params.strip() else {}
except json.JSONDecodeError as error:
_logger.warning(f"Skip malformed native tool call {raw!r}: {error}")
continue
normalized.append(ToolCall(
name=name,
params=params,
id=raw.get("id") or raw.get("call_id"),
raw=raw,
))
return normalized
def format_tool_result_messages(
self,
tool_calls: List[ToolCall],
results: List[ToolCallResult],
) -> List[Dict[str, Any]]:
"""Format tool result messages.
Args:
tool_calls: Tool calls returned by the model.
results: Result records to process.
Returns:
List[Dict[str, Any]]: The operation result.
"""
messages = []
for tool_call, result in zip(tool_calls, results):
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"name": tool_call.name,
"content": result.result_str,
})
return messages