Skip to content

Tool calls

Tools use the OpenAI format.

import { FreeTheAI, type ChatMessage, type FunctionTool } from "freetheai";

const tools: FunctionTool[] = [
  {
    type: "function",
    function: {
      name: "get_weather",
      description: "Current weather for a city",
      parameters: {
        type: "object",
        properties: { city: { type: "string" } },
        required: ["city"],
      },
    },
  },
];

const messages: ChatMessage[] = [{ role: "user", content: "Is it raining in Paris?" }];
const first = await client.chat.completions.create({ model: "fta/zai/glm-5.3", messages, tools });
const message = first.choices[0]!.message;
messages.push(message);

for (const call of message.tool_calls ?? []) {
  const args = JSON.parse(call.function.arguments) as { city: string };
  const result = { city: args.city, raining: false }; // call your real function here
  messages.push({ role: "tool", tool_call_id: call.id, content: JSON.stringify(result) });
}

const final = await client.chat.completions.create({ model: "fta/zai/glm-5.3", messages, tools });
console.log(final.choices[0]?.message.content);

When streaming, tool call pieces arrive in delta.tool_calls, keyed by index; non-streamed replies come back already assembled.

Which models take tools

Most models do. If your key is set to tool-capable models only on the API keys page, client.models.list() lists only those.