onFunctionCall

View as MarkdownOpen in Claude

Pre-execution hook called before each SWAIG function is executed. The default implementation is a no-op. Override this method in a subclass to intercept tool calls for logging, metrics, or custom dispatch logic.

Return a result object from this hook to short-circuit default execution — the returned value is sent as the function response and the registered tool handler is skipped. Return void / undefined to let the normal dispatch proceed.

Parameters

name
stringRequired

Name of the SWAIG function about to execute.

args
Record<string, unknown>Required

Parsed arguments for the function, conforming to the function’s parameter schema.

rawData
Record<string, unknown>Required

The full raw SWAIG request payload, including metadata such as call_id, caller_id_number, and global_data.

Returns

Record<string, unknown> | void | Promise<Record<string, unknown> | void> — Return a result object to short-circuit default execution; return void / undefined to proceed normally.

Example

import { AgentBase } from '@signalwire/sdk';
class LoggingAgent extends AgentBase {
constructor() {
super({ name: 'logging-agent', route: '/logging' });
this.setPromptText('You are a helpful assistant.');
this.defineTools();
}
protected override defineTools(): void {
this.defineTool({
name: 'lookup_order',
description: 'Look up an order',
parameters: {
type: 'object',
properties: { order_id: { type: 'string' } },
required: ['order_id'],
},
handler: async (args) => {
return { response: `Order ${args.order_id} is in transit.` };
},
});
}
override async onFunctionCall(
name: string,
args: Record<string, unknown>,
rawData: Record<string, unknown>,
): Promise<void> {
const callId = (rawData.call_id as string) ?? 'unknown';
console.log(`[${callId}] Tool called: ${name}(${JSON.stringify(args)})`);
}
}
const agent = new LoggingAgent();
await agent.serve();