diff --git a/src/exo/master/adapters/responses.py b/src/exo/master/adapters/responses.py index 0a40c016..c92c4e37 100644 --- a/src/exo/master/adapters/responses.py +++ b/src/exo/master/adapters/responses.py @@ -128,6 +128,28 @@ def responses_request_to_text_generation( effort_from_reasoning, request.enable_thinking ) + # The responses API often does not provide tool args nested under a "function" field. + # Since we follow the chat completions format of tools in the backend (for MLX chat templates) + # we need to normalise to this format. + normalised_tools: list[dict[str, Any]] | None = None + if request.tools: + normalised_tools = [] + for tool in request.tools: + if "function" in tool: + normalised_tools.append(tool) + else: + normalised_tools.append( + { + "type": "function", + "function": { + "name": tool.get("name", ""), + "description": tool.get("description", ""), + "parameters": tool.get("parameters", {}), + **({"strict": tool["strict"]} if "strict" in tool else {}), + }, + } + ) + return TextGenerationTaskParams( model=request.model, input=input_value, @@ -136,7 +158,7 @@ def responses_request_to_text_generation( temperature=request.temperature, top_p=request.top_p, stream=request.stream, - tools=request.tools, + tools=normalised_tools, top_k=request.top_k, stop=request.stop, seed=request.seed,