Function Calling

Function calling lets the model invoke functions you define. The model decides when to call a function and generates the arguments — your code executes it and returns the result.

How it works

  1. You define functions in the tools parameter
  2. The model decides if a function should be called
  3. The model returns a tool_calls object with function name + arguments
  4. You execute the function and send the result back
  5. The model uses the result to form its final response

Example: Weather lookup

import json
from openai import OpenAI
 
client = OpenAI(api_key="sk-...", base_url="https://sovereigneg.com/v1")
 
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "City name, e.g. Cairo, Riyadh"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "Temperature unit"
                    }
                },
                "required": ["city"]
            }
        }
    }
]
 
response = client.chat.completions.create(
    model="...",
    messages=[{"role": "user", "content": "What's the weather in Cairo?"}],
    tools=tools,
    tool_choice="auto"
)
 
message = response.choices[0].message
 
if message.tool_calls:
    for call in message.tool_calls:
        name = call.function.name
        args = json.loads(call.function.arguments)
        print(f"Model wants to call: {name}({args})")
 
        # Execute your function
        result = get_weather(**args)  # your implementation
 
        # Send result back
        followup = client.chat.completions.create(
            model="...",
            messages=[
                {"role": "user", "content": "What's the weather in Cairo?"},
                message,
                {
                    "role": "tool",
                    "tool_call_id": call.id,
                    "content": json.dumps(result)
                }
            ]
        )
        print(followup.choices[0].message.content)

Tool response format

When the model decides to call a function:

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

Multiple tools

You can define multiple functions. The model picks the right one based on the user's request:

tools = [
    {"type": "function", "function": {"name": "search_docs", ...}},
    {"type": "function", "function": {"name": "create_ticket", ...}},
    {"type": "function", "function": {"name": "get_user_info", ...}},
]

Supported models

Function calling requires a model that supports tools. Check the Model Library for models with a Tools badge — not every model supports tool calls.

Pick any live model with a Tools badge from the Model Library. Model IDs change — use GET /v1/models rather than hardcoding names from examples.

cURL quick-test

Confirm tool-calling is wired end-to-end without leaving your shell:

curl https://sovereigneg.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<your-model-id>",
    "messages": [{"role":"user","content":"What is the weather in Cairo? Use the tool."}],
    "tools": [{
      "type":"function",
      "function":{
        "name":"get_weather",
        "description":"Get the current weather for a city",
        "parameters":{
          "type":"object",
          "properties":{"city":{"type":"string"}},
          "required":["city"]
        }
      }
    }],
    "tool_choice":"auto"
  }' | jq '.choices[0].message.tool_calls'
# expect: a list with one entry whose function.arguments contains {"city":"Cairo"}.

If you get tool_calls: null and a free-form text answer, the model may not support tool calling — try another model from the catalog or contact support.