A tool
A tool is a function the model may ask for. Signal checks what the model sends, runs the function, and hands the result back until the model answers.
pnpm add @niscorp/signal zod openaiThe client
createSignal names a provider and gives you a client. The key is read from GROQ_API_KEY when a call is made, and the model is the provider’s default unless you name one with .model().
import { z } from 'zod';
import { defineTool, createSignal } from '@niscorp/signal';
const signal = createSignal('groq');The tool
A tool has a name, a sentence saying what it does, a schema for its input, and the function. The model is sent the first three.
const seatsLeft = defineTool({
name: 'seatsLeft',
description: 'How many seats are left on a night',
input: z.object({ night: z.string().describe('The night, as YYYY-MM-DD') }),
execute: ({ night }) => ({ night, left: night === '2026-10-24' ? 113 : 120 }),
});A client with the tool
tools gives a client that offers the tool to the model. onToolCall is called before each call, with the name and the arguments the model wrote.
const boxOffice = signal
.tools([seatsLeft])
.onToolCall((name, args) => console.log('asked for', name, args));The call
When the model asks for the tool, Signal checks the arguments against the tool’s schema, runs the function and sends the result back. It goes on until the model answers in words. After twelve calls to the model, ten plus the retries, the call throws.
Arguments that fail the tool’s schema and a function that throws do not end the call. The model is sent the error as the result, and may ask again. meta.toolCalls has each call with what came of it.
const { response, meta } = await boxOffice.complete('How many seats are left on 2026-10-24?');
console.log(response);
for (const call of meta.toolCalls) console.log(call.name, call.args, call.result);Run it.
This file asks a model, so it is not run on this site. It prints asked for seatsLeft { night: '2026-10-24' }, then the model’s sentence with 113 in it, then the call with its arguments and { night: '2026-10-24', left: 113 }.
GROQ_API_KEY=your-key npx tsx seats.mts