tools, and the model answers with a call instead of text when it needs one. Your code runs the function and sends the result back in the next request, and the model uses it to answer. The loop below repeats that until the model answers in text.
- Responses
- Chat Completions
- Messages
Calls and results in each format
The loop is the same everywhere, but each format names its parts differently:
Responses also accepts the Chat Completions tool shape,
{"type": "function", "function": {...}}. In Chat Completions, parallel_tool_calls: false asks for one call per turn.
Send the history back unchanged
NagaAI checks that every tool call in the conversation has its result and every result has its call. A request that breaks the pair fails with400 before it reaches a provider, so you don’t pay for it. The error code says which half is missing: tool_call_unanswered for a call without a result, tool_output_unmatched for a result without its call.
Responses keeps no state between calls, which is why the example appends the whole response.output to items. The next request needs the earlier function_call items next to their function_call_output items. Conversation state explains this for every format.
Send the assistant turn back as it came. In Chat Completions that includes tool_calls and any reasoning_details, and in Messages any thinking blocks. Some models lose their reasoning between tool calls if you rebuild the turn from its fields.
In Messages, NagaAI ignores is_error on a tool_result. To tell the model that a tool failed, say so in the result text.
Models that don’t call tools
Checkparameters of the model’s chat operation in /v1/models. If tools isn’t listed, NagaAI removes your tools from the request and the model answers in text, without an error.
A few models accept only tool_choice: "auto". For claude-opus-5.5, claude-fable-5.1 and Mythos 5.1, NagaAI turns required or a named tool into auto, so the model can still answer in text. Check for a call in the response before you rely on one.
Tool types
NagaAI supports your own function tools and web search. It drops other server-side tools, such ascode_interpreter or file_search, and the full list is in Differences from OpenAI and Anthropic. Web search has its own guide, Web search.
Troubleshooting
400 on functions or function_call
NagaAI refuses the legacy Chat Completions fields: functions, the function role and function_call on a message. It drops a top-level function_call. Move to tools, tool_choice, tool_calls and the tool role.
400 tool_call_unanswered
The history has a tool call without a result. The message names the first call_id that has none. Add a result for every call the model made, with the same id.
400 tool_output_unmatched
The history has a tool result whose call isn’t there. This usually means the code relies on previous_response_id, which NagaAI doesn’t keep. Send the call item itself along with its result.