Tools and function calling

Tools turn the agent from a talking head into a participant. Define a typed function, hand the schema to Saaya, and the agent will call it during a conversation, to look up an order, charge a card, schedule a follow-up, or route a ticket.

Defining a tool

tool.ts
await saaya.agents.update(agent.id, {
  tools: [
    {
      name: "orders.fetch",
      description: "Look up an order by id. Returns null if not found.",
      input: {
        type: "object",
        required: ["orderId"],
        properties: {
          orderId: { type: "string", pattern: "^ord_[a-zA-Z0-9]+$" },
        },
      },
      output: {
        type: "object",
        properties: {
          id:       { type: "string" },
          status:   { type: "string" },
          total:    { type: "number" },
          daysOld:  { type: "integer" },
        },
      },
      endpoint: { url: "https://api.acme.com/orders/lookup", method: "POST" },
      auth:     { type: "bearer", secretRef: "ACME_API_KEY" },
      timeoutMs: 4000,
    },
  ],
});

How the agent picks a tool

The model sees tool name + description + input schema. The description matters more than you think, write it like a teammate would, including when not to call it ("only call when the user has provided an order id"). Bad descriptions are the single biggest cause of runaway tool calls.

Errors and retries

Tools return one of three shapes: success, retryable error, terminal error. Saaya retries retryable errors up to three times with exponential backoff (250ms, 1s, 4s). Terminal errors surface back to the agent as a message, the model is told the tool failed and asked to recover gracefully.

Idempotency keys

Mutating tools (`payments.refund`, `tickets.create`) must accept an idempotency key. Saaya generates one per tool call and re-sends it on retry, your backend should de-duplicate on it.

Inspecting tool calls

Every tool invocation is recorded on the session, input, output, duration, retries, final status. Open the Session viewer or pull `session.toolCalls` programmatically to debug. Most "the agent did the wrong thing" tickets resolve here in a minute.

Was this page helpful?