> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boson.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Tool use

> Declare functions, execute tool calls in your application, return results, and continue the Realtime response.

Declare function tools in `session.update`:

```json theme={null}
{
  "tools": [
    {
      "type": "function",
      "name": "get_weather",
      "description": "Get current weather for a city",
      "parameters": {
        "type": "object",
        "properties": { "city": { "type": "string" } },
        "required": ["city"]
      }
    }
  ]
}
```

When the model calls a tool, the server streams [`response.function_call_arguments.delta`](/api-reference/realtime/server-events#response-function_call_arguments-delta) events and finishes with [`response.function_call_arguments.done`](/api-reference/realtime/server-events#response-function_call_arguments-done), then ends the response with [`response.done`](/api-reference/realtime/server-events#response-done) carrying the completed `function_call` item (`call_id`, `name`, `arguments`). It is now your client's turn:

1. Execute the function locally with the provided arguments.
2. Return the result with [`conversation.item.create`](/api-reference/realtime/client-events#conversation-item-create) (`type: "function_call_output"`, echoing the `call_id`).
3. Send [`response.create`](/api-reference/realtime/client-events#response-create) — the model continues with the result and speaks the answer.

The core handler flow is shown below. Pass the connected WebSocket as `ws`:

```python theme={null}
import json

TOOLS = [
    {
        "type": "function",
        "name": "get_weather",
        "description": "Get current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    }
]


def get_weather(city: str) -> dict:
    ...  # your implementation


async def run_tool_turn(ws):
    # Declare the tool and ask a question that needs it.
    await ws.send(json.dumps({
        "type": "session.update",
        "session": {
            "model": "higgs-realtime",
            "tools": TOOLS,
            "instructions": "Use the available tools when needed.",
        },
    }))
    await ws.send(json.dumps({
        "type": "conversation.item.create",
        "item": {
            "type": "message",
            "role": "user",
            "content": [
                {"type": "input_text", "text": "What's the weather in Tokyo?"}
            ],
        },
    }))
    await ws.send(json.dumps({"type": "response.create"}))

    async for msg in ws:
        event = json.loads(msg)

        if event["type"] == "response.done":
            # A response ending in a tool call carries the function_call item.
            calls = [
                item
                for item in event["response"]["output"]
                if item.get("type") == "function_call"
            ]
            if not calls:
                break  # Final spoken reply finished.

            call = calls[0]
            result = get_weather(**json.loads(call["arguments"]))  # 1. Execute.
            await ws.send(json.dumps({
                "type": "conversation.item.create",  # 2. Return the result.
                "item": {
                    "type": "function_call_output",
                    "call_id": call["call_id"],
                    "output": json.dumps(result),
                },
            }))
            await ws.send(
                json.dumps({"type": "response.create"})
            )  # 3. Continue.

        elif event["type"] == "response.output_audio.delta":
            ...  # Play audio as usual.
```
