onSwmlRequest

View as MarkdownOpen in Claude

Lifecycle hook called on every incoming SWML request before the SWML document is rendered. The default implementation is a no-op. Override this method in a subclass to inspect or modify agent state before each call is processed.

Common uses include loading caller-specific data from a database, adjusting prompts based on request metadata, or logging request details.

Parameters

rawData
Record<string, unknown>Required

The parsed request body. Contains call metadata such as call_id, caller_id_number, caller_id_name, and any custom SIP headers.

callbackPath
string

Optional callback path from the request body (callback_path field), when the request was triggered via a callback URL.

context
any

The raw Hono request context (c), providing access to headers, query parameters, and the underlying HTTP request.

Returns

Record<string, unknown> | void | Promise<Record<string, unknown> | void> — Return a modifications object to merge into the AI verb config before rendering. global_data is deep-merged; all other keys override AI config fields directly. Return void / undefined to render without modifications.

For most per-request customization scenarios, prefer setDynamicConfigCallback() which provides a higher-level interface with access to query params, body, headers, and an ephemeral agent copy.

Example

import { AgentBase } from '@signalwire/sdk';
class PersonalizedAgent extends AgentBase {
constructor() {
super({ name: 'personalized', route: '/personalized' });
this.setPromptText('You are a helpful assistant.');
}
override async onSwmlRequest(
rawData: Record<string, unknown>,
): Promise<void> {
const callerId = (rawData.caller_id_number as string) ?? 'unknown';
console.log(`Incoming call from ${callerId}`);
this.updateGlobalData({ caller_number: callerId });
}
}
const agent = new PersonalizedAgent();
await agent.serve();