Capabilities

Tool calling

Tool calling lets a model reach beyond text — look something up, hit your API, query a database, run a calculation. You describe the functions available; the model decides when to call one and with what arguments. Pendra is OpenAI-shaped, so it works exactly like the OpenAI tools API.

Describe your tools

Pass a tools array, each entry a function with a name, description, and JSON Schema parameters. When the model wants to use one, it replies with a tool_calls array on the assistant message instead of a plain answer.

from pendra import Pendra

client = Pendra()

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

response = client.chat.completions.create(
    model="qwen3.6:27b",
    tools=tools,
    messages=[{"role": "user", "content": "What's the weather in Cardiff?"}],
)

call = response.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)
Tool call
get_weather {"city": "Cardiff"}

Instead of answering directly, the model asks you to run get_weather with city: "Cardiff". You run it and pass the result back.

Run the loop

Tool calling is a round trip you drive:

  1. Send the conversation with your tools.
  2. If the reply contains tool_calls, run each one in your code.
  3. Append a { "role": "tool", "tool_call_id": ..., "content": ... } message with each result.
  4. Call the endpoint again so the model can use the results to answer.

Use tool_choice to force or forbid a call, and parallel_tool_calls to allow several at once. Tool calling works on tool-capable chat models (for example Qwen Instruct) — browse available models to see which advertise it.

For the full request and response schema, see the Chat completions API reference.