Register functions the model can invoke in a Responses API request, and send their results back.
Tool calling lets you expose functions to the model. When the model decides a function should run, it returns a function_call item; your code executes the function and sends the result back, with the conversation, in the next request.
Include a tools array in your request. Each tool is a JSON Schema function definition:
{
"model": "google/gemini-2.5-pro",
"input": "What is the current balance on my account?",
"tools": [
{
"type": "function",
"name": "get_account_balance",
"description": "Returns the caller's current credit balance in micro-DA.",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
]
}When the model decides to invoke a tool, the response contains a function_call output item instead of (or before) the assistant's text:
{
"id": "resp_01ABCdef...",
"output": [
{
"type": "function_call",
"id": "fc_abc123",
"call_id": "call_xyz",
"name": "get_account_balance",
"arguments": "{}"
}
]
}Your code runs the function, then sends the whole conversation again — the user's turn, the function_call item, and a function_call_output carrying the result under the same call_id. The API keeps nothing between requests, so previous_response_id is refused with a 400.
result = get_account_balance() # your implementation
response = client.responses.create(
model="google/gemini-2.5-pro",
input=[
{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "What is the current balance on my account?"}]},
{"type": "function_call", "id": "fc_abc123", "call_id": "call_xyz", "name": "get_account_balance", "arguments": "{}"},
{"type": "function_call_output", "call_id": "call_xyz", "output": str(result)},
],
tools=tools, # the same tools as the first request
)
print(response.output_text)Control whether the model must call a tool, may call one, or is forbidden from calling:
tool_choice value | Behaviour |
|---|---|
"auto" (default) | Model decides |
"required" | Model must call at least one tool |
"none" | No tool calls allowed this turn |
{"type": "function", "name": "..."} | Force a specific function |
You can register as many tools as the model's context window allows. The model may call several in a single turn; handle each function_call item in the output array before submitting results.
Set "stream": true and handle response.function_call_arguments.delta events to receive tool call arguments incrementally, then response.function_call_arguments.done — useful when argument payloads are large.
Next to your own functions, tools takes the helpers OpenDunes runs for the model — opendunes:web_search, opendunes:web_fetch, opendunes:shell, opendunes:apply_patch, opendunes:tool_search and the others on the Responses reference. A helper's step is run for you inside the request, and billed in DA on its own meter. See Web Search.