tool function calling.md

For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to page URLs; this page is available as Markdown.

Tool/Function Calling

Overview

Tool (function) calling lets a model decide when to invoke an external function—a weather API, a database query, a calculator—and emit a structured request for it. Your application runs the function and feeds the result back to the model.

Parasail exposes tool calling through two OpenAI-compatible surfaces:

Both use the same base URL and API key:

https://api.parasail.io/v1

The tool schema (name, description, JSON Schema parameters) is the same in both APIs—only the wrapper shape and the response handling differ. Pick Chat Completions for simple one-shot tool calls, and the Responses API for multi-turn agentic workflows.

Supported models

The following models support tool calling and tool_choice as of June 2026. Verify current availability via the models endpoint.

Treat this table as a starting point for validation. Test your actual tool schema and prompt before depending on tool calls in production.

Model Tools Tool Choice
parasail-llama-33-70b-fp8
parasail-llama-4-scout-instruct
parasail-llama-4-maverick-instruct-fp8
parasail-qwen3-30b-a3b
parasail-qwen3-235b-a22b
parasail-qwen3-32b
parasail-mistral-devstral-small

{% tabs %} {% tab title="Chat Completions API" %} In the Chat Completions API, each tool must be wrapped as {"type": "function", "function": {...}}. The function object holds the name, description, and a JSON Schema parameters.

import os
import json
from openai import OpenAI

client = OpenAI(
    base_url="https://api.parasail.io/v1",
    api_key="<PARASAIL_API_KEY>",
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Retrieve weather information for a given location and date.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string"},
                    "date": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"},
                },
                "required": ["location", "date"],
            },
        },
    }
]

messages = [
    {"role": "user", "content": "What's the weather like in Manhattan Beach on 2025-06-03?"}
]

response = client.chat.completions.create(
    model="parasail-llama-4-scout-instruct",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
print(json.dumps(args, indent=2))

Expected arguments:

{
  "location": "Manhattan Beach",
  "date": "2025-06-03"
}

Returning the tool result

Run your function, then append the assistant's tool call and a tool message with the result before calling the model again:

def get_weather(location, date):
    # Replace with a real API call
    return {"location": location, "date": date, "weather": "Sunny", "temperature": "75F"}

result = get_weather(**args)

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

final = client.chat.completions.create(
    model="parasail-llama-4-scout-instruct",
    messages=messages,
    tools=tools,
)
print(final.choices[0].message.content)

{% endtab %}

{% tab title="Responses API" %} In the Responses API, tools are defined with a flat shape—type, name, description, and parameters at the top level (no nested function object). Tool calls come back as function_call items in response.output, and you return results as function_call_output items.

import json
from openai import OpenAI

client = OpenAI(
    base_url="https://api.parasail.io/v1",
    api_key="<PARASAIL_API_KEY>",
)

tools = [
    {
        "type": "function",
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "City name"},
                "units": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "default": "celsius",
                },
            },
            "required": ["city"],
        },
    }
]

def handle_tool_call(name, arguments):
    args = json.loads(arguments)
    if name == "get_weather":
        return json.dumps({"city": args["city"], "temperature": 22, "condition": "sunny"})
    return json.dumps({"error": "unknown function"})

# Initial request (store must be false on the Parasail gateway)
response = client.responses.create(
    model="parasail-kimi-k25-elicit",
    store=False,
    tools=tools,
    input=[{"role": "user", "content": "What's the weather in Tokyo?"}],
)

# Agentic loop—continue until the model stops calling tools
while response.output:
    tool_calls = [item for item in response.output if item.type == "function_call"]
    if not tool_calls:
        break

next_input = list(response.output)
    for tool_call in tool_calls:
        result = handle_tool_call(tool_call.name, tool_call.arguments)
        next_input.append(
            {
                "type": "function_call_output",
                "call_id": tool_call.call_id,
                "output": result,
            }
        )

response = client.responses.create(
        model="parasail-kimi-k25-elicit",
        store=False,
        tools=tools,
        input=next_input,
    )

print(response.output_text)

The Responses API requires store=False on every request. See the Responses API reference for the full compatibility table. {% endtab %}

Chat Completions tools vs. Responses tools

Chat Completions Responses API
Tool definition {"type": "function", "function": {name, description, parameters}} {"type": "function", name, description, parameters} (flat)
Where calls appear message.tool_calls[] response.output[] items with type == "function_call"
Returning results {"role": "tool", "tool_call_id": ..., "content": ...} {"type": "function_call_output", "call_id": ..., "output": ...}
Best for One-shot tool calls Multi-step agentic loops

The underlying schema—the function name, description, and JSON Schema parameters—is identical between the two; only the wrapper and the result-handling differ.

Next steps