Tool Calling
The Inceptron Chat Completions API supports OpenAI-compatible tool calling. This lets the model decide when to call one of your application functions, return structured arguments for that function, and then continue the conversation after you run it.
This guide shows how to define tools and call them through the OpenAI-compatible Chat Completions API at https://api.inceptron.io/v1.
Define Your Tools
Pass your available functions in the tools field. Each tool includes a name, a description, and a JSON Schema object describing the expected arguments.
- Python
- JavaScript
- cURL
from openai import OpenAI
import json
client = OpenAI(
base_url="https://api.inceptron.io/v1",
api_key="replace me",
)
def get_mission_status(mission_name: str, detail_level: str):
return f"Getting {detail_level} mission status for {mission_name}..."
tool_functions = {
"get_mission_status": get_mission_status,
}
tools = [
{
"type": "function",
"function": {
"name": "get_mission_status",
"description": "Get the latest status for a space mission",
"parameters": {
"type": "object",
"properties": {
"mission_name": {
"type": "string",
"description": "The mission name, e.g. 'Artemis II'",
},
"detail_level": {
"type": "string",
"enum": ["summary", "full"],
},
},
"required": ["mission_name", "detail_level"],
},
},
},
]
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.inceptron.io/v1",
apiKey: process.env.INCEPTRON_API_KEY,
});
function getMissionStatus(missionName, detailLevel) {
return `Getting ${detailLevel} mission status for ${missionName}...`;
}
const toolFunctions = {
get_mission_status: getMissionStatus,
};
const tools = [
{
type: "function",
function: {
name: "get_mission_status",
description: "Get the latest status for a space mission",
parameters: {
type: "object",
properties: {
mission_name: {
type: "string",
description: "The mission name, e.g. 'Artemis II'",
},
detail_level: {
type: "string",
enum: ["summary", "full"],
},
},
required: ["mission_name", "detail_level"],
},
},
},
];
curl https://api.inceptron.io/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $INCEPTRON_API_KEY" \
-d '{
"model": "moonshotai/Kimi-K2.6",
"messages": [
{"role": "user", "content": "Give me the latest status for Artemis II."}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_mission_status",
"description": "Get the latest status for a space mission",
"parameters": {
"type": "object",
"properties": {
"mission_name": {
"type": "string",
"description": "The mission name, e.g. '''Artemis II'''"
},
"detail_level": {
"type": "string",
"enum": ["summary", "full"]
}
},
"required": ["mission_name", "detail_level"]
}
}
}
],
"tool_choice": "auto"
}'
Send a Tool-Enabled Request
Set the tools parameter on the chat completion request. In this example, tool_choice="auto" allows the model to either answer normally or call a tool.
- Python
- JavaScript
- cURL
completion = client.chat.completions.create(
model="moonshotai/Kimi-K2.6",
messages=[
{
"role": "user",
"content": "Give me the latest status for Artemis II.",
}
],
tools=tools,
tool_choice="auto",
)
const completion = await client.chat.completions.create({
model: "moonshotai/Kimi-K2.6",
messages: [
{
role: "user",
content: "Give me the latest status for Artemis II.",
},
],
tools,
tool_choice: "auto",
});
curl https://api.inceptron.io/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $INCEPTRON_API_KEY" \
-d '{
"model": "moonshotai/Kimi-K2.6",
"messages": [
{"role": "user", "content": "Give me the latest status for Artemis II."}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_mission_status",
"description": "Get the latest status for a space mission",
"parameters": {
"type": "object",
"properties": {
"mission_name": {
"type": "string",
"description": "The mission name, e.g. '''Artemis II'''"
},
"detail_level": {
"type": "string",
"enum": ["summary", "full"]
}
},
"required": ["mission_name", "detail_level"]
}
}
}
],
"tool_choice": "auto"
}'
Handle Streamed Tool Calls
When streaming is enabled, tool calls may arrive in multiple chunks. Accumulate the function name and arguments until the stream finishes, then parse the final JSON arguments and run your local function.
- Python
- JavaScript
- cURL
tool_calls = {}
for chunk in stream:
# Some providers emit stream events with no choices payload.
if not chunk.choices:
continue
delta = chunk.choices[0].delta
if not delta:
continue
if delta.tool_calls:
for tool_call_delta in delta.tool_calls:
index = tool_call_delta.index
if index not in tool_calls:
tool_calls[index] = {
"id": tool_call_delta.id,
"type": tool_call_delta.type,
"function": {
"name": "",
"arguments": "",
},
}
if tool_call_delta.function:
if tool_call_delta.function.name:
tool_calls[index]["function"]["name"] += tool_call_delta.function.name
if tool_call_delta.function.arguments:
tool_calls[index]["function"]["arguments"] += (
tool_call_delta.function.arguments
)
for tool_call in tool_calls.values():
function_name = tool_call["function"]["name"]
arguments = tool_call["function"]["arguments"]
print(f"Function called: {function_name}")
print(f"Arguments: {arguments}")
print(f"Result: {tool_functions[function_name](**json.loads(arguments))}")
const toolCalls = {};
for await (const chunk of stream) {
const delta = chunk.choices?.[0]?.delta;
if (!delta?.tool_calls) {
continue;
}
for (const toolCallDelta of delta.tool_calls) {
const index = toolCallDelta.index;
if (!(index in toolCalls)) {
toolCalls[index] = {
id: toolCallDelta.id,
type: toolCallDelta.type,
function: {
name: "",
arguments: "",
},
};
}
if (toolCallDelta.function?.name) {
toolCalls[index].function.name += toolCallDelta.function.name;
}
if (toolCallDelta.function?.arguments) {
toolCalls[index].function.arguments += toolCallDelta.function.arguments;
}
}
}
for (const toolCall of Object.values(toolCalls)) {
const functionName = toolCall.function.name;
const args = JSON.parse(toolCall.function.arguments);
console.log("Function called:", functionName);
console.log("Arguments:", toolCall.function.arguments);
console.log("Result:", toolFunctions[functionName](args.mission_name, args.detail_level));
}
Use curl when you only need to inspect the raw streamed response. Tool execution still happens in your application after you parse the streamed tool_calls deltas.
Complete Example
- Python
- JavaScript
- cURL
from openai import OpenAI
import json
client = OpenAI(base_url="https://api.inceptron.io/v1", api_key="replace me")
def get_mission_status(mission_name: str, detail_level: str):
return f"Getting {detail_level} mission status for {mission_name}..."
tool_functions = {"get_mission_status": get_mission_status}
tools = [
{
"type": "function",
"function": {
"name": "get_mission_status",
"description": "Get the latest status for a space mission",
"parameters": {
"type": "object",
"properties": {
"mission_name": {
"type": "string",
"description": "The mission name, e.g. 'Artemis II'",
},
"detail_level": {
"type": "string",
"enum": ["summary", "full"],
},
},
"required": ["mission_name", "detail_level"],
},
},
},
]
completion = client.chat.completions.create(
model="moonshotai/Kimi-K2.6",
messages=[{"role": "user", "content": "Give me the latest status for Artemis II."}],
tools=tools,
tool_choice="auto",
)
for tool_call in completion.choices[0].message.tool_calls or []:
function_name = tool_call.function.name
arguments = tool_call.function.arguments
print(f"Function called: {function_name}")
print(f"Arguments: {arguments}")
print(f"Result: {tool_functions[function_name](**json.loads(arguments))}")
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.inceptron.io/v1",
apiKey: process.env.INCEPTRON_API_KEY,
});
function getMissionStatus(missionName, detailLevel) {
return `Getting ${detailLevel} mission status for ${missionName}...`;
}
const toolFunctions = {
get_mission_status: getMissionStatus,
};
const tools = [
{
type: "function",
function: {
name: "get_mission_status",
description: "Get the latest status for a space mission",
parameters: {
type: "object",
properties: {
mission_name: {
type: "string",
description: "The mission name, e.g. 'Artemis II'",
},
detail_level: {
type: "string",
enum: ["summary", "full"],
},
},
required: ["mission_name", "detail_level"],
},
},
},
];
const completion = await client.chat.completions.create({
model: "moonshotai/Kimi-K2.6",
messages: [
{
role: "user",
content: "Give me the latest status for Artemis II.",
},
],
tools,
tool_choice: "auto",
});
for (const toolCall of completion.choices[0].message.tool_calls || []) {
const functionName = toolCall.function.name;
const args = JSON.parse(toolCall.function.arguments);
console.log("Function called:", functionName);
console.log("Arguments:", toolCall.function.arguments);
console.log("Result:", toolFunctions[functionName](args.mission_name, args.detail_level));
}
curl https://api.inceptron.io/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $INCEPTRON_API_KEY" \
-d '{
"model": "moonshotai/Kimi-K2.6",
"messages": [
{"role": "user", "content": "Give me the latest status for Artemis II."}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_mission_status",
"description": "Get the latest status for a space mission",
"parameters": {
"type": "object",
"properties": {
"mission_name": {
"type": "string",
"description": "The mission name, e.g. '''Artemis II'''"
},
"detail_level": {
"type": "string",
"enum": ["summary", "full"]
}
},
"required": ["mission_name", "detail_level"]
}
}
}
],
"tool_choice": "auto"
}'
tool_choice Options
Use tool_choice to control whether the model can call tools.
| Value | Behavior |
|---|---|
"auto" | The model chooses whether to respond normally or call a tool. |
"required" | The model must call a tool. |
"none" | Tool calling is disabled for that request. |
{"type": "function", "function": {"name": "get_mission_status"}} | Force a specific function call. |
Notes
- The model returns tool call arguments as a JSON string, so parse them with
json.loads(...)before invoking your function. - With streaming enabled, arguments may arrive over multiple chunks, so you should accumulate them before parsing.
- In production, validate tool arguments before executing any side effects.
- After running the tool, you can send the tool result back in a follow-up chat completion request so the model can produce a final user-facing answer.