Tool calling
Type: Recipe
Outcome
Let an agent call a typed function and use its result in a final answer. Choose this pattern when the model needs live application data or a capability that should remain in trusted code.
Prerequisites
- Node.js 22 or newer, pnpm, and a server-side
OPENAI_API_KEY pnpm add @anvia/core @anvia/openai zodpnpm add -D tsx typescript @types/node
Implementation
import { AgentBuilder } from '@anvia/core/agent'
import { createTool } from '@anvia/core/tool'
import { OpenAIClient } from '@anvia/openai'
import { z } from 'zod'
const add = createTool({
name: 'add',
description: 'Add two numbers.',
input: z.object({ x: z.number(), y: z.number() }),
output: z.number(),
execute: ({ x, y }) => x + y,
})
const agent = new AgentBuilder(
'calculator',
new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY }).completionModel('gpt-5'),
)
.instructions('Use the add tool for arithmetic, then explain the result briefly.')
.tools([add])
.defaultMaxTurns(2)
.build()
console.log((await agent.prompt('What is 12 + 30?').send()).output)Run and expected behavior
Save as tool-call.ts, run pnpm tsx tool-call.ts, and expect an answer containing 42. The first model turn can request add; Anvia validates its arguments, runs the handler, returns the validated tool result, and gives the model another turn to answer.
Boundaries
Zod validates shape, not identity, authorization, or business invariants. Enforce those inside the handler using trusted request context. Keep side effects idempotent where possible, set a turn limit, and never expose arbitrary network, filesystem, or database access as a broad tool.
For production, separate tool definitions from service implementations, add audit-safe hooks, map tool failures to safe results, and test the complete call/result/final-answer loop for each model.
Source and extensions
Run the tool-call cookbook. Next, add permissions, approval, or concurrent independent tool calls.