session.tools:
- Function tools (
"type": "function"): you define them, and your client executes each call and returns the result. - Server-side tools: built in and executed by Higgs Realtime. Today that is web search (
"type": "web_search").
Server-side tools (
web_search) are executed automatically by Higgs Realtime — you don’t need to handle their calls or return their results. Only custom function tools require client-side handling.Function tools
Declare function tools insession.update:
response.function_call_arguments.delta events and finishes with response.function_call_arguments.done, then ends the response with response.done carrying the completed function_call item (call_id, name, arguments). It is now your client’s turn:
- Execute the function locally with the provided arguments.
- Return the result with
conversation.item.create(type: "function_call_output", echoing thecall_id). - Send
response.create— the model continues with the result and speaks the answer.
ws:
Web search
web_search is a built-in, server-side tool. Add it to session.tools and the model can look things up on the web when a question needs current or factual information it doesn’t reliably know — prices, news, scores, schedules.
Enable web search
Declare the tool insession.update, and use instructions to tell the model when to search:
Parameters
All parameters are optional. Without any, the search covers the whole web.- Domains are bare hostnames such as
example.com— no scheme, path, or query (https://example.com/newsis rejected). A domain also matches its subdomains:noaa.govcoverswww.weather.noaa.gov. allowed_domainsandexcluded_domainsare mutually exclusive — set one or the other. An empty list means no restriction.location.countryis an ISO 3166-1 alpha-2 code (US,GB,JP; case-insensitive). Full country names such as"United States"are rejected.
error event, and the session keeps its previous configuration.
What your client sees
A search shows up on the wire as an ordinaryfunction_call item named web_search, with "executor": "server". You don’t need to act on it — the events are there so you can show progress (for example a “Searching…” indicator) or log what was searched.
- Preamble. The model speaks a short filler in its own words (for example, “Let me check that for you.”) as an assistant message.
- The call.
response.output_item.addedcarries thefunction_callitem (name: "web_search",executor: "server"), followed byresponse.function_call_arguments.delta/.done. The arguments are the model’s search request, e.g.{"objective": "Find tonight's weather in Tokyo", "queries": ["Tokyo weather tonight"]}. - The response ends.
response.donearrives right after the preamble — it doesn’t wait for the search. - The result. When the search finishes, the server adds a
function_call_outputitem with the samecall_idand announces it withconversation.item.added. - The answer. The server starts a new response on its own, and the model speaks the answer. If the user starts talking before that, the result is folded into the reply to what they said instead.
- Interruptions. Once the user has heard the preamble, the search runs to completion and its result is delivered even if they barge in. If the user interrupts before any audio plays, the search doesn’t run; you may then see a
web_searchfunction_callwith no matchingfunction_call_output. - Failures. If the search fails or times out, the
function_call_outputsays so and the model answers from what it already knows. - The output text is for the model. It lists up to five ranked results (title, URL, and a short excerpt) per search. Treat its format as unstable — don’t parse it.
- The name is reserved. Declare
{"type": "web_search"}once, and don’t name one of your own function toolsweb_search.
Combining multiple tools
A session can mixweb_search with your own function tools. The model chooses between them per turn, and only the function tools need client-side handling.
function_call item carries executor. Handle the ones marked "client" as described in Function tools, and skip the ones marked "server":