Tools & Function Calling

Use tools and function calling with the Sansa API

Overview

Tools let the model call functions you define. The model decides when to call a tool and generates the arguments — your code executes it and sends the result back.

Tool Definition Format

{
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "Get current weather for a location",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "City name or coordinates"
          },
          "units": {
            "type": "string",
            "enum": ["celsius", "fahrenheit"],
            "description": "Temperature unit"
          }
        },
        "required": ["location"]
      }
    }
  }]
}
  • type must be "function"
  • function.name: descriptive, snake_case recommended
  • function.description: detailed, helps the model decide when to use it
  • function.parameters: JSON Schema object

Three-Step Flow

Step 1: Send request with tools

Include tools in your request. The model may respond with text or with tool_calls.

Step 2: Model responds with tool_calls

When the model wants to call a tool, content is null and tool_calls contains the calls:

{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": null,
      "tool_calls": [{
        "id": "call_abc123",
        "type": "function",
        "function": {
          "name": "get_weather",
          "arguments": "{\"location\": \"Tokyo\", \"units\": \"celsius\"}"
        }
      }]
    },
    "finish_reason": "tool_calls"
  }]
}

Step 3: Send tool result back

Append the assistant message and a tool message with the result. Include tools in every request — not just the first one.

{
  "messages": [
    {"role": "user", "content": "What's the weather in Tokyo?"},
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [{
        "id": "call_abc123",
        "type": "function",
        "function": {
          "name": "get_weather",
          "arguments": "{\"location\": \"Tokyo\", \"units\": \"celsius\"}"
        }
      }]
    },
    {
      "role": "tool",
      "tool_call_id": "call_abc123",
      "content": "{\"temperature\": 22, \"conditions\": \"sunny\"}"
    }
  ],
  "tools": [/* same tool definitions */]
}

tool_choice

ValueBehavior
"auto" (default when tools present)Model decides
"none"Model won't use tools
"required"Model must use at least one tool
{"type":"function","function":{"name":"..."}}Force a specific tool

parallel_tool_calls

  • Default: true
  • When true, the model may request multiple tool calls in a single response
  • When false, the model makes one tool call at a time
  • Each tool call has a unique id — match results by tool_call_id

Streaming with Tool Calls

  • delta.tool_calls[].id and delta.tool_calls[].function.name arrive first
  • delta.tool_calls[].function.arguments streams as partial JSON fragments
  • Client must accumulate argument fragments, then JSON.parse the complete string
  • finish_reason: "tool_calls" signals all tool calls are complete

Best Practices

  • Use descriptive function names and detailed descriptions
  • Include property descriptions in the JSON Schema
  • Design tools that compose well (search → get details → take action)
  • Set a max iteration limit in agentic loops
  • Handle errors in tool execution gracefully (return error info as tool content)