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 writes the arguments; your code runs it and sends the result back.
Tool Definition Format
{
"tools": [{
"type": "function",
"function": {
// Descriptive name, snake_case recommended.
"name": "get_weather",
// Detailed description helps the model decide when to use it.
"description": "Get current weather for a location",
// JSON Schema object.
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or coordinates"
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit"
}
},
"required": ["location"]
}
}
}]
}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 calls a tool, content is null and tool_calls holds the calls, each with an id you send back in Step 3:
{
"choices": [{
"message": {
"role": "assistant",
"content": null,
"tool_calls": [{
"id": "call12345",
"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 from Step 2 and a tool message with the result. Pass back the exact id; you don't need to worry about its format. Include tools in every request, not just the first.
{
"messages": [
{"role": "user", "content": "What's the weather in Tokyo?"},
{
"role": "assistant",
"content": null,
"tool_calls": [{
"id": "call12345",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\": \"Tokyo\", \"units\": \"celsius\"}"
}
}]
},
{
"role": "tool",
"tool_call_id": "call12345", // Same ID as the assistant's tool call
"content": "{\"temperature\": 22, \"conditions\": \"sunny\"}"
}
],
"tools": [/* same tool definitions */]
}tool_choice
See tool_choice for the values.
parallel_tool_calls
Default: true. When false, the model makes one tool call at a time. Match each result to its call by tool_call_id.
Streaming with Tool Calls
delta.tool_calls[].idanddelta.tool_calls[].function.namearrive first.delta.tool_calls[].function.argumentsstreams as partial JSON fragments.- Client must accumulate argument fragments, then
JSON.parsethe 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).