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

# Tool calling

> Let the model call your functions with structured arguments.

Tool calling (function calling) lets a model decide to invoke a function you
define and return structured arguments for it. Omnia supports the standard
OpenAI tools interface through `/v1/chat/completions`, so any OpenAI SDK works
unchanged.

## Defining tools

A tool is an object with `type: "function"` and a `function` describing its
`name`, `description`, and `parameters` (a JSON Schema for the arguments).

<CodeGroup>
  ```python Python theme={null}
  tools = [
      {
          "type": "function",
          "function": {
              "name": "get_weather",
              "description": "Get the current weather for a city.",
              "parameters": {
                  "type": "object",
                  "properties": {
                      "city": {"type": "string", "description": "City name"},
                  },
                  "required": ["city"],
              },
          },
      }
  ]

  resp = client.chat.completions.create(
      model="Qwen/Qwen3-32B",
      messages=[{"role": "user", "content": "What's the weather in Paris?"}],
      tools=tools,
      tool_choice="auto",
  )

  tool_calls = resp.choices[0].message.tool_calls
  ```

  ```javascript JavaScript theme={null}
  const tools = [
    {
      type: "function",
      function: {
        name: "get_weather",
        description: "Get the current weather for a city.",
        parameters: {
          type: "object",
          properties: { city: { type: "string", description: "City name" } },
          required: ["city"],
        },
      },
    },
  ];

  const resp = await client.chat.completions.create({
    model: "Qwen/Qwen3-32B",
    messages: [{ role: "user", content: "What's the weather in Paris?" }],
    tools,
    tool_choice: "auto",
  });
  ```

  ```bash cURL theme={null}
  curl https://gateway.omnia-voice.com/v1/chat/completions \
    -H "Authorization: Bearer $OMNIA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "Qwen/Qwen3-32B",
      "messages": [{ "role": "user", "content": "What'\''s the weather in Paris?" }],
      "tool_choice": "auto",
      "tools": [{
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "Get the current weather for a city.",
          "parameters": {
            "type": "object",
            "properties": { "city": { "type": "string", "description": "City name" } },
            "required": ["city"]
          }
        }
      }]
    }'
  ```
</CodeGroup>

## A full round trip

### 1. The model asks to call a tool

When the model decides to call a tool, `finish_reason` is `tool_calls` and the
assistant message carries a `tool_calls` array. Each call has an `id`, the
function `name`, and JSON-encoded `arguments`:

```json theme={null}
{
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\": \"Paris\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}
```

### 2. You run the function and send the result back

<Steps>
  <Step title="Read the tool call">
    Parse `message.tool_calls[i].function.name` and `.arguments` (a JSON string).
  </Step>

  <Step title="Run your function">
    Execute the function with those arguments in your own code.
  </Step>

  <Step title="Send the result back">
    Append the assistant's tool-call message, then a `role: "tool"` message whose
    `tool_call_id` matches the call's `id` and whose `content` is the result.
    Call the model again to get the final answer.
  </Step>
</Steps>

```python theme={null}
import json

tool_call = resp.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)  # {"city": "Paris"}
result = get_weather(**args)                      # your own function

messages.append(resp.choices[0].message)          # the assistant's tool-call
messages.append({
    "role": "tool",
    "tool_call_id": tool_call.id,
    "content": json.dumps(result),                # {"temp_c": 18, "condition": "cloudy"}
})

final = client.chat.completions.create(
    model="Qwen/Qwen3-32B",
    messages=messages,
)
print(final.choices[0].message.content)
# "It's currently 18°C and cloudy in Paris."
```

## `tool_choice`

| Value                                                   | Behaviour                                 |
| ------------------------------------------------------- | ----------------------------------------- |
| `"auto"`                                                | The model decides whether to call a tool. |
| `"required"`                                            | The model must call a tool.               |
| `"none"`                                                | The model won't call any tool.            |
| `{ "type": "function", "function": { "name": "..." } }` | Force a specific tool.                    |

## Parallel tool calls

Set `parallel_tool_calls: true` to let the model request several tool calls in a
single turn (the `tool_calls` array will have multiple entries). Execute each
one, then append a matching `role: "tool"` message per `tool_call_id` before
calling the model again.

<Note>
  **Observability captures tool names only, never argument values.** Omnia's
  telemetry records which tools were called for metrics, but it does not store the
  `arguments` you pass or the results you send back.
</Note>

<Tip>
  Each round-trip (the tool-call request and the follow-up with the result) is a
  separate, independently-metered request, because Omnia is stateless and you
  resend the growing message history each time. Keep tool `description`s and
  schemas tight to minimize prompt tokens.
</Tip>
