Skip to content

Tools

Use tool(...) to define a callable capability exposed to the model.

const myTool = tool<TContext, TSchema, TOutput>({
name: string,
description: string,
parameters?: z.ZodTypeAny,
execute: (input, runContext?) => TOutput | Promise<TOutput>,
})
import { z } from "zod";
import { tool } from "@axiastudio/aioc";
const getFinanceReport = tool<{ actor: { team: string } }>({
name: "get_finance_report",
description: "Return the current finance report for the requested quarter.",
parameters: z.object({
quarter: z.string(),
}),
execute: async ({ quarter }, runContext) => {
return {
quarter,
requestedBy: runContext?.context.actor.team ?? "unknown",
};
},
});

Optional. When omitted, tool(...) normalizes it to an empty object schema.

The runtime converts it to a JSON schema before sending the tool definition to the provider.

The schema may validate, default, coerce, strip, or transform input, but its output must remain a JSON data tree. Convert strings or numbers into Date, Map, domain classes, or other rich application values inside execute(...).

Receives:

  • an isolated decoded view of the authorized canonical argument snapshot
  • optional RunContext

It may return synchronously or asynchronously.

Must be stable and application-meaningful.

Tool call history, policy decisions, replay utilities, and run-record comparisons all rely on this name.

A tool definition does not mean the tool will execute whenever the model mentions it.

The actual flow is:

  1. provider emits a tool call proposal
  2. aioc decodes and validates the arguments once
  3. runtime creates an RFC 8785 JSON snapshot
  4. policy evaluates an isolated decoded view of that snapshot
  5. only an allowed proposal reaches execute(...), with a new decoded view

This separation is one of the core technical properties of the runtime.