twilio-agent-connect 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +63 -1
- package/dist/index.js +125 -57
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../packages/core/src/types/config.ts","../packages/core/src/types/handoff.ts","../packages/core/src/types/conversation.ts","../packages/core/src/types/tac.ts","../packages/core/src/lib/tac-memory-response.ts","../packages/core/src/types/memory.ts","../packages/core/src/types/crelay.ts","../packages/core/src/types/tools.ts","../packages/core/src/types/cintel.ts","../packages/core/src/types/knowledge.ts","../packages/core/src/lib/config.ts","../packages/core/src/util/log-redaction.ts","../packages/core/src/lib/logger.ts","../package.json","../packages/core/src/clients/base.ts","../packages/core/src/clients/memory.ts","../packages/core/src/clients/conversation.ts","../packages/core/src/clients/knowledge.ts","../packages/core/src/lib/operator-result-processor.ts","../packages/core/src/lib/tac.ts","../packages/core/src/channels/base.ts","../packages/core/src/channels/messaging.ts","../packages/core/src/channels/sms.ts","../packages/core/src/channels/rcs.ts","../packages/core/src/channels/whatsapp.ts","../packages/core/src/channels/chat.ts","../packages/core/src/util/handoff-urls.ts","../packages/core/src/channels/voice.ts","../packages/core/src/lib/conversation-session-helpers.ts","../packages/core/src/adapters/options.ts","../packages/core/src/adapters/prompt-builder.ts","../packages/tools/src/lib/builder.ts","../packages/tools/src/built-in/memory.ts","../packages/tools/src/built-in/messaging.ts","../packages/tools/src/built-in/handoff.ts","../packages/tools/src/built-in/knowledge.ts","../packages/server/src/lib/server.ts"],"names":["z","record","axios","session","Twilio"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\n/**\n * Channel types supported by the framework\n */\nexport const ChannelTypeSchema = z.enum(['sms', 'voice', 'chat', 'rcs', 'whatsapp']);\nexport type ChannelType = z.infer<typeof ChannelTypeSchema>;\n\n/**\n * Twilio Memory configuration schema\n */\nexport const TwilioMemoryConfigSchema = z.object({\n traitGroups: z.array(z.string()).optional(),\n observationsLimit: z.number().int().min(0).max(100).default(20),\n summariesLimit: z.number().int().min(0).max(100).default(5),\n // 0 matches the Memory API and Python SDK. Above 0, Memory requires a\n // conversationId on every /Recall, forcing the query expansion that\n // `memoryMode: \"once\"` exists to avoid.\n communicationsLimit: z.number().int().min(0).max(100).default(0),\n relevanceThreshold: z.number().min(0.0).max(1.0).default(0.0),\n /**\n * Trait group name that holds the phone identifier on newly created profiles.\n * Must match the promoted-to-identifier configuration of the Conversation Memory store.\n */\n phoneTraitGroup: z.string().default('Contact'),\n /** Trait field name within `phoneTraitGroup` that holds the phone identifier. */\n phoneTraitField: z.string().default('phone'),\n});\n\nexport type TwilioMemoryConfig = z.infer<typeof TwilioMemoryConfigSchema>;\n\n/**\n * Schema for a voice route path (e.g. voiceWebsocketPath). Trims whitespace,\n * maps an empty string to undefined so the `.default` applies, and requires a\n * leading '/' so path concatenation onto the domain can't produce a malformed\n * URL (e.g. `wss://example.comws`).\n */\nconst voicePathSchema = (defaultPath: string): z.ZodType<string> =>\n z.preprocess(v => {\n if (typeof v !== 'string') return v;\n const trimmed = v.trim();\n return trimmed.length === 0 ? undefined : trimmed;\n }, z.string().startsWith('/', 'Path must start with \"/\"').default(defaultPath));\n\n/** The three Twilio call callbacks TAC serves, one route per kind. */\nexport const CallEventKindSchema = z.enum(['status', 'amd', 'recording']);\n\nexport type CallEventKind = z.infer<typeof CallEventKindSchema>;\n\n/** Iterable form of {@link CallEventKind}, for registering every route. */\nexport const CALL_EVENT_KINDS: readonly CallEventKind[] = CallEventKindSchema.options;\n\n/**\n * TAC configuration schema\n */\nexport const TACConfigSchema = z.object({\n accountSid: z.string().min(1, 'Twilio Account SID is required'),\n authToken: z.string().min(1, 'Twilio Auth Token is required'),\n apiKey: z.string().min(1, 'Twilio API Key is required'),\n apiSecret: z.string().min(1, 'Twilio API Secret is required'),\n phoneNumber: z.string().min(1, 'Twilio Phone Number is required'),\n rcsSenderId: z\n .string()\n .regex(\n /^rcs:.+$/,\n 'RCS sender ID must be in format: rcs:<sender-id-or-phone> (e.g., rcs:brand_acme_agent or rcs:+1234567890)'\n )\n .optional(),\n whatsappNumber: z\n .string()\n .regex(/^whatsapp:\\+\\d+$/, 'WhatsApp number must be in format: whatsapp:+1234567890')\n .optional(),\n memoryConfig: TwilioMemoryConfigSchema.prefault({}),\n conversationConfigurationId: z\n .string()\n .regex(/^conv_configuration_[0-9a-z]{26}$/, 'Invalid Conversation Configuration ID format')\n .optional(),\n /**\n * Public domain where voice routes are reachable, optionally including a port\n * and/or base path (e.g. \"example.ngrok.app\", \"example.ngrok.app:8080\",\n * or \"example.com/server1\"). Used by VoiceChannel to construct the public\n * WebSocket URL and ConversationRelay action URL. Required when using the Voice channel.\n *\n * Whitespace, schemes (https://, wss://), and trailing slashes are stripped\n * automatically; anything else is passed through as given. Mirrors the Python\n * SDK's `_normalize_voice_public_domain` — keep the two in step.\n */\n voicePublicDomain: z\n .preprocess(v => {\n if (typeof v !== 'string') return v;\n let s = v.trim();\n if (s.length === 0) return undefined;\n for (const scheme of ['https://', 'http://', 'wss://', 'ws://']) {\n if (s.toLowerCase().startsWith(scheme)) {\n s = s.slice(scheme.length);\n break;\n }\n }\n s = s.replace(/\\/+$/, '');\n return s.length === 0 ? undefined : s;\n }, z.string().optional())\n .optional(),\n\n /**\n * Path the voice WebSocket is served at. Combined with voicePublicDomain to\n * build the public WebSocket URL the voice channel hands to Twilio in TwiML;\n * TACServer also registers its WebSocket route at this path. Override only if\n * you mount the route at a non-default path. Must start with '/'.\n */\n voiceWebsocketPath: voicePathSchema('/ws'),\n\n /**\n * Path the ConversationRelay action callback is served at. Same role as\n * voiceWebsocketPath but for the `<Connect action=...>` cleanup callback.\n * Must start with '/'.\n */\n voiceActionPath: voicePathSchema('/conversation-relay-callback'),\n\n /**\n * Base path for the call-event callbacks (status, async AMD, recording).\n * TACServer registers one route per callback under it — `<base>/status`,\n * `<base>/amd`, `<base>/recording` — so the route identifies the event. Same\n * role as voiceActionPath. Must start with '/'.\n */\n voiceCallEventPath: voicePathSchema('/twilio/call-events'),\n cintelConfigurationId: z.string().optional(),\n cintelSummaryOperatorSid: z.string().optional(),\n region: z\n .string()\n .max(63, 'Invalid Twilio region format (must be a valid DNS label)')\n .regex(\n /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/,\n 'Invalid Twilio region format (must be a valid DNS label)'\n )\n .optional(),\n /**\n * Twilio Studio Flow SID (FWxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) for handoff.\n * TAC derives both the digital-handoff Studio Executions URL and the voice\n * `<Connect action>` webhook URL from this SID.\n */\n studioHandoffFlowSid: z\n .string()\n .regex(\n /^FW[0-9a-f]{32}$/,\n 'Invalid Studio Flow SID format (expected FW followed by 32 hex chars)'\n )\n .optional(),\n});\n\nexport type TACConfigData = z.infer<typeof TACConfigSchema>;\n\n/**\n * Environment variable mapping for configuration\n */\nexport const EnvironmentVariables = {\n TWILIO_ACCOUNT_SID: 'TWILIO_ACCOUNT_SID',\n TWILIO_AUTH_TOKEN: 'TWILIO_AUTH_TOKEN',\n TWILIO_API_KEY: 'TWILIO_API_KEY',\n TWILIO_API_SECRET: 'TWILIO_API_SECRET',\n TWILIO_PHONE_NUMBER: 'TWILIO_PHONE_NUMBER',\n TWILIO_RCS_SENDER_ID: 'TWILIO_RCS_SENDER_ID',\n TWILIO_WHATSAPP_NUMBER: 'TWILIO_WHATSAPP_NUMBER',\n TWILIO_MEMORY_PROFILE_TRAIT_GROUPS: 'TWILIO_MEMORY_PROFILE_TRAIT_GROUPS',\n TWILIO_MEMORY_OBSERVATIONS_LIMIT: 'TWILIO_MEMORY_OBSERVATIONS_LIMIT',\n TWILIO_MEMORY_SUMMARIES_LIMIT: 'TWILIO_MEMORY_SUMMARIES_LIMIT',\n TWILIO_MEMORY_COMMUNICATIONS_LIMIT: 'TWILIO_MEMORY_COMMUNICATIONS_LIMIT',\n TWILIO_MEMORY_RELEVANCE_THRESHOLD: 'TWILIO_MEMORY_RELEVANCE_THRESHOLD',\n TWILIO_MEMORY_PHONE_TRAIT_GROUP: 'TWILIO_MEMORY_PHONE_TRAIT_GROUP',\n TWILIO_MEMORY_PHONE_TRAIT_FIELD: 'TWILIO_MEMORY_PHONE_TRAIT_FIELD',\n TWILIO_CONVERSATION_CONFIGURATION_ID: 'TWILIO_CONVERSATION_CONFIGURATION_ID',\n TWILIO_VOICE_PUBLIC_DOMAIN: 'TWILIO_VOICE_PUBLIC_DOMAIN',\n TWILIO_VOICE_WEBSOCKET_PATH: 'TWILIO_VOICE_WEBSOCKET_PATH',\n TWILIO_VOICE_ACTION_PATH: 'TWILIO_VOICE_ACTION_PATH',\n TWILIO_VOICE_CALL_EVENT_PATH: 'TWILIO_VOICE_CALL_EVENT_PATH',\n TWILIO_TAC_CI_CONFIGURATION_ID: 'TWILIO_TAC_CI_CONFIGURATION_ID',\n TWILIO_TAC_CI_SUMMARY_OPERATOR_SID: 'TWILIO_TAC_CI_SUMMARY_OPERATOR_SID',\n TWILIO_REGION: 'TWILIO_REGION',\n TWILIO_STUDIO_HANDOFF_FLOW_SID: 'TWILIO_STUDIO_HANDOFF_FLOW_SID',\n} as const;\n","import { z } from 'zod';\n\n/**\n * Structured payload generated during a handoff.\n *\n * Contains conversation context and developer-defined attributes\n * for routing to the target system (e.g., Flex TaskRouter).\n *\n * Serialized with camelCase aliases (conversationId/storeId/profileId)\n * for the Studio Executions wire format.\n */\nexport const HandoffPayloadSchema = z.object({\n conversationId: z.string(),\n storeId: z.string(),\n profileId: z.string(),\n attributes: z.record(z.string(), z.unknown()).default({}),\n});\n\nexport type HandoffPayload = z.infer<typeof HandoffPayloadSchema>;\n\n/**\n * ConversationRelay WebSocket ``end`` message carrying a handoff payload.\n *\n * ``handoffData`` is a JSON *string* (not a nested object) — ConversationRelay\n * forwards it verbatim in the POST body to the ``<Connect action>`` URL.\n */\nexport const PendingHandoffDataSchema = z.object({\n type: z.literal('end').default('end'),\n handoffData: z.string(),\n});\n\nexport type PendingHandoffData = z.infer<typeof PendingHandoffDataSchema>;\n","import { z } from 'zod';\nimport { ChannelTypeSchema } from './config';\nimport { PendingHandoffDataSchema } from './handoff';\nimport type { TACMemoryResponse } from '../lib/tac-memory-response';\n\n/**\n * Participant address type for different communication channels\n */\nexport const ParticipantAddressTypeSchema = z.enum([\n 'VOICE',\n 'SMS',\n 'RCS',\n 'EMAIL',\n 'WHATSAPP',\n 'CHAT',\n 'API',\n 'SYSTEM',\n]);\nexport type ParticipantAddressType = z.infer<typeof ParticipantAddressTypeSchema>;\n\n/**\n * Participant address containing channel and address\n */\nexport const ParticipantAddressSchema = z.object({\n channel: ParticipantAddressTypeSchema,\n address: z.string().min(1, 'Address is required'),\n channelId: z.string().nullable().optional(),\n});\n\nexport type ParticipantAddress = z.infer<typeof ParticipantAddressSchema>;\n\n/**\n * Communication participant for Conversations Service API (Conversation Orchestrator).\n *\n * Note: participantId is required for SDK validation when creating communications.\n */\nexport const CommunicationParticipantSchema = z.object({\n address: z.string().max(254),\n channel: ParticipantAddressTypeSchema,\n participantId: z.string(),\n deliveryStatus: z\n .enum(['INITIATED', 'IN_PROGRESS', 'DELIVERED', 'COMPLETED', 'FAILED'])\n .optional(),\n});\n\nexport type CommunicationParticipant = z.infer<typeof CommunicationParticipantSchema>;\n\n/**\n * Word-level transcription data with timing information.\n */\nexport const TranscriptionWordSchema = z.object({\n text: z.string(),\n startTime: z.string().optional(),\n endTime: z.string().optional(),\n});\n\nexport type TranscriptionWord = z.infer<typeof TranscriptionWordSchema>;\n\n/**\n * Transcription metadata for communication content.\n */\nexport const TranscriptionSchema = z.object({\n channel: z.number().optional(),\n confidence: z.number().min(0).max(1).optional(),\n engine: z.string().optional(),\n words: z.array(TranscriptionWordSchema).optional(),\n});\n\nexport type Transcription = z.infer<typeof TranscriptionSchema>;\n\n/**\n * Communication content (ContentText or ContentTranscription).\n *\n * Note: In the Conversation Orchestrator API, both `type` and `text` are required fields.\n */\nexport const CommunicationContentSchema = z.object({\n type: z.enum(['TEXT', 'TRANSCRIPTION']),\n text: z.string().max(8388608),\n transcription: TranscriptionSchema.optional(),\n});\n\nexport type CommunicationContent = z.infer<typeof CommunicationContentSchema>;\n\n/**\n * Communication from Conversations Service API (Conversation Orchestrator).\n *\n * Note: `createdAt` is optional per API spec.\n */\nexport const CommunicationSchema = z.object({\n id: z.string(),\n conversationId: z.string(),\n accountId: z.string(),\n author: CommunicationParticipantSchema,\n content: CommunicationContentSchema,\n recipients: z.array(CommunicationParticipantSchema),\n channelId: z.string().nullable().optional(),\n createdAt: z.string().nullable().optional(),\n updatedAt: z.string().nullable().optional(),\n occurredAt: z.string().nullable().optional(),\n});\n\nexport type Communication = z.infer<typeof CommunicationSchema>;\n\n/**\n * List communications response\n */\nexport const ListCommunicationsResponseSchema = z.object({\n communications: z.array(CommunicationSchema),\n});\n\nexport type ListCommunicationsResponse = z.infer<typeof ListCommunicationsResponseSchema>;\n\n/**\n * Participant reference for the Actions API (`from`/`to` entries).\n *\n * Either `participantId` or `address` must be supplied; `channel` is always required.\n * When both are provided, Conversation Orchestrator uses `participantId` and\n * `channel` disambiguates which of the participant's addresses to use.\n */\nexport const ActionParticipantRefSchema = z\n .object({\n participantId: z.string().min(1).optional(),\n address: z.string().min(1).max(254).optional(),\n channel: ParticipantAddressTypeSchema,\n })\n .refine(v => Boolean(v.participantId) || Boolean(v.address), {\n message: 'ActionParticipantRef requires at least `participantId` or `address`',\n });\n\nexport type ActionParticipantRef = z.infer<typeof ActionParticipantRefSchema>;\n\n/**\n * Plain-text content for a SEND_MESSAGE action.\n */\nexport const ActionTextContentSchema = z.object({\n text: z.string().max(8388608),\n});\n\nexport type ActionTextContent = z.infer<typeof ActionTextContentSchema>;\n\n/**\n * Channel-specific settings forwarded to the downstream backend.\n *\n * Open pass-through: any field not explicitly modeled here (e.g.\n * `messagingServiceSid`, `statusCallback`, `Attributes`) can be set by callers and\n * will be forwarded as-is.\n */\nexport const ActionChannelSettingsSchema = z.looseObject({\n channelId: z.string().optional(),\n});\n\nexport type ActionChannelSettings = z.infer<typeof ActionChannelSettingsSchema>;\n\n/**\n * Inner payload for a SEND_MESSAGE action.\n */\nexport const SendMessageActionPayloadSchema = z.object({\n from: ActionParticipantRefSchema,\n to: z.array(ActionParticipantRefSchema).min(1),\n content: ActionTextContentSchema,\n channelSettings: ActionChannelSettingsSchema.optional(),\n});\n\nexport type SendMessageActionPayload = z.infer<typeof SendMessageActionPayloadSchema>;\n\n/**\n * Request for POST /v2/Conversations/{id}/Actions with type=SEND_MESSAGE.\n *\n * Body is discriminated by `type` with the action-specific fields under `payload`.\n */\nexport const SendMessageActionRequestSchema = z.object({\n type: z.literal('SEND_MESSAGE').default('SEND_MESSAGE'),\n payload: SendMessageActionPayloadSchema,\n});\n\nexport type SendMessageActionRequest = z.infer<typeof SendMessageActionRequestSchema>;\n\n/**\n * Response from POST /v2/Conversations/{id}/Actions (202 Accepted).\n *\n * Listen for COMMUNICATION_CREATED webhook to get the full Communication.\n */\nexport const ActionResponseSchema = z.object({\n id: z.string(),\n // Kept as string (not enum) to tolerate future action types. Known: SEND_MESSAGE.\n type: z.string(),\n // Kept as string (not enum) to tolerate future statuses. Known: PENDING, COMPLETED, FAILED.\n status: z.string(),\n conversationId: z.string(),\n createdAt: z.string().nullish(),\n});\n\nexport type ActionResponse = z.infer<typeof ActionResponseSchema>;\n\n/**\n * Author information for a conversation session\n */\nexport const AuthorInfoSchema = z.object({\n address: z.string(),\n participantId: z.string().optional(),\n});\n\nexport type AuthorInfo = z.infer<typeof AuthorInfoSchema>;\n\n/**\n * Profile information for a conversation participant\n */\nexport interface Profile {\n profileId: string;\n traits?: Record<string, unknown>;\n}\n\n/**\n * Conversation session context\n */\nexport const ConversationSessionSchema = z.object({\n conversationId: z.string().min(1, 'Conversation ID is required'),\n /**\n * Twilio Call SID on the Voice channel, unset on messaging. The correlation\n * key for call events (`VoiceChannel.onCallStatus` / `onAmd` / `onRecording`)\n * and `endCall`. Equals `conversationId` in relay-only mode; look the session\n * up the other way with `VoiceChannel.getConversationSessionByCallSid`.\n */\n callSid: z.string().optional(),\n profileId: z.string().optional(),\n serviceId: z.string().optional(),\n channel: ChannelTypeSchema,\n startedAt: z.date(),\n authorInfo: AuthorInfoSchema.optional(),\n /**\n * Agent-side participant info stashed by inbound reconciliation or outbound\n * initiation. `sendResponse` reads this to avoid re-listing participants at\n * send time.\n */\n aiAgentInfo: AuthorInfoSchema.optional(),\n profile: z.custom<Profile>().optional(),\n metadata: z.record(z.string(), z.unknown()).optional().default({}),\n /**\n * Pending handoff payload set by the handoff tool. Voice channel sends\n * this as a WS \"end\" message after the LLM's final response.\n */\n pendingHandoffData: PendingHandoffDataSchema.optional(),\n /**\n * Cached memory for \"once\" mode. Set on the first retrieval, cleared when\n * the conversation becomes INACTIVE. Not persisted/serialized.\n */\n cachedMemory: z.custom<TACMemoryResponse>().optional(),\n});\n\nexport type ConversationSession = z.infer<typeof ConversationSessionSchema>;\n\n/**\n * Branded types for type safety\n */\nexport type ConversationId = string & { readonly _brand: 'ConversationId' };\nexport type ProfileId = string & { readonly _brand: 'ProfileId' };\nexport type ParticipantId = string & { readonly _brand: 'ParticipantId' };\n\n/**\n * Type guards for branded types\n */\nexport function isConversationId(value: string): value is ConversationId {\n return value.length > 0;\n}\n\nexport function isProfileId(value: string): value is ProfileId {\n return value.length > 0;\n}\n\nexport function isParticipantId(value: string): value is ParticipantId {\n return value.length > 0;\n}\n\n/**\n * Conversation response from Conversations Service API\n */\nexport const ConversationResponseSchema = z.object({\n id: z.string(),\n accountId: z.string(),\n status: z.string().optional(),\n name: z.string().nullish(), // API returns null when not set\n configurationId: z.string().optional(),\n createdAt: z.string().optional(),\n updatedAt: z.string().optional(),\n});\n\nexport type ConversationResponse = z.infer<typeof ConversationResponseSchema>;\n\n/**\n * List conversations response\n */\nexport const ListConversationsResponseSchema = z.object({\n conversations: z.array(ConversationResponseSchema),\n});\n\nexport type ListConversationsResponse = z.infer<typeof ListConversationsResponseSchema>;\n\n/**\n * Participant address from Conversations Service API (camelCase format)\n */\nexport const ConversationAddressSchema = z.object({\n channel: ParticipantAddressTypeSchema,\n address: z.string(),\n channelId: z.string().nullish(), // API returns null when not set\n});\n\nexport type ConversationAddress = z.infer<typeof ConversationAddressSchema>;\n\n/**\n * Participant response from Conversations Service API\n */\nexport const ConversationParticipantSchema = z.object({\n id: z.string(),\n conversationId: z.string(),\n accountId: z.string(),\n name: z.string().optional(),\n type: z.enum(['HUMAN_AGENT', 'CUSTOMER', 'AI_AGENT', 'AGENT', 'UNKNOWN']).optional(),\n profileId: z.string().nullable().optional(),\n addresses: z.array(ConversationAddressSchema).default([]),\n createdAt: z.string().optional(),\n updatedAt: z.string().optional(),\n});\n\nexport type ConversationParticipant = z.infer<typeof ConversationParticipantSchema>;\n\n/**\n * List participants response\n */\nexport const ListParticipantsResponseSchema = z.object({\n participants: z.array(ConversationParticipantSchema),\n});\n\nexport type ListParticipantsResponse = z.infer<typeof ListParticipantsResponseSchema>;\n\n/**\n * Timeout settings for channel status transitions\n */\nexport const StatusTimeoutsSchema = z.object({\n inactive: z.number().int().gte(1).nullable().optional(),\n closed: z.number().int().gte(1),\n});\n\nexport type StatusTimeouts = z.infer<typeof StatusTimeoutsSchema>;\n\n/**\n * Capture rule with from/to addresses and optional metadata\n */\nexport const CaptureRuleSchema = z.object({\n from: z.string(),\n to: z.string(),\n metadata: z.record(z.string(), z.string()).nullable().optional(),\n});\n\nexport type CaptureRule = z.infer<typeof CaptureRuleSchema>;\n\n/**\n * Configuration settings for a specific channel type\n */\nexport const ChannelSettingsSchema = z.object({\n statusTimeouts: StatusTimeoutsSchema.nullable().optional(),\n captureRules: z.array(CaptureRuleSchema).nullable().optional(),\n});\n\nexport type ChannelSettings = z.infer<typeof ChannelSettingsSchema>;\n\n/**\n * Webhook configuration for status callbacks\n */\nexport const StatusCallbackSchema = z.object({\n url: z.url(),\n method: z.enum(['POST', 'GET', 'PUT', 'DELETE', 'PATCH']).optional().default('POST'),\n});\n\nexport type StatusCallback = z.infer<typeof StatusCallbackSchema>;\n\n/**\n * Conversation grouping type\n *\n * - `GROUP_BY_PROFILE`: Groups communications by participant profile. Communications\n * with the same profile go to the same conversation, regardless of the channel or address.\n * - `GROUP_BY_PARTICIPANT_ADDRESSES`: Groups communications by participant addresses\n * across all channels. A customer using +15551234567 will be in the same conversation\n * whether they contact via SMS, WhatsApp, or RCS.\n * - `GROUP_BY_PARTICIPANT_ADDRESSES_AND_CHANNEL_TYPE`: Groups communications by both\n * participant addresses AND channel. A customer using +15551234567 via SMS will be in\n * a different conversation than the same customer via WhatsApp.\n */\nexport const ConversationGroupingTypeSchema = z.enum([\n 'GROUP_BY_PROFILE',\n 'GROUP_BY_PARTICIPANT_ADDRESSES',\n 'GROUP_BY_PARTICIPANT_ADDRESSES_AND_CHANNEL_TYPE',\n]);\n\nexport type ConversationGroupingType = z.infer<typeof ConversationGroupingTypeSchema>;\n\n/**\n * Configuration settings for a conversation\n */\nexport const ConversationConfigurationSchema = z.object({\n id: z.string(),\n displayName: z\n .string()\n .max(32)\n .regex(/^[a-zA-Z0-9-_ ]+$/)\n .nullable()\n .optional(),\n description: z.string(),\n conversationGroupingType: ConversationGroupingTypeSchema,\n memoryStoreId: z\n .string()\n .regex(/^mem_(store|service)_[0-7][0-9a-z]{25}$/, 'Invalid Memory Store ID format'),\n channelSettings: z.record(z.string(), ChannelSettingsSchema).nullable().optional(),\n statusCallbacks: z.array(StatusCallbackSchema).max(20).nullable().optional(),\n intelligenceConfigurationIds: z.array(z.string()).max(5).nullable().optional(),\n createdAt: z.string().nullable().optional(),\n updatedAt: z.string().nullable().optional(),\n version: z.number().int().nullable().optional(),\n});\n\nexport type ConversationConfiguration = z.infer<typeof ConversationConfigurationSchema>;\n\n// =========================================================================\n// Outbound Conversation Types\n// =========================================================================\n\n/**\n * Options for initiating an outbound SMS conversation.\n *\n * The sender is always TAC's configured `config.phoneNumber`. Multi-sender\n * deployments should run one TAC instance per sender so inbound webhook\n * routing, memory scoping, and configuration stay in sync.\n */\nexport const InitiateMessagingConversationOptionsSchema = z.object({\n to: z.string().min(1, 'Recipient address is required'),\n message: z.string().min(1, 'Initial message is required'),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type InitiateMessagingConversationOptions = z.infer<\n typeof InitiateMessagingConversationOptionsSchema\n>;\n\n/**\n * Result of initiating an outbound conversation\n */\nexport interface InitiateConversationResult {\n conversationId: ConversationId;\n session: ConversationSession;\n}\n\n/**\n * Result of initiating an outbound voice conversation.\n * Note: conversationId is not included because the conversation is created by\n * Conversation Orchestrator during passive hydration — the SDK discovers it by\n * callSid, in the background from WebSocket setup.\n */\nexport interface InitiateVoiceConversationResult {\n callSid: string;\n}\n\n/**\n * Webhook payload structure from Twilio Conversation Orchestrator.\n * This structure is used by all channels (messaging and voice) for webhook events.\n */\nexport interface ConversationWebhookPayload {\n eventType: string;\n timestamp?: string;\n data?: {\n id?: string;\n conversationId?: string;\n accountId?: string;\n serviceId?: string;\n status?: string;\n participantType?: string;\n profileId?: string;\n channelId?: string;\n author?: {\n address?: string;\n channel?: string;\n participantId?: string;\n };\n content?: {\n type?: string;\n text?: string;\n };\n recipients?: Array<{\n address?: string;\n channel?: string;\n participantId?: string;\n deliveryStatus?: string;\n }>;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n","import { z } from 'zod';\nimport { TranscriptionSchema } from './conversation';\n\n/**\n * Channel type for communications\n */\nexport const TACChannelTypeSchema = z.enum([\n 'VOICE',\n 'SMS',\n 'RCS',\n 'EMAIL',\n 'WHATSAPP',\n 'CHAT',\n 'API',\n 'SYSTEM',\n]);\nexport type TACChannelType = z.infer<typeof TACChannelTypeSchema>;\n\n/**\n * Delivery status for communications\n */\nexport const TACDeliveryStatusSchema = z.enum([\n 'INITIATED',\n 'IN_PROGRESS',\n 'DELIVERED',\n 'COMPLETED',\n 'FAILED',\n]);\nexport type TACDeliveryStatus = z.infer<typeof TACDeliveryStatusSchema>;\n\n/**\n * Participant type\n */\nexport const TACParticipantTypeSchema = z.enum(['HUMAN_AGENT', 'CUSTOMER', 'AI_AGENT', 'AGENT']);\nexport type TACParticipantType = z.infer<typeof TACParticipantTypeSchema>;\n\n/**\n * Unified author model with all fields from both Memory and Conversation Orchestrator APIs.\n *\n * Fields not available from a particular API will be undefined.\n */\nexport const TACCommunicationAuthorSchema = z.object({\n // Common fields (both APIs)\n address: z.string(),\n channel: TACChannelTypeSchema,\n\n // Conversation Orchestrator-only fields\n participantId: z.string().optional(),\n deliveryStatus: TACDeliveryStatusSchema.optional(),\n\n // Memory-only fields\n id: z.string().optional(),\n name: z.string().optional(),\n type: TACParticipantTypeSchema.optional(),\n profileId: z.string().nullable().optional(),\n});\n\nexport type TACCommunicationAuthor = z.infer<typeof TACCommunicationAuthorSchema>;\n\n/**\n * Unified content model with all fields from both Memory and Conversation Orchestrator APIs.\n */\nexport const TACCommunicationContentSchema = z.object({\n // Conversation Orchestrator-only: content type discriminator\n type: z.enum(['TEXT', 'TRANSCRIPTION']).optional(),\n // Both APIs: message text (optional in unified model to handle both)\n text: z.string().optional(),\n // Conversation Orchestrator-only: transcription metadata\n transcription: TranscriptionSchema.optional(),\n});\n\nexport type TACCommunicationContent = z.infer<typeof TACCommunicationContentSchema>;\n\n/**\n * Unified communication model with all fields from both Memory and Conversation Orchestrator APIs.\n *\n * Provides complete access to all communication fields regardless of the source.\n * Fields not available from a particular API will be undefined.\n */\nexport const TACCommunicationSchema = z.object({\n // Common fields (both APIs)\n id: z.string(),\n author: TACCommunicationAuthorSchema,\n content: TACCommunicationContentSchema,\n recipients: z.array(TACCommunicationAuthorSchema).default([]),\n channelId: z.string().nullable().optional(),\n createdAt: z.string().optional(),\n updatedAt: z.string().optional(),\n\n // Conversation Orchestrator-only fields\n conversationId: z.string().optional(),\n accountId: z.string().optional(),\n});\n\nexport type TACCommunication = z.infer<typeof TACCommunicationSchema>;\n","import { Communication } from '../types/conversation';\nimport { MemoryRetrievalResponse, ObservationInfo, SummaryInfo } from '../types/memory';\nimport { TACCommunication, TACCommunicationSchema } from '../types/tac';\n\n/**\n * Type guard to check if data is MemoryRetrievalResponse.\n */\nfunction isMemoryRetrievalResponse(\n data: MemoryRetrievalResponse | Communication[]\n): data is MemoryRetrievalResponse {\n return !Array.isArray(data);\n}\n\n/**\n * Unified response wrapper for TAC.retrieveMemory().\n *\n * Provides a consistent interface for accessing memory data regardless of whether\n * Memory API is configured or falling back to Conversation Orchestrator Communications API.\n *\n * Memory configured:\n * - observations, summaries, communications all populated\n * - communications include Memory-specific fields (author id, name, type, profileId)\n *\n * Conversation Orchestrator fallback:\n * - observations and summaries are empty arrays\n * - communications include Conversation Orchestrator-specific fields (conversationId, accountId, etc.)\n */\nexport class TACMemoryResponse {\n private readonly _data: MemoryRetrievalResponse | Communication[];\n private readonly _communications: TACCommunication[];\n\n /**\n * Initialize wrapper with either Memory or Conversation Orchestrator data.\n *\n * @param data - Either MemoryRetrievalResponse (Memory) or Communication[] (Conversation Orchestrator)\n */\n constructor(data: MemoryRetrievalResponse | Communication[]) {\n this._data = data;\n\n if (isMemoryRetrievalResponse(data)) {\n this._communications = (data.communications ?? []).map(comm =>\n TACCommunicationSchema.parse(comm)\n );\n } else {\n this._communications = data.map(comm => TACCommunicationSchema.parse(comm));\n }\n }\n\n /**\n * Get observation memories.\n *\n * @returns List of observations if Memory is configured, empty array for Conversation Orchestrator fallback\n */\n get observations(): ObservationInfo[] {\n if (isMemoryRetrievalResponse(this._data)) {\n return this._data.observations;\n }\n return [];\n }\n\n /**\n * Get summary memories.\n *\n * @returns List of summaries if Memory is configured, empty array for Conversation Orchestrator fallback\n */\n get summaries(): SummaryInfo[] {\n if (isMemoryRetrievalResponse(this._data)) {\n return this._data.summaries;\n }\n return [];\n }\n\n /**\n * Get communications in unified format with all available fields.\n *\n * Communications are converted to a common format during initialization that includes\n * all fields from both Memory and Conversation Orchestrator APIs. Fields not available from a particular\n * API will be undefined.\n *\n * @returns List of unified communications with all available fields\n */\n get communications(): TACCommunication[] {\n return this._communications;\n }\n\n /**\n * Check if Memory API is configured and providing full features.\n *\n * @returns true if Memory is configured (observations/summaries available),\n * false if using Conversation Orchestrator fallback (only communications available)\n */\n get hasMemoryFeatures(): boolean {\n return isMemoryRetrievalResponse(this._data);\n }\n\n /**\n * Access raw underlying data for advanced use cases.\n *\n * Use this when you need access to all fields from the original API responses,\n * not just the unified common fields.\n *\n * @returns Either MemoryRetrievalResponse or Communication[] depending on configuration\n */\n get rawData(): MemoryRetrievalResponse | Communication[] {\n return this._data;\n }\n\n /**\n * Build formatted prompt sections from available memory data.\n *\n * Generates markdown-formatted sections for observations, summaries, and communications\n * that can be injected into LLM prompts. Each section includes a heading and formatted content.\n * Sections with no data are omitted from the result.\n *\n * @returns Array of formatted prompt sections, empty array if no memory data available\n */\n buildMemoryPrompts(): string[] {\n const sections: string[] = [];\n\n const observationsSection = this.buildObservationsPrompt();\n if (observationsSection) {\n sections.push(observationsSection);\n }\n\n const summariesSection = this.buildSummariesPrompt();\n if (summariesSection) {\n sections.push(summariesSection);\n }\n\n const communicationsSection = this.buildCommunicationsPrompt();\n if (communicationsSection) {\n sections.push(communicationsSection);\n }\n\n return sections;\n }\n\n private buildObservationsPrompt(): string | null {\n if (this.observations.length === 0) {\n return null;\n }\n\n const lines = [\n '## Key Observations',\n 'Important notes about the customer from previous interactions:',\n ];\n\n for (const obs of this.observations) {\n lines.push(`- ${obs.content}`);\n }\n\n return lines.join('\\n');\n }\n\n private buildSummariesPrompt(): string | null {\n if (this.summaries.length === 0) {\n return null;\n }\n\n const lines = [\n '## Past Conversation Summaries',\n 'Summaries of previous conversations with this customer:',\n ];\n\n for (const summary of this.summaries) {\n lines.push(`- ${summary.content}`);\n }\n\n return lines.join('\\n');\n }\n\n private buildCommunicationsPrompt(): string | null {\n if (this.communications.length === 0) {\n return null;\n }\n\n const lines = ['## Recent Message History', 'Recent messages exchanged with this customer:'];\n\n for (const comm of this.communications) {\n const content = comm.content?.text;\n if (typeof content !== 'string' || content.trim().length === 0) {\n continue;\n }\n // Determine role - defaults to \"Assistant\" for undefined or non-CUSTOMER authors\n const role = comm.author?.type === 'CUSTOMER' ? 'User' : 'Assistant';\n lines.push(`${role}: ${content}`);\n }\n\n return lines.length > 2 ? lines.join('\\n') : null;\n }\n}\n","import { z } from 'zod';\n\n/**\n * Memory retrieval mode for channels.\n *\n * - \"always\": Fetch memory with the message as query on every inbound message.\n * - \"once\": Fetch memory once at conversation start with no query (and no\n * conversation id, skipping query expansion) and cache it. The cache is\n * invalidated when the conversation becomes INACTIVE.\n * - \"never\": Never automatically fetch memory (default).\n */\nexport const MemoryModeSchema = z.enum(['always', 'never', 'once']);\nexport type MemoryMode = z.infer<typeof MemoryModeSchema>;\n\n/**\n * Message direction in a conversation\n */\nexport const MessageDirectionSchema = z.enum(['inbound', 'outbound']);\nexport type MessageDirection = z.infer<typeof MessageDirectionSchema>;\n\n/**\n * Channel type for Memory communications\n */\nexport const MemoryChannelTypeSchema = z.enum([\n 'VOICE',\n 'SMS',\n 'RCS',\n 'EMAIL',\n 'WHATSAPP',\n 'CHAT',\n 'API',\n 'SYSTEM',\n]);\nexport type MemoryChannelType = z.infer<typeof MemoryChannelTypeSchema>;\n\n/**\n * Participant type in Memory API\n */\nexport const MemoryParticipantTypeSchema = z.enum([\n 'HUMAN_AGENT',\n 'CUSTOMER',\n 'AI_AGENT',\n 'AGENT',\n 'UNKNOWN',\n]);\nexport type MemoryParticipantType = z.infer<typeof MemoryParticipantTypeSchema>;\n\n/**\n * Delivery status for Memory communications\n */\nexport const MemoryDeliveryStatusSchema = z.enum([\n 'INITIATED',\n 'IN_PROGRESS',\n 'DELIVERED',\n 'COMPLETED',\n 'FAILED',\n]);\nexport type MemoryDeliveryStatus = z.infer<typeof MemoryDeliveryStatusSchema>;\n\n/**\n * Participant in a Memory communication (author or recipient).\n *\n * Memory API has different field requirements than Conversation Orchestrator:\n * - Uses `id` and `name` instead of just `participant_id`\n * - Includes `type` and `profileId` fields\n */\nexport const MemoryParticipantSchema = z.object({\n id: z.string(),\n name: z.string().max(256),\n address: z.string().max(254),\n channel: MemoryChannelTypeSchema,\n type: MemoryParticipantTypeSchema.optional(),\n profileId: z.string().nullable().optional(),\n deliveryStatus: MemoryDeliveryStatusSchema.optional(),\n});\n\nexport type MemoryParticipant = z.infer<typeof MemoryParticipantSchema>;\n\n/**\n * Content of a Memory communication.\n *\n * Memory API content is simpler than Conversation Orchestrator - no type discriminator field.\n * The `text` field is optional in Memory API models.\n */\nexport const MemoryCommunicationContentSchema = z.object({\n text: z.string().max(8388608).optional(),\n});\n\nexport type MemoryCommunicationContent = z.infer<typeof MemoryCommunicationContentSchema>;\n\n/**\n * A communication from Memory API (historical conversation data).\n *\n * Memory API has different field requirements than Conversation Orchestrator:\n * - No `conversationId`, `accountId`, or `content.type` fields\n * - Participants use `id`, `name`, `type`, `profileId`\n */\nexport const MemoryCommunicationSchema = z.object({\n id: z.string(),\n author: MemoryParticipantSchema,\n content: MemoryCommunicationContentSchema,\n recipients: z.array(MemoryParticipantSchema).max(100),\n channelId: z.string().max(256).nullable().optional(),\n createdAt: z.string(),\n updatedAt: z.string().optional(),\n});\n\nexport type MemoryCommunication = z.infer<typeof MemoryCommunicationSchema>;\n\n/**\n * Individual session message\n */\nexport const SessionMessageSchema = z.object({\n direction: MessageDirectionSchema,\n channel: z.string(),\n from_address: z.string().optional(),\n to_address: z.string().optional(),\n content: z.string(),\n timestamp: z.iso.datetime(),\n});\n\nexport type SessionMessage = z.infer<typeof SessionMessageSchema>;\n\n/**\n * Session information containing conversation history\n */\nexport const SessionInfoSchema = z.object({\n session_id: z.string(),\n started_at: z.iso.datetime(),\n ended_at: z.iso.datetime().optional(),\n channel: z.string(),\n messages: z.array(SessionMessageSchema),\n});\n\nexport type SessionInfo = z.infer<typeof SessionInfoSchema>;\n\n/**\n * Individual observation extracted from conversations\n */\nexport const ObservationInfoSchema = z.object({\n id: z.string(),\n content: z.string(),\n createdAt: z.iso.datetime(),\n occurredAt: z.iso.datetime().optional(),\n updatedAt: z.iso.datetime().optional(),\n conversationIds: z.array(z.string()).nullable().optional(),\n source: z.string().optional(),\n});\n\nexport type ObservationInfo = z.infer<typeof ObservationInfoSchema>;\n\n/**\n * Conversation summary information\n */\nexport const SummaryInfoSchema = z.object({\n id: z.string(),\n content: z.string(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime().optional(),\n conversationIds: z.array(z.string()).optional(),\n});\n\nexport type SummaryInfo = z.infer<typeof SummaryInfoSchema>;\n\n/**\n * Memory retrieval request parameters.\n *\n * Defaults match the Memory API server defaults. The SDK-level defaults in\n * TwilioMemoryConfigSchema may differ (e.g. communicationsLimit defaults to 10\n * in the SDK config for a better out-of-box experience, vs 0 on the API).\n */\nexport const MemoryRetrievalRequestSchema = z.object({\n conversationId: z.string().optional(),\n query: z.string().optional(),\n beginDate: z.iso.datetime().optional(),\n endDate: z.iso.datetime().optional(),\n observationsLimit: z.number().int().min(0).max(100).optional(),\n summariesLimit: z.number().int().min(0).max(100).optional(),\n communicationsLimit: z.number().int().min(0).max(100).optional(),\n relevanceThreshold: z.number().min(0.0).max(1.0).optional(),\n});\n\nexport type MemoryRetrievalRequest = z.infer<typeof MemoryRetrievalRequestSchema>;\n\n/**\n * Memory retrieval response from the Memory API /Recall endpoint.\n *\n * Contains observations, summaries, and communications from Memory API.\n */\nexport const MemoryRetrievalResponseSchema = z.object({\n observations: z.array(ObservationInfoSchema),\n summaries: z.array(SummaryInfoSchema),\n communications: z.array(MemoryCommunicationSchema).optional().default([]),\n meta: z\n .object({\n queryTime: z.number().optional(),\n })\n .optional(),\n});\n\nexport type MemoryRetrievalResponse = z.infer<typeof MemoryRetrievalResponseSchema>;\n\n/**\n * Profile lookup response\n */\nexport const ProfileLookupResponseSchema = z.object({\n normalizedValue: z.string().max(255),\n profiles: z\n .array(z.string())\n .max(100)\n .nullable()\n .transform(v => v ?? []),\n});\n\nexport type ProfileLookupResponse = z.infer<typeof ProfileLookupResponseSchema>;\n\n/**\n * Profile response with traits\n */\nexport const ProfileResponseSchema = z.object({\n id: z.string(),\n createdAt: z.string(),\n traits: z.record(z.string(), z.unknown()),\n});\n\nexport type ProfileResponse = z.infer<typeof ProfileResponseSchema>;\n\n/**\n * Empty memory response for error fallback\n */\nexport const EMPTY_MEMORY_RESPONSE: MemoryRetrievalResponse = {\n observations: [],\n summaries: [],\n communications: [],\n};\n\n/**\n * A single observation in a create request.\n *\n * `occurredAt` is required by the Memory API and formatted as ISO 8601.\n */\nexport const ObservationCreateRequestSchema = z.object({\n content: z.string(),\n source: z.string(),\n occurredAt: z.string(),\n conversationIds: z.array(z.string()).optional(),\n});\n\nexport type ObservationCreateRequest = z.infer<typeof ObservationCreateRequestSchema>;\n\n/**\n * Request body for the Memory API Observations endpoint.\n *\n * The endpoint is a batch create that wraps observations in an array.\n */\nexport const CreateObservationsRequestSchema = z.object({\n observations: z.array(ObservationCreateRequestSchema),\n});\n\nexport type CreateObservationsRequest = z.infer<typeof CreateObservationsRequestSchema>;\n\n/**\n * Response from creating an observation.\n *\n * The Memory API Observations endpoint is a batch create that returns a\n * confirmation message rather than the persisted observation.\n */\nexport const CreateObservationResponseSchema = z.object({\n message: z.string(),\n});\n\nexport type CreateObservationResponse = z.infer<typeof CreateObservationResponseSchema>;\n\n/**\n * Response from creating conversation summaries\n */\nexport const CreateConversationSummariesResponseSchema = z.object({\n message: z.string(),\n});\n\nexport type CreateConversationSummariesResponse = z.infer<\n typeof CreateConversationSummariesResponseSchema\n>;\n","import { z } from 'zod';\nimport type VoiceResponse from 'twilio/lib/twiml/VoiceResponse.js';\nimport type { CallListInstanceCreateOptions } from 'twilio/lib/rest/api/v2010/account/call.js';\n\n/**\n * ConversationRelay API Types\n *\n * Zod schemas are the single source of truth for runtime validation. Types are\n * inferred from schemas via z.infer. Compile-time drift guards (type assertions\n * against VoiceResponse.ConversationRelayAttributes / LanguageAttributes) ensure\n * that if the Twilio SDK types change, `npm run typecheck` will fail immediately.\n *\n * @see https://www.twilio.com/docs/voice/conversationrelay\n * @see https://www.twilio.com/docs/voice/conversationrelay/conversationrelay-noun\n */\n\n/**\n * Language configuration for multi-language ConversationRelay support\n * @see https://www.twilio.com/docs/voice/conversationrelay/conversationrelay-noun#language-attributes\n */\nexport const LanguageAttributesSchema = z.object({\n /** Language code (e.g., 'en-US', 'es-ES', 'en-AU') */\n code: z.string(),\n /** TTS provider for this language */\n ttsProvider: z.string().optional(),\n /** TTS voice for this language */\n voice: z.string().optional(),\n /** TTS language (may differ from code) */\n ttsLanguage: z.string().optional(),\n /** Transcription provider for this language */\n transcriptionProvider: z.string().optional(),\n /** Speech model for transcription */\n speechModel: z.string().optional(),\n /** Transcription language (may differ from code) */\n transcriptionLanguage: z.string().optional(),\n});\n\nexport type LanguageAttributes = z.infer<typeof LanguageAttributesSchema>;\n\n/**\n * ConversationRelay attributes for TwiML configuration\n * @see https://www.twilio.com/docs/voice/conversationrelay/conversationrelay-noun\n */\nexport const ConversationRelayAttributesSchema = z.object({\n /** WebSocket URL for ConversationRelay (required) */\n url: z.url(),\n\n // Welcome greeting settings\n /** Initial greeting to play when call connects */\n welcomeGreeting: z.string().optional(),\n /** Whether welcome greeting can be interrupted */\n welcomeGreetingInterruptible: z.enum(['any', 'speech', 'none']).optional(),\n\n // Transcription settings\n /** Transcription provider (e.g., 'Deepgram', 'Google') */\n transcriptionProvider: z.string().optional(),\n /** Language for transcription (e.g., 'en-US') */\n transcriptionLanguage: z.string().optional(),\n /** Speech model for transcription (e.g., 'nova-3-general') */\n speechModel: z.string().optional(),\n\n // TTS settings\n /** Text-to-speech provider (e.g., 'Google', 'ElevenLabs') */\n ttsProvider: z.string().optional(),\n /** Language for TTS (e.g., 'en-US') */\n ttsLanguage: z.string().optional(),\n /** Voice identifier for TTS (e.g., 'en-US-Journey-O') */\n voice: z.string().optional(),\n /** ElevenLabs text normalization setting */\n elevenlabsTextNormalization: z.string().optional(),\n\n // Interaction settings\n /** When agent speech can be interrupted */\n interruptible: z.enum(['any', 'speech', 'none']).optional(),\n /** Interrupt detection sensitivity */\n interruptSensitivity: z.enum(['low', 'medium', 'high']).optional(),\n /** Enable DTMF tone detection */\n dtmfDetection: z.boolean().optional(),\n /** Recognition hints for domain-specific vocabulary */\n hints: z.string().optional(),\n /** Whether prompts should be reported when TTS is playing and interrupt is disabled */\n reportInputDuringAgentSpeech: z.boolean().optional(),\n\n // Advanced settings\n /** Enable partial prompts (streaming) */\n partialPrompts: z.boolean().optional(),\n /** Enable profanity filtering */\n profanityFilter: z.boolean().optional(),\n /** Allow preemption of agent speech */\n preemptible: z.boolean().optional(),\n /** Default language code */\n language: z.string().optional(),\n /** Debug options for troubleshooting (string per SDK, not boolean) */\n debug: z.string().optional(),\n\n // Intelligence service\n /** Conversational Intelligence Service ID or unique name */\n intelligenceService: z.string().optional(),\n\n // Conversation orchestrator\n /** Twilio Conversation Orchestrator configuration ID */\n conversationConfiguration: z.string().optional(),\n});\n\nexport type ConversationRelayAttributes = z.infer<typeof ConversationRelayAttributesSchema>;\n\n/**\n * @internal Compile-time SDK drift guards — do not use directly.\n * If the Twilio SDK updates VoiceResponse.ConversationRelayAttributes or\n * VoiceResponse.LanguageAttributes, these checks will fail during typecheck,\n * signaling that our Zod schemas need to be updated to match.\n */\nexport type _SDKDriftGuards = {\n langCompat: LanguageAttributes extends VoiceResponse.LanguageAttributes ? true : never;\n langKeys: keyof VoiceResponse.LanguageAttributes extends keyof LanguageAttributes ? true : never;\n crelayCompat: ConversationRelayAttributes extends VoiceResponse.ConversationRelayAttributes\n ? true\n : never;\n crelayKeys: keyof VoiceResponse.ConversationRelayAttributes extends keyof ConversationRelayAttributes\n ? true\n : never;\n};\n\n/**\n * Custom parameters passed via TwiML\n * Can contain any key-value pairs with unknown values\n */\nexport const CustomParametersSchema = z.record(z.string(), z.unknown());\n\nexport type CustomParameters = z.infer<typeof CustomParametersSchema>;\n\n/**\n * WebSocket setup message from ConversationRelay\n */\nexport const SetupMessageSchema = z.object({\n type: z.literal('setup'),\n sessionId: z.string(),\n callSid: z.string(),\n parentCallSid: z.string().optional(),\n from: z.string(),\n to: z.string(),\n forwardedFrom: z.string().optional(),\n callerName: z.string().optional(),\n direction: z.string(),\n callType: z.string(),\n callStatus: z.string(),\n accountSid: z.string(),\n customParameters: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type SetupMessage = z.infer<typeof SetupMessageSchema>;\n\n/**\n * WebSocket prompt message (user speech)\n */\nexport const PromptMessageSchema = z.object({\n type: z.literal('prompt'),\n voicePrompt: z.string(),\n lang: z.string().optional(),\n last: z.boolean().optional(),\n agentSpeaking: z.string().optional(),\n});\n\nexport type PromptMessage = z.infer<typeof PromptMessageSchema>;\n\n/**\n * WebSocket interrupt message (user interruption)\n */\nexport const InterruptMessageSchema = z.object({\n type: z.literal('interrupt'),\n utteranceUntilInterrupt: z.string().optional(),\n durationUntilInterruptMs: z.number().int().nonnegative().optional(),\n});\n\nexport type InterruptMessage = z.infer<typeof InterruptMessageSchema>;\n\n/**\n * Union of all WebSocket message types\n */\nexport const WebSocketMessageSchema = z.union([\n SetupMessageSchema,\n PromptMessageSchema,\n InterruptMessageSchema,\n]);\n\nexport type WebSocketMessage = z.infer<typeof WebSocketMessageSchema>;\n\n/**\n * Text Token Message to send back via WebSocket\n * @see https://www.twilio.com/docs/voice/conversationrelay/websocket-messages#text-tokens-message\n */\nexport const TextTokenMessageSchema = z.object({\n type: z.literal('text'),\n token: z.string(),\n last: z.boolean().optional().default(true),\n});\n\nexport type TextTokenMessage = z.infer<typeof TextTokenMessageSchema>;\n\n/**\n * Extended ConversationRelay configuration that includes child elements.\n * Includes all ConversationRelayAttributes fields plus support for languages array.\n *\n * Note: The type is defined as an explicit interface and the schema is annotated\n * with z.ZodType<ConversationRelayConfig> to prevent TypeScript's type inference\n * from collapsing to `any` when resolving complex Zod generics with many optional\n * fields (especially under exactOptionalPropertyTypes).\n */\nexport interface ConversationRelayConfig extends ConversationRelayAttributes {\n /** Optional language configurations as child <Language> elements */\n languages?: LanguageAttributes[] | undefined;\n}\n\nexport const ConversationRelayConfigSchema: z.ZodType<ConversationRelayConfig> =\n ConversationRelayAttributesSchema.extend({\n /** Optional language configurations as child <Language> elements */\n languages: z.array(LanguageAttributesSchema).optional(),\n });\n\n// =========================================================================\n// TwiML customization layer\n// =========================================================================\n\n/**\n * Twilio uses the same four-value enum for several attributes that control\n * what caller input (DTMF, speech, both, neither) triggers a given behavior.\n */\nexport const InterruptModeSchema = z.enum(['none', 'dtmf', 'speech', 'any']);\nexport type InterruptMode = z.infer<typeof InterruptModeSchema>;\n\n/**\n * A single `<Language>` child for multi-language ConversationRelay setups.\n *\n * Maps to the `<Language>` element documented at\n * https://www.twilio.com/docs/voice/twiml/connect/conversationrelay#language-element\n *\n * Distinct from {@link LanguageAttributes} (the Twilio-SDK-shaped type used by\n * `connectConversationRelay`): this is the customization-facing model used in\n * {@link TwiMLOptions}, mirroring the Python SDK's `LanguageConfig`.\n */\nexport const LanguageConfigSchema = z.object({\n /**\n * Language code, e.g. 'es-MX'. Can be 'multi' for automatic language\n * detection (requires ElevenLabs TTS and Deepgram STT).\n */\n code: z.string(),\n /** TTS voice name for this language */\n voice: z.string().optional(),\n /** TTS provider, e.g. 'google' */\n ttsProvider: z.string().optional(),\n /** Transcription provider, e.g. 'deepgram' */\n transcriptionProvider: z.string().optional(),\n /** Speech model for STT. Choices vary by transcriptionProvider. */\n speechModel: z.string().optional(),\n});\n\nexport type LanguageConfig = z.infer<typeof LanguageConfigSchema>;\n\n/**\n * Options for the TwiML inside `<ConversationRelay>` (plus the\n * `<Connect action>` URL).\n *\n * Fields map to the attributes documented at\n * https://www.twilio.com/docs/voice/twiml/connect/conversationrelay . All\n * fields are optional. `VoiceChannel.handleIncomingCall` merges these values\n * over TAC defaults per-field — only fields explicitly present on the object\n * override lower layers (see `VoiceChannel`'s overlay logic).\n *\n * This is the customization-facing counterpart to {@link ConversationRelayConfig}\n * (which is the Twilio-SDK-shaped emit model and carries the required `url`).\n * Mirrors the Python SDK's `TwiMLOptions`.\n */\nexport const TwiMLOptionsSchema = z\n .object({\n /** Custom parameters to pass to ConversationRelay as `<Parameter>` children */\n customParameters: CustomParametersSchema.optional(),\n /** Initial greeting message for the caller */\n welcomeGreeting: z.string().optional(),\n /**\n * What caller input can interrupt the welcome greeting.\n * Defaults to 'any' on Twilio.\n */\n welcomeGreetingInterruptible: InterruptModeSchema.optional(),\n /**\n * URL for Twilio to request when the call ends (`<Connect action>`). Set to\n * a non-empty URL, or leave unset. An explicit `undefined` suppresses the\n * action entirely (see `VoiceChannel`'s actionUrl resolution); an empty\n * string is rejected so it can't silently drop the action.\n */\n actionUrl: z.string().min(1, 'actionUrl must not be empty').optional(),\n /**\n * Conversation Service SID. When set, ConversationRelay will manage\n * conversation creation and participants.\n */\n conversationConfiguration: z.string().optional(),\n /**\n * ConversationRelay WebSocket URL (the `<ConversationRelay url=...>`\n * attribute). Leave unset (the default) to use the URL the channel derives\n * from `TACConfig.voicePublicDomain` + `voiceWebsocketPath`. Set it only for\n * a per-call URL — e.g. an affinity-routed host that appends a token to the\n * upgrade URL — typically from an `onInboundCallTwiml` customizer. Layers\n * per-field like every other field. Must be non-empty when set.\n */\n websocketUrl: z.string().min(1, 'websocketUrl must not be empty').optional(),\n\n // Language, TTS, STT\n /**\n * Language for both STT and TTS, e.g. 'en-US'. Equivalent to setting both\n * ttsLanguage and transcriptionLanguage.\n */\n language: z.string().optional(),\n /** TTS language code; overrides `language` for TTS. */\n ttsLanguage: z.string().optional(),\n /**\n * STT language code; overrides `language` for transcription. Can be\n * 'multi' for automatic language detection (Deepgram only).\n */\n transcriptionLanguage: z.string().optional(),\n /** TTS voice name (choices vary by ttsProvider) */\n voice: z.string().optional(),\n /** TTS provider: 'Google', 'Amazon', or 'ElevenLabs'. Defaults to 'ElevenLabs'. */\n ttsProvider: z.string().optional(),\n /**\n * STT provider: 'Google' or 'Deepgram'. Defaults to 'Deepgram' (or 'Google'\n * for accounts that used ConversationRelay before 2025-09-12).\n */\n transcriptionProvider: z.string().optional(),\n /** Speech model for STT. Choices vary by transcriptionProvider. */\n speechModel: z.string().optional(),\n /**\n * Text normalization for ElevenLabs TTS. Defaults to 'off'. 'auto' behaves\n * like 'off' for ConversationRelay calls.\n */\n elevenlabsTextNormalization: z.enum(['on', 'auto', 'off']).optional(),\n\n // Turn detection / interruption\n /**\n * Confidence required to finish a turn. Only applies with Deepgram + flux\n * speech model. Twilio enforces the accepted range — see ConversationRelay docs.\n */\n eotThreshold: z.number().optional(),\n /**\n * Send unfinalized prompts and eager end-of-turn events (last=false). Only\n * applies with Deepgram + flux speech model.\n */\n partialPrompts: z.boolean().optional(),\n /**\n * Use Deepgram Smart Format for transcription output. Defaults to true when\n * transcriptionProvider='Deepgram'.\n */\n deepgramSmartFormat: z.boolean().optional(),\n /**\n * Silence (ms) after speech before finalizing the prompt. Integer\n * milliseconds or the literal 'auto' (the platform default). Twilio enforces\n * the accepted range — see ConversationRelay docs.\n */\n speechTimeout: z.union([z.number().int(), z.literal('auto')]).optional(),\n /**\n * What caller input interrupts TTS playback. Boolean accepted for backward\n * compat: true='any', false='none'. Defaults to 'any'.\n */\n interruptible: z.union([InterruptModeSchema, z.boolean()]).optional(),\n /** How easily caller speech triggers an interrupt. Defaults to 'high'. */\n interruptSensitivity: z.enum(['high', 'medium', 'low']).optional(),\n /**\n * What caller input gets reported while the agent is speaking (independent\n * of whether playback is interrupted). Defaults to 'none' since May 2025.\n */\n reportInputDuringAgentSpeech: InterruptModeSchema.optional(),\n /**\n * Filter short conversational feedback ('yeah', 'uh-huh', …) so it doesn't\n * interrupt the agent. Defaults to false.\n */\n ignoreBackchannel: z.boolean().optional(),\n /**\n * Allow text tokens from the next talk cycle to interrupt the current one.\n * Defaults to false.\n */\n preemptible: z.boolean().optional(),\n /** Emit DTMF keypress events over the WebSocket. */\n dtmfDetection: z.boolean().optional(),\n\n // Recognition hints / events / debug / intelligence\n /**\n * Comma-separated words/phrases likely to appear in speech. Capitalize\n * proper nouns.\n */\n hints: z.string().optional(),\n /** Space-separated event subscriptions, e.g. 'speaker-events tokens-played'. */\n events: z.string().optional(),\n /**\n * Debug subscription, e.g. 'debugging'. Note: 'speaker-events' and\n * 'tokens-played' have moved to the `events` attribute — only use them here\n * for backward compatibility.\n */\n debug: z.string().optional(),\n /**\n * Conversation Intelligence (classic) Service SID or unique name for\n * persisting transcripts and running Language Operators.\n */\n intelligenceService: z.string().optional(),\n\n // Nested <Language> children\n /** Additional `<Language>` children for multi-language support */\n languages: z.array(LanguageConfigSchema).optional(),\n\n /**\n * Escape hatch for ConversationRelay attributes not yet typed on this model.\n * Keys are emitted as-is on `<ConversationRelay>`; Twilio's SDK converts\n * snake_case to camelCase, lowercases bools to 'true'/'false', and\n * stringifies numbers. Prefer a typed field when one exists — use `extra`\n * only for newly-added Twilio attributes not yet in this SDK.\n */\n extra: z.record(z.string(), z.union([z.string(), z.boolean(), z.number()])).optional(),\n })\n // Forbid unknown keys so a typo in a field name fails loudly rather than\n // being silently dropped from the emitted TwiML.\n .strict()\n // Fail fast when `extra` includes a key that has a typed field on this model.\n // Without this, the user's value would be silently dropped by the TwiML\n // serializer in favor of the typed default — a footgun.\n .superRefine((value, ctx) => {\n if (!value.extra) return;\n const typed = new Set(Object.keys(TwiMLOptionsShape).filter(k => k !== 'extra'));\n const shadowed = Object.keys(value.extra)\n .filter(k => typed.has(k))\n .sort();\n if (shadowed.length > 0) {\n ctx.addIssue({\n code: 'custom',\n path: ['extra'],\n message:\n `TwiMLOptions.extra keys [${shadowed.join(', ')}] shadow typed fields. ` +\n 'Set the typed field directly instead of using `extra`.',\n });\n }\n });\n\n/**\n * @internal Field names of {@link TwiMLOptionsSchema}, used by the shadow-guard\n * refinement above. Declared separately because `.strict().superRefine(...)`\n * erases the object shape on the schema instance.\n */\nconst TwiMLOptionsShape = {\n customParameters: true,\n welcomeGreeting: true,\n welcomeGreetingInterruptible: true,\n actionUrl: true,\n conversationConfiguration: true,\n websocketUrl: true,\n language: true,\n ttsLanguage: true,\n transcriptionLanguage: true,\n voice: true,\n ttsProvider: true,\n transcriptionProvider: true,\n speechModel: true,\n elevenlabsTextNormalization: true,\n eotThreshold: true,\n partialPrompts: true,\n deepgramSmartFormat: true,\n speechTimeout: true,\n interruptible: true,\n interruptSensitivity: true,\n reportInputDuringAgentSpeech: true,\n ignoreBackchannel: true,\n preemptible: true,\n dtmfDetection: true,\n hints: true,\n events: true,\n debug: true,\n intelligenceService: true,\n languages: true,\n extra: true,\n} as const;\n\nexport type TwiMLOptions = z.infer<typeof TwiMLOptionsSchema>;\n\n/**\n * Framework-neutral view of the Twilio TwiML webhook form.\n *\n * Populated by `TACServer` from the incoming Twilio webhook, then passed to a\n * customizer registered via `VoiceChannel.onInboundCallTwiml(...)` so the\n * application can produce per-call {@link TwiMLOptions} overrides without\n * depending on Fastify types. Mirrors the Python SDK's `TwiMLRequest`.\n */\nexport const TwiMLRequestSchema = z.object({\n from: z.string().optional(),\n to: z.string().optional(),\n callSid: z.string().optional(),\n callerCountry: z.string().optional(),\n callerState: z.string().optional(),\n callerCity: z.string().optional(),\n direction: z.string().optional(),\n /**\n * Any other fields from the Twilio webhook not captured above. Values are\n * always strings here (webhook form fields are url-encoded), unlike\n * TwiMLOptions.extra which accepts string | boolean | number for emitted\n * TwiML attributes.\n */\n extra: z.record(z.string(), z.string()).default({}),\n});\n\nexport type TwiMLRequest = z.infer<typeof TwiMLRequestSchema>;\n\n/**\n * Map from Twilio webhook form field names to {@link TwiMLRequest} keys.\n * Fields not in this map are bucketed into `extra` by {@link twiMLRequestFromForm}.\n */\nconst TWIML_REQUEST_FORM_ALIASES: Record<string, keyof Omit<TwiMLRequest, 'extra'>> = {\n From: 'from',\n To: 'to',\n CallSid: 'callSid',\n CallerCountry: 'callerCountry',\n CallerState: 'callerState',\n CallerCity: 'callerCity',\n Direction: 'direction',\n};\n\n/**\n * Build a {@link TwiMLRequest} from a raw Twilio form dict, bucketing unknown\n * keys into `extra`. Mirrors the Python SDK's `TwiMLRequest.from_form`.\n */\nexport function twiMLRequestFromForm(form: Record<string, string>): TwiMLRequest {\n const known: Record<string, string> = {};\n const extra: Record<string, string> = {};\n for (const [key, value] of Object.entries(form)) {\n const alias = TWIML_REQUEST_FORM_ALIASES[key];\n if (alias) {\n known[alias] = value;\n } else {\n extra[key] = value;\n }\n }\n return TwiMLRequestSchema.parse({ ...known, extra });\n}\n\n/**\n * Voice channel specific events\n */\nexport interface VoiceChannelEvents {\n setup: SetupMessage;\n prompt: PromptMessage;\n interrupt: InterruptMessage;\n error: Error;\n}\n\n/**\n * ConversationRelay callback payload from Twilio webhook\n *\n * Sent when a ConversationRelay session ends or transitions state.\n * Includes standard voice webhook parameters plus ConversationRelay-specific fields.\n *\n * @see https://www.twilio.com/docs/voice/twiml#request-parameters\n * @see https://www.twilio.com/docs/voice/conversationrelay/conversationrelay-noun#statuscallback\n */\nexport const ConversationRelayCallbackPayloadSchema = z.object({\n // Core Twilio identifiers (required)\n AccountSid: z.string(),\n CallSid: z.string(),\n\n /** Call status with strict type checking for all valid Twilio call states */\n CallStatus: z.enum([\n 'queued',\n 'initiated',\n 'ringing',\n 'in-progress',\n 'completed',\n 'busy',\n 'no-answer',\n 'failed',\n 'canceled',\n ]),\n\n // Call participants (required)\n From: z.string(),\n To: z.string(),\n\n /** Direction of the call */\n Direction: z.enum(['inbound', 'outbound-api', 'outbound-dial']),\n\n // Standard voice webhook parameters (optional)\n ApiVersion: z.string().optional(),\n ForwardedFrom: z.string().optional(),\n CallerName: z.string().optional(),\n ParentCallSid: z.string().optional(),\n ApplicationSid: z.string().optional(),\n\n // ConversationRelay session information (optional)\n SessionId: z.string().optional(),\n SessionStatus: z.string().optional(),\n SessionDuration: z.string().optional(),\n});\n\nexport type ConversationRelayCallbackPayload = z.infer<\n typeof ConversationRelayCallbackPayloadSchema\n>;\n\n// =========================================================================\n// Call Events (status callback, async AMD, recording status)\n// =========================================================================\n\n/**\n * Split a Twilio webhook form into aliased fields and everything else.\n *\n * Unknown keys — including fields that belong to a different call event — are\n * bucketed rather than dropped, so a handler can still reach them via `extra`.\n */\nfunction splitCallEventForm(\n form: Record<string, string>,\n aliases: Record<string, string>\n): { known: Record<string, string>; extra: Record<string, string> } {\n const known: Record<string, string> = {};\n const extra: Record<string, string> = {};\n for (const [key, value] of Object.entries(form)) {\n const alias = aliases[key];\n if (alias) {\n known[alias] = value;\n } else {\n extra[key] = value;\n }\n }\n return { known, extra };\n}\n\n/**\n * Fields shared by the three Twilio call-webhook events.\n *\n * `callSid` is the correlation key across every surface — it matches\n * `ConversationSession.callSid` and the SID from\n * `initiateOutboundConversation`. It's required: every real call webhook\n * carries one, and defaulting it would hand handlers an empty SID to act on\n * (`endCall('')` is a Twilio 404). Missing or blank fails validation, which the\n * channel turns into a 400.\n */\nconst CallEventBaseShape = {\n callSid: z.string().min(1, 'CallSid is required'),\n accountSid: z.string().optional(),\n /** Any other Twilio webhook fields not surfaced above. */\n extra: z.record(z.string(), z.string()).default({}),\n};\n\nconst CALL_EVENT_BASE_ALIASES = {\n CallSid: 'callSid',\n AccountSid: 'accountSid',\n} as const;\n\n/**\n * Call statuses that mean the call ended without reaching the callee — i.e.\n * worth a retry.\n */\nconst UNREACHED_CALL_STATUSES: readonly string[] = ['busy', 'no-answer', 'failed', 'canceled'];\n\n/**\n * A Twilio `statusCallback` webhook — call progress and disposition.\n *\n * By default Twilio sends only the terminal event, which covers every\n * disposition (`completed` / `busy` / `no-answer` / `failed` / `canceled`); set\n * `CallOptions.statusCallbackEvent` for the intermediate ones. Register a\n * handler via `VoiceChannel.onCallStatus`.\n *\n * `isUnreached` is computed at parse time so application code doesn't have to\n * match disposition strings itself.\n */\nexport const CallStatusEventSchema = z\n .object({\n ...CallEventBaseShape,\n callStatus: z.string().optional(),\n callDuration: z.string().optional(),\n sipResponseCode: z.string().optional(),\n })\n .transform(event => ({\n ...event,\n /** Call ended without reaching the callee — i.e. worth a retry. */\n isUnreached: UNREACHED_CALL_STATUSES.includes(event.callStatus ?? ''),\n }));\n\nexport type CallStatusEvent = z.infer<typeof CallStatusEventSchema>;\n\nconst CALL_STATUS_EVENT_ALIASES: Record<string, string> = {\n ...CALL_EVENT_BASE_ALIASES,\n CallStatus: 'callStatus',\n CallDuration: 'callDuration',\n SipResponseCode: 'sipResponseCode',\n};\n\n/** Build a {@link CallStatusEvent} from a raw Twilio webhook form. */\nexport function callStatusEventFromForm(form: Record<string, string>): CallStatusEvent {\n const { known, extra } = splitCallEventForm(form, CALL_STATUS_EVENT_ALIASES);\n return CallStatusEventSchema.parse({ ...known, extra });\n}\n\n/**\n * A Twilio `asyncAmdStatusCallback` webhook — answering machine detection.\n *\n * Fires at most once per call, and only when the call set both\n * `CallOptions.machineDetection` and `asyncAmd`.\n *\n * `answeredBy` is mode-dependent — `machine_start` under `'Enable'`,\n * `machine_end_beep` / `machine_end_silence` / `machine_end_other` under\n * `'DetectMessageEnd'`, plus `human` / `fax` / `unknown` in both. Use\n * `isMachine` rather than matching those yourself. Register a handler via\n * `VoiceChannel.onAmd`.\n */\nexport const AmdEventSchema = z\n .object({\n ...CallEventBaseShape,\n answeredBy: z.string().optional(),\n machineDetectionDuration: z.string().optional(),\n })\n .transform(event => ({\n ...event,\n /**\n * A machine answered — any `machine_*` value, either mode. `unknown`\n * (detection timed out) is false, so a call is never hung up on a guess.\n */\n isMachine: (event.answeredBy ?? '').startsWith('machine'),\n }));\n\nexport type AmdEvent = z.infer<typeof AmdEventSchema>;\n\nconst AMD_EVENT_ALIASES: Record<string, string> = {\n ...CALL_EVENT_BASE_ALIASES,\n AnsweredBy: 'answeredBy',\n MachineDetectionDuration: 'machineDetectionDuration',\n};\n\n/** Build an {@link AmdEvent} from a raw Twilio webhook form. */\nexport function amdEventFromForm(form: Record<string, string>): AmdEvent {\n const { known, extra } = splitCallEventForm(form, AMD_EVENT_ALIASES);\n return AmdEventSchema.parse({ ...known, extra });\n}\n\n/**\n * A Twilio `recordingStatusCallback` webhook — a recording became available.\n *\n * Fires when the recording is ready (`recordingUrl` accessible), only when\n * recording is enabled. Register a handler via `VoiceChannel.onRecording`.\n */\nexport const RecordingEventSchema = z.object({\n ...CallEventBaseShape,\n recordingSid: z.string().optional(),\n recordingUrl: z.string().optional(),\n recordingStatus: z.string().optional(),\n recordingDuration: z.string().optional(),\n});\n\nexport type RecordingEvent = z.infer<typeof RecordingEventSchema>;\n\nconst RECORDING_EVENT_ALIASES: Record<string, string> = {\n ...CALL_EVENT_BASE_ALIASES,\n RecordingSid: 'recordingSid',\n RecordingUrl: 'recordingUrl',\n RecordingStatus: 'recordingStatus',\n RecordingDuration: 'recordingDuration',\n};\n\n/** Build a {@link RecordingEvent} from a raw Twilio webhook form. */\nexport function recordingEventFromForm(form: Record<string, string>): RecordingEvent {\n const { known, extra } = splitCallEventForm(form, RECORDING_EVENT_ALIASES);\n return RecordingEventSchema.parse({ ...known, extra });\n}\n\n// =========================================================================\n// Calls API parameters (calls.create passthrough)\n// =========================================================================\n\n/**\n * Every parameter `client.calls.create()` accepts, as of the pinned Twilio SDK.\n *\n * Unlike Python's `inspect.signature`, TypeScript has no runtime view of a\n * function's accepted keys, so the set is listed here and pinned to the SDK by\n * {@link _CallsCreateDriftGuards} at typecheck time. It's needed at runtime\n * because the Node SDK builds its request body from an explicit whitelist —\n * an unrecognized key is **silently dropped**, not an error, so without this a\n * typo would look like it worked.\n */\nconst CALLS_CREATE_PARAMS = [\n 'applicationSid',\n 'asyncAmd',\n 'asyncAmdStatusCallback',\n 'asyncAmdStatusCallbackMethod',\n 'byoc',\n 'callerId',\n 'callReason',\n 'callToken',\n 'clientNotificationUrl',\n 'fallbackMethod',\n 'fallbackUrl',\n 'from',\n 'machineDetection',\n 'machineDetectionSilenceTimeout',\n 'machineDetectionSpeechEndThreshold',\n 'machineDetectionSpeechThreshold',\n 'machineDetectionTimeout',\n 'method',\n 'record',\n 'recordingChannels',\n 'recordingStatusCallback',\n 'recordingStatusCallbackEvent',\n 'recordingStatusCallbackMethod',\n 'recordingTrack',\n 'sendDigits',\n 'sipAuthPassword',\n 'sipAuthUsername',\n 'statusCallback',\n 'statusCallbackEvent',\n 'statusCallbackMethod',\n 'timeLimit',\n 'timeout',\n 'to',\n 'trim',\n 'twiml',\n 'url',\n] as const;\n\n/**\n * `calls.create` parameters TAC owns — it builds the call and its TwiML, so a\n * caller setting these would either be overwritten or break the call.\n */\nconst RESERVED_CALL_PARAMS = ['to', 'from', 'twiml', 'url', 'applicationSid'] as const;\n\ntype ReservedCallParam = (typeof RESERVED_CALL_PARAMS)[number];\n\n/**\n * The `calls.create` parameters TAC types explicitly — the ones outbound\n * ConversationRelay reaches for. Everything else the SDK accepts is still\n * forwarded, typed by the SDK itself via {@link CallOptions}.\n */\nexport interface TypedCallOptions {\n /**\n * Enables AMD. `'Enable'` reports as soon as it can tell human from machine\n * (to hang up on voicemail); `'DetectMessageEnd'` waits out the greeting (to\n * leave a message). Required, together with `asyncAmd`, for `onAmd` to fire.\n */\n machineDetection?: 'Enable' | 'DetectMessageEnd' | undefined;\n /**\n * Detect in the background. Required for `onAmd`: with it off, `AnsweredBy`\n * comes back on the TwiML request, which inline TwiML can't receive.\n *\n * Twilio's API types this as a string; a boolean is serialized for you.\n */\n asyncAmd?: boolean | string | undefined;\n asyncAmdStatusCallback?: string | undefined;\n asyncAmdStatusCallbackMethod?: string | undefined;\n machineDetectionTimeout?: number | undefined;\n machineDetectionSpeechThreshold?: number | undefined;\n machineDetectionSpeechEndThreshold?: number | undefined;\n machineDetectionSilenceTimeout?: number | undefined;\n\n /** Required for `onRecording`. */\n record?: boolean | undefined;\n recordingStatusCallback?: string | undefined;\n recordingStatusCallbackEvent?: string[] | undefined;\n recordingChannels?: string | undefined;\n recordingTrack?: string | undefined;\n\n statusCallback?: string | undefined;\n /**\n * Lifecycle events to report. Omitted, Twilio sends only `'completed'` —\n * which covers busy/canceled/failed/no-answer. Set it for ringing/answered.\n */\n statusCallbackEvent?: string[] | undefined;\n statusCallbackMethod?: string | undefined;\n /** Seconds to ring before giving up. Twilio defaults to 60. */\n timeout?: number | undefined;\n}\n\n/**\n * Parameters for Twilio's `client.calls.create()`.\n *\n * {@link TypedCallOptions} covers the ones outbound ConversationRelay reaches\n * for; any other parameter `calls.create()` accepts is forwarded too, typed by\n * the Twilio SDK. TAC-owned parameters (`to`, `from`, `twiml`, `url`,\n * `applicationSid`) are excluded — TAC builds the call and its TwiML.\n *\n * Unknown keys are rejected at validation, so a typo fails at\n * `initiateOutboundConversation` rather than being silently dropped by the SDK.\n *\n * @example\n * ```typescript\n * const callOptions: CallOptions = {\n * machineDetection: 'Enable',\n * asyncAmd: true,\n * record: true,\n * };\n * ```\n */\nexport type CallOptions = TypedCallOptions &\n Omit<CallListInstanceCreateOptions, ReservedCallParam | keyof TypedCallOptions>;\n\n/**\n * @internal Fails typecheck unless instantiated with `true`. A conditional type\n * that merely resolves to `never` is not an error on its own, so the assertion\n * has to be a constraint violation to be load-bearing.\n */\ntype _AssertTrue<T extends true> = T;\n\n/**\n * @internal Compile-time SDK drift guards — do not use directly.\n * If the Twilio SDK adds, removes, or renames a `calls.create` parameter these\n * checks fail during `npm run typecheck`, signaling that\n * {@link CALLS_CREATE_PARAMS} needs updating. Without the `complete` direction a\n * newly added SDK parameter would be rejected at runtime as unknown.\n */\nexport type _CallsCreateDriftGuards = {\n known: _AssertTrue<\n (typeof CALLS_CREATE_PARAMS)[number] extends keyof CallListInstanceCreateOptions ? true : false\n >;\n complete: _AssertTrue<\n keyof CallListInstanceCreateOptions extends (typeof CALLS_CREATE_PARAMS)[number] ? true : false\n >;\n typedAreRealParams: _AssertTrue<\n keyof TypedCallOptions extends keyof CallListInstanceCreateOptions ? true : false\n >;\n reservedAreRealParams: _AssertTrue<\n ReservedCallParam extends keyof CallListInstanceCreateOptions ? true : false\n >;\n};\n\nconst ACCEPTED_CALL_PARAMS: ReadonlySet<string> = new Set(CALLS_CREATE_PARAMS);\n\n/**\n * Whether an `asyncAmd` value actually turns background detection on.\n *\n * Accepts the boolean TAC serializes for callers and the string Twilio's API\n * types the parameter as, so `'false'` reads as off rather than as a non-empty\n * (therefore truthy) string.\n */\nfunction isAsyncAmdEnabled(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.trim().toLowerCase() === 'true';\n return false;\n}\n\n/**\n * Runtime validation for {@link CallOptions}.\n *\n * Loose rather than strict so untyped-but-real Calls API parameters pass\n * through; `superRefine` then rejects TAC-owned and unknown keys explicitly so\n * the message says which mistake was made.\n */\nconst CallOptionsObjectSchema = z\n .looseObject({\n machineDetection: z.enum(['Enable', 'DetectMessageEnd']).optional(),\n asyncAmd: z.union([z.boolean(), z.string()]).optional(),\n asyncAmdStatusCallback: z.string().optional(),\n asyncAmdStatusCallbackMethod: z.string().optional(),\n machineDetectionTimeout: z.number().int().optional(),\n machineDetectionSpeechThreshold: z.number().int().optional(),\n machineDetectionSpeechEndThreshold: z.number().int().optional(),\n machineDetectionSilenceTimeout: z.number().int().optional(),\n\n record: z.boolean().optional(),\n recordingStatusCallback: z.string().optional(),\n recordingStatusCallbackEvent: z.array(z.string()).optional(),\n recordingChannels: z.string().optional(),\n recordingTrack: z.string().optional(),\n\n statusCallback: z.string().optional(),\n statusCallbackEvent: z.array(z.string()).optional(),\n statusCallbackMethod: z.string().optional(),\n timeout: z.number().int().optional(),\n })\n .superRefine((value, ctx) => {\n const supplied = Object.keys(value);\n\n const conflict = supplied.filter(key =>\n (RESERVED_CALL_PARAMS as readonly string[]).includes(key)\n );\n if (conflict.length > 0) {\n ctx.addIssue({\n code: 'custom',\n message:\n `callOptions may not set TAC-owned call parameters: ${conflict.sort().join(', ')}. ` +\n 'TAC builds the call and its TwiML.',\n });\n }\n\n const unknown = supplied.filter(key => !ACCEPTED_CALL_PARAMS.has(key));\n if (unknown.length > 0) {\n ctx.addIssue({\n code: 'custom',\n message:\n \"callOptions has parameters Twilio's calls.create() does not accept: \" +\n `${unknown.sort().join(', ')}. Check for a typo, or upgrade the twilio package.`,\n });\n }\n\n // AMD needs both flags. machineDetection turns detection on; asyncAmd\n // delivers AnsweredBy to a callback. Without asyncAmd, Twilio returns it on\n // the TwiML request instead — unreachable, since TAC sends inline TwiML.\n //\n // asyncAmd is checked by value, not truthiness: Twilio's API types it as a\n // string, and `Boolean('false')` is true — so a plain truthiness test would\n // wave through `asyncAmd: 'false'` and silently deliver no AMD event.\n if (Boolean(value.machineDetection) !== isAsyncAmdEnabled(value.asyncAmd)) {\n ctx.addIssue({\n code: 'custom',\n message:\n 'AMD requires both machineDetection and asyncAmd; got ' +\n `machineDetection=${JSON.stringify(value.machineDetection)}, ` +\n `asyncAmd=${JSON.stringify(value.asyncAmd)}.`,\n });\n }\n });\n\n/**\n * Validates {@link CallOptions}. The parsed value is re-widened to `CallOptions`\n * because the loose object's inferred index signature would otherwise erase the\n * SDK-derived parameter types.\n */\nexport const CallOptionsSchema: z.ZodType<CallOptions, unknown> = CallOptionsObjectSchema.transform(\n value => value as CallOptions\n);\n\n/**\n * Serialize {@link CallOptions} into the argument object for\n * `client.calls.create()`, dropping unset keys.\n *\n * `asyncAmd` is coerced to a string because Twilio's SDK types it as one,\n * unlike `record`.\n */\nexport function callOptionsToCreateParams(options: CallOptions): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(options)) {\n if (value === undefined) continue;\n params[key] = key === 'asyncAmd' && typeof value === 'boolean' ? String(value) : value;\n }\n return params;\n}\n\n// =========================================================================\n// Outbound Voice Conversation Types\n// =========================================================================\n\n/**\n * Options for initiating an outbound voice conversation.\n *\n * The caller identity is always TAC's configured `config.phoneNumber`.\n * Multi-number deployments should run one TAC instance per line.\n *\n * TwiML for the outbound call is built by merging per-field, highest precedence\n * first:\n * 1. This call's `twimlOptions` (per-call overrides)\n * 2. `VoiceChannelConfig.defaultTwimlOptions` (channel-wide defaults)\n * 3. TAC defaults (welcome greeting, conversationConfiguration, actionUrl\n * resolved via Studio handoff if configured, else derived from\n * `TACConfig.voicePublicDomain` + `voiceActionPath`)\n *\n * Fields you don't set at a layer fall through to lower layers — so\n * `twimlOptions: { voice: 'es-MX-Neural2-A' }` on this call overrides only\n * `voice`; `language`, `interruptible`, etc. from the channel config still apply.\n */\nexport interface InitiateVoiceConversationOptions {\n to: string;\n /**\n * Public WebSocket URL for ConversationRelay (e.g. 'wss://your-domain.ngrok.app/ws').\n * Optional — defaults to the URL derived from `TACConfig.voicePublicDomain` +\n * `voiceWebsocketPath`. Pass it here only to override the URL for a specific call.\n */\n websocketUrl?: string | undefined;\n /**\n * Per-call overrides for the TwiML inside `<ConversationRelay>`. Merged over\n * `VoiceChannelConfig.defaultTwimlOptions` and TAC defaults.\n */\n twimlOptions?: TwiMLOptions | undefined;\n /**\n * Parameters for Twilio's `calls.create()` — AMD, recording, status\n * callbacks, timeout (see {@link CallOptions}). Callback URLs auto-wire when\n * the matching handler is registered; an explicit URL wins.\n */\n callOptions?: CallOptions | undefined;\n}\n\nexport const InitiateVoiceConversationOptionsSchema: z.ZodType<InitiateVoiceConversationOptions> = z\n .object({\n to: z.string().min(1, 'Recipient phone number is required'),\n websocketUrl: z.url().optional(),\n twimlOptions: TwiMLOptionsSchema.optional(),\n callOptions: CallOptionsSchema.optional(),\n })\n // Reject removed flat fields (welcomeGreeting, actionUrl, customParameters,\n // conversationRelayConfig) so callers upgrading from older TAC versions get\n // a clear error instead of having their values silently dropped.\n .strict();\n","import { z } from 'zod';\n\n/**\n * JSON Schema definition for tool parameters\n */\nexport const JSONSchemaSchema = z.object({\n type: z.enum(['object', 'string', 'number', 'boolean', 'array']),\n properties: z.record(z.string(), z.any()).optional(),\n required: z.array(z.string()).optional(),\n items: z.any().optional(),\n enum: z.array(z.any()).optional(),\n description: z.string().optional(),\n});\n\nexport type JSONSchema = z.infer<typeof JSONSchemaSchema>;\n\n/**\n * Tool function signature\n */\nexport type ToolFunction<TParams = unknown, TResult = unknown> = (\n params: TParams\n) => Promise<TResult> | TResult;\n\n/**\n * Core tool definition\n */\nexport interface TACTool<TParams = unknown, TResult = unknown> {\n name: string;\n description: string;\n parameters: JSONSchema;\n implementation: ToolFunction<TParams, TResult>;\n}\n\n/**\n * OpenAI tool format\n */\nexport const OpenAIToolSchema = z.object({\n type: z.literal('function'),\n function: z.object({\n name: z.string(),\n description: z.string(),\n parameters: JSONSchemaSchema,\n }),\n});\n\nexport type OpenAITool = z.infer<typeof OpenAIToolSchema>;\n\n/**\n * Anthropic tool format\n */\nexport const AnthropicToolSchema = z.object({\n name: z.string(),\n description: z.string(),\n input_schema: JSONSchemaSchema,\n});\n\nexport type AnthropicTool = z.infer<typeof AnthropicToolSchema>;\n\n/**\n * Tool execution context\n */\nexport interface ToolContext {\n conversationId?: string;\n profileId?: string;\n channel?: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Tool execution result\n */\nexport const ToolExecutionResultSchema = z.object({\n success: z.boolean(),\n data: z.any().optional(),\n error: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type ToolExecutionResult = z.infer<typeof ToolExecutionResultSchema>;\n\n/**\n * Built-in tool types\n */\nexport const BuiltInTools = {\n RETRIEVE_MEMORY: 'retrieve_profile_memory',\n SEND_MESSAGE: 'send_message',\n HANDOFF: 'handoff',\n SEARCH_KNOWLEDGE: 'search_knowledge',\n} as const;\n\nexport type BuiltInToolName = (typeof BuiltInTools)[keyof typeof BuiltInTools];\n","import { z } from 'zod';\n\n/**\n * Conversation Intelligence Types\n *\n * These types represent the webhook payloads and configuration for\n * processing Conversation Intelligence operator results.\n */\n\n/**\n * Participant in operator execution (e.g., CUSTOMER, AGENT)\n */\nexport const CintelParticipantSchema = z.object({\n type: z.string(),\n profileId: z.string().optional(),\n mediaParticipantId: z.string().optional(),\n});\n\nexport type CintelParticipant = z.infer<typeof CintelParticipantSchema>;\n\n/**\n * Execution details for an operator result\n */\nexport const ExecutionDetailsSchema = z.object({\n participants: z.array(CintelParticipantSchema).optional(),\n});\n\nexport type ExecutionDetails = z.infer<typeof ExecutionDetailsSchema>;\n\n/**\n * Operator metadata\n */\nexport const OperatorSchema = z.object({\n id: z.string(),\n name: z.string().optional(),\n});\n\nexport type Operator = z.infer<typeof OperatorSchema>;\n\n/**\n * Individual operator result from Conversation Intelligence\n */\nexport const OperatorResultSchema = z.object({\n id: z.string(),\n operator: OperatorSchema,\n outputFormat: z.string(),\n result: z.unknown(),\n dateCreated: z.string(),\n referenceIds: z.array(z.string()).optional().default([]),\n executionDetails: ExecutionDetailsSchema.optional(),\n});\n\nexport type OperatorResult = z.infer<typeof OperatorResultSchema>;\n\n/**\n * Intelligence configuration metadata\n */\nexport const IntelligenceConfigurationSchema = z.object({\n id: z.string(),\n friendlyName: z.string().optional(),\n});\n\nexport type IntelligenceConfiguration = z.infer<typeof IntelligenceConfigurationSchema>;\n\n/**\n * Full webhook payload for operator result events\n */\nexport const OperatorResultEventSchema = z.object({\n accountId: z.string(),\n conversationId: z.string(),\n memoryStoreId: z.string().optional(),\n intelligenceConfiguration: IntelligenceConfigurationSchema,\n operatorResults: z.array(OperatorResultSchema),\n});\n\nexport type OperatorResultEvent = z.infer<typeof OperatorResultEventSchema>;\n\n/**\n * Result of processing an operator result event\n */\nexport const OperatorProcessingResultSchema = z.object({\n success: z.boolean(),\n eventType: z.string().optional(),\n skipped: z.boolean().default(false),\n skipReason: z.string().optional(),\n error: z.string().optional(),\n createdCount: z.number().default(0),\n});\n\nexport type OperatorProcessingResult = z.infer<typeof OperatorProcessingResultSchema>;\n\n/**\n * Conversation Intelligence configuration for TAC\n */\nexport const ConversationIntelligenceConfigSchema = z.object({\n configurationId: z.string(),\n summaryOperatorSid: z.string().optional(),\n});\n\nexport type ConversationIntelligenceConfig = z.infer<typeof ConversationIntelligenceConfigSchema>;\n\n/**\n * Summary item for batch creation\n */\nexport const ConversationSummaryItemSchema = z.object({\n content: z.string(),\n conversationId: z.string(),\n occurredAt: z.string(),\n source: z.string().optional(),\n});\n\nexport type ConversationSummaryItem = z.infer<typeof ConversationSummaryItemSchema>;\n","import { z } from 'zod';\n\n/**\n * Knowledge base status enum\n */\nexport const KnowledgeBaseStatusSchema = z.enum([\n 'QUEUED',\n 'PROVISIONING',\n 'ACTIVE',\n 'FAILED',\n 'DELETING',\n]);\n\nexport type KnowledgeBaseStatus = z.infer<typeof KnowledgeBaseStatusSchema>;\n\n/**\n * Knowledge base metadata (from GET endpoint)\n */\nexport const KnowledgeBaseSchema = z.object({\n id: z.string(),\n displayName: z.string(),\n description: z.string(),\n status: KnowledgeBaseStatusSchema,\n createdAt: z.string(),\n updatedAt: z.string(),\n version: z.number(),\n});\n\nexport type KnowledgeBase = z.infer<typeof KnowledgeBaseSchema>;\n\n/**\n * Search result chunk (from POST search endpoint)\n */\nexport const KnowledgeChunkResultSchema = z.object({\n content: z.string(),\n knowledgeId: z.string(),\n createdAt: z.string(),\n score: z.number().optional(),\n});\n\nexport type KnowledgeChunkResult = z.infer<typeof KnowledgeChunkResultSchema>;\n\n/**\n * Search response wrapper\n */\nexport const KnowledgeSearchResponseSchema = z.object({\n chunks: z.array(KnowledgeChunkResultSchema),\n});\n\nexport type KnowledgeSearchResponse = z.infer<typeof KnowledgeSearchResponseSchema>;\n","import { TACConfigData, TACConfigSchema, EnvironmentVariables } from '../types/index';\nimport type { CallEventKind } from '../types/index';\nimport { z } from 'zod';\n\n/**\n * TAC Configuration class with Python-like static factory methods\n *\n * Example usage:\n * ```typescript\n * // Load from environment variables\n * const config = TACConfig.fromEnv();\n *\n * // Or create manually\n * const config = new TACConfig({\n * accountSid: 'ACxxxx',\n * // ...\n * });\n * ```\n */\nexport class TACConfig {\n public readonly accountSid: string;\n public readonly authToken: string;\n public readonly apiKey: string;\n public readonly apiSecret: string;\n public readonly phoneNumber: string;\n public readonly rcsSenderId?: string;\n public readonly whatsappNumber?: string;\n public readonly memoryConfig: TACConfigData['memoryConfig'];\n public readonly conversationConfigurationId?: string;\n public readonly voicePublicDomain?: string;\n /** Path the voice WebSocket is served at (default '/ws'). */\n public readonly voiceWebsocketPath: string;\n /** Path the ConversationRelay action callback is served at (default '/conversation-relay-callback'). */\n public readonly voiceActionPath: string;\n /** Base path the call-event callbacks are served under (default '/twilio/call-events'). */\n public readonly voiceCallEventPath: string;\n public readonly cintelConfigurationId?: string;\n public readonly cintelSummaryOperatorSid?: string;\n /** Optional Twilio region subdomain for API routing (e.g. transforms base URLs to `https://{product}.{region}.twilio.com`) */\n public readonly region?: string;\n /**\n * Twilio Studio Flow SID for handoff. TAC derives both the digital-handoff\n * Studio Executions URL (`studio.twilio.com/v2/Flows/{SID}/Executions`) and\n * the voice `<Connect action>` webhook URL\n * (`webhooks.twilio.com/v1/Accounts/{AccountSid}/Flows/{SID}?Trigger=incomingCall`)\n * from this SID.\n */\n public readonly studioHandoffFlowSid?: string;\n constructor(data: TACConfigData | z.input<typeof TACConfigSchema>) {\n // Validate the configuration data\n const validatedConfig = TACConfigSchema.parse(data);\n\n // Assign all properties\n this.accountSid = validatedConfig.accountSid;\n this.authToken = validatedConfig.authToken;\n this.apiKey = validatedConfig.apiKey;\n this.apiSecret = validatedConfig.apiSecret;\n this.phoneNumber = validatedConfig.phoneNumber;\n if (validatedConfig.rcsSenderId) {\n this.rcsSenderId = validatedConfig.rcsSenderId;\n }\n if (validatedConfig.whatsappNumber) {\n this.whatsappNumber = validatedConfig.whatsappNumber;\n }\n // Assign the validated memory config directly; schema parsing already validates shape and applies defaults\n this.memoryConfig = validatedConfig.memoryConfig;\n if (validatedConfig.conversationConfigurationId) {\n this.conversationConfigurationId = validatedConfig.conversationConfigurationId;\n }\n if (validatedConfig.voicePublicDomain) {\n this.voicePublicDomain = validatedConfig.voicePublicDomain;\n }\n // voiceWebsocketPath / voiceActionPath / voiceCallEventPath always have schema defaults\n this.voiceWebsocketPath = validatedConfig.voiceWebsocketPath;\n this.voiceActionPath = validatedConfig.voiceActionPath;\n this.voiceCallEventPath = validatedConfig.voiceCallEventPath;\n if (validatedConfig.cintelConfigurationId) {\n this.cintelConfigurationId = validatedConfig.cintelConfigurationId;\n }\n if (validatedConfig.cintelSummaryOperatorSid) {\n this.cintelSummaryOperatorSid = validatedConfig.cintelSummaryOperatorSid;\n }\n if (validatedConfig.region) {\n this.region = validatedConfig.region;\n }\n if (validatedConfig.studioHandoffFlowSid) {\n this.studioHandoffFlowSid = validatedConfig.studioHandoffFlowSid;\n }\n }\n\n /**\n * Create TACConfig from environment variables.\n *\n * Required environment variables:\n * - TWILIO_ACCOUNT_SID: Twilio Account SID\n * - TWILIO_AUTH_TOKEN: Twilio Auth Token for API authentication\n * - TWILIO_API_KEY: Twilio API Key SID (starts with SK)\n * - TWILIO_API_SECRET: Twilio API Secret for API Key authentication\n * - TWILIO_PHONE_NUMBER: Phone number for voice and SMS channels\n *\n * Optional environment variables:\n * - TWILIO_WHATSAPP_NUMBER: WhatsApp number for WhatsApp channel (e.g., 'whatsapp:+1234567890')\n * - TWILIO_CONVERSATION_CONFIGURATION_ID: Conversation Orchestrator configuration ID (enables orchestrated mode)\n * - TWILIO_VOICE_PUBLIC_DOMAIN: Public domain for voice routes (required for voice; a port and/or base path are allowed, e.g., 'abc123.ngrok.app', 'example.ngrok.app:8080', or 'example.com/server1')\n * - TWILIO_VOICE_WEBSOCKET_PATH: Path for the voice WebSocket (default: /ws)\n * - TWILIO_VOICE_ACTION_PATH: Path for the ConversationRelay action callback (default: /conversation-relay-callback)\n * - TWILIO_VOICE_CALL_EVENT_PATH: Base path for the call-event callbacks — status, async AMD, recording (default: /twilio/call-events)\n * - TWILIO_REGION: Twilio region subdomain for API routing (e.g. transforms base URLs to `https://{product}.{region}.twilio.com`)\n * - TWILIO_STUDIO_HANDOFF_FLOW_SID: Studio Flow SID used by createStudioHandoffTool for human handoff\n * - TWILIO_RCS_SENDER_ID: RCS Sender ID for the RCS channel\n *\n * Memory Configuration (defaults defined in TwilioMemoryConfigSchema):\n * - TWILIO_MEMORY_PROFILE_TRAIT_GROUPS: Trait groups to include (comma-separated, e.g., \"Contact,Preferences\")\n * - TWILIO_MEMORY_OBSERVATIONS_LIMIT: Max observations in memory retrieval\n * - TWILIO_MEMORY_SUMMARIES_LIMIT: Max summaries in memory retrieval\n * - TWILIO_MEMORY_COMMUNICATIONS_LIMIT: Max communications in memory retrieval\n * - TWILIO_MEMORY_RELEVANCE_THRESHOLD: Min relevance score (0.0-1.0)\n * - TWILIO_MEMORY_PHONE_TRAIT_GROUP: Trait group that holds the phone identifier on new profiles (default \"Contact\")\n * - TWILIO_MEMORY_PHONE_TRAIT_FIELD: Trait field within phoneTraitGroup (default \"phone\")\n *\n * @throws Error if required environment variables are not set or invalid\n *\n * @example\n * ```typescript\n * // Ensure env vars are set before calling (e.g. via dotenv, Docker, CI, etc.)\n * const config = TACConfig.fromEnv();\n *\n * // Use in TAC initialization\n * const tac = new TAC({ config });\n * ```\n */\n public static fromEnv(): TACConfig {\n // Check for required environment variables\n const requiredVars = [\n { key: EnvironmentVariables.TWILIO_ACCOUNT_SID, name: 'TWILIO_ACCOUNT_SID' },\n { key: EnvironmentVariables.TWILIO_AUTH_TOKEN, name: 'TWILIO_AUTH_TOKEN' },\n { key: EnvironmentVariables.TWILIO_API_KEY, name: 'TWILIO_API_KEY' },\n { key: EnvironmentVariables.TWILIO_API_SECRET, name: 'TWILIO_API_SECRET' },\n { key: EnvironmentVariables.TWILIO_PHONE_NUMBER, name: 'TWILIO_PHONE_NUMBER' },\n ];\n\n // Throw error for missing required variables (like Python's KeyError)\n for (const { key, name } of requiredVars) {\n if (!process.env[key]) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n }\n\n // Parse memory configuration from environment variables\n const traitGroupsStr = process.env[EnvironmentVariables.TWILIO_MEMORY_PROFILE_TRAIT_GROUPS];\n // Parse trait groups, filtering out empty strings from malformed CSV (e.g., \"A,,B,\")\n // Treat empty/whitespace-only strings and delimiter-only inputs as undefined for consistency\n const trimmedTraitGroups = traitGroupsStr?.trim();\n const parsedTraitGroups =\n trimmedTraitGroups && trimmedTraitGroups.length > 0\n ? trimmedTraitGroups\n .split(',')\n .map(g => g.trim())\n .filter(g => g.length > 0)\n : undefined;\n const traitGroups =\n parsedTraitGroups && parsedTraitGroups.length > 0 ? parsedTraitGroups : undefined;\n\n // Helper to parse integer from env var with validation and bounds checking.\n // Returns undefined when the env var is not set, letting the Zod schema apply defaults.\n const parseIntEnv = (\n envVarName: string,\n value: string | undefined,\n min: number,\n max: number\n ): number | undefined => {\n if (!value) return undefined;\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n\n const parsed = Number(trimmed);\n if (!Number.isFinite(parsed)) {\n throw new Error(`Invalid ${envVarName}: expected an integer, got \"${value}\"`);\n }\n if (!Number.isInteger(parsed)) {\n throw new Error(`Invalid ${envVarName}: expected an integer, got \"${value}\"`);\n }\n if (parsed < min || parsed > max) {\n throw new Error(`Invalid ${envVarName}: must be between ${min} and ${max}, got ${parsed}`);\n }\n return parsed;\n };\n\n // Helper to parse float from env var with validation and bounds checking.\n // Returns undefined when the env var is not set, letting the Zod schema apply defaults.\n const parseFloatEnv = (\n envVarName: string,\n value: string | undefined,\n min: number,\n max: number\n ): number | undefined => {\n if (!value) return undefined;\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n\n const parsed = Number(trimmed);\n if (!Number.isFinite(parsed)) {\n throw new Error(`Invalid ${envVarName}: expected a number, got \"${value}\"`);\n }\n if (parsed < min || parsed > max) {\n throw new Error(`Invalid ${envVarName}: must be between ${min} and ${max}, got ${parsed}`);\n }\n return parsed;\n };\n\n const rawConfig = {\n accountSid: process.env[EnvironmentVariables.TWILIO_ACCOUNT_SID]!,\n authToken: process.env[EnvironmentVariables.TWILIO_AUTH_TOKEN]!,\n apiKey: process.env[EnvironmentVariables.TWILIO_API_KEY]!,\n apiSecret: process.env[EnvironmentVariables.TWILIO_API_SECRET]!,\n phoneNumber: process.env[EnvironmentVariables.TWILIO_PHONE_NUMBER]!,\n rcsSenderId: process.env[EnvironmentVariables.TWILIO_RCS_SENDER_ID],\n whatsappNumber: process.env[EnvironmentVariables.TWILIO_WHATSAPP_NUMBER] || undefined,\n memoryConfig: {\n traitGroups,\n observationsLimit: parseIntEnv(\n 'TWILIO_MEMORY_OBSERVATIONS_LIMIT',\n process.env[EnvironmentVariables.TWILIO_MEMORY_OBSERVATIONS_LIMIT],\n 0,\n 100\n ),\n summariesLimit: parseIntEnv(\n 'TWILIO_MEMORY_SUMMARIES_LIMIT',\n process.env[EnvironmentVariables.TWILIO_MEMORY_SUMMARIES_LIMIT],\n 0,\n 100\n ),\n communicationsLimit: parseIntEnv(\n 'TWILIO_MEMORY_COMMUNICATIONS_LIMIT',\n process.env[EnvironmentVariables.TWILIO_MEMORY_COMMUNICATIONS_LIMIT],\n 0,\n 100\n ),\n relevanceThreshold: parseFloatEnv(\n 'TWILIO_MEMORY_RELEVANCE_THRESHOLD',\n process.env[EnvironmentVariables.TWILIO_MEMORY_RELEVANCE_THRESHOLD],\n 0.0,\n 1.0\n ),\n phoneTraitGroup:\n process.env[EnvironmentVariables.TWILIO_MEMORY_PHONE_TRAIT_GROUP] || undefined,\n phoneTraitField:\n process.env[EnvironmentVariables.TWILIO_MEMORY_PHONE_TRAIT_FIELD] || undefined,\n },\n conversationConfigurationId:\n process.env[EnvironmentVariables.TWILIO_CONVERSATION_CONFIGURATION_ID] || undefined,\n voicePublicDomain: process.env[EnvironmentVariables.TWILIO_VOICE_PUBLIC_DOMAIN],\n voiceWebsocketPath:\n process.env[EnvironmentVariables.TWILIO_VOICE_WEBSOCKET_PATH] || undefined,\n voiceActionPath: process.env[EnvironmentVariables.TWILIO_VOICE_ACTION_PATH] || undefined,\n voiceCallEventPath:\n process.env[EnvironmentVariables.TWILIO_VOICE_CALL_EVENT_PATH] || undefined,\n cintelConfigurationId: process.env[EnvironmentVariables.TWILIO_TAC_CI_CONFIGURATION_ID],\n cintelSummaryOperatorSid:\n process.env[EnvironmentVariables.TWILIO_TAC_CI_SUMMARY_OPERATOR_SID],\n region: process.env[EnvironmentVariables.TWILIO_REGION],\n studioHandoffFlowSid: process.env[EnvironmentVariables.TWILIO_STUDIO_HANDOFF_FLOW_SID],\n };\n\n return new TACConfig(rawConfig);\n }\n\n /**\n * Path a call-event callback is served at.\n *\n * Single source of truth: the voice channel builds callback URLs from this\n * and TACServer registers routes at it, so the two can't drift.\n */\n public callEventPath(kind: CallEventKind): string {\n return `${this.voiceCallEventPath.replace(/\\/+$/, '')}/${kind}`;\n }\n\n /**\n * Public URL for a call-event callback, or `undefined` without a public domain.\n */\n public callEventUrl(kind: CallEventKind): string | undefined {\n if (!this.voicePublicDomain) {\n return undefined;\n }\n return `https://${this.voicePublicDomain}${this.callEventPath(kind)}`;\n }\n\n /**\n * Whether Conversation Orchestrator is configured.\n * Returns false in voice-only mode (no conversationConfigurationId).\n *\n * @internal\n */\n public isOrchestratorEnabled(): boolean {\n return this.conversationConfigurationId !== undefined;\n }\n\n /**\n * Get basic auth credentials for Twilio APIs\n */\n public getBasicAuthCredentials(): { username: string; password: string } {\n return {\n username: this.accountSid,\n password: this.authToken,\n };\n }\n}\n","function scrubPhoneMatch(match: string): string {\n const digits = match.replace(/[\\s\\-()]/g, '');\n if (digits.length < 8) return '***';\n return `${digits.slice(0, 2)}***${digits.slice(-4)}`;\n}\n\nfunction scrubEmailMatch(match: string): string {\n const atIndex = match.indexOf('@');\n if (atIndex <= 0) return '***';\n return `${match[0]}***${match.slice(atIndex)}`;\n}\n\nexport function scrubPii(value: string): string {\n // Fresh RegExp each call — avoids lastIndex state bugs from the g flag\n const phoneRe = /\\+\\d[\\d\\s()-]{6,}\\d/g;\n const emailRe = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g;\n return value.replace(phoneRe, scrubPhoneMatch).replace(emailRe, scrubEmailMatch);\n}\n\nexport function scrubObject(obj: unknown, seen?: WeakSet<object>): unknown {\n if (typeof obj === 'string') return scrubPii(obj);\n if (obj === null || typeof obj !== 'object') return obj;\n\n const visited = seen ?? new WeakSet<object>();\n if (visited.has(obj)) return '[Circular]';\n visited.add(obj);\n\n if (obj instanceof Error) {\n const record = obj as unknown as Record<string, unknown>;\n const scrubbed = Object.create(Object.getPrototypeOf(obj) as object) as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n scrubbed[key] = scrubObject(record[key], visited);\n }\n const result = scrubbed as unknown as Error;\n if (!Object.prototype.hasOwnProperty.call(scrubbed, 'message')) {\n result.message = scrubPii(obj.message);\n }\n if (!Object.prototype.hasOwnProperty.call(scrubbed, 'name')) {\n result.name = obj.name;\n }\n if (obj.stack && !Object.prototype.hasOwnProperty.call(scrubbed, 'stack')) {\n result.stack = scrubPii(obj.stack);\n }\n return result;\n }\n\n if (Array.isArray(obj)) return obj.map(item => scrubObject(item, visited));\n\n // Only deep-scrub plain objects; leave class instances (Date, URL, Map, etc.) unchanged\n if (Object.getPrototypeOf(obj) !== Object.prototype) return obj;\n\n const record = obj as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(record)) {\n out[key] = scrubObject(record[key], visited);\n }\n return out;\n}\n\nexport function maskPhone(phone: string): string {\n if (!phone || !phone.startsWith('+') || phone.length < 8) {\n return '***';\n }\n return `${phone.slice(0, 2)}***${phone.slice(-4)}`;\n}\n\nexport function maskEmail(email: string): string {\n const atIndex = email.indexOf('@');\n if (atIndex <= 0) {\n return '***';\n }\n return `${email[0]}***${email.slice(atIndex)}`;\n}\n\nexport function maskAddress(address: string): string {\n if (!address) return '***';\n if (address.includes('@')) return maskEmail(address);\n if (address.startsWith('+')) return maskPhone(address);\n if (address.length <= 1) return '***';\n return `${address[0]}***`;\n}\n\n/**\n * Mask `<Parameter value=\"...\">` contents in TwiML, keeping the names.\n *\n * `<Parameter>` children carry whatever the developer put in\n * `customParameters` — profile IDs, caller names. Names stay because knowing\n * which parameters were sent is the point of logging the TwiML.\n *\n * Handles either quote style. TAC's own TwiML comes from the Twilio SDK, which\n * always double-quotes, but this takes a plain string and shouldn't depend on\n * that to stay safe.\n */\nexport function redactTwimlParameters(twiml: string | undefined | null): string {\n if (!twiml) return '';\n // Fresh RegExp each call — avoids lastIndex state bugs from the g flag.\n const parameterValueRe = /(<Parameter\\b[^>]*?\\bvalue=)([\"'])(.*?)\\2/gi;\n return twiml.replace(parameterValueRe, (_match, prefix: string, quote: string) => {\n return `${prefix}${quote}***${quote}`;\n });\n}\n","import pino from 'pino';\nimport { scrubObject } from '../util/log-redaction';\n\n/**\n * Logger type that can be either Pino logger or Fastify's logger\n */\nexport type Logger = pino.Logger;\n\nfunction piiLogMethod(this: pino.Logger, args: unknown[], method: pino.LogFn): void {\n const scrubbed = args.map(arg =>\n typeof arg === 'string'\n ? scrubObject(arg)\n : typeof arg === 'object' && arg !== null\n ? scrubObject(arg)\n : arg\n );\n return method.apply(this, scrubbed as Parameters<pino.LogFn>);\n}\n\nexport function createLogger(options?: { level?: string; name?: string }): Logger {\n const level = options?.level || process.env.TWILIO_LOG_LEVEL || 'info';\n\n return pino({\n level,\n ...(options?.name && { name: options.name }),\n hooks: { logMethod: piiLogMethod },\n });\n}\n","{\n \"name\": \"twilio-agent-connect\",\n \"version\": \"2.2.0\",\n \"description\": \"Twilio Agent Connect - A TypeScript framework for building intelligent agents\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"clean\": \"rimraf dist packages/*/dist\",\n \"test\": \"vitest --run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest --coverage\",\n \"lint\": \"eslint packages/*/src/**/*.ts src/**/*.ts\",\n \"lint:fix\": \"eslint packages/*/src/**/*.ts src/**/*.ts --fix\",\n \"format\": \"prettier --write packages/*/src/**/*.ts src/**/*.ts getting_started/**/*.ts\",\n \"format:check\": \"prettier --check packages/*/src/**/*.ts src/**/*.ts getting_started/**/*.ts\",\n \"typecheck\": \"tsc --noEmit\",\n \"docs\": \"typedoc\",\n \"docs:watch\": \"typedoc --watch\",\n \"example:getting-started\": \"cd getting_started/examples/openai && npm install && npm run dev\",\n \"example:chat\": \"cd getting_started/examples/chat && npm install && npm run dev\"\n },\n \"keywords\": [\n \"twilio\",\n \"ai\",\n \"agents\",\n \"framework\",\n \"typescript\"\n ],\n \"author\": \"Twilio\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/twilio/twilio-agent-connect-typescript.git\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.0.0\",\n \"@shipgirl/typedoc-plugin-versions\": \"^0.3.2\",\n \"@types/node\": \"^22.0.0\",\n \"@types/ws\": \"^8.18.1\",\n \"@vitest/coverage-v8\": \"^4.1.2\",\n \"axios-mock-adapter\": \"^2.1.0\",\n \"eslint\": \"^9.0.0\",\n \"globals\": \"^15.0.0\",\n \"prettier\": \"^3.0.0\",\n \"rimraf\": \"^5.0.0\",\n \"tsup\": \"^8.5.1\",\n \"typedoc\": \"^0.28.20\",\n \"typedoc-material-theme\": \"^1.4.1\",\n \"typescript\": \"^5.0.0\",\n \"typescript-eslint\": \"^8.0.0\",\n \"vitest\": \"^4.1.2\"\n },\n \"dependencies\": {\n \"@fastify/formbody\": \"^8.0.2\",\n \"@fastify/websocket\": \"^11.2.0\",\n \"axios\": \"^1.15.2\",\n \"axios-retry\": \"^4.5.0\",\n \"dotenv\": \"^16.4.7\",\n \"fastify\": \"^5.8.5\",\n \"fastify-graceful-shutdown\": \"^5.0.0\",\n \"pino\": \"^9.0.0\",\n \"twilio\": \"^5.10.7\",\n \"ws\": \"^8.19.0\",\n \"zod\": \"^4.0.0\"\n },\n \"peerDependencies\": {\n \"@openai/agents\": \"^0.8.0\"\n },\n \"peerDependenciesMeta\": {\n \"@openai/agents\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=22.13.0\",\n \"npm\": \">=9.0.0\"\n }\n}\n","import { Logger, createLogger } from '../lib/logger';\nimport { TACConfig } from '../lib/config';\nimport packageJson from '../../../../package.json' with { type: 'json' };\nimport axios, { AxiosInstance } from 'axios';\nimport axiosRetry from 'axios-retry';\n\nfunction buildUserAgent(): string {\n return `twilio-agent-connect-typescript/${packageJson.version}`;\n}\n\n/**\n * Base HTTP client for Twilio API services\n *\n * Features:\n * - Automatic Basic Auth using Twilio API credentials\n * - User-Agent header injection\n * - 30-second request timeout\n * - HTTP redirect following (up to 5 redirects) with auth preservation\n * - Automatic retry (up to 3 retries / 4 total attempts with exponential backoff)\n * - Error logging for failed requests\n * - Automatic JSON serialization/deserialization\n */\nexport abstract class BaseClient {\n protected readonly baseUrl: string;\n protected readonly logger: Logger;\n protected readonly axiosInstance: AxiosInstance;\n\n constructor(baseUrl: string, config: TACConfig, logger?: Logger) {\n this.baseUrl = baseUrl;\n this.logger = logger || createLogger({ name: this.constructor.name });\n\n // Create Authorization header for Basic Auth\n const authHeader =\n 'Basic ' + Buffer.from(`${config.apiKey}:${config.apiSecret}`).toString('base64');\n\n // Extract origin from baseUrl for same-origin check\n const baseOrigin = new URL(baseUrl).origin;\n\n this.axiosInstance = axios.create({\n baseURL: baseUrl,\n timeout: 30000,\n maxRedirects: 5,\n headers: {\n 'User-Agent': buildUserAgent(),\n Authorization: authHeader,\n },\n beforeRedirect: (options, _responseDetails) => {\n // Preserve auth header for same-origin redirects only (prevents credential leaks)\n const redirectUrl = new URL(\n String(options.path || ''),\n `${String(options.protocol)}//${String(options.host)}`\n );\n if (redirectUrl.origin === baseOrigin && options.headers) {\n (options.headers as Record<string, string>).Authorization = authHeader;\n }\n },\n });\n\n axiosRetry(this.axiosInstance, {\n retries: 3,\n retryDelay: retryCount => axiosRetry.exponentialDelay(retryCount),\n retryCondition: error => {\n // Retry network/no-response errors for any method, and retry 5xx/429 responses only for idempotent methods\n // (which helps prevent duplicate side effects on non-idempotent requests such as POST)\n return axiosRetry.isNetworkOrIdempotentRequestError(error);\n },\n });\n\n // Response interceptor for error logging\n this.axiosInstance.interceptors.response.use(\n response => response,\n error => {\n if (axios.isAxiosError(error)) {\n const status = error.response?.status;\n const logContext = {\n error: error.message,\n method: error.config?.method,\n url: error.config?.url,\n status,\n };\n // Log 4xx as warn (client errors, may be expected/handled)\n // Log 5xx/network as error (server/infrastructure failures)\n if (status !== undefined && status >= 400 && status < 500) {\n this.logger.warn(logContext, 'HTTP request client error');\n } else {\n this.logger.error(logContext, 'HTTP request error');\n }\n }\n throw error;\n }\n );\n }\n\n /**\n * Make an HTTP request with automatic header injection and error handling\n *\n * @param url - The URL path (relative to baseURL)\n * @param method - HTTP method (GET, POST, etc.)\n * @param data - Optional request body (will be automatically serialized to JSON)\n * @param params - Optional query string parameters\n * @returns Promise resolving to the response data (already parsed from JSON)\n * @throws Error on timeout, HTTP errors, or network failures\n */\n protected async makeRequest<TResponse = unknown>(\n url: string,\n method: string,\n data?: unknown,\n params?: Record<string, string>\n ): Promise<TResponse> {\n const response = await this.axiosInstance.request<TResponse>({\n url,\n method,\n data,\n params,\n });\n\n return response.data;\n }\n}\n","import { z } from 'zod';\nimport {\n MemoryRetrievalRequest,\n MemoryRetrievalRequestSchema,\n MemoryRetrievalResponse,\n EMPTY_MEMORY_RESPONSE,\n ObservationInfoSchema,\n SummaryInfoSchema,\n MemoryCommunicationSchema,\n ProfileLookupResponse,\n ProfileLookupResponseSchema,\n ProfileResponse,\n ProfileResponseSchema,\n ObservationCreateRequest,\n CreateObservationsRequest,\n CreateObservationResponse,\n CreateObservationResponseSchema,\n CreateConversationSummariesResponse,\n CreateConversationSummariesResponseSchema,\n} from '../types';\nimport { TACConfig } from '../lib/config';\nimport { Logger } from '../lib/logger';\nimport { BaseClient } from './base';\n\n/**\n * Memory client for interacting with Twilio Memory Service\n */\nexport class MemoryClient extends BaseClient {\n private readonly storeId: string;\n\n constructor(config: TACConfig, storeId: string, logger?: Logger) {\n const baseUrl = config.region\n ? `https://memory.${config.region}.twilio.com`\n : 'https://memory.twilio.com';\n super(baseUrl, config, logger);\n this.storeId = storeId;\n }\n\n /**\n * Get the store ID this client is configured for\n */\n public getStoreId(): string {\n return this.storeId;\n }\n\n /**\n * Retrieve memories for a specific profile\n *\n * @param profileId - The profile ID to retrieve memories for\n * @param request - Optional request parameters for filtering results\n * @returns Promise containing memory retrieval response\n */\n public async retrieveMemories(\n profileId: string,\n request: Partial<MemoryRetrievalRequest> = {}\n ): Promise<MemoryRetrievalResponse> {\n try {\n const url = `/v1/Stores/${this.storeId}/Profiles/${profileId}/Recall`;\n\n this.logger.debug(\n {\n memory_store_id: this.storeId,\n profile_id: profileId,\n request,\n },\n 'Retrieving memories'\n );\n\n // Validate and apply defaults through schema\n const validatedRequest = MemoryRetrievalRequestSchema.parse(request);\n\n // Serialize request to Memory API wire format (camelCase)\n const requestBody = {\n conversationId: validatedRequest.conversationId,\n query: validatedRequest.query,\n beginDate: validatedRequest.beginDate,\n endDate: validatedRequest.endDate,\n observationsLimit: validatedRequest.observationsLimit,\n summariesLimit: validatedRequest.summariesLimit,\n communicationsLimit: validatedRequest.communicationsLimit,\n relevanceThreshold: validatedRequest.relevanceThreshold,\n };\n\n // Remove undefined values\n const cleanedBody = Object.fromEntries(\n Object.entries(requestBody).filter(([_, value]) => value !== undefined)\n );\n\n const data = await this.makeRequest<MemoryRetrievalResponse>(url, 'POST', cleanedBody);\n\n this.logger.debug(\n {\n memory_store_id: this.storeId,\n profile_id: profileId,\n },\n 'Raw memory response received'\n );\n\n if (data === null || typeof data !== 'object') {\n this.logger.warn(\n {\n profile_id: profileId,\n memory_store_id: this.storeId,\n },\n 'Invalid memory response format'\n );\n return EMPTY_MEMORY_RESPONSE;\n }\n\n // Parse each item independently so a single malformed entry (e.g. an\n // unrecognized enum value) doesn't discard the entire response.\n const response = data as Record<string, unknown>;\n const observations = this.parseItems(\n response.observations,\n ObservationInfoSchema,\n 'observation',\n profileId\n );\n const summaries = this.parseItems(\n response.summaries,\n SummaryInfoSchema,\n 'summary',\n profileId\n );\n const communications = this.parseItems(\n response.communications,\n MemoryCommunicationSchema,\n 'communication',\n profileId\n );\n\n this.logger.debug(\n {\n memory_store_id: this.storeId,\n profile_id: profileId,\n observation_count: observations.length,\n summary_count: summaries.length,\n communication_count: communications.length,\n // Server-side query time; dominates /Recall when expansion runs.\n query_time_ms: (response.meta as { queryTime?: number } | undefined)?.queryTime,\n },\n 'Memory retrieval succeeded'\n );\n\n return { observations, summaries, communications };\n } catch (error) {\n this.logger.warn(\n {\n error: error instanceof Error ? error.message : String(error),\n profile_id: profileId,\n memory_store_id: this.storeId,\n },\n 'Memory retrieval error'\n );\n return EMPTY_MEMORY_RESPONSE;\n }\n }\n\n /** Cap on per-item validation warnings logged per response, to avoid flooding logs. */\n private static readonly MAX_INVALID_ITEM_LOGS = 10;\n\n /**\n * Validate an array of memory items one at a time, dropping (and logging)\n * any that fail validation while keeping the rest.\n *\n * Per-item warnings are capped at {@link MemoryClient.MAX_INVALID_ITEM_LOGS}\n * and followed by a single summary warning with the total `invalid_count`.\n */\n private parseItems<T>(\n value: unknown,\n schema: z.ZodType<T, unknown>,\n itemType: string,\n profileId: string\n ): T[] {\n if (value === undefined) {\n return [];\n }\n\n if (!Array.isArray(value)) {\n this.logger.warn(\n {\n profile_id: profileId,\n memory_store_id: this.storeId,\n item_type: itemType,\n received_type: typeof value,\n },\n 'Expected an array of memory items but received a non-array value'\n );\n return [];\n }\n\n const parsed: T[] = [];\n let invalidCount = 0;\n for (const [index, item] of value.entries()) {\n const result = schema.safeParse(item);\n if (result.success) {\n parsed.push(result.data);\n continue;\n }\n\n invalidCount += 1;\n if (invalidCount <= MemoryClient.MAX_INVALID_ITEM_LOGS) {\n this.logger.warn(\n {\n profile_id: profileId,\n memory_store_id: this.storeId,\n item_type: itemType,\n item_index: index,\n validation_errors: result.error.issues,\n },\n 'Dropping invalid memory item'\n );\n }\n }\n\n if (invalidCount > 0) {\n this.logger.warn(\n {\n profile_id: profileId,\n memory_store_id: this.storeId,\n item_type: itemType,\n invalid_count: invalidCount,\n total_count: value.length,\n },\n 'Dropped invalid memory items'\n );\n }\n\n return parsed;\n }\n\n /**\n * Find profiles that contain a specific identifier value\n *\n * @param idType - Identifier type (e.g., 'phone', 'email')\n * @param value - Raw value captured for the identifier\n * @returns Promise containing profile lookup response with normalized value and matching profile IDs\n */\n public async lookupProfile(idType: string, value: string): Promise<ProfileLookupResponse> {\n const url = `/v1/Stores/${this.storeId}/Profiles/Lookup`;\n\n const requestBody = {\n idType,\n value,\n };\n\n try {\n const data = await this.makeRequest<ProfileLookupResponse>(url, 'POST', requestBody);\n return ProfileLookupResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to lookup profile: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create a profile via identity resolution (upsert).\n *\n * Conversation Memory runs identity resolution on the submitted traits: if an identifier\n * match is found, the existing canonical profile ID is returned; otherwise a\n * new profile is minted. The body must contain at least one\n * trait-promoted-to-identifier per the store's identity resolution settings,\n * else resolution fails with 400.\n *\n * The write is queued (202 Accepted) — the canonical profile ID is returned\n * synchronously in the response body, but downstream traits may not be fully\n * persisted immediately.\n *\n * @param traits - Trait-group → field → value mapping (e.g. `{\"Contact\": {\"phone\": \"+13175551234\"}}`)\n * @returns Canonical profile ID (`mem_profile_…`)\n * @throws Error if the API request fails or the response is missing an `id` field\n */\n public async createProfile(traits: Record<string, Record<string, unknown>>): Promise<string> {\n const url = `/v1/Stores/${this.storeId}/Profiles`;\n const requestBody = { traits };\n\n let data: unknown;\n try {\n data = await this.makeRequest<unknown>(url, 'POST', requestBody);\n } catch (error) {\n throw new Error(\n `Failed to create profile: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n\n const profileId =\n data && typeof data === 'object' && 'id' in data ? (data as { id: unknown }).id : undefined;\n if (typeof profileId !== 'string') {\n throw new Error(`CreateProfile response missing 'id' field: ${JSON.stringify(data)}`);\n }\n return profileId;\n }\n\n /**\n * Fetch profile information with traits\n *\n * @param profileId - The profile ID to fetch\n * @param traitGroups - Optional list of trait group names to include\n * @returns Promise containing profile response with ID, created timestamp, and traits\n */\n public async getProfile(profileId: string, traitGroups?: string[]): Promise<ProfileResponse> {\n const url = `/v1/Stores/${this.storeId}/Profiles/${profileId}`;\n\n const params: Record<string, string> = {};\n if (traitGroups && traitGroups.length > 0) {\n params.traitGroups = traitGroups.join(',');\n }\n\n try {\n const data = await this.makeRequest<ProfileResponse>(\n url,\n 'GET',\n undefined,\n Object.keys(params).length > 0 ? params : undefined\n );\n return ProfileResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to get profile: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create an observation for a profile.\n *\n * The Memory API Observations endpoint is a batch create: the observation is\n * wrapped in an `observations` array and `occurredAt` is required, so it\n * defaults to the current time (ISO 8601) when omitted or blank.\n *\n * @param profileId - The profile ID to create the observation for\n * @param content - The observation content\n * @param source - Source of the observation (default: 'conversation-intelligence')\n * @param conversationIds - Optional array of conversation IDs associated with this observation\n * @param occurredAt - Timestamp when the observation occurred (ISO 8601); defaults to now when omitted or blank\n * @returns Promise containing the API confirmation message\n */\n public async createObservation(\n profileId: string,\n content: string,\n source: string = 'conversation-intelligence',\n conversationIds?: string[],\n occurredAt?: string\n ): Promise<CreateObservationResponse> {\n const url = `/v1/Stores/${this.storeId}/Profiles/${profileId}/Observations`;\n\n const observation: ObservationCreateRequest = {\n content,\n source,\n occurredAt: occurredAt && occurredAt.trim() ? occurredAt : new Date().toISOString(),\n };\n\n if (conversationIds && conversationIds.length > 0) {\n observation.conversationIds = conversationIds;\n }\n\n const requestBody: CreateObservationsRequest = { observations: [observation] };\n\n try {\n const data = await this.makeRequest<CreateObservationResponse>(url, 'POST', requestBody);\n return CreateObservationResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to create observation: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create conversation summaries for a profile\n *\n * @param profileId - The profile ID to create summaries for\n * @param summaries - Array of summary items to create\n * @returns Promise containing a success message for the created conversation summaries\n */\n public async createConversationSummaries(\n profileId: string,\n summaries: Array<{\n content: string;\n conversationId: string;\n occurredAt: string;\n source?: string;\n }>\n ): Promise<CreateConversationSummariesResponse> {\n const url = `/v1/Stores/${this.storeId}/Profiles/${profileId}/ConversationSummaries`;\n\n const requestBody = {\n summaries: summaries.map(s => ({\n content: s.content,\n conversationId: s.conversationId,\n occurredAt: s.occurredAt,\n source: s.source ?? 'conversation-intelligence',\n })),\n };\n\n try {\n const data = await this.makeRequest<CreateConversationSummariesResponse>(\n url,\n 'POST',\n requestBody\n );\n return CreateConversationSummariesResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to create conversation summaries: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n}\n","import {\n ActionResponse,\n ActionResponseSchema,\n Communication,\n ConversationResponse,\n ConversationResponseSchema,\n ConversationAddress,\n ConversationParticipant,\n ConversationParticipantSchema,\n SendMessageActionRequest,\n ConversationConfiguration,\n ConversationConfigurationSchema,\n ListCommunicationsResponse,\n ListCommunicationsResponseSchema,\n ListParticipantsResponse,\n ListParticipantsResponseSchema,\n ListConversationsResponse,\n ListConversationsResponseSchema,\n} from '../types';\nimport axios from 'axios';\nimport { TACConfig } from '../lib/config';\nimport { Logger } from '../lib/logger';\nimport { BaseClient } from './base';\n\n/**\n * Conversation client for interacting with Twilio Conversations Service\n */\nexport class ConversationClient extends BaseClient {\n private readonly conversationConfigurationId: string;\n\n constructor(config: TACConfig, logger?: Logger) {\n const baseUrl = config.region\n ? `https://conversations.${config.region}.twilio.com`\n : 'https://conversations.twilio.com';\n super(baseUrl, config, logger);\n if (!config.conversationConfigurationId) {\n throw new Error('conversationConfigurationId is required to create ConversationClient');\n }\n this.conversationConfigurationId = config.conversationConfigurationId;\n }\n\n /**\n * Create an action on a conversation via the Conversation Orchestrator Actions API.\n *\n * Currently supports SEND_MESSAGE actions. Returns 202 Accepted; the action is\n * processed asynchronously and delivered via COMMUNICATION_CREATED webhook.\n *\n * @param conversationId - The conversation ID\n * @param request - The action request ({type, payload})\n * @returns Promise containing the ActionResponse\n */\n public async createAction(\n conversationId: string,\n request: SendMessageActionRequest\n ): Promise<ActionResponse> {\n const url = `/v2/Conversations/${conversationId}/Actions`;\n\n try {\n const data = await this.makeRequest<ActionResponse>(url, 'POST', request);\n return ActionResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to create action: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * List communications for a conversation\n *\n * @param conversationId - The conversation ID\n * @returns Promise containing array of communications\n */\n public async listCommunications(conversationId: string): Promise<Communication[]> {\n const url = `/v2/Conversations/${conversationId}/Communications`;\n\n try {\n const data = await this.makeRequest<ListCommunicationsResponse>(url, 'GET');\n const validated = ListCommunicationsResponseSchema.parse(data);\n return validated.communications;\n } catch (error) {\n throw new Error(\n `Failed to list communications: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create a new conversation, optionally with inline participants.\n *\n * When participants are provided, CO creates them atomically with the\n * conversation. If an active conversation with the same participant\n * addresses already exists (respecting the configuration's group-by\n * rules), CO returns 409 with a pointer to the existing conversation.\n */\n public async createConversation(options?: {\n name?: string;\n participants?: Array<{\n type: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT';\n addresses: ConversationAddress[];\n }>;\n }): Promise<ConversationResponse> {\n const url = `/v2/Conversations`;\n\n const requestBody: Record<string, unknown> = {\n configurationId: this.conversationConfigurationId,\n };\n\n if (options?.name) {\n requestBody.name = options.name;\n }\n\n if (options?.participants) {\n requestBody.participants = options.participants;\n }\n\n try {\n const data = await this.makeRequest<ConversationResponse>(url, 'POST', requestBody);\n return ConversationResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to create conversation: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create a conversation with inline participants, reusing an existing active\n * conversation if CO returns 409 (group-by dedup).\n *\n * On 409 CO returns the existing conversation ID in the\n * X-Conflicting-Resource-Id response header.\n */\n public async createOrReuseConversation(\n participants: Array<{\n type: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT';\n addresses: ConversationAddress[];\n }>\n ): Promise<{ conversation: { id: string }; reused: boolean }> {\n try {\n const conversation = await this.createConversation({ participants });\n return { conversation, reused: false };\n } catch (error) {\n const existingId = this.extractConversationIdFrom409(error);\n if (existingId) {\n this.logger.info(\n { conversation_id: existingId },\n 'Reusing existing active conversation (409 dedup)'\n );\n return { conversation: { id: existingId }, reused: true };\n }\n throw error;\n }\n }\n\n /**\n * Extract conversation ID from a 409 response's X-Conflicting-Resource-Id header.\n */\n private extractConversationIdFrom409(error: unknown): string | null {\n // Unwrap: createConversation wraps the axios error in a generic Error\n const cause = error instanceof Error ? (error.cause ?? error) : error;\n if (!axios.isAxiosError(cause) || cause.response?.status !== 409) {\n return null;\n }\n\n const headers = cause.response.headers as Record<string, string> | undefined;\n const conflictId = headers?.['x-conflicting-resource-id'];\n return typeof conflictId === 'string' && conflictId.length > 0 ? conflictId : null;\n }\n\n /**\n * Add a participant to a conversation.\n *\n * @param conversationId - The conversation ID\n * @param addresses - Array of participant addresses\n * @param participantType - Type of participant (CUSTOMER, AI_AGENT, HUMAN_AGENT, AGENT)\n * @returns Promise containing participant response\n */\n public async addParticipant(\n conversationId: string,\n addresses: ConversationAddress[],\n participantType: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT' | 'AGENT'\n ): Promise<ConversationParticipant> {\n const url = `/v2/Conversations/${conversationId}/Participants`;\n\n const requestBody = {\n type: participantType,\n addresses,\n };\n\n try {\n const data = await this.makeRequest<ConversationParticipant>(url, 'POST', requestBody);\n return ConversationParticipantSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to add participant: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Replace an existing participant.\n *\n * PUT is a full resource replacement per the Conversation Orchestrator spec —\n * any field omitted from the body is cleared on the server. Callers must pass\n * the current `addresses` (and `name` if set) to preserve them.\n *\n * @param conversationId - Conversation ID containing the participant\n * @param participantId - Participant ID to update\n * @param participantType - New participant type\n * @param addresses - Current participant addresses (required to avoid wiping)\n * @param options.name - Current participant display name (optional)\n * @param options.profileId - Conversation Memory profile ID to attach (optional)\n * @returns Promise containing the updated participant\n */\n public async updateParticipant(\n conversationId: string,\n participantId: string,\n participantType: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT' | 'AGENT',\n addresses: ConversationAddress[],\n options?: { name?: string; profileId?: string }\n ): Promise<ConversationParticipant> {\n const url = `/v2/Conversations/${conversationId}/Participants/${participantId}`;\n\n const requestBody: Record<string, unknown> = {\n type: participantType,\n addresses,\n };\n if (options?.name !== undefined) {\n requestBody.name = options.name;\n }\n if (options?.profileId !== undefined) {\n requestBody.profileId = options.profileId;\n }\n\n try {\n const data = await this.makeRequest<ConversationParticipant>(url, 'PUT', requestBody);\n return ConversationParticipantSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to update participant: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * List participants in a conversation\n *\n * @param conversationId - The conversation ID\n * @returns Promise containing array of participants\n */\n public async listParticipants(conversationId: string): Promise<ConversationParticipant[]> {\n const url = `/v2/Conversations/${conversationId}/Participants`;\n\n try {\n const data = await this.makeRequest<ListParticipantsResponse>(url, 'GET');\n const validated = ListParticipantsResponseSchema.parse(data);\n return validated.participants;\n } catch (error) {\n throw new Error(\n `Failed to list participants: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * List conversations with optional filters\n *\n * @param filters - Optional filters (channelId, status)\n * @returns Promise containing array of conversations\n */\n public async listConversations(filters?: {\n channelId?: string;\n status?: string[];\n }): Promise<ConversationResponse[]> {\n const url = `/v2/Conversations`;\n\n const params: Record<string, string> = {};\n if (filters?.channelId) {\n params.channelId = filters.channelId;\n }\n if (filters?.status && filters.status.length > 0) {\n params.status = filters.status.join(',');\n }\n\n try {\n const data = await this.makeRequest<ListConversationsResponse>(\n url,\n 'GET',\n undefined,\n Object.keys(params).length > 0 ? params : undefined\n );\n const validated = ListConversationsResponseSchema.parse(data);\n return validated.conversations;\n } catch (error) {\n throw new Error(\n `Failed to list conversations: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Clear statusCallbacks on a conversation's instance configuration.\n *\n * This stops the conversation from sending webhook events to TAC,\n * which is needed during handoff so the receiving system can take over.\n *\n * @param conversationId - The conversation ID to update\n */\n public async clearStatusCallbacks(conversationId: string): Promise<void> {\n const url = `/v2/Conversations/${conversationId}`;\n\n try {\n await this.makeRequest<unknown>(url, 'PATCH', {\n configuration: { statusCallbacks: [] },\n });\n } catch (error) {\n throw new Error(\n `Failed to clear status callbacks: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Update conversation status\n *\n * @param conversationId - The conversation ID\n * @param status - New status (ACTIVE, INACTIVE, CLOSED)\n * @returns Promise containing updated conversation\n */\n public async updateConversation(\n conversationId: string,\n status: 'ACTIVE' | 'INACTIVE' | 'CLOSED'\n ): Promise<ConversationResponse> {\n const url = `/v2/Conversations/${conversationId}`;\n\n const requestBody = { status };\n\n try {\n const data = await this.makeRequest<ConversationResponse>(url, 'PUT', requestBody);\n return ConversationResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to update conversation: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Retrieve the details for a single configuration\n *\n * @param configurationId - The configuration ID to retrieve\n * @returns Promise containing configuration details\n */\n public async getConfiguration(configurationId: string): Promise<ConversationConfiguration> {\n const url = `/v2/ControlPlane/Configurations/${configurationId}`;\n\n try {\n const data = await this.makeRequest<ConversationConfiguration>(url, 'GET');\n return ConversationConfigurationSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to get configuration: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n}\n","import {\n KnowledgeBase,\n KnowledgeBaseSchema,\n KnowledgeChunkResult,\n KnowledgeSearchResponse,\n KnowledgeSearchResponseSchema,\n} from '../types';\nimport { TACConfig } from '../lib/config';\nimport { Logger } from '../lib/logger';\nimport { BaseClient } from './base';\n\n/**\n * Knowledge client for interacting with Twilio Knowledge Service\n */\nexport class KnowledgeClient extends BaseClient {\n constructor(config: TACConfig, logger?: Logger) {\n const baseUrl = config.region\n ? `https://knowledge.${config.region}.twilio.com`\n : 'https://knowledge.twilio.com';\n super(baseUrl, config, logger);\n }\n\n /**\n * Get knowledge base metadata\n *\n * @param knowledgeBaseId - The knowledge base ID (format: know_knowledgebase_*)\n * @returns Promise containing knowledge base metadata\n */\n public async getKnowledgeBase(knowledgeBaseId: string): Promise<KnowledgeBase> {\n const url = `/v2/ControlPlane/KnowledgeBases/${knowledgeBaseId}`;\n\n try {\n const data = await this.makeRequest<KnowledgeBase>(url, 'GET');\n return KnowledgeBaseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to get knowledge base: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Search knowledge base for relevant content\n *\n * @param knowledgeBaseId - The knowledge base ID (format: know_knowledgebase_*)\n * @param query - Search query (max 2048 characters)\n * @param topK - Maximum number of results to return (default: 5, max: 20)\n * @param knowledgeIds - Optional list of knowledge IDs to filter results\n * @returns Promise containing array of search result chunks\n */\n public async searchKnowledgeBase(\n knowledgeBaseId: string,\n query: string,\n topK: number = 5,\n knowledgeIds?: string[]\n ): Promise<KnowledgeChunkResult[]> {\n const url = `/v2/KnowledgeBases/${knowledgeBaseId}/Search`;\n\n const requestBody: Record<string, unknown> = {\n query,\n top: Math.min(Math.max(topK, 1), 20), // Clamp to 1-20\n };\n\n if (knowledgeIds && knowledgeIds.length > 0) {\n requestBody.knowledgeIds = knowledgeIds;\n }\n\n try {\n const data = await this.makeRequest<KnowledgeSearchResponse>(url, 'POST', requestBody);\n const validated = KnowledgeSearchResponseSchema.parse(data);\n return validated.chunks;\n } catch (error) {\n throw new Error(\n `Failed to search knowledge base: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n}\n","import {\n OperatorResultEvent,\n OperatorResultEventSchema,\n OperatorResult,\n OperatorProcessingResult,\n ConversationIntelligenceConfig,\n} from '../types/index';\nimport { MemoryClient } from '../clients/memory';\nimport { Logger, createLogger } from './logger';\n\n/**\n * Extract profile IDs from operator result execution details\n *\n * @param operatorResult - The operator result to extract profile IDs from\n * @returns Array of profile IDs found in participants\n */\nfunction extractProfileIds(operatorResult: OperatorResult): string[] {\n const profileIds: string[] = [];\n\n if (operatorResult.executionDetails?.participants) {\n for (const participant of operatorResult.executionDetails.participants) {\n if (participant.profileId) {\n profileIds.push(participant.profileId);\n }\n }\n }\n\n return profileIds;\n}\n\n/**\n * Generate content string from operator result\n *\n * @param operatorResult - The operator result to generate content from\n * @returns Content string or undefined if result is empty\n */\nfunction generateContent(operatorResult: OperatorResult): string | undefined {\n const result = operatorResult.result;\n\n if (result === null || result === undefined) {\n return undefined;\n }\n\n if (typeof result === 'string') {\n return result.trim() || undefined;\n }\n\n // For objects/arrays, stringify them\n const jsonString = JSON.stringify(result);\n return jsonString === '{}' || jsonString === '[]' ? undefined : jsonString;\n}\n\n/**\n * Parse summaries content from JSON result\n *\n * Expects format: { \"summaries\": [\"summary1\", \"summary2\", ...] }\n *\n * @param jsonContent - JSON string to parse\n * @returns Array of summary strings\n */\nfunction parseSummariesContent(jsonContent: string): string[] {\n try {\n const parsed = JSON.parse(jsonContent) as unknown;\n\n if (typeof parsed === 'object' && parsed !== null && 'summaries' in parsed) {\n const summaries = (parsed as { summaries: unknown }).summaries;\n if (Array.isArray(summaries)) {\n return summaries.filter((s): s is string => typeof s === 'string' && s.trim() !== '');\n }\n }\n\n return [];\n } catch {\n return [];\n }\n}\n\n/**\n * Processor for Conversation Intelligence operator result webhooks\n *\n * Processes operator results from CI and creates conversation summaries in the\n * Memory service based on the operator configuration.\n */\nexport class OperatorResultProcessor {\n private readonly memoryClient: MemoryClient;\n private readonly config: ConversationIntelligenceConfig;\n private readonly logger: Logger;\n\n constructor(memoryClient: MemoryClient, config: ConversationIntelligenceConfig, logger?: Logger) {\n this.memoryClient = memoryClient;\n this.config = config;\n this.logger = logger ?? createLogger({ name: 'cintel-processor' });\n }\n\n /**\n * Process an operator result event webhook payload\n *\n * @param payload - The raw webhook payload\n * @returns Processing result indicating success/failure and details\n */\n public async processEvent(payload: unknown): Promise<OperatorProcessingResult> {\n // Validate the payload\n const parseResult = OperatorResultEventSchema.safeParse(payload);\n\n if (!parseResult.success) {\n this.logger.warn(\n { validation_errors: parseResult.error.issues },\n 'Invalid operator result event payload'\n );\n return {\n success: false,\n skipped: false,\n error: `Invalid payload: ${parseResult.error.message}`,\n createdCount: 0,\n };\n }\n\n const event = parseResult.data;\n\n // Check if this event is from the configured CI configuration\n if (event.intelligenceConfiguration.id !== this.config.configurationId) {\n this.logger.debug(\n {\n received_config_id: event.intelligenceConfiguration.id,\n expected_config_id: this.config.configurationId,\n },\n 'Skipping event from different CI configuration'\n );\n return {\n success: true,\n skipped: true,\n skipReason: `Event from different CI configuration: ${event.intelligenceConfiguration.id}`,\n createdCount: 0,\n };\n }\n\n // Check for memory store ID and verify it matches the client's store ID\n if (!event.memoryStoreId) {\n this.logger.warn({ conversation_id: event.conversationId }, 'No memory store ID in event');\n return {\n success: false,\n skipped: false,\n error: 'No memory store ID provided in event',\n createdCount: 0,\n };\n }\n\n const clientStoreId = this.memoryClient.getStoreId();\n if (event.memoryStoreId !== clientStoreId) {\n this.logger.debug(\n {\n conversation_id: event.conversationId,\n event_store_id: event.memoryStoreId,\n client_store_id: clientStoreId,\n },\n 'Skipping event from different memory store'\n );\n return {\n success: true,\n skipped: true,\n skipReason: `Event from different memory store: ${event.memoryStoreId} (expected ${clientStoreId})`,\n createdCount: 0,\n };\n }\n\n // Process each operator result\n const results: OperatorProcessingResult[] = [];\n\n for (const operatorResult of event.operatorResults) {\n const result = await this.processOperatorResult(event, operatorResult);\n results.push(result);\n }\n\n // Aggregate results\n const successCount = results.filter(r => r.success && !r.skipped).length;\n const skippedCount = results.filter(r => r.skipped).length;\n const errorCount = results.filter(r => !r.success).length;\n const totalCreated = results.reduce((sum, r) => sum + r.createdCount, 0);\n\n // Determine overall event type\n const eventTypes = results\n .filter(r => r.success && !r.skipped && r.eventType)\n .map(r => r.eventType);\n const uniqueEventTypes = [...new Set(eventTypes)];\n const eventType =\n uniqueEventTypes.length === 1\n ? uniqueEventTypes[0]\n : uniqueEventTypes.length > 1\n ? 'mixed'\n : undefined;\n\n if (errorCount > 0) {\n const errors = results.filter(r => !r.success).map(r => r.error);\n return {\n success: false,\n eventType,\n skipped: false,\n error: `${errorCount} operator(s) failed: ${errors.join('; ')}`,\n createdCount: totalCreated,\n };\n }\n\n if (skippedCount === results.length) {\n return {\n success: true,\n skipped: true,\n skipReason: 'All operator results were skipped',\n createdCount: 0,\n };\n }\n\n this.logger.info(\n {\n conversation_id: event.conversationId,\n success_count: successCount,\n skipped_count: skippedCount,\n created_count: totalCreated,\n event_type: eventType,\n },\n 'Processed operator result event'\n );\n\n return {\n success: true,\n eventType,\n skipped: false,\n createdCount: totalCreated,\n };\n }\n\n /**\n * Process an individual operator result\n */\n private async processOperatorResult(\n event: OperatorResultEvent,\n operatorResult: OperatorResult\n ): Promise<OperatorProcessingResult> {\n const operatorSid = operatorResult.operator.id;\n\n // Check if this is a configured operator\n const isSummaryOperator = this.config.summaryOperatorSid === operatorSid;\n\n if (!isSummaryOperator) {\n this.logger.debug(\n {\n operator_sid: operatorSid,\n summary_operator_sid: this.config.summaryOperatorSid,\n },\n 'Skipping unconfigured operator'\n );\n return {\n success: true,\n skipped: true,\n skipReason: `Operator ${operatorSid} is not configured for processing`,\n createdCount: 0,\n };\n }\n\n // Generate content from operator result\n const content = generateContent(operatorResult);\n\n if (!content) {\n this.logger.debug(\n { operator_sid: operatorSid },\n 'Skipping operator result with empty content'\n );\n return {\n success: true,\n skipped: true,\n skipReason: 'Operator result has empty content',\n createdCount: 0,\n };\n }\n\n // Extract profile IDs from execution details\n const profileIds = extractProfileIds(operatorResult);\n\n if (profileIds.length === 0) {\n this.logger.warn(\n { operator_sid: operatorSid, conversation_id: event.conversationId },\n 'No profile IDs found in operator result'\n );\n return {\n success: true,\n skipped: true,\n skipReason: 'No profile IDs found in operator result execution details',\n createdCount: 0,\n };\n }\n\n return this.processSummaryEvent(event, operatorResult, content, profileIds);\n }\n\n /**\n * Process a summary operator result\n */\n private async processSummaryEvent(\n event: OperatorResultEvent,\n operatorResult: OperatorResult,\n content: string,\n profileIds: string[]\n ): Promise<OperatorProcessingResult> {\n // Parse summaries from JSON content\n const summaries = parseSummariesContent(content);\n\n if (summaries.length === 0) {\n this.logger.debug(\n { operator_sid: operatorResult.operator.id },\n 'No summaries found in content'\n );\n return {\n success: true,\n eventType: 'summary',\n skipped: true,\n skipReason: 'No summaries found in operator result content',\n createdCount: 0,\n };\n }\n\n let createdCount = 0;\n\n // Create summaries for each profile\n for (const profileId of profileIds) {\n try {\n const summaryItems = summaries.map(summaryContent => ({\n content: summaryContent,\n conversationId: event.conversationId,\n occurredAt: operatorResult.dateCreated,\n source: 'conversation-intelligence',\n }));\n\n await this.memoryClient.createConversationSummaries(profileId, summaryItems);\n createdCount += summaries.length;\n\n this.logger.debug(\n {\n profile_id: profileId,\n conversation_id: event.conversationId,\n summary_count: summaries.length,\n },\n 'Created conversation summaries'\n );\n } catch (error) {\n this.logger.error(\n {\n err: error,\n profile_id: profileId,\n conversation_id: event.conversationId,\n },\n 'Failed to create conversation summaries'\n );\n return {\n success: false,\n eventType: 'summary',\n skipped: false,\n error: `Failed to create summaries: ${error instanceof Error ? error.message : String(error)}`,\n createdCount,\n };\n }\n }\n\n return {\n success: true,\n eventType: 'summary',\n skipped: false,\n createdCount,\n };\n }\n}\n","import {\n TACConfigData,\n ConversationSession,\n ConversationId,\n ProfileId,\n ProfileResponse,\n ChannelType,\n OperatorProcessingResult,\n} from '../types';\nimport { TACMemoryResponse } from './tac-memory-response';\nimport { TACConfig } from './config';\nimport { MemoryClient } from '../clients/memory';\nimport { ConversationClient } from '../clients/conversation';\nimport { KnowledgeClient } from '../clients/knowledge';\nimport { BaseChannel } from '../channels/base';\nimport { Logger, createLogger } from './logger';\nimport { maskAddress } from '../util/log-redaction';\nimport { OperatorResultProcessor } from './operator-result-processor';\n\nexport interface TACOptions {\n config?: TACConfig | TACConfigData;\n logger?: Logger;\n}\n\n/**\n * Callback function signatures for TAC events\n */\nexport type MessageReadyCallback = (params: {\n conversationId: ConversationId;\n profileId: ProfileId | undefined;\n message: string;\n author: string;\n memory: TACMemoryResponse | undefined;\n session: ConversationSession;\n channel: ChannelType;\n abortSignal?: AbortSignal;\n}) => Promise<string | null | void> | string | null | void;\n\nexport type InterruptCallback = (params: {\n conversationId: ConversationId;\n utteranceUntilInterrupt: string | undefined;\n durationUntilInterruptMs: number | undefined;\n session: ConversationSession;\n}) => Promise<void> | void;\n\nexport type ConversationEndedCallback = (params: {\n session: ConversationSession;\n}) => Promise<void> | void;\n\n/**\n * Main Twilio Agent Connect class\n *\n * Central orchestrator that manages configuration, channels (SMS, WhatsApp, Chat, Voice),\n * callbacks, and coordinates between memory, conversations, and LLM integrations.\n */\nexport class TAC {\n private static readonly FACTORY_TOKEN = Symbol('TAC.create');\n\n private readonly config: TACConfig;\n public readonly logger: Logger;\n private memoryClient: MemoryClient | null = null;\n private knowledgeClient: KnowledgeClient | null = null;\n private conversationClient: ConversationClient | null = null;\n private readonly channels: Map<ChannelType, BaseChannel>;\n private cintelProcessor?: OperatorResultProcessor;\n\n private memoryStoreId: string | undefined;\n\n // Callback registrations\n private messageReadyCallback?: MessageReadyCallback;\n private interruptCallback?: InterruptCallback;\n private conversationEndedCallback?: ConversationEndedCallback;\n\n private constructor(token: symbol, options: TACOptions = {}) {\n if (token !== TAC.FACTORY_TOKEN) {\n throw new Error('TAC constructor is private. Use TAC.create() instead of new TAC().');\n }\n // Handle config resolution:\n // - If it's already a TACConfig instance, use it\n // - If it's data, create a new TACConfig\n // - If not provided, load from environment variables\n const finalConfig = options.config\n ? options.config instanceof TACConfig\n ? options.config\n : new TACConfig(options.config)\n : TACConfig.fromEnv();\n const finalLogger = options.logger ?? createLogger({ name: 'tac' });\n\n this.config = finalConfig;\n this.logger = finalLogger;\n this.channels = new Map();\n }\n\n public static async create(options: TACOptions = {}): Promise<TAC> {\n const tac = new TAC(TAC.FACTORY_TOKEN, options);\n\n if (!tac.config.isOrchestratorEnabled()) {\n tac.logger.info(\n 'Voice-only mode: conversationConfigurationId not set, skipping Conversation Orchestrator initialization'\n );\n return tac;\n }\n\n try {\n tac.conversationClient = new ConversationClient(\n tac.config,\n tac.logger.child({ component: 'conversation' })\n );\n\n // Safe: we already returned early if !isOrchestratorEnabled(), so conversationConfigurationId is defined\n const conversationConfig = await tac.conversationClient.getConfiguration(\n tac.config.conversationConfigurationId!\n );\n\n tac.memoryStoreId = conversationConfig.memoryStoreId;\n tac.memoryClient = new MemoryClient(\n tac.config,\n conversationConfig.memoryStoreId,\n tac.logger.child({ component: 'memory' })\n );\n\n tac.knowledgeClient = new KnowledgeClient(\n tac.config,\n tac.logger.child({ component: 'knowledge' })\n );\n\n if (tac.config.cintelConfigurationId) {\n tac.cintelProcessor = new OperatorResultProcessor(\n tac.memoryClient,\n {\n configurationId: tac.config.cintelConfigurationId,\n summaryOperatorSid: tac.config.cintelSummaryOperatorSid,\n },\n tac.logger.child({ component: 'cintel' })\n );\n }\n\n return tac;\n } catch (error) {\n tac.logger.error({ err: error }, 'TAC initialization failed');\n throw error;\n }\n }\n\n /**\n * Register a channel with the framework\n */\n public registerChannel(channel: BaseChannel): void {\n this.logger.info({ channel: channel.channelType }, 'Registering channel');\n\n // Remove existing channel of same type\n const existingChannel = this.channels.get(channel.channelType);\n if (existingChannel) {\n this.logger.info({ channel: channel.channelType }, 'Replacing existing channel registration');\n existingChannel.shutdown();\n }\n\n this.channels.set(channel.channelType, channel);\n\n // Set up channel event listeners\n this.setupChannelEventListeners(channel);\n\n this.logger.info({ channel: channel.channelType }, 'Channel registration complete');\n }\n\n /**\n * Set up event listeners for a channel\n */\n private setupChannelEventListeners(channel: BaseChannel): void {\n // Handle channel errors directly\n channel.on(\n 'error',\n ({ error, context }: { error: Error; context?: Record<string, unknown> }) => {\n this.logger.error({ err: error, ...context }, 'Channel error');\n }\n );\n\n // Handle message received events for SMS channels\n channel.on(\n 'messageReceived',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises -- Intentionally async callback\n async (data: {\n conversationId: ConversationId;\n profileId: ProfileId | undefined;\n message: string;\n author: string;\n userMemory: TACMemoryResponse | undefined;\n }): Promise<void> => {\n await this.handleMessageReady({ ...data, channelType: channel.channelType });\n }\n );\n\n // Handle voice prompt events\n channel.on(\n 'prompt',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises -- Intentionally async callback\n async ({\n conversationId,\n transcript,\n userMemory,\n session,\n abortSignal,\n }: {\n conversationId: ConversationId;\n transcript: string;\n userMemory?: TACMemoryResponse;\n session?: ConversationSession;\n abortSignal: AbortSignal;\n }): Promise<void> => {\n // Use session from event if available, otherwise get from channel\n const eventSession = session || channel.getConversationSession(conversationId);\n if (eventSession) {\n await this.handleMessageReady({\n conversationId,\n profileId: eventSession.profileId ? (eventSession.profileId as ProfileId) : undefined,\n message: transcript,\n author: 'user',\n userMemory,\n channelType: channel.channelType,\n abortSignal,\n });\n }\n }\n );\n\n // Handle voice interrupt events\n channel.on(\n 'interrupt',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises -- Intentionally async event handler\n async ({\n conversationId,\n utteranceUntilInterrupt,\n durationUntilInterruptMs,\n }: {\n conversationId: ConversationId;\n utteranceUntilInterrupt: string | undefined;\n durationUntilInterruptMs: number | undefined;\n }) => {\n const session = channel.getConversationSession(conversationId);\n if (session && this.interruptCallback) {\n try {\n await this.interruptCallback({\n conversationId,\n utteranceUntilInterrupt,\n durationUntilInterruptMs,\n session,\n });\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: conversationId },\n 'Interrupt callback error'\n );\n }\n }\n }\n );\n\n // Handle conversation ended events\n channel.on(\n 'conversationEnded',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises -- Intentionally async event handler\n async ({ session }: { session: ConversationSession }) => {\n if (this.conversationEndedCallback) {\n try {\n await this.conversationEndedCallback({ session });\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: session.conversationId },\n 'Conversation ended callback error'\n );\n }\n }\n }\n );\n }\n\n /**\n * Handle message ready event from channels\n */\n private async handleMessageReady(data: {\n conversationId: ConversationId;\n profileId: ProfileId | undefined;\n message: string;\n author: string;\n userMemory: TACMemoryResponse | undefined;\n channelType: ChannelType;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n this.logger.debug(\n {\n conversation_id: data.conversationId,\n profile_id: data.profileId,\n author: maskAddress(data.author),\n message_length: data.message.length,\n channel: data.channelType,\n operation: 'handle_message_ready',\n },\n 'Handling message ready'\n );\n\n if (!this.messageReadyCallback) {\n this.logger.warn('No message ready callback registered');\n return;\n }\n\n try {\n // Use the channel type passed from the event handler, not lookup by conversation ID\n // This ensures voice prompts use voice channel even if SMS also has this conversation\n const channel = this.channels.get(data.channelType);\n if (!channel) {\n throw new Error(`No channel found for type ${data.channelType}`);\n }\n\n this.logger.debug(\n { conversation_id: data.conversationId, channel: channel.channelType },\n 'Using channel for message'\n );\n\n const session = channel.getConversationSession(data.conversationId);\n if (!session) {\n throw new Error(`No session found for conversation ${data.conversationId}`);\n }\n\n // Memory is now fetched by channels based on their memoryMode configuration\n const memory = data.userMemory;\n\n // Execute callback\n this.logger.debug(\n { conversation_id: data.conversationId },\n 'Executing message ready callback'\n );\n try {\n const response = await this.messageReadyCallback({\n conversationId: data.conversationId,\n profileId: data.profileId,\n message: data.message,\n author: data.author,\n memory: memory ?? undefined,\n session,\n channel: channel.channelType,\n ...(data.abortSignal !== undefined && { abortSignal: data.abortSignal }),\n });\n this.logger.debug(\n { conversation_id: data.conversationId },\n 'Message ready callback completed'\n );\n\n // Auto-send if callback returned a string\n if (typeof response === 'string') {\n if (response === '') {\n this.logger.warn(\n { conversation_id: data.conversationId },\n 'Callback returned empty string, skipping auto-send'\n );\n } else {\n try {\n await channel.sendResponse(data.conversationId, response);\n } catch (sendError) {\n this.logger.error(\n { err: sendError, conversation_id: data.conversationId },\n 'Failed to auto-send callback response'\n );\n }\n }\n }\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: data.conversationId },\n 'Message ready callback error'\n );\n }\n\n this.logger.debug({ conversation_id: data.conversationId }, 'Message handling completed');\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: data.conversationId },\n 'Message handling error'\n );\n }\n }\n\n /**\n * Register callback for when messages are ready to be processed.\n * Return a string to auto-send, or null/void for manual handling.\n */\n public onMessageReady(callback: MessageReadyCallback): void {\n this.messageReadyCallback = callback;\n }\n\n /**\n * Register callback for when user interrupts (voice channel)\n */\n public onInterrupt(callback: InterruptCallback): void {\n this.interruptCallback = callback;\n }\n\n /**\n * Register callback for when a conversation ends.\n *\n * The callback is triggered by channels when a conversation is closed\n * (e.g., SMS conversation status changed to CLOSED, or voice WebSocket\n * disconnected). The callback receives the full ConversationSession before\n * it is cleaned up.\n */\n public onConversationEnded(callback: ConversationEndedCallback): void {\n this.conversationEndedCallback = callback;\n }\n\n /**\n * Whether Conversation Orchestrator is configured.\n * Returns false in voice-only mode.\n *\n * @internal\n */\n public isOrchestratorEnabled(): boolean {\n return this.config.isOrchestratorEnabled();\n }\n\n /**\n * Get registered channel by type\n */\n public getChannel<T extends BaseChannel>(channelType: ChannelType): T | undefined {\n return this.channels.get(channelType) as T | undefined;\n }\n\n /**\n * Get configuration\n */\n public getConfig(): TACConfig {\n return this.config;\n }\n\n /**\n * Get memory client for advanced memory operations.\n * Returns null in voice-only mode.\n */\n public getMemoryClient(): MemoryClient | null {\n return this.memoryClient;\n }\n\n /**\n * Get the memory store ID resolved from the ConversationConfiguration at startup.\n * Returns undefined in voice-only mode.\n */\n public getMemoryStoreId(): string | undefined {\n return this.memoryStoreId;\n }\n\n /**\n * Get knowledge client for knowledge base operations.\n * Returns null in voice-only mode.\n */\n public getKnowledgeClient(): KnowledgeClient | null {\n return this.knowledgeClient;\n }\n\n /**\n * Get conversation client for advanced conversation operations.\n * Returns null in voice-only mode.\n */\n public getConversationClient(): ConversationClient | null {\n return this.conversationClient;\n }\n\n /**\n * Check if Conversation Intelligence processing is enabled\n *\n * @returns true if CI processor is initialized, false otherwise\n */\n public isCintelEnabled(): boolean {\n return this.cintelProcessor !== undefined;\n }\n\n /**\n * Process a Conversation Intelligence operator result webhook event\n *\n * @param payload - The raw webhook payload from CI\n * @returns Promise containing the processing result\n * @throws Error if CI processor is not initialized\n */\n public async processCintelEvent(payload: unknown): Promise<OperatorProcessingResult> {\n if (!this.cintelProcessor) {\n throw new Error(\n 'Conversation Intelligence processor is not initialized. ' +\n 'Ensure cintelConfigurationId is provided in TAC configuration.'\n );\n }\n return this.cintelProcessor.processEvent(payload);\n }\n\n /**\n * Retrieve memories from Memory API with automatic fallback to Conversations API\n *\n * @param session - Conversation session context\n * @param query - Optional semantic search query\n * @param conversationId - Passed through to `/Recall` as-is. Sending one\n * without a `query` makes Memory infer one from that conversation's history\n * — an expensive server-side step — so leave it unset when there is no\n * per-turn topic (e.g. `\"once\"` mode's cache-priming fetch).\n * @returns Promise containing TACMemoryResponse wrapper providing unified access to memory data.\n *\n * Attempts to retrieve from Memory API first:\n * - observations, summaries, and communications available\n * - communications include author name and type\n *\n * Falls back to Conversations API on error:\n * - observations and summaries are empty arrays\n * - communications have basic fields only (no author name/type)\n */\n public async retrieveMemory(\n session: ConversationSession,\n query?: string,\n conversationId?: string\n ): Promise<TACMemoryResponse> {\n if (!this.isOrchestratorEnabled()) {\n return new TACMemoryResponse([]);\n }\n\n try {\n // If profileId is missing, try to lookup profile using address\n if (!session.profileId) {\n // Check if authorInfo and address are available\n if (!session.authorInfo || !session.authorInfo.address) {\n throw new Error(\n 'profileId is required for memory retrieval but was not found in ' +\n 'conversation context. Additionally, authorInfo.address is not available ' +\n 'for profile lookup. Ensure either profileId or authorInfo.address is ' +\n 'provided when creating the ConversationSession.'\n );\n }\n\n // Determine identity type based on address format\n // Email addresses contain '@', phone numbers start with '+'\n const address = session.authorInfo.address;\n let identityType: 'email' | 'phone';\n if (address.includes('@')) {\n identityType = 'email';\n } else if (address.startsWith('+')) {\n identityType = 'phone';\n } else {\n throw new Error(\n `Unsupported authorInfo.address format '${maskAddress(address)}'. ` +\n \"Expected an email address containing '@' or a phone number starting with '+'.\"\n );\n }\n this.logger.debug(\n { identityType, address: maskAddress(address), channel: session.channel },\n 'profileId not found, attempting to lookup profile'\n );\n\n if (!this.memoryClient) {\n throw new Error('Memory client is not available');\n }\n\n // Lookup profile using appropriate identity type\n const lookupResponse = await this.memoryClient.lookupProfile(\n identityType,\n session.authorInfo.address\n );\n\n // Check if any profiles were found\n if (!lookupResponse.profiles || lookupResponse.profiles.length === 0) {\n throw new Error(\n `No profile found for ${identityType} ${maskAddress(session.authorInfo.address)}. ` +\n 'Profile lookup returned no results. Ensure the identity ' +\n 'is registered in the identity resolution system.'\n );\n }\n\n // Use the first profile ID\n session.profileId = lookupResponse.profiles[0];\n }\n\n if (!session.profileId) {\n throw new Error('Profile ID is required but was not resolved');\n }\n\n if (!this.memoryClient) {\n throw new Error('Memory client is not available');\n }\n\n const memoryResponse = await this.memoryClient.retrieveMemories(session.profileId, {\n conversationId,\n query,\n observationsLimit: this.config.memoryConfig.observationsLimit,\n summariesLimit: this.config.memoryConfig.summariesLimit,\n communicationsLimit: this.config.memoryConfig.communicationsLimit,\n relevanceThreshold: this.config.memoryConfig.relevanceThreshold,\n });\n return new TACMemoryResponse(memoryResponse);\n } catch (error) {\n this.logger.warn(\n { err: error },\n 'Failed to retrieve memory from Memory API, falling back to Conversations API'\n );\n\n try {\n if (!this.conversationClient) {\n throw new Error('Conversation client is not available');\n }\n const communications = await this.conversationClient.listCommunications(\n session.conversationId\n );\n\n return new TACMemoryResponse(communications);\n } catch (fallbackError) {\n this.logger.error({ err: fallbackError }, 'Failed to retrieve communications');\n throw fallbackError;\n }\n }\n }\n\n /**\n * Fetch profile information with traits\n *\n * @param profileId - Profile ID to fetch\n * @returns Promise containing profile response or undefined if not available\n */\n public async fetchProfile(profileId: string): Promise<ProfileResponse | undefined> {\n if (!profileId) {\n this.logger.warn('profile_id is required for profile fetching but was not provided');\n return undefined;\n }\n\n if (!this.memoryClient) {\n this.logger.warn('Memory client is not available (voice-only mode)');\n return undefined;\n }\n\n try {\n const traitGroups = this.config.memoryConfig.traitGroups;\n const profileResponse = await this.memoryClient.getProfile(profileId, traitGroups);\n return profileResponse;\n } catch (error) {\n this.logger.error({ err: error }, `Failed to fetch profile for ${profileId}`);\n return undefined;\n }\n }\n\n /**\n * Shutdown TAC and cleanup resources\n */\n public shutdown(): void {\n for (const channel of this.channels.values()) {\n this.logger.debug({ channel: channel.channelType }, 'Shutting down channel');\n channel.shutdown();\n }\n\n this.channels.clear();\n this.logger.info('TAC shutdown complete');\n }\n}\n","import {\n ConversationSession,\n ChannelType,\n ConversationId,\n ConversationWebhookPayload,\n ProfileId,\n MemoryMode,\n MemoryModeSchema,\n isConversationId,\n isProfileId,\n} from '../types/index';\nimport { TACConfig } from '../lib/config';\nimport { ConversationClient } from '../clients/conversation';\nimport { Logger } from '../lib/logger';\nimport type { TAC } from '../lib/tac';\nimport { TACMemoryResponse } from '../lib/tac-memory-response';\n\n/**\n * Base channel event callbacks\n */\nexport interface BaseChannelEvents {\n onConversationStarted?: (data: { session: ConversationSession }) => void;\n onConversationEnded?: (data: { session: ConversationSession }) => Promise<void> | void;\n onError?: (data: { error: Error; context?: Record<string, unknown> }) => void;\n}\n\n/**\n * Base channel options\n */\nexport interface BaseChannelOptions {\n /**\n * Memory retrieval mode for this channel. Default is \"never\".\n *\n * - \"never\": Memory is not automatically retrieved. Use the memory TAC tool or manually call `tac.retrieveMemory()` in callbacks for conditional retrieval.\n * - \"always\": Memory is automatically retrieved (using the message as query) for every inbound message and available in `onMessageReady` callback.\n * - \"once\": Memory is retrieved once at conversation start with no query (and no conversation id) and cached on the session. Subsequent messages reuse the cache until the conversation becomes INACTIVE.\n */\n memoryMode?: MemoryMode;\n\n /**\n * Maximum number of idempotency tokens to track for webhook deduplication.\n * Default is 10000. Must be a positive integer.\n */\n dedupCapacity?: number;\n}\n\n/**\n * Abstract base class for all channel implementations\n *\n * Provides common functionality for:\n * - Conversation lifecycle management and session tracking\n * - Webhook deduplication using Twilio idempotency tokens\n * - Event filtering to prevent cross-channel fanout\n * - Memory retrieval integration\n * - Error handling and logging\n *\n * Subclasses must implement channel-specific webhook processing and message sending.\n */\nexport abstract class BaseChannel {\n protected readonly tac: TAC;\n protected readonly config: TACConfig;\n protected readonly logger: Logger;\n protected readonly conversationClient: ConversationClient | null;\n protected readonly activeConversations: Map<ConversationId, ConversationSession>;\n protected readonly callbacks: BaseChannelEvents;\n protected readonly memoryMode: MemoryMode;\n private readonly processedWebhookTokens: Set<string>;\n private readonly maxTrackedTokens: number;\n\n constructor(tac: TAC, options?: BaseChannelOptions) {\n this.tac = tac;\n this.config = tac.getConfig();\n this.logger = tac.logger.child({ component: 'channel' });\n this.conversationClient = tac.getConversationClient();\n this.activeConversations = new Map();\n this.callbacks = {};\n\n // Validate memoryMode with runtime check for JS consumers\n const providedMode = options?.memoryMode;\n const modeToValidate = providedMode === undefined ? 'never' : providedMode;\n const parseResult = MemoryModeSchema.safeParse(modeToValidate);\n if (!parseResult.success) {\n throw new Error(\n `Invalid memoryMode: \"${modeToValidate}\". Must be \"always\", \"once\", or \"never\".`\n );\n }\n this.memoryMode = parseResult.data;\n\n // Validate and set deduplication capacity\n const capacity = options?.dedupCapacity ?? 10000;\n if (capacity < 1 || !Number.isInteger(capacity)) {\n throw new Error('dedupCapacity must be a positive integer');\n }\n this.maxTrackedTokens = capacity;\n this.processedWebhookTokens = new Set();\n }\n\n /**\n * Get the channel type (implemented by subclasses)\n */\n public abstract get channelType(): ChannelType;\n\n /**\n * Register event callbacks\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic event callback needs to accept any args\n public on(event: string, callback: (...args: any[]) => void): void {\n switch (event) {\n case 'conversationStarted':\n this.callbacks.onConversationStarted = callback;\n break;\n case 'conversationEnded':\n this.callbacks.onConversationEnded = callback;\n break;\n case 'error':\n this.callbacks.onError = callback;\n break;\n }\n }\n\n /**\n * Process incoming webhook data (implemented by subclasses)\n */\n public abstract processWebhook(payload: unknown): Promise<void>;\n\n /**\n * Send a response back to the user (implemented by subclasses)\n */\n public abstract sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void>;\n\n /**\n * Start a new conversation session\n */\n protected startConversation(\n conversationId: ConversationId,\n profileId?: ProfileId,\n serviceId?: string\n ): ConversationSession {\n if (this.activeConversations.has(conversationId)) {\n this.logger.debug(\n {\n conversation_id: conversationId,\n profile_id: this.activeConversations.get(conversationId)?.profileId,\n service_id: this.activeConversations.get(conversationId)?.serviceId,\n },\n 'Conversation already active'\n );\n return this.activeConversations.get(conversationId)!;\n }\n\n const session: ConversationSession = {\n conversationId: conversationId,\n profileId: profileId,\n serviceId: serviceId,\n channel: this.channelType,\n startedAt: new Date(),\n metadata: {},\n };\n\n this.activeConversations.set(conversationId, session);\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n profile_id: profileId,\n service_id: serviceId,\n channel: this.channelType,\n },\n 'Conversation started'\n );\n\n if (this.callbacks.onConversationStarted) {\n this.callbacks.onConversationStarted({ session });\n }\n\n return session;\n }\n\n /**\n * End a conversation session.\n *\n * Triggers the onConversationEnded callback BEFORE removing the session,\n * so the callback receives the full ConversationSession data.\n * Errors in the callback do not prevent session cleanup.\n */\n protected async endConversation(conversationId: ConversationId): Promise<void> {\n const session = this.activeConversations.get(conversationId);\n\n if (session) {\n // Trigger callback BEFORE deleting the session\n if (this.callbacks.onConversationEnded) {\n try {\n await this.callbacks.onConversationEnded({ session });\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: conversationId },\n 'Error in conversation ended callback'\n );\n }\n }\n\n this.activeConversations.delete(conversationId);\n this.logger.debug(\n {\n conversation_id: conversationId,\n channel: this.channelType,\n service_id: session.serviceId,\n },\n 'Conversation ended'\n );\n } else {\n this.logger.debug(\n { conversation_id: conversationId, channel: this.channelType },\n 'Conversation end requested but no active session found'\n );\n }\n }\n\n /**\n * Get an active conversation session\n */\n public getConversationSession(conversationId: ConversationId): ConversationSession | undefined {\n return this.activeConversations.get(conversationId);\n }\n\n /**\n * Check if a conversation is active\n */\n public isConversationActive(conversationId: ConversationId): boolean {\n return this.activeConversations.has(conversationId);\n }\n\n /**\n * Handle errors with proper context\n */\n protected handleError(error: Error, context?: Record<string, unknown>): void {\n this.logger.error({ err: error }, 'Channel error');\n\n if (this.callbacks.onError) {\n if (context) {\n this.callbacks.onError({ error, context });\n } else {\n this.callbacks.onError({ error });\n }\n }\n }\n\n /**\n * Check if a webhook has already been processed using Twilio's idempotency token.\n * Uses a sliding window with fixed capacity to track tokens (FIFO eviction).\n *\n * This is intentionally a single synchronous check-and-record to prevent race conditions\n * where a duplicate arrives while the first request is still awaiting async work.\n */\n protected isDuplicateWebhook(idempotencyToken: string): boolean {\n if (this.processedWebhookTokens.has(idempotencyToken)) {\n return true;\n }\n\n if (this.processedWebhookTokens.size >= this.maxTrackedTokens) {\n const oldest = this.processedWebhookTokens.values().next().value!;\n this.processedWebhookTokens.delete(oldest);\n }\n\n this.processedWebhookTokens.add(idempotencyToken);\n return false;\n }\n\n /**\n * Remove an idempotency token from the deduplication cache.\n * Used when webhook processing fails and retries should not be blocked.\n */\n protected removeWebhookToken(idempotencyToken: string): void {\n this.processedWebhookTokens.delete(idempotencyToken);\n }\n\n /**\n * Self-filtering: check if webhook event belongs to this channel.\n *\n * - COMMUNICATION_CREATED: require author.channel matches this channel type\n * - CONVERSATION_UPDATED: only process if conversation is tracked locally\n * - Other events: pass through\n */\n protected isEventForThisChannel(webhookData: ConversationWebhookPayload): boolean {\n const eventType = webhookData.eventType;\n const authorChannel = webhookData.data?.author?.channel;\n\n // COMMUNICATION_CREATED: require author.channel for safe filtering\n // Reject events without channel to prevent fanout crosstalk\n if (eventType === 'COMMUNICATION_CREATED') {\n if (!authorChannel) {\n return false;\n }\n return authorChannel === this.channelType.toUpperCase();\n }\n\n // CONVERSATION_UPDATED: only process if this channel tracks the conversation\n if (eventType === 'CONVERSATION_UPDATED') {\n const conversationId = this.extractConversationId(webhookData);\n if (conversationId && !this.activeConversations.has(conversationId)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Validate webhook payload (override in subclasses for specific validation)\n */\n protected validateWebhookPayload(payload: unknown): boolean {\n return payload !== null && payload !== undefined;\n }\n\n /**\n * Preprocess webhook before handling event-specific logic.\n * Handles deduplication, validation, filtering, and data extraction.\n *\n * @param payload - Raw webhook payload from Twilio\n * @param idempotencyToken - Optional idempotency token for deduplication\n * @returns Preprocessed webhook data, or null if webhook should be skipped\n */\n protected preprocessWebhook(\n payload: unknown,\n idempotencyToken: string | undefined\n ): {\n webhookData: ConversationWebhookPayload;\n eventType: string;\n conversationId: string | undefined;\n } | null {\n this.logger.debug({ operation: 'webhook_processing' }, 'Processing webhook');\n\n if (idempotencyToken && this.isDuplicateWebhook(idempotencyToken)) {\n this.logger.debug({ idempotency_token: idempotencyToken }, 'Skipping duplicate webhook');\n return null;\n }\n\n if (!this.validateWebhookPayload(payload)) {\n throw new Error('Invalid webhook payload');\n }\n\n const webhookData = payload as ConversationWebhookPayload;\n const eventType = webhookData.eventType;\n const conversationId = webhookData.data?.conversationId || webhookData.data?.id;\n\n // Self-filter: ignore events meant for other channel types\n if (!this.isEventForThisChannel(webhookData)) {\n this.logger.debug(\n { event_type: eventType, channel: this.channelType, conversation_id: conversationId },\n 'Ignoring event for different channel type'\n );\n return null;\n }\n\n return { webhookData, eventType, conversationId };\n }\n\n /**\n * Extract conversation ID from webhook payload with type validation.\n *\n * Extracts conversationId from webhookData.data?.conversationId || webhookData.data?.id,\n * validates the value is a non-empty string, and ensures it passes isConversationId check.\n *\n * This prevents invalid IDs from causing downstream issues like incorrect Map key\n * matching in CONVERSATION_UPDATED self-filtering or propagating malformed IDs.\n */\n protected extractConversationId(payload: unknown): ConversationId | null {\n if (!payload || typeof payload !== 'object') {\n return null;\n }\n\n const webhookData = payload as ConversationWebhookPayload;\n const conversationId = webhookData.data?.conversationId || webhookData.data?.id;\n\n // Validate type and format before casting to ConversationId\n if (conversationId && typeof conversationId === 'string' && isConversationId(conversationId)) {\n return conversationId;\n }\n\n return null;\n }\n\n /**\n * Extract profile ID from webhook payload with type validation.\n *\n * Extracts profileId from webhookData.data?.profileId,\n * validates the value is a non-empty string, and ensures it passes isProfileId check.\n *\n * This prevents invalid IDs from propagating downstream and ensures consistent\n * validation across all channel types.\n */\n protected extractProfileId(payload: unknown): ProfileId | null {\n if (!payload || typeof payload !== 'object') {\n return null;\n }\n\n const webhookData = payload as ConversationWebhookPayload;\n const profileId = webhookData.data?.profileId;\n\n // Validate type and format before casting to ProfileId\n if (profileId && typeof profileId === 'string' && isProfileId(profileId)) {\n return profileId;\n }\n\n return null;\n }\n\n /**\n * Retrieve memory according to the channel's memoryMode.\n *\n * This method handles the common logic for memory retrieval across all channels,\n * including error handling and debug logging.\n *\n * Modes:\n * - \"always\": Fetch with the provided query on every message.\n * - \"once\": Fetch once with neither a query nor a conversation id (skipping\n * query expansion) and cache the result on the session. Subsequent calls\n * reuse the cache until it is invalidated on the INACTIVE transition.\n * - \"never\": Skip retrieval.\n *\n * Memory retrieval failures are logged and swallowed so message processing\n * continues without memory context.\n */\n protected async retrieveMemoryIfEnabled(\n session: ConversationSession,\n query?: string\n ): Promise<TACMemoryResponse | undefined> {\n // \"never\" and any unexpected value: no automatic retrieval\n if (this.memoryMode !== 'always' && this.memoryMode !== 'once') {\n return undefined;\n }\n\n // \"once\" mode reuses cached memory across messages.\n if (this.memoryMode === 'once' && session.cachedMemory !== undefined) {\n this.logger.debug({ conversation_id: session.conversationId }, 'Reusing cached memory');\n return session.cachedMemory;\n }\n\n try {\n // \"always\" sends query + conversation id so Memory ranks by relevance.\n // \"once\" sends neither: with no query, a conversation id only buys\n // Memory's expensive server-side query expansion.\n const isAlways = this.memoryMode === 'always';\n const memory = await this.tac.retrieveMemory(\n session,\n isAlways ? query : undefined,\n isAlways ? session.conversationId : undefined\n );\n if (this.memoryMode === 'once') {\n session.cachedMemory = memory;\n }\n this.logger.debug(\n { conversation_id: session.conversationId, memory_mode: this.memoryMode },\n 'Memory retrieved'\n );\n return memory;\n } catch (error) {\n this.logger.warn(\n { err: error, conversation_id: session.conversationId },\n 'Failed to retrieve memory, continuing without memory context'\n );\n // Continue without memory rather than failing entire message processing\n return undefined;\n }\n }\n\n /**\n * Invalidate cached memory for \"once\" mode when a conversation becomes\n * INACTIVE. Conversation Orchestrator updates memory on the INACTIVE\n * transition, so the next message re-fetches fresh memory. No-op for other\n * memory modes.\n */\n protected invalidateCachedMemory(conversationId: ConversationId): void {\n if (this.memoryMode !== 'once') {\n return;\n }\n\n const session = this.activeConversations.get(conversationId);\n if (session?.cachedMemory !== undefined) {\n session.cachedMemory = undefined;\n this.logger.debug(\n { conversation_id: conversationId },\n 'Invalidated cached memory on INACTIVE status'\n );\n }\n }\n\n /**\n * Cleanup resources when shutting down\n */\n public shutdown(): void {\n this.activeConversations.clear();\n delete this.callbacks.onConversationStarted;\n delete this.callbacks.onConversationEnded;\n delete this.callbacks.onError;\n }\n}\n","import {\n ActionChannelSettings,\n ConversationAddress,\n ConversationId,\n ConversationParticipant,\n ConversationWebhookPayload,\n InitiateConversationResult,\n ProfileId,\n SendMessageActionRequest,\n isConversationId,\n} from '../types/index';\nimport axios from 'axios';\nimport { BaseChannel, BaseChannelEvents, BaseChannelOptions } from './base';\nimport { ConversationClient } from '../clients/conversation';\nimport type { TAC } from '../lib/tac';\nimport { maskAddress } from '../util/log-redaction';\n\n/**\n * Participant types that represent TAC itself at TAC's (channel, address).\n *\n * `AI_AGENT` is the canonical type; `AGENT` is the legacy Conversation\n * Orchestrator form. A participant typed either way at TAC's address is\n * recognized as TAC and not overwritten; anything else (HUMAN_AGENT,\n * CUSTOMER, …) is someone else's assignment.\n */\nconst AGENT_TYPES = new Set<string>(['AGENT', 'AI_AGENT']);\n\n/**\n * Memory identifier type to use when looking up / creating a profile for a\n * channel's customer address. Channels absent from this map skip profile\n * resolution during participant reconciliation.\n */\nconst CHANNEL_IDENTITY_TYPES: Record<string, string> = {\n SMS: 'phone',\n VOICE: 'phone',\n RCS: 'rcs',\n WHATSAPP: 'whatsapp',\n};\n\n/**\n * Messaging channel configuration options.\n * Alias for BaseChannelOptions that can be extended by specific channel implementations.\n */\nexport type MessagingChannelConfig = BaseChannelOptions;\n\n/**\n * Messaging channel event callbacks extending base callbacks\n */\nexport interface MessagingChannelEvents extends BaseChannelEvents {\n onMessageReceived?: (data: {\n conversationId: ConversationId;\n profileId: ProfileId | undefined;\n message: string;\n author: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Memory structure is dynamic and defined by user\n userMemory: any;\n }) => void;\n}\n\n/**\n * Abstract Messaging Channel base class for SMS and Chat channels\n *\n * Provides shared webhook processing logic for messaging channels\n * (SMS and Chat) that use the Conversations Service webhooks.\n *\n * Subclasses must implement:\n * - `isDefaultAgentAddress`: fast-path check for the channel's default agent address\n * - `getAgentAddress`: return the agent's `ConversationAddress` for a conversation\n * - `sendResponse`: send messages back through the channel\n *\n * Subclass flags:\n * - `reconcileCustomerType`: if `true` (default), reconciliation will also\n * promote a channel-matching UNKNOWN participant (not owning the agent\n * address) to CUSTOMER. Set `false` for channels where the customer is\n * identified author-driven (e.g. chat).\n */\nexport abstract class MessagingChannel extends BaseChannel {\n protected override readonly conversationClient: ConversationClient;\n protected readonly messagingCallbacks: MessagingChannelEvents;\n\n /**\n * Controls whether reconciliation promotes an UNKNOWN customer-side\n * participant to CUSTOMER. Subclasses override to opt out (e.g. chat).\n */\n protected reconcileCustomerType: boolean = true;\n\n constructor(tac: TAC, config?: MessagingChannelConfig) {\n super(tac, config);\n if (!tac.isOrchestratorEnabled()) {\n throw new Error(\n 'Messaging channels require conversationConfigurationId to be configured. ' +\n 'Voice-only mode does not support SMS or Chat channels.'\n );\n }\n // Safe: orchestrator is enabled so conversationClient is guaranteed non-null\n this.conversationClient = tac.getConversationClient() as ConversationClient;\n this.messagingCallbacks = {};\n }\n\n /**\n * Fast-path check: is the author address this channel's default agent address?\n * (e.g., config.phoneNumber for SMS, agentAddress for Chat)\n */\n protected abstract isDefaultAgentAddress(authorAddress: string): boolean;\n\n /**\n * Return the agent-side ConversationAddress for this conversation.\n *\n * Used by `reconcileParticipants` to identify which participant (by channel\n * + address) represents the agent. May read from session state (e.g. chat's\n * per-conversation channelId) to build the address.\n */\n protected abstract getAgentAddress(conversationId: ConversationId): ConversationAddress;\n\n /**\n * Check if a message is from the bot itself (2-tier).\n *\n * 1. Default agent address (stateless, no API call)\n * 2. API fallback via listParticipants (cross-process / multi-worker)\n */\n private async isOwnMessage(\n authorAddress: string,\n conversationId: ConversationId,\n authorParticipantId: string | undefined\n ): Promise<boolean> {\n if (this.isDefaultAgentAddress(authorAddress)) return true;\n\n if (authorParticipantId) {\n try {\n const participants = await this.conversationClient.listParticipants(conversationId);\n const authorParticipant = participants.find(p => p.id === authorParticipantId);\n if (authorParticipant) {\n if (authorParticipant.type === undefined) {\n this.logger.warn(\n { conversation_id: conversationId, participant_id: authorParticipantId },\n 'Participant type is undefined — cannot determine if this is an agent message'\n );\n }\n if (authorParticipant.type && AGENT_TYPES.has(authorParticipant.type)) {\n return true;\n }\n }\n } catch (error) {\n this.logger.warn(\n { err: error, conversation_id: conversationId, participant_id: authorParticipantId },\n 'Failed to look up participant type for self-message check; falling through'\n );\n }\n }\n\n return false;\n }\n\n /**\n * Register event callbacks (override for messaging-specific events)\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic event callback needs to accept any args\n public override on(event: string, callback: (...args: any[]) => void): void {\n if (event === 'messageReceived') {\n this.messagingCallbacks.onMessageReceived = callback;\n } else {\n // Delegate to parent for base events\n super.on(event, callback);\n }\n }\n\n /**\n * Process messaging channel webhook from Conversation Orchestrator\n */\n public async processWebhook(payload: unknown, idempotencyToken?: string): Promise<void> {\n try {\n const result = this.preprocessWebhook(payload, idempotencyToken);\n if (!result) {\n return;\n }\n\n const { webhookData, eventType, conversationId } = result;\n\n switch (eventType) {\n case 'CONVERSATION_CREATED':\n this.logger.debug(\n { conversation_id: conversationId, profile_id: webhookData.data?.profileId },\n 'Handling CONVERSATION_CREATED'\n );\n this.handleConversationCreated(webhookData);\n break;\n\n case 'COMMUNICATION_CREATED':\n this.logger.debug({ conversation_id: conversationId }, 'Handling COMMUNICATION_CREATED');\n await this.handleCommunicationCreated(webhookData);\n break;\n\n case 'CONVERSATION_UPDATED':\n this.logger.debug(\n { conversation_id: conversationId, status: webhookData.data?.status },\n 'Handling CONVERSATION_UPDATED'\n );\n await this.handleConversationUpdated(webhookData);\n break;\n\n default:\n this.logger.warn(\n {\n event_type: eventType,\n raw_event_type: webhookData.eventType,\n conversation_id: conversationId,\n },\n 'Unhandled event type - this event will be ignored'\n );\n }\n\n this.logger.debug({ event_type: eventType }, 'Webhook processing completed');\n } catch (error) {\n // Remove the token so retries are not blocked\n if (idempotencyToken) {\n this.removeWebhookToken(idempotencyToken);\n }\n this.handleError(error instanceof Error ? error : new Error(String(error)), { payload });\n }\n }\n\n /**\n * Handle conversation creation event\n */\n private handleConversationCreated(payload: ConversationWebhookPayload): void {\n const conversationId = this.extractConversationId(payload);\n const profileId = this.extractProfileId(payload);\n\n if (!conversationId) {\n this.logger.warn(\n { operation: 'handle_conversation_created' },\n 'Missing conversation ID in conversation.created event'\n );\n throw new Error('Missing conversation ID in conversation.created event');\n }\n\n this.startConversation(conversationId, profileId ?? undefined, payload.data?.serviceId);\n }\n\n /**\n * Handle new communication event (incoming message)\n */\n private async handleCommunicationCreated(payload: ConversationWebhookPayload): Promise<void> {\n const conversationId = this.extractConversationId(payload);\n const profileId = this.extractProfileId(payload);\n // Extract message text from data.content.text\n const message = payload.data?.content?.text?.trim();\n // Author is in data.author.address\n const author = payload.data?.author?.address || 'unknown';\n\n this.logger.info(\n {\n conversation_id: conversationId,\n profile_id: profileId,\n author: maskAddress(author),\n message_length: message?.length,\n operation: 'handle_communication_created',\n },\n 'Handling communication.created'\n );\n\n if (!conversationId) {\n this.logger.warn(\n { operation: 'handle_communication_created' },\n 'Missing conversation ID in communication.created event'\n );\n throw new Error('Missing conversation ID in communication.created event');\n }\n\n if (!message) {\n this.logger.info({ conversation_id: conversationId }, 'Ignoring empty message');\n return;\n }\n\n // Per-conversation communication ID dedup stored in the in-memory\n // ConversationSession metadata. This only prevents duplicate processing\n // within the current process/session lifetime; it does not deduplicate\n // across horizontally-scaled instances or after a restart.\n const communicationId = payload.data?.id;\n if (communicationId) {\n const session = this.getConversationSession(conversationId);\n if (session?.metadata?.lastCommunicationId === communicationId) {\n this.logger.debug(\n { conversation_id: conversationId, communication_id: communicationId },\n 'Skipping already-processed communication'\n );\n return;\n }\n }\n\n // Filter out messages from the bot itself\n if (await this.isOwnMessage(author, conversationId, payload.data?.author?.participantId)) {\n this.logger.info(\n {\n conversation_id: conversationId,\n author_address: maskAddress(author),\n },\n 'Ignoring message from AI agent'\n );\n return;\n }\n\n // Initialize conversation if not already active\n if (!this.isConversationActive(conversationId)) {\n this.logger.debug({ conversation_id: conversationId }, 'Starting new conversation');\n this.startConversation(conversationId, profileId ?? undefined, payload.data?.serviceId);\n } else if (payload.data?.serviceId) {\n const session = this.getConversationSession(conversationId);\n if (session && session.serviceId !== payload.data.serviceId) {\n this.logger.debug(\n {\n conversation_id: conversationId,\n old_service_id: session.serviceId,\n new_service_id: payload.data.serviceId,\n },\n 'Updating conversation configuration ID from communication.created'\n );\n session.serviceId = payload.data.serviceId;\n }\n }\n\n // Get session and update with author info for profile lookup\n const session = this.getConversationSession(conversationId);\n if (session) {\n session.authorInfo = {\n address: author,\n participantId: payload.data?.author?.participantId,\n };\n\n // Store channelId (Chat Channel SID) in session metadata for reply sending\n if (payload.data?.channelId) {\n if (!session.metadata) {\n session.metadata = {};\n }\n session.metadata.channelId = payload.data.channelId;\n this.logger.debug(\n { conversation_id: conversationId, channel_id: payload.data.channelId },\n 'Stored channelId in session metadata'\n );\n }\n\n // Track communication ID for cross-process dedup\n if (communicationId) {\n if (!session.metadata) {\n session.metadata = {};\n }\n session.metadata.lastCommunicationId = communicationId;\n }\n\n // Reconcile participant types pre-LLM so v1-bridge's UNKNOWN gets\n // promoted, and to stash both participant ids on the session for\n // sendResponse. Reconcile failure means the reply would fail too —\n // skip the callback so the LLM doesn't waste a turn on an\n // un-replyable conversation.\n //\n // Gate on `aiAgentInfo` (persistent across turns) — `authorInfo` is\n // overwritten from every webhook so it's not a reliable \"already\n // reconciled\" signal.\n if (!session.aiAgentInfo) {\n const resolved = await this.reconcileParticipants(conversationId);\n if (!resolved) {\n // Surface via handleError (logs at error level AND fires the app's\n // onError callback) rather than a bare warn — otherwise the dropped\n // inbound is invisible to the app and can't be observed or retried.\n // Set a stable error.name and error_code so consumers can classify\n // this condition programmatically without string-matching the message.\n const error = new Error(\n `Participant reconciliation failed for conversation ${conversationId}; ` +\n 'inbound message dropped because no sendable participants could be resolved.'\n );\n error.name = 'ParticipantReconciliationError';\n this.handleError(error, {\n conversation_id: conversationId,\n channel: this.channelType,\n dropped_inbound: true,\n error_code: 'participant_reconciliation_failed',\n });\n return;\n }\n\n const [agentParticipant, customerParticipant] = resolved;\n const agentAddress = this.getAgentAddress(conversationId);\n session.aiAgentInfo = {\n address: agentAddress.address,\n participantId: agentParticipant.id,\n };\n // When reconcile resolved a customer (SMS path — chat disables customer\n // reconciliation and uses the authorInfo captured from the webhook\n // above), use its authoritative participant id and lift any resolved\n // profile.\n if (customerParticipant && session.authorInfo) {\n session.authorInfo.participantId = customerParticipant.id;\n if (customerParticipant.profileId && !session.profileId) {\n session.profileId = customerParticipant.profileId;\n }\n }\n }\n }\n\n // Retrieve user memory if enabled via memoryMode\n const userMemory = session ? await this.retrieveMemoryIfEnabled(session, message) : undefined;\n\n // Invoke message received callback with memory context\n if (this.messagingCallbacks.onMessageReceived) {\n this.logger.debug({ conversation_id: conversationId }, 'Invoking message received callback');\n this.messagingCallbacks.onMessageReceived({\n conversationId,\n profileId: (session?.profileId as ProfileId | undefined) ?? profileId ?? undefined,\n message,\n author,\n userMemory,\n });\n }\n }\n\n /**\n * Handle conversation updated event\n */\n private async handleConversationUpdated(payload: ConversationWebhookPayload): Promise<void> {\n const conversationId = this.extractConversationId(payload);\n\n if (!conversationId) {\n throw new Error('Missing conversation ID in conversation.updated event');\n }\n\n // Check if conversation is closed\n if (payload.data?.status === 'CLOSED') {\n this.logger.debug(\n { conversation_id: conversationId, status: payload.data.status },\n 'Conversation closed, cleaning up'\n );\n await this.endConversation(conversationId);\n } else if (payload.data?.status === 'INACTIVE') {\n // Invalidate cached memory (\"once\" mode) when the conversation becomes\n // inactive. Memory is updated by Conversation Orchestrator on the\n // INACTIVE transition, so the next message re-fetches fresh memory.\n this.invalidateCachedMemory(conversationId);\n }\n }\n\n /**\n * Validate messaging channel webhook payload structure\n */\n protected override validateWebhookPayload(payload: unknown): boolean {\n if (!super.validateWebhookPayload(payload)) {\n return false;\n }\n\n const webhookData = payload as ConversationWebhookPayload;\n return (\n typeof webhookData === 'object' &&\n typeof webhookData.eventType === 'string' &&\n webhookData.eventType.length > 0\n );\n }\n\n /**\n * Reconcile Conversation Orchestrator's participants to the types TAC\n * needs for sending.\n *\n * v1-bridge capture can leave TAC's agent participant as `UNKNOWN` (wrong\n * type at our address), or omit it entirely (customer-only conversation).\n * This pass fixes those cases; it refuses to rewrite anything else at our\n * address. Decision matrix:\n *\n * | Agent side | Customer side | Action |\n * |----------------------|---------------------|-------------------------------|\n * | AGENT / AI_AGENT | CUSTOMER | Use as-is (no profile work). |\n * | AGENT / AI_AGENT | UNKNOWN, no CUST | Resolve profile, PUT → CUST. |\n * | UNKNOWN at our addr | CUSTOMER | PUT agent → AI_AGENT. |\n * | UNKNOWN at our addr | UNKNOWN, no CUST | PUT agent; resolve, PUT CUST. |\n * | other at our addr | any | Return null (log ERROR). |\n * | none at our addr | CUSTOMER or UNKNOWN | POST AI_AGENT, then proceed. |\n * | any | no resolvable cust | Return null (caller WARNs). |\n *\n * TAC recognizes both `AGENT` and `AI_AGENT` at its address as itself.\n * `HUMAN_AGENT` is NOT treated as TAC (a real human is a separate\n * participant — TAC must not speak on their behalf); it falls into the\n * \"other at our addr\" row and causes the reconcile to bail.\n *\n * Customer-side reconciliation is gated by `reconcileCustomerType`. Chat\n * sets it to `false` because chat identifies the customer author-driven\n * (via `session.authorInfo.participantId`), so promoting some other\n * `UNKNOWN` CHAT participant could pick the wrong recipient.\n *\n * @returns `[agent, customerOrNull]` on success. `customer` is `null` when\n * `reconcileCustomerType` is `false`. `null` overall when either the agent\n * or the customer cannot be resolved — the caller treats `null` as a hard\n * stop and skips the message-ready callback.\n */\n protected async reconcileParticipants(\n conversationId: ConversationId\n ): Promise<[ConversationParticipant, ConversationParticipant | null] | null> {\n const agentAddress = this.getAgentAddress(conversationId);\n\n let participants: ConversationParticipant[];\n try {\n participants = await this.conversationClient.listParticipants(conversationId);\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: conversationId },\n 'Failed to list participants for reconciliation'\n );\n return null;\n }\n\n const channel = agentAddress.channel;\n\n const ownsAgentAddress = (p: ConversationParticipant): boolean =>\n Array.isArray(p.addresses) &&\n p.addresses.some(a => a.channel === channel && a.address === agentAddress.address);\n\n const matchesChannel = (p: ConversationParticipant): boolean =>\n Array.isArray(p.addresses) && p.addresses.some(a => a.channel === channel);\n\n let agentCandidate = participants.find(ownsAgentAddress);\n if (!agentCandidate) {\n const created = await this.addAgentParticipant(conversationId, agentAddress);\n if (!created) return null;\n agentCandidate = created;\n } else if (agentCandidate.type === 'UNKNOWN') {\n // Only promote UNKNOWN — an already-typed participant at TAC's address\n // that isn't AGENT/AI_AGENT (e.g., CUSTOMER, HUMAN_AGENT) is someone\n // else's assignment and must not be overwritten.\n const promoted = await this.promoteParticipant(conversationId, agentCandidate, 'AI_AGENT');\n if (!promoted) return null;\n agentCandidate = promoted;\n } else if (!agentCandidate.type || !AGENT_TYPES.has(agentCandidate.type)) {\n this.logger.error(\n {\n conversation_id: conversationId,\n participant_id: agentCandidate.id,\n participant_type: agentCandidate.type,\n },\n \"Participant at TAC's address has a conflicting type; refusing to overwrite. \" +\n 'Check Conversation Orchestrator participant state — a non-agent participant is holding ' +\n \"TAC's (channel, address).\"\n );\n return null;\n }\n\n if (!this.reconcileCustomerType) {\n return [agentCandidate, null];\n }\n\n const customer = participants.find(\n p => p.type === 'CUSTOMER' && matchesChannel(p) && !ownsAgentAddress(p)\n );\n if (customer) {\n return [agentCandidate, customer];\n }\n\n const customerUnknown = participants.find(\n p => p.type === 'UNKNOWN' && matchesChannel(p) && !ownsAgentAddress(p)\n );\n if (customerUnknown) {\n const profileId = await this.resolveCustomerProfile(customerUnknown, channel);\n const promotedCustomer = await this.promoteParticipant(\n conversationId,\n customerUnknown,\n 'CUSTOMER',\n profileId\n );\n if (promotedCustomer) {\n return [agentCandidate, promotedCustomer];\n }\n }\n\n this.logger.warn(\n { conversation_id: conversationId, channel },\n 'No customer participant resolvable; skipping webhook'\n );\n return null;\n }\n\n /**\n * Find or mint a Conversation Memory profile for a customer being promoted from UNKNOWN.\n *\n * Only resolves for phone-based channels (SMS, VOICE, RCS, WHATSAPP). Looks\n * up by the channel's identifier type (`phone` for SMS/VOICE, `rcs` for\n * RCS, `whatsapp` for WHATSAPP) first; on miss, creates a new profile\n * using the configured phone trait group/field. Returns undefined on any\n * failure — the caller still promotes the participant, just without a\n * `profileId` attached.\n */\n private async resolveCustomerProfile(\n customer: ConversationParticipant,\n channel: string\n ): Promise<string | undefined> {\n const identityType = CHANNEL_IDENTITY_TYPES[channel];\n if (!identityType) return undefined;\n\n const memoryClient = this.tac.getMemoryClient();\n if (!memoryClient || !this.tac.getMemoryStoreId()) return undefined;\n\n const phoneAddress = Array.isArray(customer.addresses)\n ? (customer.addresses.find(a => a.channel === channel && !!a.address)?.address ?? undefined)\n : undefined;\n if (!phoneAddress) return undefined;\n\n try {\n const lookup = await memoryClient.lookupProfile(identityType, phoneAddress);\n if (lookup.profiles && lookup.profiles.length > 0) {\n return lookup.profiles[0];\n }\n } catch (error) {\n this.logger.warn(\n { err: error, conversation_id: customer.conversationId },\n 'Profile lookup failed during reconciliation; falling back to create'\n );\n }\n\n const memoryConfig = this.config.memoryConfig;\n const traitGroup = memoryConfig.phoneTraitGroup;\n const traitField = memoryConfig.phoneTraitField;\n\n try {\n return await memoryClient.createProfile({\n [traitGroup]: { [traitField]: phoneAddress },\n });\n } catch (error) {\n this.logger.warn(\n { err: error, conversation_id: customer.conversationId },\n 'Profile creation failed during reconciliation; promoting without profile'\n );\n return undefined;\n }\n }\n\n /**\n * PUT a participant to `newType`.\n *\n * Conversation Orchestrator's PUT is a full-resource replacement, so we\n * pass the existing `name` and `addresses` back unchanged to avoid wiping\n * them. `profileId` defaults to the participant's current value; pass a\n * non-undefined override to attach a newly resolved profile during CUSTOMER\n * reconciliation.\n *\n * Returns undefined on any error (including 409). A 409 from Conversation\n * Orchestrator here means the promotion is structurally blocked — stop and\n * surface it; don't retry.\n */\n private async promoteParticipant(\n conversationId: ConversationId,\n participant: ConversationParticipant,\n newType: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT' | 'AGENT',\n profileId?: string\n ): Promise<ConversationParticipant | undefined> {\n const effectiveProfileId = profileId !== undefined ? profileId : participant.profileId;\n const updateOptions: { name?: string; profileId?: string } = {};\n if (participant.name !== undefined) updateOptions.name = participant.name;\n if (effectiveProfileId !== null && effectiveProfileId !== undefined) {\n updateOptions.profileId = effectiveProfileId;\n }\n\n try {\n const updated = await this.conversationClient.updateParticipant(\n conversationId,\n participant.id,\n newType,\n participant.addresses,\n updateOptions\n );\n this.logger.debug(\n {\n conversation_id: conversationId,\n participant_id: participant.id,\n from_type: participant.type,\n to_type: newType,\n },\n 'Promoted participant'\n );\n return updated;\n } catch (error) {\n if (this.isConflictError(error)) {\n this.logger.warn(\n {\n conversation_id: conversationId,\n participant_id: participant.id,\n target_type: newType,\n conflicting_resource_id: this.extractConflictingResourceId(error),\n },\n 'Conversation Orchestrator returned 409 on participant promotion; skipping — ' +\n 'likely a conflicting conversation or grouping constraint. Check ' +\n 'Conversation Orchestrator for duplicate active conversations.'\n );\n return undefined;\n }\n this.logger.error(\n {\n err: error,\n conversation_id: conversationId,\n participant_id: participant.id,\n target_type: newType,\n },\n 'Failed to promote participant'\n );\n return undefined;\n }\n }\n\n /**\n * POST an `AI_AGENT` participant owning `agentAddress`.\n *\n * Returns undefined on any error (including 409). A 409 here means the\n * address is already owned or the conversation's participant set can't\n * accept a new AI_AGENT — stop and surface it; don't retry.\n */\n private async addAgentParticipant(\n conversationId: ConversationId,\n agentAddress: ConversationAddress\n ): Promise<ConversationParticipant | undefined> {\n try {\n const created = await this.conversationClient.addParticipant(\n conversationId,\n [agentAddress],\n 'AI_AGENT'\n );\n this.logger.debug(\n { conversation_id: conversationId, participant_id: created.id },\n 'Added AI_AGENT participant'\n );\n return created;\n } catch (error) {\n if (this.isConflictError(error)) {\n this.logger.warn(\n {\n conversation_id: conversationId,\n conflicting_resource_id: this.extractConflictingResourceId(error),\n },\n 'Conversation Orchestrator returned 409 on AI_AGENT participant add; skipping — ' +\n \"address is already owned or the conversation can't accept a new AI_AGENT. \" +\n 'Check Conversation Orchestrator participant state.'\n );\n return undefined;\n }\n this.logger.error(\n { err: error, conversation_id: conversationId },\n 'Failed to add AI_AGENT participant'\n );\n return undefined;\n }\n }\n\n private isConflictError(error: unknown): boolean {\n const cause = error instanceof Error ? (error.cause ?? error) : error;\n return axios.isAxiosError(cause) && cause.response?.status === 409;\n }\n\n private extractConflictingResourceId(error: unknown): string | undefined {\n const cause = error instanceof Error ? (error.cause ?? error) : error;\n if (!axios.isAxiosError(cause)) return undefined;\n const headers = cause.response?.headers as Record<string, string> | undefined;\n const id = headers?.['x-conflicting-resource-id'];\n return typeof id === 'string' && id.length > 0 ? id : undefined;\n }\n\n /**\n * Shared outbound conversation initiation for messaging channels (SMS/RCS/Chat/WhatsApp).\n *\n * Handles the full flow: create conversation → find participants → start\n * session → send initial message → error cleanup.\n */\n protected async initiateOutboundMessagingConversation(params: {\n channel: 'SMS' | 'CHAT' | 'RCS' | 'WHATSAPP';\n to: string;\n from: string;\n message: string;\n metadata?: Record<string, unknown>;\n channelId?: string;\n channelSettings?: ActionChannelSettings;\n }): Promise<InitiateConversationResult> {\n const {\n channel,\n to,\n from: fromAddress,\n message,\n metadata,\n channelId,\n channelSettings,\n } = params;\n\n let conversationId: string | undefined;\n let conversationReused = false;\n\n try {\n const customerAddress: ConversationAddress = {\n channel,\n address: to,\n ...(channelId ? { channelId } : {}),\n };\n const agentAddress: ConversationAddress = {\n channel,\n address: fromAddress,\n ...(channelId ? { channelId } : {}),\n };\n\n const result = await this.conversationClient.createOrReuseConversation([\n { type: 'CUSTOMER', addresses: [customerAddress] },\n { type: 'AI_AGENT', addresses: [agentAddress] },\n ]);\n conversationId = result.conversation.id;\n conversationReused = result.reused;\n\n if (!isConversationId(conversationId)) {\n throw new Error(`Invalid conversation ID returned: ${conversationId}`);\n }\n\n const participants = await this.conversationClient.listParticipants(conversationId);\n\n const customerParticipant = participants.find(\n p =>\n p.type === 'CUSTOMER' &&\n Array.isArray(p.addresses) &&\n p.addresses.some(\n a =>\n a.channel === channel &&\n a.address === to &&\n (channelId === undefined || a.channelId === channelId)\n )\n );\n if (!customerParticipant) {\n throw new Error('Customer participant not found after conversation creation');\n }\n\n const agentParticipant = participants.find(\n p =>\n p.type !== undefined &&\n AGENT_TYPES.has(p.type) &&\n Array.isArray(p.addresses) &&\n p.addresses.some(\n a =>\n a.channel === channel &&\n a.address === fromAddress &&\n (channelId === undefined || a.channelId === channelId)\n )\n );\n if (!agentParticipant) {\n throw new Error('Agent participant not found after conversation creation');\n }\n\n // Start local session BEFORE sending the initial message so the\n // COMMUNICATION_CREATED webhook (triggered by createAction) finds a\n // correctly-configured session instead of auto-starting one with wrong\n // metadata.\n const session = this.startConversation(conversationId);\n session.authorInfo = {\n address: to,\n participantId: customerParticipant.id,\n };\n session.aiAgentInfo = {\n address: fromAddress,\n participantId: agentParticipant.id,\n };\n session.metadata = {\n ...session.metadata,\n ...(metadata ?? {}),\n direction: 'outbound',\n ...(channelId ? { channelId } : {}),\n };\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: { channel, participantId: agentParticipant.id },\n to: [{ channel, participantId: customerParticipant.id }],\n content: { text: message },\n ...(channelSettings ? { channelSettings } : {}),\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n { conversation_id: conversationId, to: maskAddress(to) },\n `Outbound ${channel} conversation initiated`\n );\n\n return { conversationId, session };\n } catch (error) {\n if (conversationId) {\n this.activeConversations.delete(conversationId as ConversationId);\n }\n if (conversationId && !conversationReused) {\n await this.conversationClient\n .updateConversation(conversationId, 'CLOSED')\n .catch(closeErr => {\n this.logger.warn(\n { err: closeErr, conversation_id: conversationId },\n 'Failed to close orphaned conversation after initiation error'\n );\n });\n }\n this.logger.error(\n { err: error, to: maskAddress(to) },\n `Failed to initiate outbound ${channel}`\n );\n this.handleError(error instanceof Error ? error : new Error(String(error)), { to });\n throw error;\n }\n }\n}\n","import {\n ChannelType,\n ConversationAddress,\n ConversationId,\n SendMessageActionRequest,\n InitiateMessagingConversationOptions,\n InitiateMessagingConversationOptionsSchema,\n InitiateConversationResult,\n} from '../types/index';\nimport { MessagingChannel } from './messaging';\nimport { maskAddress } from '../util/log-redaction';\n\n/**\n * SMS Channel implementation for Twilio Conversations Service\n *\n * Handles SMS conversations through webhook events from Twilio.\n * Automatically retrieves user memory and manages conversation lifecycle.\n */\nexport class SMSChannel extends MessagingChannel {\n public get channelType(): ChannelType {\n return 'sms';\n }\n\n protected isDefaultAgentAddress(authorAddress: string): boolean {\n return authorAddress === this.config.phoneNumber;\n }\n\n protected getAgentAddress(_conversationId: ConversationId): ConversationAddress {\n return { channel: 'SMS', address: this.config.phoneNumber };\n }\n\n /**\n * Send SMS response using the Conversation Orchestrator Actions API (SEND_MESSAGE).\n *\n * Reads the agent and customer participant ids stashed on the session by\n * inbound reconciliation or outbound initiation. Missing ids are a misuse —\n * `sendResponse` is only expected to be called after an inbound webhook\n * (COMMUNICATION_CREATED → reconcile) or after `initiateOutboundConversation`,\n * both of which populate the session.\n */\n public async sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_length: message.length,\n operation: 'send_response',\n },\n 'Sending SMS response'\n );\n\n try {\n const session = this.getConversationSession(conversationId);\n\n if (!session || !session.authorInfo || !session.aiAgentInfo) {\n throw new Error(\n `Unable to send SMS: sendResponse called without a reconciled session for ` +\n `conversation ${conversationId}. Wait for an inbound webhook or call ` +\n `initiateOutboundConversation first.`\n );\n }\n\n const customerParticipantId = session.authorInfo.participantId;\n const agentParticipantId = session.aiAgentInfo.participantId;\n if (!customerParticipantId || !agentParticipantId) {\n throw new Error(\n `Unable to send SMS: session for conversation ${conversationId} is missing ` +\n `participant ids.`\n );\n }\n\n const channelId =\n typeof session.metadata?.channelId === 'string' ? session.metadata.channelId : undefined;\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n recipient_participant_id: customerParticipantId,\n agent_participant_id: agentParticipantId,\n },\n 'Sending SMS via Actions API'\n );\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: {\n channel: 'SMS',\n participantId: agentParticipantId,\n },\n to: [\n {\n channel: 'SMS',\n participantId: customerParticipantId,\n },\n ],\n content: { text: message },\n ...(channelId ? { channelSettings: { channelId } } : {}),\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n },\n 'SMS sent successfully via Actions API'\n );\n } catch (error) {\n this.logger.error({ err: error, conversation_id: conversationId }, 'Send response error');\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Initiate an outbound SMS conversation\n *\n * Creates a conversation via Conversation Orchestrator, adds customer and\n * agent participants, then sends the initial message via the Actions API.\n * The sender is always `config.phoneNumber`.\n */\n public async initiateOutboundConversation(\n options: InitiateMessagingConversationOptions\n ): Promise<InitiateConversationResult> {\n const validated = InitiateMessagingConversationOptionsSchema.parse(options);\n\n this.logger.info(\n { to: maskAddress(validated.to), message_length: validated.message.length },\n 'Initiating outbound SMS conversation'\n );\n\n return this.initiateOutboundMessagingConversation({\n channel: 'SMS',\n to: validated.to,\n from: this.config.phoneNumber,\n message: validated.message,\n ...(validated.metadata ? { metadata: validated.metadata } : {}),\n });\n }\n}\n","import {\n ChannelType,\n ConversationAddress,\n ConversationId,\n SendMessageActionRequest,\n InitiateMessagingConversationOptions,\n InitiateMessagingConversationOptionsSchema,\n InitiateConversationResult,\n} from '../types/index';\nimport { MessagingChannel, MessagingChannelConfig } from './messaging';\nimport { maskAddress } from '../util/log-redaction';\nimport type { TAC } from '../lib/tac';\n\n/**\n * RCS Channel implementation for Twilio Conversations Service\n *\n * Handles RCS (Rich Communication Services) conversations through webhook\n * events from Twilio. The RCS Sender ID is configured on `TACConfig` via\n * `TWILIO_RCS_SENDER_ID`. Follows the same pattern as SMS (sender from\n * TAC config) for consistency with other messaging channels.\n */\nexport class RCSChannel extends MessagingChannel {\n constructor(tac: TAC, config?: MessagingChannelConfig) {\n super(tac, config);\n\n if (!this.config.rcsSenderId) {\n throw new Error(\n 'rcsSenderId is required for RCS channel. ' +\n 'Please set TWILIO_RCS_SENDER_ID environment variable or provide rcsSenderId in TACConfig.'\n );\n }\n }\n\n public get channelType(): ChannelType {\n return 'rcs';\n }\n\n protected isDefaultAgentAddress(authorAddress: string): boolean {\n return authorAddress === this.config.rcsSenderId;\n }\n\n protected getAgentAddress(_conversationId: ConversationId): ConversationAddress {\n if (!this.config.rcsSenderId) {\n throw new Error('rcsSenderId is required for RCS channel.');\n }\n return { channel: 'RCS', address: this.config.rcsSenderId };\n }\n\n /**\n * Send RCS response using the Conversation Orchestrator Actions API (SEND_MESSAGE).\n *\n * Reads the agent and customer participant ids stashed on the session by\n * inbound reconciliation or outbound initiation. Missing ids are a misuse —\n * `sendResponse` is only expected to be called after an inbound webhook\n * (COMMUNICATION_CREATED → reconcile) or after `initiateOutboundConversation`,\n * both of which populate the session.\n */\n public async sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_length: message.length,\n operation: 'send_response',\n },\n 'Sending RCS response'\n );\n\n try {\n const session = this.getConversationSession(conversationId);\n\n if (!session || !session.authorInfo || !session.aiAgentInfo) {\n throw new Error(\n `Unable to send RCS: sendResponse called without a reconciled session for ` +\n `conversation ${conversationId}. Wait for an inbound webhook or call ` +\n `initiateOutboundConversation first.`\n );\n }\n\n const customerParticipantId = session.authorInfo.participantId;\n const agentParticipantId = session.aiAgentInfo.participantId;\n if (!customerParticipantId || !agentParticipantId) {\n throw new Error(\n `Unable to send RCS: session for conversation ${conversationId} is missing ` +\n `participant ids.`\n );\n }\n\n const channelId =\n typeof session.metadata?.channelId === 'string' ? session.metadata.channelId : undefined;\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n recipient_participant_id: customerParticipantId,\n agent_participant_id: agentParticipantId,\n },\n 'Sending RCS via Actions API'\n );\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: {\n channel: 'RCS',\n participantId: agentParticipantId,\n },\n to: [\n {\n channel: 'RCS',\n participantId: customerParticipantId,\n },\n ],\n content: { text: message },\n ...(channelId ? { channelSettings: { channelId } } : {}),\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n },\n 'RCS sent successfully via Actions API'\n );\n } catch (error) {\n this.logger.error({ err: error, conversation_id: conversationId }, 'Send response error');\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Initiate an outbound RCS conversation\n *\n * Creates a conversation via Conversation Orchestrator, adds customer and\n * agent participants, then sends the initial message via the Actions API.\n * The sender is always `config.rcsSenderId`.\n */\n public async initiateOutboundConversation(\n options: InitiateMessagingConversationOptions\n ): Promise<InitiateConversationResult> {\n const validated = InitiateMessagingConversationOptionsSchema.parse(options);\n\n if (!this.config.rcsSenderId) {\n throw new Error('rcsSenderId is required for RCS channel.');\n }\n\n this.logger.info(\n { to: maskAddress(validated.to), message_length: validated.message.length },\n 'Initiating outbound RCS conversation'\n );\n\n return this.initiateOutboundMessagingConversation({\n channel: 'RCS',\n to: validated.to,\n from: this.config.rcsSenderId,\n message: validated.message,\n ...(validated.metadata ? { metadata: validated.metadata } : {}),\n });\n }\n}\n","import {\n ChannelType,\n ConversationAddress,\n ConversationId,\n SendMessageActionRequest,\n InitiateMessagingConversationOptions,\n InitiateMessagingConversationOptionsSchema,\n InitiateConversationResult,\n} from '../types/index';\nimport { MessagingChannel } from './messaging';\nimport { maskAddress } from '../util/log-redaction';\n\n/**\n * WhatsApp Channel implementation for Twilio Conversations Service\n *\n * Handles WhatsApp conversations through webhook events from Twilio.\n * Automatically retrieves user memory and manages conversation lifecycle.\n *\n * WhatsApp uses WhatsApp sender phone numbers configured in TACConfig\n * (via TWILIO_WHATSAPP_NUMBER). Address format: whatsapp:+1234567890\n */\nexport class WhatsAppChannel extends MessagingChannel {\n public get channelType(): ChannelType {\n return 'whatsapp';\n }\n\n protected isDefaultAgentAddress(authorAddress: string): boolean {\n if (!this.config.whatsappNumber) {\n throw new Error(\n 'whatsappNumber is required for WhatsApp channel. ' +\n 'Please set TWILIO_WHATSAPP_NUMBER environment variable or ' +\n 'provide whatsappNumber in TACConfig.'\n );\n }\n return authorAddress === this.config.whatsappNumber;\n }\n\n protected getAgentAddress(_conversationId: ConversationId): ConversationAddress {\n if (!this.config.whatsappNumber) {\n throw new Error(\n 'whatsappNumber is required for WhatsApp channel. ' +\n 'Please set TWILIO_WHATSAPP_NUMBER environment variable or ' +\n 'provide whatsappNumber in TACConfig.'\n );\n }\n return { channel: 'WHATSAPP', address: this.config.whatsappNumber };\n }\n\n /**\n * Send WhatsApp response using the Conversation Orchestrator Actions API (SEND_MESSAGE).\n *\n * Reads the agent and customer participant ids stashed on the session by\n * inbound reconciliation or outbound initiation. Missing ids are a misuse —\n * `sendResponse` is only expected to be called after an inbound webhook\n * (COMMUNICATION_CREATED → reconcile) or after `initiateOutboundConversation`,\n * both of which populate the session.\n */\n public async sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_length: message.length,\n operation: 'send_response',\n },\n 'Sending WhatsApp response'\n );\n\n try {\n const session = this.getConversationSession(conversationId);\n\n if (!session || !session.authorInfo || !session.aiAgentInfo) {\n throw new Error(\n `Unable to send WhatsApp: sendResponse called without a reconciled session for ` +\n `conversation ${conversationId}. Wait for an inbound webhook or call ` +\n `initiateOutboundConversation first.`\n );\n }\n\n const customerParticipantId = session.authorInfo.participantId;\n const agentParticipantId = session.aiAgentInfo.participantId;\n if (!customerParticipantId || !agentParticipantId) {\n throw new Error(\n `Unable to send WhatsApp: session for conversation ${conversationId} is missing ` +\n `participant ids.`\n );\n }\n\n const channelId =\n typeof session.metadata?.channelId === 'string' ? session.metadata.channelId : undefined;\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n recipient_participant_id: customerParticipantId,\n agent_participant_id: agentParticipantId,\n },\n 'Sending WhatsApp via Actions API'\n );\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: {\n channel: 'WHATSAPP',\n participantId: agentParticipantId,\n },\n to: [\n {\n channel: 'WHATSAPP',\n participantId: customerParticipantId,\n },\n ],\n content: { text: message },\n ...(channelId ? { channelSettings: { channelId } } : {}),\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n },\n 'WhatsApp sent successfully via Actions API'\n );\n } catch (error) {\n this.logger.error({ err: error, conversation_id: conversationId }, 'Send response error');\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Initiate an outbound WhatsApp conversation\n *\n * Creates a conversation via Conversation Orchestrator, adds customer and\n * agent participants, then sends the initial message via the Actions API.\n * The sender is always `config.whatsappNumber`.\n */\n public async initiateOutboundConversation(\n options: InitiateMessagingConversationOptions\n ): Promise<InitiateConversationResult> {\n const validated = InitiateMessagingConversationOptionsSchema.parse(options);\n\n if (!this.config.whatsappNumber) {\n throw new Error(\n 'whatsappNumber is required for WhatsApp channel. ' +\n 'Please set TWILIO_WHATSAPP_NUMBER environment variable or ' +\n 'provide whatsappNumber in TACConfig.'\n );\n }\n\n this.logger.info(\n { to: maskAddress(validated.to), message_length: validated.message.length },\n 'Initiating outbound WhatsApp conversation'\n );\n\n return this.initiateOutboundMessagingConversation({\n channel: 'WHATSAPP',\n to: validated.to,\n from: this.config.whatsappNumber,\n message: validated.message,\n ...(validated.metadata ? { metadata: validated.metadata } : {}),\n });\n }\n}\n","import {\n ActionChannelSettings,\n ChannelType,\n ConversationAddress,\n ConversationId,\n SendMessageActionRequest,\n InitiateConversationResult,\n} from '../types/index';\nimport { z } from 'zod';\nimport { MessagingChannel, MessagingChannelConfig } from './messaging';\nimport type { TAC } from '../lib/tac';\nimport { maskAddress } from '../util/log-redaction';\n\n/**\n * Options for initiating an outbound chat conversation.\n *\n * The sender is always the channel's configured `agentAddress`. Multi-sender\n * deployments should run one TAC instance per sender.\n */\nexport const InitiateChatConversationOptionsSchema = z.object({\n to: z.string().min(1, 'Recipient identity is required'),\n channelId: z.string().min(1, 'Chat Channel SID is required'),\n message: z.string().min(1, 'Initial message is required'),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type InitiateChatConversationOptions = z.infer<typeof InitiateChatConversationOptionsSchema>;\n\n/**\n * Chat channel configuration options\n */\nexport interface ChatChannelConfig extends MessagingChannelConfig {\n /** Chat agent identity string (defaults to 'ai-assistant') */\n agentAddress?: string;\n}\n\n/**\n * Chat Channel implementation for Twilio Conversations Service\n *\n * Handles web chat conversations through webhook events from Twilio.\n * Uses identity-based addressing instead of phone numbers.\n * Automatically creates AI_AGENT participant if needed and manages conversation lifecycle.\n */\nexport class ChatChannel extends MessagingChannel {\n private readonly agentAddress: string;\n\n // Chat identifies the customer author-driven from the webhook's\n // `author.participantId`; promoting some other channel-matching UNKNOWN\n // CHAT participant could pick the wrong recipient.\n protected override reconcileCustomerType: boolean = false;\n\n constructor(tac: TAC, config?: ChatChannelConfig) {\n super(tac, config);\n this.agentAddress = config?.agentAddress ?? 'ai-assistant';\n }\n\n public get channelType(): ChannelType {\n return 'chat';\n }\n\n protected isDefaultAgentAddress(authorAddress: string): boolean {\n return authorAddress === this.agentAddress;\n }\n\n protected getAgentAddress(conversationId: ConversationId): ConversationAddress {\n const session = this.getConversationSession(conversationId);\n const channelId =\n session && typeof session.metadata?.channelId === 'string'\n ? session.metadata.channelId\n : undefined;\n return {\n channel: 'CHAT',\n address: this.agentAddress,\n ...(channelId ? { channelId } : {}),\n };\n }\n\n /**\n * Send chat response using the Conversation Orchestrator Actions API (SEND_MESSAGE).\n *\n * Reads the agent and customer participant ids stashed on the session by\n * inbound reconciliation or outbound initiation. Missing ids are a misuse —\n * `sendResponse` is only expected to be called after an inbound webhook\n * (COMMUNICATION_CREATED → reconcile) or after `initiateOutboundConversation`,\n * both of which populate the session.\n */\n public async sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_length: message.length,\n operation: 'send_response',\n },\n 'Sending chat response'\n );\n\n try {\n const session = this.getConversationSession(conversationId);\n\n if (!session || !session.authorInfo || !session.aiAgentInfo) {\n throw new Error(\n `Unable to send chat message: sendResponse called without a reconciled session ` +\n `for conversation ${conversationId}. Wait for an inbound webhook or call ` +\n `initiateOutboundConversation first.`\n );\n }\n\n const customerParticipantId = session.authorInfo.participantId;\n const agentParticipantId = session.aiAgentInfo.participantId;\n if (!customerParticipantId || !agentParticipantId) {\n throw new Error(\n `Unable to send chat message: session for conversation ${conversationId} is ` +\n `missing participant ids.`\n );\n }\n\n // channelId (Chat Channel SID) is required for CHAT delivery — the V1\n // Chat backend uses it to pick the destination thread. Inbound webhooks\n // always populate it, so a missing value here is a misuse.\n const chatChannelSid =\n typeof session.metadata?.channelId === 'string' ? session.metadata.channelId : undefined;\n\n if (!chatChannelSid) {\n throw new Error(\n \"Missing required session.metadata['channelId'] for chat sendResponse; \" +\n 'this is normally populated by an inbound webhook. Ensure an inbound ' +\n 'message has been processed before calling sendResponse, or set ' +\n \"session.metadata['channelId'] explicitly in advanced usage.\"\n );\n }\n\n const channelSettings: ActionChannelSettings = {\n channelId: chatChannelSid,\n };\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n recipient_participant_id: customerParticipantId,\n agent_participant_id: agentParticipantId,\n channel_id: chatChannelSid,\n },\n 'Sending chat message via Actions API'\n );\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: {\n channel: 'CHAT',\n participantId: agentParticipantId,\n },\n to: [\n {\n channel: 'CHAT',\n participantId: customerParticipantId,\n },\n ],\n content: { text: message },\n channelSettings,\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n { conversation_id: conversationId, channel_id: chatChannelSid },\n 'Chat message sent successfully via Actions API'\n );\n } catch (error) {\n this.logger.error({ err: error, conversation_id: conversationId }, 'Send response error');\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Initiate an outbound chat conversation\n *\n * Creates a conversation via Conversation Orchestrator, adds customer and\n * agent participants, then sends the initial message via the Actions API.\n * The sender is always this channel's configured `agentAddress`.\n */\n public async initiateOutboundConversation(\n options: InitiateChatConversationOptions\n ): Promise<InitiateConversationResult> {\n const validated = InitiateChatConversationOptionsSchema.parse(options);\n\n this.logger.info(\n { to: maskAddress(validated.to), channel_id: validated.channelId },\n 'Initiating outbound chat conversation'\n );\n\n return this.initiateOutboundMessagingConversation({\n channel: 'CHAT',\n to: validated.to,\n from: this.agentAddress,\n message: validated.message,\n ...(validated.metadata ? { metadata: validated.metadata } : {}),\n channelId: validated.channelId,\n channelSettings: {\n channelId: validated.channelId,\n },\n });\n }\n}\n","/**\n * URL builders for Twilio Studio handoff.\n *\n * Shared between the tools package (digital handoff POSTs) and the server\n * package (voice `<Connect action>` URL).\n */\n\n/**\n * Build the Twilio Studio Flow Executions URL for a given Flow SID.\n *\n * Used for digital (messaging/chat) handoff — POST the handoff payload\n * to this URL to start a Studio flow execution.\n */\nexport function studioExecutionsUrl(flowSid: string): string {\n return `https://studio.twilio.com/v2/Flows/${flowSid}/Executions`;\n}\n\n/**\n * Build the Twilio Studio Flow voice webhook URL for a given Flow SID.\n *\n * Used as the `<Connect action=...>` URL in TwiML for voice handoff,\n * so that when ConversationRelay ends the session Twilio triggers the\n * Studio flow for an incoming call.\n */\nexport function studioVoiceHandoffUrl(accountSid: string, flowSid: string): string {\n return `https://webhooks.twilio.com/v1/Accounts/${accountSid}/Flows/${flowSid}?Trigger=incomingCall`;\n}\n","import { WebSocket } from 'ws';\nimport VoiceResponse from 'twilio/lib/twiml/VoiceResponse.js';\nimport Twilio from 'twilio';\nimport {\n ChannelType,\n ConversationId,\n ConversationSession,\n ProfileId,\n WebSocketMessageSchema,\n PromptMessage,\n InterruptMessage,\n TextTokenMessage,\n CustomParameters,\n ConversationRelayConfig,\n ConversationRelayConfigSchema,\n ConversationRelayCallbackPayload,\n InitiateVoiceConversationOptions,\n InitiateVoiceConversationOptionsSchema,\n TwiMLOptions,\n TwiMLRequest,\n ConversationWebhookPayload,\n CallOptions,\n CallEventKind,\n CallStatusEvent,\n AmdEvent,\n RecordingEvent,\n CallOptionsSchema,\n callOptionsToCreateParams,\n callStatusEventFromForm,\n amdEventFromForm,\n recordingEventFromForm,\n} from '../types/index';\nimport type { InitiateVoiceConversationResult } from '../types/conversation';\nimport { BaseChannel, BaseChannelEvents, BaseChannelOptions } from './base';\nimport type { TAC } from '../lib/tac';\nimport { TACMemoryResponse } from '../lib/tac-memory-response';\nimport { maskAddress, redactTwimlParameters } from '../util/log-redaction';\nimport { studioVoiceHandoffUrl } from '../util/handoff-urls';\n\n/** Fixed default welcome greeting applied when no layer sets one. */\nconst DEFAULT_WELCOME_GREETING = 'Hello! How can I assist you today?';\n\n/** Poll window from call-connect: 10 attempts, 250ms doubling to a 1.5s cap (~11s). */\nconst POLL_ATTEMPTS = 10;\nconst POLL_BASE_DELAY_MS = 250;\nconst POLL_MAX_DELAY_MS = 1500;\n\n/**\n * Configuration for the Voice channel.\n *\n * `defaultTwimlOptions` is one of several TwiML layers that merge per-field;\n * see `handleIncomingCall` (inbound) and `initiateOutboundConversation`\n * (outbound) for the full precedence order.\n */\nexport interface VoiceChannelConfig extends BaseChannelOptions {\n /**\n * Static `TwiMLOptions` applied to every call (inbound and outbound).\n * Controls the TwiML inside `<ConversationRelay>` — voice, language,\n * transcription provider, welcomeGreeting, `<Language>` children, etc. Use\n * this when the same ConversationRelay configuration is correct for every call.\n *\n * Per-call inbound customization is registered via\n * `VoiceChannel.onInboundCallTwiml(...)` (not on this config).\n *\n * Note: `customParameters` and `languages` replace wholesale when a\n * higher-priority layer sets them.\n */\n defaultTwimlOptions?: TwiMLOptions;\n\n /**\n * Static {@link CallOptions} applied to every outbound call — the\n * `calls.create` parameters, including the call-event callback URLs. This is\n * the layer to use for a custom server or non-default routes: URLs set here\n * override the ones TAC would derive from `voicePublicDomain` +\n * `voiceCallEventPath`.\n */\n defaultCallOptions?: CallOptions;\n}\n\n/**\n * Callback that produces per-call overrides for the TwiML inside\n * `<ConversationRelay>` on inbound calls. Receives a framework-neutral\n * {@link TwiMLRequest} and returns {@link TwiMLOptions}.\n */\nexport type InboundCallTwimlHandler = (req: TwiMLRequest) => Promise<TwiMLOptions>;\n\n/** Handler for Twilio `statusCallback` webhooks. */\nexport type CallStatusHandler = (event: CallStatusEvent) => Promise<void> | void;\n\n/** Handler for Twilio `asyncAmdStatusCallback` webhooks. */\nexport type AmdHandler = (event: AmdEvent) => Promise<void> | void;\n\n/** Handler for Twilio `recordingStatusCallback` webhooks. */\nexport type RecordingHandler = (event: RecordingEvent) => Promise<void> | void;\n\n/**\n * Stringify a custom-parameter value for emission as a `<Parameter value=...>`.\n * Parameter values are scalars in practice; objects are JSON-encoded rather\n * than producing '[object Object]'.\n */\nfunction stringifyParameterValue(value: unknown): string {\n if (typeof value === 'object') {\n return JSON.stringify(value);\n }\n // string | number | boolean | bigint | symbol — all safely stringifiable.\n return String(value as string | number | boolean | bigint);\n}\n\n/**\n * Voice channel event callbacks extending base callbacks\n */\nexport interface VoiceChannelEvents extends BaseChannelEvents {\n onSetup?: (data: {\n callSid: string;\n from: string;\n to: string;\n customParameters: Record<string, unknown> | undefined;\n }) => void;\n onPrompt?: (data: {\n conversationId: ConversationId;\n transcript: string;\n userMemory?: TACMemoryResponse;\n session?: ConversationSession;\n abortSignal: AbortSignal;\n }) => Promise<void> | void;\n onInterrupt?: (data: {\n conversationId: ConversationId;\n utteranceUntilInterrupt: string | undefined;\n durationUntilInterruptMs: number | undefined;\n }) => void;\n /**\n * Fired once the session and WebSocket registration exist — in orchestrated\n * mode possibly before the first prompt, since the lookup starts at setup.\n */\n onWebSocketConnected?: (data: { conversationId: ConversationId }) => void;\n onWebSocketDisconnected?: (data: { conversationId: ConversationId }) => void;\n}\n\n/**\n * Voice Channel implementation for Twilio ConversationRelay\n *\n * Handles voice conversations through WebSocket connections.\n * Manages real-time audio streaming and conversation state.\n */\nexport interface StreamTask {\n controller: AbortController;\n hasSentTokens: boolean;\n}\n\nexport class VoiceChannel extends BaseChannel {\n private readonly webSocketConnections: Map<ConversationId, WebSocket>;\n private readonly voiceCallbacks: VoiceChannelEvents;\n private readonly streamTasks: Map<ConversationId, StreamTask>;\n private readonly promptQueues: Map<ConversationId, Promise<void>>;\n private readonly initializationRetries: Map<string, number>;\n private readonly callSidToConversationId: Map<string, ConversationId>;\n private readonly MAX_INITIALIZATION_RETRIES = 3;\n private twilioClient: ReturnType<typeof Twilio> | undefined;\n private readonly voiceConfig: VoiceChannelConfig;\n private onInboundCallTwimlHandler: InboundCallTwimlHandler | undefined;\n private onCallStatusHandler: CallStatusHandler | undefined;\n private onAmdHandler: AmdHandler | undefined;\n private onRecordingHandler: RecordingHandler | undefined;\n\n constructor(tac: TAC, options?: VoiceChannelConfig) {\n super(tac, options);\n this.voiceConfig = options ?? {};\n this.webSocketConnections = new Map();\n this.voiceCallbacks = {};\n this.streamTasks = new Map();\n this.promptQueues = new Map();\n this.initializationRetries = new Map();\n this.callSidToConversationId = new Map();\n }\n\n /**\n * Register a callback that produces per-call overrides for the TwiML inside\n * `<ConversationRelay>` on inbound calls.\n *\n * The callback receives a framework-neutral {@link TwiMLRequest} (parsed from\n * the Twilio webhook form) and returns {@link TwiMLOptions}. Fields the\n * callback explicitly sets override `defaultTwimlOptions` and TAC defaults;\n * unset fields fall through.\n *\n * @example\n * ```typescript\n * voiceChannel.onInboundCallTwiml(async req => {\n * if (req.callerCountry === 'MX') {\n * return { language: 'es-MX', welcomeGreeting: '¡Hola!' };\n * }\n * return {};\n * });\n * ```\n *\n * Outbound calls don't use this — pass per-call TwiML via\n * `InitiateVoiceConversationOptions.twimlOptions` directly.\n */\n public onInboundCallTwiml(callback: InboundCallTwimlHandler): void {\n this.onInboundCallTwimlHandler = callback;\n }\n\n /**\n * Register a handler for Twilio `statusCallback` webhooks.\n *\n * This is the Calls-API status callback (call disposition), not the\n * ConversationRelay session callback — see\n * {@link handleConversationRelayCallback}.\n *\n * Registering does two things: it stores the handler, and it makes later\n * outbound calls pass `statusCallback` to `calls.create`. With no handler\n * registered TAC omits that parameter, so Twilio has nowhere to post and the\n * event never arrives.\n *\n * Twilio reports only the terminal event by default, which covers every\n * disposition; set `CallOptions.statusCallbackEvent` for ringing/answered.\n *\n * @example\n * ```typescript\n * voiceChannel.onCallStatus(async event => {\n * if (event.isUnreached) {\n * // queue a retry\n * }\n * });\n * ```\n */\n public onCallStatus(callback: CallStatusHandler): void {\n this.onCallStatusHandler = callback;\n }\n\n /**\n * Register a handler for Twilio `asyncAmdStatusCallback` webhooks.\n *\n * Registering makes later outbound calls pass `asyncAmdStatusCallback` to\n * `calls.create`; without a handler TAC omits it and Twilio has nowhere to\n * post the result. It does not enable detection — that's per-call, via\n * `CallOptions.machineDetection` and `asyncAmd`, both of which are required\n * for this to fire (at most once per call).\n *\n * @example\n * ```typescript\n * voiceChannel.onAmd(async event => {\n * if (event.isMachine) {\n * await voiceChannel.endCall(event.callSid); // voicemail → hang up\n * }\n * });\n * ```\n */\n public onAmd(callback: AmdHandler): void {\n this.onAmdHandler = callback;\n }\n\n /**\n * Register a handler for Twilio `recordingStatusCallback` webhooks.\n *\n * Registering makes later outbound calls pass `recordingStatusCallback` to\n * `calls.create`; without a handler TAC omits it and Twilio has nowhere to\n * post. It does not start recording — that's `CallOptions.record`, which is\n * required for this to fire.\n *\n * @example\n * ```typescript\n * voiceChannel.onRecording(async event => {\n * if (event.recordingStatus === 'completed') {\n * // store event.recordingUrl\n * }\n * });\n * ```\n */\n public onRecording(callback: RecordingHandler): void {\n this.onRecordingHandler = callback;\n }\n\n /**\n * Resolve the public WebSocket URL from `TACConfig.voicePublicDomain` +\n * `TACConfig.voiceWebsocketPath`. Throws if `voicePublicDomain` isn't set.\n */\n private resolveWebsocketUrl(action: string): string {\n if (this.config.voicePublicDomain) {\n return `wss://${this.config.voicePublicDomain}${this.config.voiceWebsocketPath}`;\n }\n throw new Error(\n `${action} needs a WebSocket URL. Set TWILIO_VOICE_PUBLIC_DOMAIN ` +\n '(or TACConfig.voicePublicDomain).'\n );\n }\n\n /**\n * Resolve the default `<Connect action=...>` cleanup URL.\n *\n * Returns undefined if `voicePublicDomain` isn't set; that's fine because\n * actionUrl has higher-priority layers (customizer, twimlOptions, Studio\n * handoff) above this fallback.\n */\n private resolveDefaultActionUrl(): string | undefined {\n if (this.config.voicePublicDomain) {\n return `https://${this.config.voicePublicDomain}${this.config.voiceActionPath}`;\n }\n return undefined;\n }\n\n private getTwilioClient(): ReturnType<typeof Twilio> {\n if (!this.twilioClient) {\n this.twilioClient = Twilio(this.config.apiKey, this.config.apiSecret, {\n accountSid: this.config.accountSid,\n });\n }\n return this.twilioClient;\n }\n\n public get channelType(): ChannelType {\n return 'voice';\n }\n\n /**\n * Register event callbacks (override for Voice-specific events)\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic event callback needs to accept any args\n public override on(event: string, callback: (...args: any[]) => void): void {\n switch (event) {\n case 'setup':\n this.voiceCallbacks.onSetup = callback;\n break;\n case 'prompt':\n this.voiceCallbacks.onPrompt = callback;\n break;\n case 'interrupt':\n this.voiceCallbacks.onInterrupt = callback;\n break;\n case 'webSocketConnected':\n this.voiceCallbacks.onWebSocketConnected = callback;\n break;\n case 'webSocketDisconnected':\n this.voiceCallbacks.onWebSocketDisconnected = callback;\n break;\n default:\n // Delegate to parent for base events\n super.on(event, callback);\n break;\n }\n }\n\n /**\n * Process conversation webhooks for cleanup.\n *\n * Voice channel processes CONVERSATION_UPDATED events:\n * - CLOSED status: Clean up local session state\n *\n * Note: Conversation tracking uses instance-local memory. In multi-instance\n * deployments, webhooks may route to a different instance, preventing cleanup.\n *\n * @param payload - Raw webhook event data from Twilio\n * @param idempotencyToken - Optional Twilio idempotency token from request headers\n */\n public async processWebhook(payload: unknown, idempotencyToken?: string): Promise<void> {\n try {\n const result = this.preprocessWebhook(payload, idempotencyToken);\n if (!result) {\n return;\n }\n\n const { webhookData, eventType, conversationId } = result;\n\n switch (eventType) {\n case 'CONVERSATION_UPDATED':\n this.logger.debug(\n { conversation_id: conversationId, status: webhookData.data?.status },\n 'Handling CONVERSATION_UPDATED'\n );\n await this.handleConversationUpdated(webhookData);\n break;\n\n default:\n this.logger.debug(\n {\n event_type: eventType,\n raw_event_type: webhookData.eventType,\n conversation_id: conversationId,\n },\n 'Unhandled event type - this event will be ignored'\n );\n }\n\n this.logger.debug({ event_type: eventType }, 'Webhook processing completed');\n } catch (error) {\n // Remove the token so retries are not blocked\n if (idempotencyToken) {\n this.removeWebhookToken(idempotencyToken);\n }\n this.handleError(error instanceof Error ? error : new Error(String(error)), { payload });\n }\n }\n\n /**\n * Handle conversation updated event\n */\n private async handleConversationUpdated(payload: ConversationWebhookPayload): Promise<void> {\n const conversationId = this.extractConversationId(payload);\n\n if (!conversationId) {\n throw new Error('Missing conversation ID in conversation.updated event');\n }\n\n // Check if conversation is closed\n if (payload.data?.status === 'CLOSED') {\n this.logger.debug(\n { conversation_id: conversationId, status: payload.data.status },\n 'Conversation closed, cleaning up'\n );\n await this.endConversation(conversationId);\n } else if (payload.data?.status === 'INACTIVE') {\n // \"once\" mode: drop the cache so the next message re-fetches.\n this.invalidateCachedMemory(conversationId);\n }\n }\n\n /**\n * Get active WebSocket connection for a conversation\n */\n public getWebsocket(conversationId: ConversationId): WebSocket | null {\n return this.webSocketConnections.get(conversationId) || null;\n }\n\n /**\n * Poll Conversation Orchestrator for the conversation ConversationRelay\n * created for `callSid`, then register the local session and WebSocket.\n * Runs in the background from `setup`, so those can exist before the\n * caller speaks.\n */\n private async initializeOrchestratedConversation(\n callSid: string,\n fromNumber: string | null,\n ws: WebSocket\n ): Promise<ConversationId> {\n if (!this.conversationClient) {\n throw new Error('Conversation client is required in orchestrated mode');\n }\n\n let conversations: Awaited<ReturnType<typeof this.conversationClient.listConversations>> = [];\n\n for (let attempt = 0; attempt < POLL_ATTEMPTS; attempt++) {\n // ACTIVE only: a stale conversation on the same CallSid would break the\n // \"exactly 1\" check below.\n conversations = await this.conversationClient.listConversations({\n channelId: callSid,\n status: ['ACTIVE'],\n });\n if (conversations.length === 1) break;\n if (attempt < POLL_ATTEMPTS - 1) {\n this.logger.debug(\n { call_sid: callSid, attempt: attempt + 1, found: conversations.length },\n 'Conversation not ready yet, polling again'\n );\n const delayMs = Math.min(POLL_BASE_DELAY_MS * 2 ** attempt, POLL_MAX_DELAY_MS);\n await new Promise(resolve => setTimeout(resolve, delayMs));\n }\n }\n\n if (conversations.length !== 1) {\n throw new Error(\n `Expected exactly 1 conversation for callSid ${callSid}, ` +\n `but found ${conversations.length} after ${POLL_ATTEMPTS} attempts`\n );\n }\n\n const conversation = conversations[0]!;\n const conversationId = conversation.id as ConversationId;\n\n const participants = await this.conversationClient.listParticipants(conversationId);\n\n const customerParticipant = participants.find(p => p.type === 'CUSTOMER');\n const customerAddress =\n customerParticipant?.addresses?.find(a => a.channel === 'VOICE')?.address ??\n fromNumber ??\n undefined;\n const profileId: ProfileId | undefined = customerParticipant?.profileId\n ? (customerParticipant.profileId as ProfileId)\n : undefined;\n\n this.webSocketConnections.set(conversationId, ws);\n this.callSidToConversationId.set(callSid, conversationId);\n const session = this.startConversation(conversationId, profileId);\n // conversationId is the Orchestrator's, so record the CallSid too —\n // out-of-band call webhooks resolve via getConversationSessionByCallSid.\n session.callSid = callSid;\n\n if (customerAddress) {\n session.authorInfo = {\n address: customerAddress,\n };\n }\n\n if (this.voiceCallbacks.onWebSocketConnected) {\n this.voiceCallbacks.onWebSocketConnected({ conversationId });\n }\n\n return conversationId;\n }\n\n /**\n * Handle WebSocket connection from ConversationRelay\n */\n public handleWebSocketConnection(ws: WebSocket): void {\n let conversationId: ConversationId | null = null;\n let callSid: string | null = null;\n let fromNumber: string | null = null;\n let initializationFailed = false;\n // Background conversation lookup started on `setup`; cleared once claimed,\n // by the first prompt or by the close handler.\n let initPromise: Promise<ConversationId> | null = null;\n\n ws.on('message', (data: Buffer) => {\n (async (): Promise<void> => {\n try {\n const messageData = JSON.parse(data.toString()) as unknown;\n const result = WebSocketMessageSchema.safeParse(messageData);\n\n if (!result.success) {\n this.logger.debug(\n {\n validation_errors: result.error.issues.map(issue => ({\n path: issue.path.join('.'),\n message: issue.message,\n })),\n },\n 'Invalid or unrecognized WebSocket message, skipping'\n );\n return;\n }\n\n const message = result.data;\n\n switch (message.type) {\n case 'setup':\n callSid = message.callSid;\n fromNumber = message.from;\n\n // ConversationRelay creates the conversation at call-connect, so\n // start the lookup now and let it overlap the wait for the\n // caller's first utterance instead of delaying it.\n if (this.tac.isOrchestratorEnabled()) {\n this.logger.debug(\n { call_sid: callSid },\n 'Starting background conversation initialization'\n );\n initPromise = this.initializeOrchestratedConversation(callSid, fromNumber, ws);\n // Marks it handled; whoever claims it still sees the rejection.\n void initPromise.catch(() => undefined);\n }\n\n if (this.voiceCallbacks.onSetup) {\n this.voiceCallbacks.onSetup({\n callSid,\n from: message.from,\n to: message.to,\n customParameters: message.customParameters,\n });\n }\n break;\n\n case 'prompt':\n if (!conversationId && callSid) {\n // Check retry limit before attempting initialization\n const retryCount = this.initializationRetries.get(callSid) ?? 0;\n if (retryCount >= this.MAX_INITIALIZATION_RETRIES) {\n throw new Error(\n `Cannot process prompt - conversation initialization failed after ${retryCount} attempts for callSid ${callSid}`\n );\n }\n\n try {\n if (initializationFailed) {\n this.logger.info(\n { call_sid: callSid, retry_count: retryCount },\n 'Retrying conversation initialization after previous failure'\n );\n }\n\n if (!this.tac.isOrchestratorEnabled()) {\n // Voice-only mode: use callSid as conversationId directly\n conversationId = callSid as ConversationId;\n this.webSocketConnections.set(conversationId, ws);\n this.callSidToConversationId.set(callSid, conversationId);\n const session = this.startConversation(conversationId);\n // Relay-only: conversationId === callSid.\n session.callSid = callSid;\n\n if (fromNumber) {\n session.authorInfo = { address: fromNumber };\n }\n\n if (this.voiceCallbacks.onWebSocketConnected) {\n this.voiceCallbacks.onWebSocketConnected({ conversationId });\n }\n } else {\n // Await the lookup from `setup` — usually already done.\n // Stays visible to the close handler while awaited, so a\n // hangup mid-lookup still cleans up; cleared after so a\n // retry starts fresh and `close` uses conversationId.\n initPromise ??= this.initializeOrchestratedConversation(\n callSid,\n fromNumber,\n ws\n );\n try {\n conversationId = await initPromise;\n } finally {\n initPromise = null;\n }\n }\n\n // Success! Clear retry count and failed flag\n initializationFailed = false;\n this.initializationRetries.delete(callSid);\n this.logger.info(\n { conversation_id: conversationId, call_sid: callSid },\n 'Conversation initialization succeeded'\n );\n } catch (err) {\n initializationFailed = true;\n this.initializationRetries.set(callSid, retryCount + 1);\n this.logger.error(\n { err, call_sid: callSid, retry_count: retryCount + 1 },\n 'Conversation initialization failed'\n );\n throw err;\n }\n }\n\n if (conversationId) {\n const previousPrompt = this.promptQueues.get(conversationId) ?? Promise.resolve();\n const currentPrompt = previousPrompt\n .then(() => this.handlePromptMessage(conversationId!, message))\n .catch((err: unknown) => {\n this.handleError(err instanceof Error ? err : new Error(String(err)), {\n conversationId,\n message: data.toString(),\n });\n });\n this.promptQueues.set(conversationId, currentPrompt);\n } else {\n this.logger.warn('Received prompt before conversation initialized');\n }\n break;\n\n case 'interrupt':\n if (conversationId) {\n this.handleInterruptMessage(conversationId, message);\n }\n break;\n\n default:\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_type: (messageData as Record<string, unknown>)?.type,\n },\n 'Unhandled WebSocket event type'\n );\n break;\n }\n } catch (error) {\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n callSid,\n message: data.toString(),\n });\n }\n })().catch((err: unknown) => {\n this.logger.error({ err }, 'Unhandled error in WebSocket message handler');\n });\n });\n\n ws.on('close', () => {\n // Call ended before any prompt claimed the lookup. A promise can't be\n // cancelled, so adopt what it registers and tear that down, or the\n // WebSocket registration leaks. The conversation stays tracked (CLOSED).\n const pendingInit = initPromise;\n initPromise = null;\n if (pendingInit && !conversationId) {\n void pendingInit\n .then(async adoptedId => {\n await this.handleWebSocketDisconnect(adoptedId);\n if (callSid) this.callSidToConversationId.delete(callSid);\n })\n // No prompt ever arrived to surface a lookup failure, so log here.\n .catch((err: unknown) => {\n this.logger.error(\n { err, call_sid: callSid },\n 'Background conversation initialization failed after the call ended'\n );\n });\n }\n\n if (conversationId) {\n void this.handleWebSocketDisconnect(conversationId).catch((err: unknown) => {\n this.logger.error(\n { err, conversation_id: conversationId },\n 'WebSocket disconnect handler error'\n );\n });\n }\n if (callSid) {\n this.initializationRetries.delete(callSid);\n this.callSidToConversationId.delete(callSid);\n }\n });\n\n ws.on('error', (error: Error) => {\n this.handleError(error, { conversationId });\n });\n }\n\n /**\n * Handle WebSocket prompt message (user speech)\n */\n private async handlePromptMessage(\n conversationId: ConversationId,\n message: PromptMessage\n ): Promise<void> {\n const transcript = message.voicePrompt;\n\n // Start a new stream task so the AbortSignal is available to handlers.\n // startStreamTask() cancels any existing task internally.\n const streamTask = this.startStreamTask(conversationId);\n\n // Get session for memory retrieval\n const session = this.getConversationSession(conversationId);\n\n // Retrieve memory if enabled via memoryMode\n const userMemory = session\n ? await this.retrieveMemoryIfEnabled(session, transcript)\n : undefined;\n\n if (this.voiceCallbacks.onPrompt) {\n await this.voiceCallbacks.onPrompt({\n conversationId,\n transcript,\n abortSignal: streamTask.controller.signal,\n ...(userMemory !== undefined && { userMemory }),\n ...(session !== undefined && { session }),\n });\n }\n }\n\n /**\n * Handle WebSocket interrupt message\n */\n private handleInterruptMessage(conversationId: ConversationId, message: InterruptMessage): void {\n const { utteranceUntilInterrupt, durationUntilInterruptMs } = message;\n\n // Check whether tokens were sent before cancelling (cancel deletes the entry)\n const streamTask = this.streamTasks.get(conversationId);\n const wasStreaming = streamTask?.hasSentTokens ?? false;\n\n // Cancel any in-flight stream task on interrupt\n const cancelled = this.cancelStreamTask(conversationId);\n if (cancelled) {\n this.logger.info(\n { conversation_id: conversationId },\n 'Cancelled stream task due to interrupt'\n );\n }\n\n // Finalize the interrupted token stream so ConversationRelay stops\n // waiting for more tokens. Only needed when tokens were actually sent;\n // sending last:true without a preceding stream creates a spurious empty turn.\n if (cancelled && wasStreaming) {\n const ws = this.webSocketConnections.get(conversationId);\n if (ws?.readyState === WebSocket.OPEN) {\n try {\n ws.send(JSON.stringify({ type: 'text', token: '', last: true }));\n } catch (err) {\n this.logger.debug(\n { conversation_id: conversationId, err },\n 'WebSocket closed before sending stream finalization'\n );\n }\n }\n }\n\n if (this.voiceCallbacks.onInterrupt) {\n this.voiceCallbacks.onInterrupt({\n conversationId,\n utteranceUntilInterrupt,\n durationUntilInterruptMs,\n });\n }\n }\n\n /**\n * Handle WebSocket disconnection. In orchestrated mode the conversation stays\n * tracked until the CLOSED webhook (so a follow-up call can reuse it); in\n * voice-only mode there is no such webhook, so it ends here.\n */\n private async handleWebSocketDisconnect(conversationId: ConversationId): Promise<void> {\n this.cancelStreamTask(conversationId);\n this.webSocketConnections.delete(conversationId);\n this.promptQueues.delete(conversationId);\n\n if (this.voiceCallbacks.onWebSocketDisconnected) {\n this.voiceCallbacks.onWebSocketDisconnected({ conversationId });\n }\n\n if (!this.tac.isOrchestratorEnabled()) {\n await this.endConversation(conversationId);\n }\n }\n\n /**\n * Send voice response via WebSocket\n */\n public sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n try {\n const ws = this.webSocketConnections.get(conversationId);\n\n if (ws?.readyState !== WebSocket.OPEN) {\n throw new Error(`No active WebSocket connection for conversation ${conversationId}`);\n }\n\n const response: TextTokenMessage = {\n type: 'text',\n token: message,\n last: true,\n };\n\n ws.send(JSON.stringify(response));\n\n // If a handoff is pending, send the WS \"end\" message now that the\n // LLM's final response has been delivered to the caller.\n const session = this.getConversationSession(conversationId);\n if (session?.pendingHandoffData) {\n try {\n ws.send(JSON.stringify(session.pendingHandoffData));\n delete session.pendingHandoffData;\n } catch (err) {\n this.logger.warn(\n { err, conversation_id: conversationId },\n 'WebSocket closed before sending handoff end message; caller will not be transferred'\n );\n }\n }\n\n return Promise.resolve();\n } catch (error) {\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Send a streaming voice response via WebSocket, token by token.\n *\n * Each chunk from the iterable is sent as a text token message with last: false.\n * After the iterable completes, a final empty marker with last: true is sent\n * only if at least one token was emitted. If the AbortSignal fires (e.g., user\n * interrupted), iteration stops and no final marker is sent (the interrupt\n * handler sends the finalization instead).\n *\n * @returns The accumulated full response text.\n */\n public async sendStreamingResponse(\n conversationId: ConversationId,\n stream: AsyncIterable<string>,\n options?: { signal?: AbortSignal }\n ): Promise<string> {\n const ws = this.webSocketConnections.get(conversationId);\n\n if (ws?.readyState !== WebSocket.OPEN) {\n throw new Error(`No active WebSocket connection for conversation ${conversationId}`);\n }\n\n const activeTask = this.streamTasks.get(conversationId);\n const signal = options?.signal ?? activeTask?.controller.signal;\n let fullResponse = '';\n let hasSentTokens = false;\n\n if (signal?.aborted) {\n return fullResponse;\n }\n\n try {\n for await (const chunk of stream) {\n if (signal?.aborted) {\n break;\n }\n\n if (ws.readyState !== WebSocket.OPEN) {\n this.logger.info(\n { conversation_id: conversationId },\n 'WebSocket closed during streaming'\n );\n break;\n }\n\n fullResponse += chunk;\n const tokenMessage: TextTokenMessage = {\n type: 'text',\n token: chunk,\n last: false,\n };\n ws.send(JSON.stringify(tokenMessage));\n hasSentTokens = true;\n if (activeTask) {\n activeTask.hasSentTokens = true;\n }\n }\n\n if (!signal?.aborted && hasSentTokens && ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: 'text', token: '', last: true }));\n }\n } catch (error) {\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n });\n throw error;\n } finally {\n // Only clean up if we still own the active stream task.\n // A new prompt may have replaced it while we were unwinding.\n if (activeTask && this.streamTasks.get(conversationId) === activeTask) {\n this.completeStreamTask(conversationId);\n }\n }\n\n return fullResponse;\n }\n\n // =========================================================================\n // Incoming Call Handling\n // =========================================================================\n\n /**\n * Generate the TwiML response for an incoming voice call.\n *\n * ConversationRelay automatically handles conversation creation and\n * participant management via the `conversationConfiguration` parameter.\n *\n * The WebSocket URL and default session-cleanup action URL are derived from\n * `TACConfig.voicePublicDomain` + `TACConfig.voiceWebsocketPath` /\n * `voiceActionPath`.\n *\n * TwiML fields are merged per-field, highest precedence first:\n * 1. Output of the customizer registered via\n * `VoiceChannel.onInboundCallTwiml(...)` if configured and `twimlRequest`\n * is given. (Application-owned.)\n * 2. `VoiceChannelConfig.defaultTwimlOptions` — per-channel defaults.\n * 3. `hostTwimlOptions` — per-call transport facts supplied by the host (the\n * code owning the route), e.g. a per-call `websocketUrl` with an affinity\n * token.\n * 4. TAC defaults: a fixed default welcomeGreeting, `conversationConfiguration`\n * from `TACConfig`, `actionUrl` resolved via Studio handoff (when\n * `studioHandoffFlowSid` is configured), else derived from\n * `TACConfig.voicePublicDomain` + `voiceActionPath`, and the `websocketUrl`\n * derived from `TACConfig.voicePublicDomain` + `voiceWebsocketPath`.\n *\n * Fields not set at a layer fall through to lower layers. Arrays (`languages`)\n * and nested objects (`customParameters`) replace wholesale when set at a\n * higher-priority layer. `websocketUrl` falls back to the `TACConfig`-derived\n * URL if unset at every layer.\n *\n * @param twimlRequest - Parsed Twilio webhook fields. Passed to the customizer\n * if one is configured on the channel.\n * @param options - Additional per-call inputs.\n * @param options.hostTwimlOptions - Per-call TwiML supplied by a custom\n * in-process host (e.g. an affinity-routed deployment injecting a per-call\n * `websocketUrl`), layered below `defaultTwimlOptions` and the application\n * customizer but above the TAC defaults.\n * @returns TwiML XML string for call connection.\n */\n public async handleIncomingCall(\n twimlRequest?: TwiMLRequest,\n options?: { hostTwimlOptions?: TwiMLOptions }\n ): Promise<string> {\n let customized: TwiMLOptions | undefined;\n if (this.onInboundCallTwimlHandler && twimlRequest) {\n customized = await this.onInboundCallTwimlHandler(twimlRequest);\n }\n\n const merged = this.buildTwimlOptions(options?.hostTwimlOptions, customized);\n const websocketUrl = merged.websocketUrl ?? this.resolveWebsocketUrl('handleIncomingCall');\n return this.generateTwiml(websocketUrl, merged);\n }\n\n /**\n * Layer TwiML options, lowest precedence first: TAC defaults → `host`\n * (calling host's per-call values) → channel `defaultTwimlOptions` → `perCall`\n * (application customizer output for inbound, or\n * `InitiateVoiceConversationOptions.twimlOptions` for outbound).\n */\n private buildTwimlOptions(\n host: TwiMLOptions | undefined,\n perCall: TwiMLOptions | undefined\n ): TwiMLOptions {\n const merged: TwiMLOptions = {\n welcomeGreeting: DEFAULT_WELCOME_GREETING,\n ...(this.tac.isOrchestratorEnabled() && this.config.conversationConfigurationId !== undefined\n ? { conversationConfiguration: this.config.conversationConfigurationId }\n : {}),\n };\n const resolvedActionUrl = this.resolveActionUrl(host, perCall);\n if (resolvedActionUrl !== undefined) {\n merged.actionUrl = resolvedActionUrl;\n }\n if (host) {\n this.overlayFields(merged, host);\n }\n if (this.voiceConfig.defaultTwimlOptions) {\n this.overlayFields(merged, this.voiceConfig.defaultTwimlOptions);\n }\n if (perCall) {\n this.overlayFields(merged, perCall);\n }\n return merged;\n }\n\n /**\n * Apply fields explicitly present on `source` onto `target`.\n *\n * Nested objects (`customParameters`), arrays (`languages`), and dicts\n * (`extra`) replace wholesale — there's no per-key merging.\n *\n * `actionUrl` is skipped here on purpose — it's resolved once via\n * `resolveActionUrl` looking at every layer at once, and that resolved value\n * is written into `target` before this overlay runs. Letting it through here\n * would let a higher-priority layer that didn't set actionUrl silently clobber\n * a lower layer that did.\n *\n * \"Explicitly present\" is detected via key presence (`key in source`), which\n * mirrors Python's `model_fields_set`: a key set to `undefined` is still\n * \"present\" and overrides lower layers, while an absent key falls through.\n */\n private overlayFields(target: TwiMLOptions, source: TwiMLOptions): void {\n for (const key of Object.keys(source) as (keyof TwiMLOptions)[]) {\n if (key === 'actionUrl') {\n continue;\n }\n // Index assignment across a heterogeneous record; both sides are TwiMLOptions.\n (target as Record<string, unknown>)[key] = (source as Record<string, unknown>)[key];\n }\n }\n\n /**\n * Resolve the TwiML `<Connect action=...>` URL.\n *\n * Precedence (highest to lowest):\n * 1. application customizer\n * 2. channel `defaultTwimlOptions`\n * 3. `host` (calling host's per-call options)\n * 4. Studio handoff (when `studioHandoffFlowSid` is configured)\n * 5. Channel default — derived from `TACConfig.voicePublicDomain` +\n * `TACConfig.voiceActionPath`.\n *\n * User-expressed intent (Studio handoff is configured explicitly on\n * `TACConfig`) beats the SDK's generated cleanup default.\n *\n * Explicit `actionUrl: undefined` on a layer (key present, value undefined)\n * suppresses `<Connect action=...>` entirely — all lower layers are skipped.\n * `actionUrl` left absent (key not present) falls through to the next layer.\n */\n private resolveActionUrl(\n host: TwiMLOptions | undefined,\n customized: TwiMLOptions | undefined\n ): string | undefined {\n if (customized && 'actionUrl' in customized) {\n return customized.actionUrl;\n }\n if (\n this.voiceConfig.defaultTwimlOptions &&\n 'actionUrl' in this.voiceConfig.defaultTwimlOptions\n ) {\n return this.voiceConfig.defaultTwimlOptions.actionUrl;\n }\n if (host && 'actionUrl' in host) {\n return host.actionUrl;\n }\n if (this.config.studioHandoffFlowSid) {\n return studioVoiceHandoffUrl(this.config.accountSid, this.config.studioHandoffFlowSid);\n }\n return this.resolveDefaultActionUrl();\n }\n\n // =========================================================================\n // Outbound Call Handling\n // =========================================================================\n\n /**\n * Overlay `perCall` onto `VoiceChannelConfig.defaultCallOptions`.\n *\n * Per-field via key presence, the same convention {@link overlayFields} uses\n * for TwiML options — so a per-call `{ machineDetection: undefined }`\n * explicitly clears the channel default rather than falling through to it.\n *\n * The result is always validated, for two reasons: a combination only\n * reachable by layering — per-call clearing `machineDetection` while the\n * default set `asyncAmd` — must still fail instead of reaching Twilio, and\n * `VoiceChannelConfig` is a plain interface, so `defaultCallOptions` has had\n * no runtime validation of its own.\n */\n private mergeCallOptions(perCall: CallOptions | undefined): CallOptions | undefined {\n const defaults = this.voiceConfig.defaultCallOptions;\n if (!defaults && !perCall) {\n return undefined;\n }\n\n const merged: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(defaults ?? {})) {\n if (value !== undefined) {\n merged[key] = value;\n }\n }\n for (const key of Object.keys(perCall ?? {})) {\n merged[key] = (perCall as Record<string, unknown>)[key];\n }\n return CallOptionsSchema.parse(merged);\n }\n\n /**\n * Build the extra arguments for `client.calls.create`.\n *\n * Layers, highest precedence first: this call's `callOptions`,\n * `VoiceChannelConfig.defaultCallOptions`, then callback URLs derived from\n * `voicePublicDomain` + `voiceCallEventPath`.\n *\n * A URL is derived only when its handler is registered. That's a deliberate\n * deviation from `websocketUrl` / `actionUrl`, which derive unconditionally:\n * those are load-bearing, so a wrong one fails loudly on the first call,\n * whereas an unwanted call-event URL fails as silent 11200 alerts for a\n * feature nobody asked for. Set the URLs in `defaultCallOptions` when TAC\n * isn't serving the routes.\n */\n private buildCallParams(callOptions: CallOptions | undefined): Record<string, unknown> {\n const merged = this.mergeCallOptions(callOptions);\n const params = merged ? callOptionsToCreateParams(merged) : {};\n\n const wiring: [CallEventKind, string, unknown][] = [\n ['status', 'statusCallback', this.onCallStatusHandler],\n ['amd', 'asyncAmdStatusCallback', this.onAmdHandler],\n ['recording', 'recordingStatusCallback', this.onRecordingHandler],\n ];\n for (const [kind, param, handler] of wiring) {\n if (!handler) continue;\n const url = this.config.callEventUrl(kind);\n // An explicit URL from either options layer is never overwritten.\n if (url !== undefined && params[param] === undefined) {\n params[param] = url;\n }\n }\n\n return params;\n }\n\n /**\n * Initiate an outbound voice conversation\n *\n * Places an outbound call with inline TwiML that connects to ConversationRelay.\n * The conversationConfiguration attribute tells CO to create and manage the\n * conversation during passive hydration. The session is initialized when the\n * background callSid lookup started at WebSocket setup finds it.\n *\n * TwiML fields are merged per-field, highest precedence first:\n * 1. `options.twimlOptions` — per-call overrides\n * 2. `VoiceChannelConfig.defaultTwimlOptions` — channel-wide defaults\n * 3. TAC defaults: welcome greeting, `conversationConfiguration` from\n * `TACConfig`, and `actionUrl` from Studio handoff (if configured), else\n * derived from `TACConfig.voicePublicDomain` + `voiceActionPath`.\n *\n * Calls-API parameters merge the same way:\n * 1. `options.callOptions` — per-call overrides\n * 2. `VoiceChannelConfig.defaultCallOptions` — channel-wide defaults\n * 3. Callback URLs derived from `TACConfig.voicePublicDomain` +\n * `voiceCallEventPath`, for handlers that are registered\n *\n * The WebSocket URL is derived from `TACConfig.voicePublicDomain` +\n * `TACConfig.voiceWebsocketPath`, unless overridden per-call via\n * `options.websocketUrl`.\n */\n public async initiateOutboundConversation(\n options: InitiateVoiceConversationOptions\n ): Promise<InitiateVoiceConversationResult> {\n const validated = InitiateVoiceConversationOptionsSchema.parse(options);\n const fromNumber = this.config.phoneNumber;\n\n this.logger.info(\n { to: validated.to, from: fromNumber },\n 'Initiating outbound voice conversation'\n );\n\n try {\n // Outbound has no inbound customizer and no host layer; the per-call\n // override is options.twimlOptions.\n const merged = this.buildTwimlOptions(undefined, validated.twimlOptions);\n\n // `options.websocketUrl` is the dedicated per-call outbound override and\n // wins over any websocketUrl that came through the layered twimlOptions\n // merge; both fall back to the TACConfig-derived URL.\n const websocketUrl =\n validated.websocketUrl ??\n merged.websocketUrl ??\n this.resolveWebsocketUrl('initiateOutboundConversation');\n const twiml = this.generateTwiml(websocketUrl, merged);\n const callParams = this.buildCallParams(validated.callOptions);\n\n // The inline TwiML handed to Twilio, useful for debugging the\n // <Connect action> handoff target. customParameters values are masked —\n // they're arbitrary developer data (profile IDs, caller names), unlike\n // the WS/action URLs and conversation config.\n this.logger.debug(\n { twiml: redactTwimlParameters(twiml), to: maskAddress(validated.to) },\n 'Outbound call TwiML'\n );\n\n // Place the outbound call with inline TwiML\n const client = this.getTwilioClient();\n const call = await client.calls.create({\n to: validated.to,\n from: fromNumber,\n twiml,\n ...callParams,\n });\n\n this.logger.info(\n { call_sid: call.sid, to: maskAddress(validated.to) },\n 'Outbound voice call placed'\n );\n\n return { callSid: call.sid };\n } catch (error) {\n this.logger.error(\n { err: error, to: maskAddress(validated.to) },\n 'Failed to initiate outbound call'\n );\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n to: validated.to,\n });\n throw error;\n }\n }\n\n // =========================================================================\n // ConversationRelay Callback Handling\n // =========================================================================\n\n /**\n * Handle ConversationRelay callback from Twilio. Cleans up on call completion\n * in voice-only mode; in orchestrated mode the CO webhook owns cleanup.\n *\n * @param payload - Callback payload from Twilio\n * @returns Response with status, content, and content type\n */\n public async handleConversationRelayCallback(\n payload: ConversationRelayCallbackPayload\n ): Promise<{ status: number; content: string; contentType: string }> {\n this.logger.debug(\n { call_sid: payload.CallSid, call_status: payload.CallStatus },\n 'ConversationRelay callback received'\n );\n\n if (payload.AccountSid !== this.config.accountSid) {\n this.logger.warn(\n { expected: this.config.accountSid, received: payload.AccountSid },\n 'ConversationRelay callback AccountSid mismatch, ignoring'\n );\n return { status: 403, content: 'Forbidden', contentType: 'text/plain' };\n }\n\n if (payload.CallStatus === 'completed' && !this.tac.isOrchestratorEnabled()) {\n const conversationId = this.callSidToConversationId.get(payload.CallSid);\n if (conversationId) {\n this.callSidToConversationId.delete(payload.CallSid);\n await this.endConversation(conversationId);\n }\n }\n\n return { status: 200, content: 'OK', contentType: 'text/plain' };\n }\n\n // =========================================================================\n // Call Event Handling (status callback, async AMD, recording)\n // =========================================================================\n\n /**\n * Whether a call-webhook payload belongs to the configured account.\n *\n * Twilio signature validation already gates the route; this is defense in\n * depth. A payload with no `AccountSid` is allowed through.\n *\n * Subaccounts: events carry the SID the call was placed on, so configure TAC\n * with that account or its events get dropped here.\n */\n private callEventAccountOk(form: Record<string, string>): boolean {\n const accountSid = form['AccountSid'];\n if (accountSid && accountSid !== this.config.accountSid) {\n this.logger.warn(\n { expected: this.config.accountSid, received: accountSid },\n 'Call event AccountSid mismatch, ignoring'\n );\n return false;\n }\n return true;\n }\n\n /**\n * Parse a call-event webhook form and dispatch it to its handler.\n *\n * Returns 400 when the payload can't be parsed (no `CallSid`) or the handler\n * throws — better than handing Twilio a 200 for an event that wasn't\n * processed. Everything else, including no handler registered and an\n * account mismatch, is a 200 no-op.\n */\n private async dispatchCallEvent<T>(\n kind: CallEventKind,\n form: Record<string, string>,\n handler: ((event: T) => Promise<void> | void) | undefined,\n parse: (form: Record<string, string>) => T,\n logFields: (event: T) => Record<string, unknown>\n ): Promise<{ status: number; content: string; contentType: string }> {\n const ok = { status: 200, content: 'OK', contentType: 'text/plain' };\n if (!handler || !this.callEventAccountOk(form)) {\n return ok;\n }\n\n try {\n const event = parse(form);\n this.logger.debug(logFields(event), `Call ${kind} event received`);\n await handler(event);\n } catch (error) {\n this.logger.error({ err: error, kind }, 'Failed to process call event callback');\n return { status: 400, content: 'Bad Request', contentType: 'text/plain' };\n }\n return ok;\n }\n\n /**\n * Handle a Twilio `statusCallback` webhook.\n *\n * The developer routes the request here (`TACServer` does this automatically\n * for its `/status` call-event route). Parsed into a {@link CallStatusEvent}\n * and dispatched to the {@link onCallStatus} handler. No-op if no handler is\n * registered.\n *\n * @param form - Raw form data from the webhook request.\n */\n public async handleCallStatusEvent(\n form: Record<string, string>\n ): Promise<{ status: number; content: string; contentType: string }> {\n return this.dispatchCallEvent(\n 'status',\n form,\n this.onCallStatusHandler,\n callStatusEventFromForm,\n event => ({ call_sid: event.callSid, call_status: event.callStatus })\n );\n }\n\n /**\n * Handle a Twilio `asyncAmdStatusCallback` webhook.\n *\n * The developer routes the request here (`TACServer` does this automatically\n * for its `/amd` call-event route). Parsed into an {@link AmdEvent} and\n * dispatched to the {@link onAmd} handler. No-op if no handler is registered.\n *\n * @param form - Raw form data from the webhook request.\n */\n public async handleAmdEvent(\n form: Record<string, string>\n ): Promise<{ status: number; content: string; contentType: string }> {\n return this.dispatchCallEvent('amd', form, this.onAmdHandler, amdEventFromForm, event => ({\n call_sid: event.callSid,\n answered_by: event.answeredBy,\n }));\n }\n\n /**\n * Handle a Twilio `recordingStatusCallback` webhook.\n *\n * The developer routes the request here (`TACServer` does this automatically\n * for its `/recording` call-event route). Parsed into a\n * {@link RecordingEvent} and dispatched to the {@link onRecording} handler.\n * No-op if no handler is registered.\n *\n * @param form - Raw form data from the webhook request.\n */\n public async handleRecordingEvent(\n form: Record<string, string>\n ): Promise<{ status: number; content: string; contentType: string }> {\n return this.dispatchCallEvent(\n 'recording',\n form,\n this.onRecordingHandler,\n recordingEventFromForm,\n event => ({ call_sid: event.callSid, recording_status: event.recordingStatus })\n );\n }\n\n /**\n * Hang up a call and clean up its ConversationRelay session.\n *\n * Works on `callSid` alone, whether or not a session exists yet. No-ops the\n * session cleanup if none is tracked.\n *\n * Does not throw — hanging up an already-ended call is routine (the callee\n * hangs up while AMD is still resolving), and handlers shouldn't have to\n * guard against it.\n *\n * @param callSid - Twilio Call SID (from a call event, the outbound result, or\n * `ConversationSession.callSid`).\n * @returns True if Twilio accepted the hangup, false if it failed (logged).\n * Session cleanup runs either way.\n */\n public async endCall(callSid: string): Promise<boolean> {\n const client = this.getTwilioClient();\n let hungUp = true;\n try {\n await client.calls(callSid).update({ status: 'completed' });\n } catch (error) {\n hungUp = false;\n this.logger.error({ err: error, call_sid: callSid }, 'Failed to hang up call');\n }\n\n const session = this.getConversationSessionByCallSid(callSid);\n if (session) {\n await this.endConversation(session.conversationId as ConversationId);\n }\n return hungUp;\n }\n\n /**\n * Look up the active voice session for a Twilio Call SID.\n *\n * Out-of-band code holding a CallSid — a dashboard route, an operator action,\n * a call-event handler — can't reach the session-facing methods, which are\n * keyed by conversation id: the Orchestrator conversation id in orchestrator\n * mode, the CallSid only in ConversationRelay-only mode.\n *\n * Relay-only mode creates the session on the first prompt; orchestrated\n * mode creates it when the lookup started at setup finishes, so it may\n * exist before the caller speaks — including before `onAmd` fires. Treat it\n * as racy and hang up with {@link endCall}, which needs no session.\n *\n * At the other end, orchestrator mode keeps the session until Conversation\n * Orchestrator's CLOSED webhook, so it outlives the call and `onCallStatus` /\n * `onRecording` do resolve. Relay-only mode tears down on the\n * ConversationRelay callback instead, which races them.\n *\n * @example\n * ```typescript\n * async function nudge(callSid: string): Promise<void> {\n * const session = voiceChannel.getConversationSessionByCallSid(callSid);\n * if (session) {\n * await voiceChannel.sendResponse(session.conversationId, 'Still there?');\n * }\n * }\n * ```\n *\n * @param callSid - Twilio Call SID, e.g. from\n * `InitiateVoiceConversationResult.callSid` or a call event.\n * @returns The session, or `undefined` — not created yet, the call ended, or\n * it landed on another instance (see the horizontal-scaling note in\n * CLAUDE.md).\n */\n public getConversationSessionByCallSid(callSid: string): ConversationSession | undefined {\n for (const session of this.activeConversations.values()) {\n if (session.callSid === callSid) {\n return session;\n }\n }\n return undefined;\n }\n\n // =========================================================================\n // Stream Task Management\n // =========================================================================\n\n /**\n * Start tracking a streaming task for a conversation\n *\n * @param conversationId - The conversation ID\n * @returns The stream task with its AbortController\n */\n public startStreamTask(conversationId: ConversationId): StreamTask {\n // Cancel any existing task\n this.cancelStreamTask(conversationId);\n\n const task: StreamTask = { controller: new AbortController(), hasSentTokens: false };\n this.streamTasks.set(conversationId, task);\n\n this.logger.debug({ conversation_id: conversationId }, 'Started stream task');\n return task;\n }\n\n /**\n * Cancel an active streaming task\n *\n * @param conversationId - The conversation ID\n * @returns true if a task was cancelled, false otherwise\n */\n public cancelStreamTask(conversationId: ConversationId): boolean {\n const task = this.streamTasks.get(conversationId);\n if (task) {\n task.controller.abort();\n this.streamTasks.delete(conversationId);\n this.logger.debug({ conversation_id: conversationId }, 'Cancelled stream task');\n return true;\n }\n return false;\n }\n\n /**\n * Complete a streaming task (remove from tracking)\n *\n * @param conversationId - The conversation ID\n */\n public completeStreamTask(conversationId: ConversationId): void {\n this.streamTasks.delete(conversationId);\n this.logger.debug({ conversation_id: conversationId }, 'Completed stream task');\n }\n\n /**\n * Check if a stream task is active\n *\n * @param conversationId - The conversation ID\n * @returns true if an active task exists\n */\n public hasActiveStreamTask(conversationId: ConversationId): boolean {\n const task = this.streamTasks.get(conversationId);\n return task !== undefined && !task.controller.signal.aborted;\n }\n\n // =========================================================================\n // ConversationRelay TwiML Generation\n // =========================================================================\n\n /**\n * Field names on {@link TwiMLOptions} that map directly to `<ConversationRelay>`\n * attributes (camelCase, emitted as-is). Excludes the fields handled specially\n * by {@link generateTwiml}: websocketUrl (resolved through the layered merge and\n * emitted as the `url` attribute), actionUrl, languages, customParameters, extra.\n */\n private static readonly RELAY_ATTR_FIELDS: readonly (keyof TwiMLOptions)[] = [\n 'welcomeGreeting',\n 'welcomeGreetingInterruptible',\n 'conversationConfiguration',\n 'language',\n 'ttsLanguage',\n 'transcriptionLanguage',\n 'voice',\n 'ttsProvider',\n 'transcriptionProvider',\n 'speechModel',\n 'elevenlabsTextNormalization',\n 'eotThreshold',\n 'partialPrompts',\n 'deepgramSmartFormat',\n 'speechTimeout',\n 'interruptible',\n 'interruptSensitivity',\n 'reportInputDuringAgentSpeech',\n 'ignoreBackchannel',\n 'preemptible',\n 'dtmfDetection',\n 'hints',\n 'events',\n 'debug',\n 'intelligenceService',\n ];\n\n /**\n * Generate TwiML XML for ConversationRelay from a merged {@link TwiMLOptions}.\n *\n * This is the low-level emitter used by `handleIncomingCall` and\n * `initiateOutboundConversation` after layering. It mirrors the Python SDK's\n * `generate_twiml`. The WebSocket URL may be passed as `websocketUrl` or via\n * `options.websocketUrl` (the explicit argument wins when both are given), so a\n * channel-less caller can pass everything in one object.\n *\n * @param websocketUrl - Public WebSocket URL (e.g. 'wss://example.ngrok.app/ws').\n * Optional if `options.websocketUrl` is set.\n * @param options - Merged TwiMLOptions to emit.\n * @returns TwiML XML string ready to return to Twilio.\n * @throws {Error} if no WebSocket URL is provided via either source.\n */\n private generateTwiml(websocketUrl: string | undefined, options: TwiMLOptions): string {\n const resolvedWebsocketUrl = websocketUrl || options.websocketUrl;\n if (!resolvedWebsocketUrl) {\n throw new Error(\n 'generateTwiml requires a WebSocket URL — pass it explicitly or set options.websocketUrl.'\n );\n }\n\n const response = new VoiceResponse();\n\n // <Connect action=...> — actionUrl undefined means no action attribute.\n const connect = response.connect(options.actionUrl ? { action: options.actionUrl } : {});\n\n // Build ConversationRelay attributes. Keys on TwiMLOptions are already\n // camelCase; the Twilio SDK serializes booleans/numbers as TwiML attribute\n // values.\n const relayAttrs: Record<string, unknown> = { url: resolvedWebsocketUrl };\n for (const field of VoiceChannel.RELAY_ATTR_FIELDS) {\n let value = options[field];\n if (value === undefined) {\n continue;\n }\n // Twilio accepts true/false on `interruptible` for backward-compat but the\n // documented enum is none|dtmf|speech|any. Normalize so we emit canonical\n // values regardless of the SDK's bool serialization.\n if (field === 'interruptible' && typeof value === 'boolean') {\n value = value ? 'any' : 'none';\n }\n relayAttrs[field] = value;\n }\n\n // `extra` is the escape hatch for attributes not yet typed. The schema's\n // shadow-guard rejects keys colliding with typed fields, so pass them\n // through as-is — except `url`: it's not a TwiMLOptions field (invisible to\n // the shadow-guard) but IS the resolved WebSocket endpoint, so letting\n // `extra.url` through would silently point the call at the wrong socket.\n if (options.extra) {\n for (const [key, value] of Object.entries(options.extra)) {\n if (key === 'url') {\n this.logger.warn(\n 'Ignoring `url` in TwiMLOptions.extra; set `websocketUrl` to override the ConversationRelay URL.'\n );\n continue;\n }\n relayAttrs[key] = value;\n }\n }\n\n const relay = connect.conversationRelay(\n relayAttrs as Parameters<typeof connect.conversationRelay>[0]\n );\n\n // Emit <Language> children, if any.\n if (options.languages && options.languages.length > 0) {\n for (const lang of options.languages) {\n const langAttrs = this.filterUnsetValues(lang);\n relay.language(langAttrs as Parameters<typeof relay.language>[0]);\n }\n }\n\n // Emit custom parameters as <Parameter> children, skipping null/undefined.\n if (options.customParameters) {\n for (const [name, value] of Object.entries(options.customParameters)) {\n if (value !== null && value !== undefined) {\n relay.parameter({ name, value: stringifyParameterValue(value) });\n }\n }\n }\n\n return response.toString();\n }\n\n /**\n * Generate TwiML to connect a call to ConversationRelay.\n * Validates configuration with Zod before generating TwiML.\n *\n * @param config - ConversationRelay configuration (url, transcription, TTS, etc.)\n * @param options - Optional settings for parameters and the Connect verb\n * @returns TwiML XML string\n * @throws {Error} if config validation fails\n */\n public connectConversationRelay(\n config: ConversationRelayConfig,\n options?: { parameters?: CustomParameters; actionUrl?: string }\n ): string {\n // Validate configuration with Zod schema (consistent with project pattern)\n const validationResult = ConversationRelayConfigSchema.safeParse(config);\n\n if (!validationResult.success) {\n const errorMessage = validationResult.error.issues\n .map(issue => `${issue.path.join('.')}: ${issue.message}`)\n .join(', ');\n throw new Error(`Invalid ConversationRelay configuration: ${errorMessage}`);\n }\n\n const validatedConfig = validationResult.data;\n\n // Extract languages array (child elements, not attributes)\n const { languages, ...conversationRelayAttributes } = validatedConfig;\n\n // Filter out undefined values to keep TwiML clean\n const filteredConfig = this.filterUnsetValues(conversationRelayAttributes);\n\n // Build TwiML using SDK\n const response = new VoiceResponse();\n const connect = response.connect(options?.actionUrl ? { action: options.actionUrl } : {});\n const relay = connect.conversationRelay(filteredConfig);\n\n // Add language configurations as child <Language> elements\n if (languages && languages.length > 0) {\n for (const lang of languages) {\n // Filter out undefined values to satisfy exactOptionalPropertyTypes\n // Type assertion is safe here because we've already validated with Zod\n const filteredLang = this.filterUnsetValues(lang);\n relay.language(filteredLang as Parameters<typeof relay.language>[0]);\n }\n }\n\n // Add custom parameters as child <Parameter> elements\n if (options?.parameters) {\n for (const [name, value] of Object.entries(options.parameters)) {\n relay.parameter({ name, value: String(value) });\n }\n }\n\n return response.toString();\n }\n\n /**\n * Filter out undefined values from configuration object.\n * Keeps null, false, 0, and empty strings as they are valid values.\n */\n private filterUnsetValues(config: Record<string, unknown>): Record<string, unknown> {\n const filtered: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(config)) {\n if (value !== undefined) {\n filtered[key] = value;\n }\n }\n return filtered;\n }\n\n /**\n * Cleanup channel state on shutdown\n *\n * Note: WebSocket connections are managed by the server and closed there.\n * This method only cleans up internal channel state.\n */\n public override shutdown(): void {\n this.streamTasks.clear();\n this.webSocketConnections.clear();\n this.promptQueues.clear();\n this.initializationRetries.clear();\n this.callSidToConversationId.clear();\n super.shutdown();\n }\n}\n","import { ConversationSession } from '../types/conversation';\n\nfunction formatTraitValue(value: unknown): string {\n // For primitives (string, number, boolean, bigint), return as-is for readability\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n typeof value === 'bigint'\n ) {\n return String(value);\n }\n // For objects and arrays, use JSON.stringify with bigint replacer\n try {\n return (\n JSON.stringify(value, (_key, replacerValue: unknown) => {\n if (typeof replacerValue === 'bigint') {\n return String(replacerValue);\n }\n return replacerValue;\n }) ?? String(value)\n );\n } catch {\n return String(value);\n }\n}\n\n/**\n * Build a formatted profile prompt section from conversation session data.\n *\n * Generates a markdown-formatted Customer Profile section with trait information.\n * Each trait is displayed as a bulleted list item with the trait name and formatted value.\n * Primitive values (string, number, boolean, bigint) are shown without quotes for readability,\n * while objects and arrays are JSON-stringified.\n *\n * @param context - The conversation session containing profile data\n * @param traitGroups - Optional array of trait group names to include. If provided, only\n * these trait groups will be included in the output. If an empty array\n * is provided, returns null.\n * @returns Formatted profile section or null if no profile data or no traits match filter\n */\nexport function buildProfilePrompt(\n context: ConversationSession,\n traitGroups?: string[]\n): string | null {\n if (!context.profile || !context.profile.traits) {\n return null;\n }\n\n let filteredTraits: Record<string, unknown>;\n\n if (traitGroups !== undefined) {\n if (traitGroups.length === 0) {\n return null;\n }\n\n filteredTraits = Object.fromEntries(\n Object.entries(context.profile.traits).filter(\n ([key, value]) => traitGroups.includes(key) && value != null\n )\n );\n } else {\n filteredTraits = Object.fromEntries(\n Object.entries(context.profile.traits).filter(([, value]) => value != null)\n );\n }\n\n if (Object.keys(filteredTraits).length === 0) {\n return null;\n }\n\n const lines = ['## Customer Profile', 'Information about this customer:'];\n\n for (const [key, value] of Object.entries(filteredTraits)) {\n lines.push(`- ${key}: ${formatTraitValue(value)}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * Configuration options for adapter utilities like MemoryPromptBuilder.\n */\nexport interface AdapterOptions {\n /**\n * Optional array of profile trait group names to include in the output.\n *\n * - If undefined or not provided, all available trait groups are included\n * - If empty array ([]), no profile traits are included (profile section is omitted)\n * - If populated array, only the specified trait groups are included\n *\n * @example\n * ```typescript\n * // Include only Contact and Preferences traits\n * { profileTraits: ['Contact', 'Preferences'] }\n *\n * // Exclude all profile traits\n * { profileTraits: [] }\n *\n * // Include all traits (default)\n * { } // or undefined\n * ```\n */\n profileTraits?: string[];\n}\n\n/**\n * Extract and normalize profile trait groups from adapter options.\n *\n * This is an internal helper function used by MemoryPromptBuilder to handle trait filtering.\n * The returned array should be treated as immutable.\n *\n * @param options - Adapter options containing optional profileTraits configuration\n * @returns undefined if all traits should be included, empty array if traits should be\n * excluded, or the specified trait groups array. The array is returned by reference.\n * @internal\n */\nexport function getProfileTraits(options?: AdapterOptions): string[] | undefined {\n if (!options || options.profileTraits === undefined) {\n return undefined;\n }\n\n if (options.profileTraits.length === 0) {\n return [];\n }\n\n return options.profileTraits;\n}\n","import { TACMemoryResponse } from '../lib/tac-memory-response';\nimport { buildProfilePrompt } from '../lib/conversation-session-helpers';\nimport { ConversationSession } from '../types/conversation';\nimport { AdapterOptions, getProfileTraits } from './options';\n\n/**\n * Utility class for building formatted LLM prompts from TAC memory and profile data.\n *\n * Generates markdown-formatted prompt sections that can be injected into LLM system messages,\n * providing context about the customer from previous interactions.\n *\n * @example\n * ```typescript\n * // Simple usage with compose() - no if/else needed\n * const systemPrompt = MemoryPromptBuilder.compose(\n * 'You are a helpful assistant.',\n * memoryResponse,\n * session\n * );\n *\n * // Advanced usage with trait filtering\n * const systemPrompt = MemoryPromptBuilder.compose(\n * 'You are a helpful assistant.',\n * memoryResponse,\n * session,\n * { profileTraits: ['Contact', 'Preferences'] }\n * );\n * ```\n */\nexport class MemoryPromptBuilder {\n /**\n * Build a formatted memory prompt from available memory and profile data.\n *\n * **Note:** Most users should use `compose()` instead, which automatically handles\n * combining memory with your system prompt. Use `build()` only if you need the raw\n * memory content without a system prompt.\n *\n * Generates a structured prompt with up to four sections:\n * - **Customer Profile**: Profile traits (filtered by options if provided)\n * - **Key Observations**: Important notes from previous interactions\n * - **Past Conversation Summaries**: Summaries of previous conversations\n * - **Recent Message History**: Recent communications with the customer\n *\n * Sections with no data are omitted. If no data is available at all, returns an empty string.\n *\n * @param memoryResponse - Memory data from TAC.retrieveMemory() containing observations,\n * summaries, and communications. Optional.\n * @param context - Conversation session containing profile data. Optional.\n * @param options - Configuration options for filtering profile traits. If profileTraits is\n * provided, only those trait groups will be included in the output. If an\n * empty array is provided, profile section is omitted. Optional.\n * @returns Formatted markdown prompt string ready for injection into LLM system messages.\n * Returns empty string if no memory or profile data is available.\n *\n * @example\n * ```typescript\n * // Recommended: Use compose() for most cases\n * const prompt = MemoryPromptBuilder.compose(basePrompt, memory, session);\n *\n * // Advanced: Use build() only if you need raw memory content\n * const rawMemory = MemoryPromptBuilder.build(memory, session);\n * if (rawMemory) {\n * // Custom handling of memory content\n * }\n * ```\n */\n static build(\n memoryResponse?: TACMemoryResponse | null,\n context?: ConversationSession | null,\n options?: AdapterOptions\n ): string {\n if (!memoryResponse && (!context || !context.profile)) {\n return '';\n }\n\n const sections: string[] = [];\n\n if (context) {\n const traitGroups = getProfileTraits(options);\n const profileSection = buildProfilePrompt(context, traitGroups);\n if (profileSection) {\n sections.push(profileSection);\n }\n }\n\n if (memoryResponse) {\n const memorySections = memoryResponse.buildMemoryPrompts();\n sections.push(...memorySections);\n }\n\n if (sections.length === 0) {\n return '';\n }\n\n return this.assemblePrompt(sections);\n }\n\n /**\n * Compose system prompt with memory context.\n *\n * Appends memory to systemPrompt if available. Always returns a string.\n * Eliminates the need for manual if/else checks when combining prompts.\n *\n * **Note:** Empty strings and whitespace-only strings are treated as \"no system prompt\"\n * (same as null/undefined). Whitespace is automatically trimmed from systemPrompt.\n *\n * @param systemPrompt - Base system prompt for the LLM. Empty string, whitespace-only,\n * null, and undefined are all treated as \"no system prompt\". Optional.\n * @param memoryResponse - Memory data from TAC.retrieveMemory(). Optional.\n * @param context - Conversation session containing profile data. Optional.\n * @param options - Configuration options for filtering profile traits. Optional.\n * @returns Composed prompt with memory appended to systemPrompt. Returns empty string\n * if both systemPrompt and memory are empty/null/undefined.\n *\n * @example\n * ```typescript\n * // Before (manual if/else)\n * const memoryContext = MemoryPromptBuilder.build(memoryResponse, context);\n * const systemPrompt = basePrompt + (memoryContext ? `\\n\\n${memoryContext}` : '');\n *\n * // After (compose handles it)\n * const systemPrompt = MemoryPromptBuilder.compose(basePrompt, memoryResponse, context);\n *\n * // Empty strings and whitespace are treated as \"no prompt\"\n * MemoryPromptBuilder.compose('', memoryResponse, context); // Returns just memory\n * MemoryPromptBuilder.compose(' ', memoryResponse, context); // Returns just memory (trimmed)\n * MemoryPromptBuilder.compose(null, memoryResponse, context); // Returns just memory\n * ```\n */\n static compose(\n systemPrompt?: string | null,\n memoryResponse?: TACMemoryResponse | null,\n context?: ConversationSession | null,\n options?: AdapterOptions\n ): string {\n const memoryContent = this.build(memoryResponse, context, options);\n const trimmedPrompt = systemPrompt?.trim() || null;\n\n if (!trimmedPrompt && !memoryContent) {\n return '';\n }\n\n if (!trimmedPrompt) {\n return memoryContent;\n }\n\n if (!memoryContent) {\n return trimmedPrompt;\n }\n\n return `${trimmedPrompt}\\n\\n${memoryContent}`;\n }\n\n private static assemblePrompt(sections: string[]): string {\n const header = [\n '# Customer Context',\n 'You have access to the following information about this customer ' +\n 'from previous interactions:',\n '',\n ];\n\n const body = sections.join('\\n\\n');\n\n return header.join('\\n') + body;\n }\n}\n","import { ToolFunction, JSONSchema, OpenAITool, AnthropicTool } from '@twilio/tac-core';\n\n/**\n * TAC Tool class with helper methods for LLM integration\n *\n * Matches Python's TACTool dataclass with conversion methods.\n */\nexport class TACTool<TParams = unknown, TResult = unknown> {\n constructor(\n public readonly name: string,\n public readonly description: string,\n public readonly parameters: JSONSchema,\n public readonly implementation: ToolFunction<TParams, TResult>\n ) {}\n\n /**\n * Convert to OpenAI function calling format\n */\n toOpenAIFormat(): OpenAITool {\n return {\n type: 'function',\n function: {\n name: this.name,\n description: this.description,\n parameters: this.parameters,\n },\n };\n }\n\n /**\n * Convert to Anthropic tool calling format\n */\n toAnthropicFormat(): AnthropicTool {\n return {\n name: this.name,\n description: this.description,\n input_schema: this.parameters,\n };\n }\n\n /**\n * Convert to JSON string (OpenAI format by default)\n */\n toJSON(): string {\n return JSON.stringify(this.toOpenAIFormat(), null, 2);\n }\n\n /**\n * Convert this tool to an OpenAI Agents SDK `FunctionTool` instance.\n *\n * Unlike `toOpenAIFormat` and `toAnthropicFormat` (which return plain\n * objects consumed by HTTP APIs), the OpenAI Agents SDK dispatches on tool\n * *type*, so this returns a live `tool(...)` object with an invoke callback\n * that calls this tool and JSON-encodes the result.\n *\n * Requires the `@openai/agents` package:\n *\n * npm install @openai/agents\n *\n * @returns A FunctionTool ready to pass to `new Agent({ tools: [...] })`.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Return type depends on an optional peer dep we don't declare\n async toOpenAIAgentsSDKTool(): Promise<any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Optional peer dep: dynamic import, can't declare types\n let agentsModule: any;\n try {\n // Dynamic import of an optional peer dependency. The indirection via a\n // string variable keeps TypeScript from trying to resolve the module\n // at compile time (it isn't a declared dependency).\n const moduleSpec = '@openai/agents';\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- Dynamic optional-dep import\n agentsModule = await import(/* @vite-ignore */ moduleSpec);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new Error(\n 'toOpenAIAgentsSDKTool() failed to load @openai/agents. ' +\n 'Install with: npm install @openai/agents. ' +\n `Underlying error: ${cause}`,\n { cause: err }\n );\n }\n\n const impl = this.implementation;\n // The Agents SDK's `JsonObjectSchemaNonStrict` requires `additionalProperties: true`\n // (and `Strict` requires `: false`). Our schema sets neither by default, so normalize\n // for the non-strict path we're opting into.\n const parameters = {\n ...this.parameters,\n additionalProperties: true,\n };\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call -- Optional peer dep\n return agentsModule.tool({\n name: this.name,\n description: this.description,\n parameters,\n // Disable strict mode: the Agents SDK's strict JSON schema rejects\n // some features TAC emits (e.g. unions, top-level description).\n strict: false,\n execute: async (args: unknown): Promise<string> => {\n const result = await impl(args as TParams);\n return JSON.stringify(result);\n },\n });\n }\n}\n\n/**\n * Create a tool directly with all parameters\n *\n * Simplified approach matching Python's create_tool function.\n * No builder pattern - just a simple function call.\n */\nexport function defineTool<TParams = unknown, TResult = unknown>(\n name: string,\n description: string,\n parameters: JSONSchema,\n implementation: ToolFunction<TParams, TResult>\n): TACTool<TParams, TResult> {\n if (!name) {\n throw new Error('Tool name is required');\n }\n\n if (!description) {\n throw new Error('Tool description is required');\n }\n\n if (!parameters) {\n throw new Error('Tool parameters schema is required');\n }\n\n if (!implementation) {\n throw new Error('Tool implementation is required');\n }\n\n return new TACTool(name, description, parameters, implementation);\n}\n","import {\n MemoryRetrievalRequest,\n MemoryRetrievalResponse,\n BuiltInTools,\n MemoryClient,\n} from '@twilio/tac-core';\nimport { TACTool, defineTool } from '../lib/builder';\n\n/**\n * Parameters for memory retrieval tool\n */\ninterface MemoryRetrievalParams {\n query?: string;\n beginDate?: string;\n endDate?: string;\n observationsLimit?: number;\n summariesLimit?: number;\n communicationsLimit?: number;\n relevanceThreshold?: number;\n}\n\n/**\n * Create memory retrieval tool.\n *\n * @param memoryClient - Memory client instance (must be initialized with storeId)\n * @param profileId - Optional profile ID for memory retrieval\n * @param conversationId - Optional conversation ID for memory retrieval\n * @param options - Optional overrides for tool metadata.\n * @param options.name - Tool name exposed to the LLM. Defaults to `retrieve_profile_memory`.\n * @param options.description - Tool description exposed to the LLM. Defaults to a\n * generic \"retrieve memories\" prompt.\n */\nexport function createMemoryRetrievalTool(\n memoryClient: MemoryClient,\n profileId?: string,\n conversationId?: string,\n options: { name?: string; description?: string } = {}\n): TACTool<MemoryRetrievalParams, MemoryRetrievalResponse> {\n return defineTool(\n options.name ?? BuiltInTools.RETRIEVE_MEMORY,\n options.description ??\n 'Retrieve user memories including observations, summaries, and conversation history',\n {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Optional semantic search query to filter memories',\n },\n beginDate: {\n type: 'string',\n description: 'Optional start date for filtering memories (ISO 8601 format)',\n },\n endDate: {\n type: 'string',\n description: 'Optional end date for filtering memories (ISO 8601 format)',\n },\n observationsLimit: {\n type: 'integer',\n minimum: 0,\n maximum: 100,\n default: 20,\n description: 'Maximum number of observations to retrieve. Set to 0 to skip observations.',\n },\n summariesLimit: {\n type: 'integer',\n minimum: 0,\n maximum: 100,\n default: 5,\n description: 'Maximum number of summaries to retrieve. Set to 0 to skip summaries.',\n },\n communicationsLimit: {\n type: 'integer',\n minimum: 0,\n maximum: 100,\n default: 0,\n description:\n 'Maximum number of communications to retrieve. Set to 0 to skip communications.',\n },\n relevanceThreshold: {\n type: 'number',\n minimum: 0.0,\n maximum: 1.0,\n default: 0.0,\n description: 'Minimum relevance score threshold for observations and summaries.',\n },\n },\n required: [], // No required parameters\n description: 'Retrieve memories for the current user',\n },\n async (params: MemoryRetrievalParams) => {\n if (!profileId) {\n throw new Error('No profile ID available for memory retrieval');\n }\n\n const request = Object.fromEntries(\n Object.entries({\n conversationId,\n query: params.query,\n beginDate: params.beginDate,\n endDate: params.endDate,\n observationsLimit: params.observationsLimit,\n summariesLimit: params.summariesLimit,\n communicationsLimit: params.communicationsLimit,\n relevanceThreshold: params.relevanceThreshold,\n }).filter(([_, value]) => value !== undefined)\n ) as Partial<MemoryRetrievalRequest>;\n\n return memoryClient.retrieveMemories(profileId, request);\n }\n );\n}\n\n/**\n * Create factory function for memory tools\n *\n * @param memoryClient - Memory client instance (must be initialized with storeId)\n */\nexport function createMemoryTools(memoryClient: MemoryClient): {\n forProfile: (\n profileId: string,\n conversationId?: string\n ) => TACTool<MemoryRetrievalParams, MemoryRetrievalResponse>;\n forSession: (\n profileId?: string,\n conversationId?: string\n ) => TACTool<MemoryRetrievalParams, MemoryRetrievalResponse>;\n} {\n return {\n forProfile: (profileId: string, conversationId?: string) =>\n createMemoryRetrievalTool(memoryClient, profileId, conversationId),\n\n forSession: (profileId?: string, conversationId?: string) =>\n createMemoryRetrievalTool(memoryClient, profileId, conversationId),\n };\n}\n","import { BuiltInTools, ConversationId, BaseChannel } from '@twilio/tac-core';\nimport { TACTool, defineTool } from '../lib/builder';\n\n/**\n * Parameters for send message tool\n */\ninterface SendMessageParams {\n message: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Result from send message tool\n */\ninterface SendMessageResult {\n success: boolean;\n message_id?: string;\n error?: string;\n}\n\n/**\n * Create send message tool\n */\nexport function createSendMessageTool(\n channel: BaseChannel,\n conversationId: ConversationId\n): TACTool<SendMessageParams, SendMessageResult> {\n return defineTool(\n BuiltInTools.SEND_MESSAGE,\n 'Send a message to the user in the current conversation',\n {\n type: 'object',\n properties: {\n message: {\n type: 'string',\n description: 'The message content to send to the user',\n },\n metadata: {\n type: 'object',\n description: 'Optional metadata to include with the message',\n },\n },\n required: ['message'],\n description: 'Send a message to the user',\n },\n async (params: SendMessageParams) => {\n try {\n await channel.sendResponse(conversationId, params.message, params.metadata);\n\n return {\n success: true,\n message_id: `msg_${Date.now()}`, // Simple ID generation\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n );\n}\n\n/**\n * Create factory function for messaging tools\n */\nexport function createMessagingTools(): {\n forConversation: (\n channel: BaseChannel,\n conversationId: ConversationId\n ) => TACTool<SendMessageParams, SendMessageResult>;\n} {\n return {\n /**\n * Create send message tool for specific channel and conversation\n */\n forConversation: (channel: BaseChannel, conversationId: ConversationId) =>\n createSendMessageTool(channel, conversationId),\n };\n}\n","/**\n * Handoff tool for the Twilio Agent Connect.\n *\n * Generic Studio-backed handoff that routes a conversation to a human agent.\n * Produces a structured HandoffPayload and delivers it as a Twilio Studio\n * Execution (voice via `<Connect action>`, digital channels via direct POST).\n */\n\nimport axios, { AxiosError } from 'axios';\nimport {\n ConversationSession,\n HandoffPayload,\n PendingHandoffData,\n TAC,\n studioExecutionsUrl,\n studioVoiceHandoffUrl,\n} from '@twilio/tac-core';\nimport { TACTool, defineTool } from '../lib/builder';\n\n// Re-export URL helpers for backward compatibility with the Python factory surface.\nexport { studioExecutionsUrl, studioVoiceHandoffUrl };\n\n/**\n * Build a HandoffPayload from session context and attributes.\n *\n * Useful for custom handoff tools that want TAC's payload shape without\n * the Studio-specific delivery in `postStudioHandoff`.\n */\nexport function buildHandoffPayload(\n session: ConversationSession,\n memoryStoreId: string,\n attributes: Record<string, unknown>\n): HandoffPayload {\n return {\n conversationId: session.conversationId,\n storeId: memoryStoreId,\n profileId: session.profileId ?? '',\n attributes,\n };\n}\n\n/**\n * POST a handoff payload to a Twilio Studio Flow Executions endpoint.\n *\n * Emits the Twilio Studio Executions API wire format: form-encoded\n * `To` / `From` / `Parameters` fields with HTTP Basic auth.\n * `Parameters` is a JSON string keyed under `HandoffData` so Studio\n * can reference it via `{{flow.data.HandoffData.*}}`.\n */\nexport async function postStudioHandoff(\n payload: HandoffPayload,\n session: ConversationSession,\n options: {\n handoffUrl: string;\n fromAddress: string;\n apiKey: string;\n apiSecret: string;\n }\n): Promise<void> {\n const { handoffUrl, fromAddress, apiKey, apiSecret } = options;\n const toAddress = session.authorInfo?.address ?? '';\n\n const form = new URLSearchParams();\n form.append('To', toAddress);\n form.append('From', fromAddress);\n form.append('Parameters', JSON.stringify({ HandoffData: payload }));\n\n await axios.post(handoffUrl, form.toString(), {\n timeout: 10_000,\n auth: { username: apiKey, password: apiSecret },\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n });\n}\n\n/**\n * Result returned by the handoff tool.\n */\nexport interface HandoffResult {\n status: 'handoff_initiated' | 'handoff_failed';\n channel: string;\n error?: string;\n}\n\ninterface HandoffParams {\n reason: string;\n}\n\nconst DEFAULT_HANDOFF_TOOL_NAME = 'handoff';\nconst DEFAULT_HANDOFF_TOOL_DESCRIPTION =\n 'Hand off the conversation to a human agent. ' +\n 'Use this when the customer requests a human, or when you ' +\n 'cannot adequately handle the request.';\n\n/**\n * Create a handoff tool that delivers in the Twilio Studio Executions API shape.\n *\n * The returned tool exposes only `handoff({ reason })` to the LLM. All other\n * dependencies (TAC instance, session, static attributes) are captured in the\n * closure.\n *\n * On digital channels, the tool POSTs to the Studio Flow Executions endpoint\n * derived from `tac.getConfig().studioHandoffFlowSid`. For voice channels,\n * the payload is stored on the session and the voice channel automatically\n * sends the WS `end` message with `handoffData` after the LLM's final\n * response is delivered.\n *\n * The tool also sets the conversation to INACTIVE and clears status callbacks\n * to prevent further webhook events from being routed to TAC.\n *\n * **Not available in voice-only mode.** This tool requires Conversation\n * Orchestrator for conversation state management and Conversation Memory for\n * the handoff payload. In voice-only mode, implement your own handoff by\n * setting `session.pendingHandoffData` directly — the voice channel will\n * send the WS `end` message with your payload, and your `<Connect action>`\n * URL handler can route the call accordingly.\n *\n * @throws Error if `tac.getConfig().studioHandoffFlowSid` is unset, if\n * Conversation Orchestrator is not configured (voice-only mode), or if\n * the memory store ID was not resolved at startup.\n */\nexport function createStudioHandoffTool(\n tac: TAC,\n session: ConversationSession,\n options: {\n attributes?: Record<string, unknown>;\n name?: string;\n description?: string;\n } = {}\n): TACTool<HandoffParams, HandoffResult> {\n const config = tac.getConfig();\n if (!config.studioHandoffFlowSid) {\n throw new Error(\n 'createStudioHandoffTool requires tac.getConfig().studioHandoffFlowSid ' +\n '(set TWILIO_STUDIO_HANDOFF_FLOW_SID in your environment).'\n );\n }\n const flowSid = config.studioHandoffFlowSid;\n\n const coClient = tac.getConversationClient();\n if (!coClient) {\n throw new Error(\n 'createStudioHandoffTool requires Conversation Orchestrator ' +\n '(not available in voice-only mode)'\n );\n }\n const memoryStoreId = tac.getMemoryStoreId();\n if (!memoryStoreId) {\n throw new Error(\n 'createStudioHandoffTool requires a memory store ID ' +\n '(resolved from conversationConfigurationId at startup)'\n );\n }\n\n const staticAttributes = options.attributes ?? {};\n const toolName = options.name ?? DEFAULT_HANDOFF_TOOL_NAME;\n const toolDescription = options.description ?? DEFAULT_HANDOFF_TOOL_DESCRIPTION;\n\n return defineTool<HandoffParams, HandoffResult>(\n toolName,\n toolDescription,\n {\n type: 'object',\n properties: {\n reason: {\n type: 'string',\n description: 'The reason for handing off to a human agent',\n },\n },\n required: ['reason'],\n description: 'Hand off the conversation to a human agent',\n },\n async (params: HandoffParams): Promise<HandoffResult> => {\n const attributes = { ...staticAttributes, reason: params.reason };\n const payload = buildHandoffPayload(session, memoryStoreId, attributes);\n\n // 1. Set conversation to INACTIVE to trigger the CO-generated\n // conversation summary that Flex fetches on pickup. Downstream\n // (Studio/Flex) flips it back to ACTIVE on pickup and CLOSED on hangup —\n // we don't close it ourselves.\n try {\n await coClient.updateConversation(session.conversationId, 'INACTIVE');\n } catch (err) {\n tac.logger.warn(\n { err, conversation_id: session.conversationId },\n 'Failed to set conversation INACTIVE during handoff'\n );\n }\n\n // 2. Clear statusCallbacks so TAC stops receiving webhook events for\n // this conversation (Flex/human agent will handle it from here).\n try {\n await coClient.clearStatusCallbacks(session.conversationId);\n } catch (err) {\n tac.logger.warn(\n { err, conversation_id: session.conversationId },\n 'Failed to clear status callbacks during handoff'\n );\n }\n\n // 3. Deliver handoff payload.\n if (session.channel === 'voice') {\n // Voice: store on session for deferred delivery. The voice channel\n // sends the WS \"end\" message after the LLM's final response so the\n // caller hears a goodbye before transfer. handoffData is a JSON\n // *string* — ConversationRelay forwards it verbatim in the POST body\n // to the action URL.\n const pending: PendingHandoffData = {\n type: 'end',\n handoffData: JSON.stringify(payload),\n };\n session.pendingHandoffData = pending;\n } else {\n // Digital channels: POST handoff payload to the Studio Flow Executions\n // endpoint. If the POST fails (network, 4xx, 5xx, timeout), return\n // handoff_failed so the LLM can tell the user instead of claiming\n // success.\n try {\n await postStudioHandoff(payload, session, {\n handoffUrl: studioExecutionsUrl(flowSid),\n fromAddress: config.phoneNumber,\n apiKey: config.apiKey,\n apiSecret: config.apiSecret,\n });\n } catch (err) {\n const message =\n err instanceof AxiosError\n ? err.message\n : err instanceof Error\n ? err.message\n : String(err);\n tac.logger.error(\n { err, conversation_id: session.conversationId },\n 'Failed to deliver handoff payload'\n );\n return {\n status: 'handoff_failed',\n channel: session.channel,\n error: message,\n };\n }\n }\n\n return { status: 'handoff_initiated', channel: session.channel };\n }\n );\n}\n","import { KnowledgeClient, KnowledgeChunkResult } from '@twilio/tac-core';\nimport { TACTool, defineTool } from '../lib/builder';\n\n/**\n * Parameters for knowledge search tool (visible to LLM)\n */\ninterface KnowledgeSearchParams {\n query: string;\n}\n\n/**\n * Configuration for knowledge search tool\n */\ninterface KnowledgeToolConfig {\n name?: string;\n description?: string;\n topK?: number;\n}\n\n/**\n * Create knowledge search tool with explicit name and description\n *\n * @param knowledgeClient - The Knowledge client instance\n * @param knowledgeBaseId - The knowledge base ID to search\n * @param config - Configuration with required name and description\n * @returns TACTool configured for knowledge search\n */\nexport function createKnowledgeSearchTool(\n knowledgeClient: KnowledgeClient,\n knowledgeBaseId: string,\n config: { name: string; description: string; topK?: number }\n): TACTool<KnowledgeSearchParams, KnowledgeChunkResult[]> {\n const topK = config.topK ?? 5;\n\n return defineTool(\n config.name,\n config.description,\n {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'The search query to find relevant knowledge',\n },\n },\n required: ['query'],\n description: config.description,\n },\n async (params: KnowledgeSearchParams) => {\n return knowledgeClient.searchKnowledgeBase(knowledgeBaseId, params.query, topK);\n }\n );\n}\n\n/**\n * Create knowledge search tool with auto-fetched metadata from knowledge base\n *\n * This async version fetches the knowledge base metadata to auto-generate\n * the tool name and description if not provided.\n *\n * @param knowledgeClient - The Knowledge client instance\n * @param knowledgeBaseId - The knowledge base ID to search\n * @param config - Optional configuration (name/description auto-generated if not provided)\n * @returns Promise containing TACTool configured for knowledge search\n */\nexport async function createKnowledgeSearchToolAsync(\n knowledgeClient: KnowledgeClient,\n knowledgeBaseId: string,\n config?: KnowledgeToolConfig\n): Promise<TACTool<KnowledgeSearchParams, KnowledgeChunkResult[]>> {\n let name = config?.name;\n let description = config?.description;\n\n // Fetch knowledge base metadata if name or description not provided\n if (!name || !description) {\n const kb = await knowledgeClient.getKnowledgeBase(knowledgeBaseId);\n if (!name) {\n // Generate tool name from display name (normalized snake_case)\n const normalized = kb.displayName\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_+|_+$/g, '');\n\n name = normalized ? `search_${normalized}` : 'search_knowledge_base';\n }\n if (!description) {\n description = kb.description || `Search the ${kb.displayName} knowledge base`;\n }\n }\n\n const toolConfig: { name: string; description: string; topK?: number } = {\n name,\n description,\n };\n if (config?.topK !== undefined) {\n toolConfig.topK = config.topK;\n }\n return createKnowledgeSearchTool(knowledgeClient, knowledgeBaseId, toolConfig);\n}\n\n/**\n * Create factory for knowledge tools\n *\n * @param knowledgeClient - The Knowledge client instance\n * @returns Factory object with methods to create knowledge tools\n */\nexport function createKnowledgeTools(knowledgeClient: KnowledgeClient): {\n forKnowledgeBase: (\n knowledgeBaseId: string,\n config: { name: string; description: string; topK?: number }\n ) => TACTool<KnowledgeSearchParams, KnowledgeChunkResult[]>;\n forKnowledgeBaseAsync: (\n knowledgeBaseId: string,\n config?: KnowledgeToolConfig\n ) => Promise<TACTool<KnowledgeSearchParams, KnowledgeChunkResult[]>>;\n} {\n return {\n /**\n * Create knowledge search tool with explicit config\n */\n forKnowledgeBase: (\n knowledgeBaseId: string,\n config: { name: string; description: string; topK?: number }\n ) => createKnowledgeSearchTool(knowledgeClient, knowledgeBaseId, config),\n\n /**\n * Create knowledge search tool with auto-fetched metadata\n */\n forKnowledgeBaseAsync: (knowledgeBaseId: string, config?: KnowledgeToolConfig) =>\n createKnowledgeSearchToolAsync(knowledgeClient, knowledgeBaseId, config),\n };\n}\n","import Fastify, {\n FastifyInstance,\n FastifyServerOptions,\n FastifyRequest,\n FastifyReply,\n} from 'fastify';\nimport formbody from '@fastify/formbody';\nimport websocket from '@fastify/websocket';\nimport gracefulShutdown from 'fastify-graceful-shutdown';\nimport type { WebSocket } from 'ws';\nimport twilio from 'twilio';\n\nimport {\n ConversationRelayCallbackPayloadSchema,\n twiMLRequestFromForm,\n CALL_EVENT_KINDS,\n} from '@twilio/tac-core';\nimport { TAC, VoiceChannel, MessagingChannel } from '@twilio/tac-core';\n\n/**\n * Server configuration options\n */\nexport interface TACServerConfig {\n /** Fastify server options (ignored if `fastifyInstance` is provided) */\n fastify?: FastifyServerOptions;\n\n /**\n * Pre-configured Fastify instance to mount TAC routes onto.\n *\n * Use this to control construction-time settings (logger, `trustProxy`,\n * schema, ...) or to register your own plugins/hooks before TAC's\n * routes are set up. If provided, the `fastify` options field is\n * ignored.\n */\n fastifyInstance?: FastifyInstance;\n\n /** Host to bind the server to (default: '0.0.0.0') */\n host?: string;\n\n /** Port to bind the server to (default: 8000) */\n port?: number;\n\n /**\n * Custom server-only webhook paths. The voice WebSocket and ConversationRelay\n * action callback paths live on `TACConfig` (`voiceWebsocketPath` /\n * `voiceActionPath`) because they're consumed by the voice channel regardless\n * of which web framework is used; this server reads them from there.\n */\n webhookPaths?: {\n /**\n * @deprecated Use `conversation` instead. This field will be removed in a future version.\n * If both `messaging` and `conversation` are set, `conversation` takes precedence.\n */\n messaging?: string;\n conversation?: string;\n twiml?: string;\n /** Path for Conversation Intelligence webhook (optional - only registered if provided) */\n cintel?: string;\n };\n\n /** Voice channel instance (alternative to registering on TAC) */\n voiceChannel?: VoiceChannel;\n\n /** Messaging channel instances — webhooks are fanned out to all (alternative to registering on TAC) */\n messagingChannels?: MessagingChannel[];\n}\n\n/**\n * Default server configuration\n */\nconst DEFAULT_CONFIG = {\n host: '0.0.0.0',\n port: 8000,\n webhookPaths: {\n conversation: '/webhook',\n twiml: '/twiml',\n },\n} satisfies Omit<\n TACServerConfig,\n 'fastify' | 'fastifyInstance' | 'voiceChannel' | 'messagingChannels'\n>;\n\n/** Normalize a route path for comparison, so '/hooks' and '/hooks/' collide. */\nfunction stripTrailingSlash(path: string): string {\n return path.replace(/\\/+$/, '');\n}\n\n/** What the voice channel's webhook handlers hand back for a reply. */\ntype CallEventResult = { status: number; content: string; contentType: string };\n\n/**\n * Batteries-included Fastify server for TAC\n *\n * Provides out-of-the-box setup for SMS and Voice channels with\n * proper webhook handling, WebSocket support, and production-ready defaults.\n *\n * Customization:\n * - Pass your own Fastify instance via `config.fastifyInstance` to control\n * construction-time settings (logger, `trustProxy`, schema, ...) and to\n * register plugins/hooks before TAC's routes are set up.\n * - Or mutate `server.fastify` after construction to add routes,\n * decorators, or hooks — before calling `start()`.\n *\n * Example:\n * import Fastify from 'fastify';\n *\n * const app = Fastify({ logger: true, trustProxy: true });\n * const server = new TACServer(tac, { fastifyInstance: app });\n *\n * server.fastify.get('/health', async () => ({ status: 'ok' }));\n *\n * await server.start();\n */\nexport class TACServer {\n public readonly fastify: FastifyInstance;\n private readonly tac: TAC;\n private readonly config: Required<\n Omit<TACServerConfig, 'fastify' | 'fastifyInstance' | 'voiceChannel' | 'messagingChannels'>\n >;\n /** All enabled messaging channels */\n private readonly messagingChannels: MessagingChannel[];\n /** Voice channel instance */\n private readonly voiceChannel: VoiceChannel | undefined;\n /** All channels that need webhook processing (voice + messaging) */\n private readonly webhookChannels: (VoiceChannel | MessagingChannel)[];\n\n constructor(tac: TAC, config: TACServerConfig = {}) {\n this.tac = tac;\n\n // Handle deprecated `messaging` field: log warning and apply fallback if needed\n const webhookPaths = { ...DEFAULT_CONFIG.webhookPaths, ...config.webhookPaths };\n if (config.webhookPaths?.messaging) {\n console.warn(\n 'TACServer: The \"webhookPaths.messaging\" field is deprecated and will be removed in a future version. ' +\n 'Please update your configuration to use \"webhookPaths.conversation\" instead.'\n );\n // If conversation isn't explicitly set, use messaging value as fallback\n if (!config.webhookPaths.conversation) {\n webhookPaths.conversation = config.webhookPaths.messaging;\n }\n }\n\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n webhookPaths,\n };\n\n // Resolve channels: prefer explicit kwargs, fall back to tac.getChannel()\n this.voiceChannel = config.voiceChannel ?? tac.getChannel<VoiceChannel>('voice');\n\n // Fail fast at construction if a voice channel is attached but no public\n // URL is configured. Without this check, the misconfiguration would only\n // surface on the first inbound call as a 500 — easy to miss in CI or smoke\n // tests that don't hit voice. Custom adapters (Express/etc.) constructing\n // VoiceChannel directly still get the runtime error on first request.\n if (this.voiceChannel && !tac.getConfig().voicePublicDomain) {\n throw new Error(\n 'Voice channel is configured but TACConfig.voicePublicDomain is not set. ' +\n 'Set it directly or via the TWILIO_VOICE_PUBLIC_DOMAIN env var.'\n );\n }\n // Unconditional, because the call-event routes register unconditionally\n // (like the TwiML and ConversationRelay routes) — so the collision is real\n // whether or not a voice channel is attached.\n this.validateCallEventPaths();\n this.messagingChannels =\n config.messagingChannels ??\n (\n [\n tac.getChannel<MessagingChannel>('sms'),\n tac.getChannel<MessagingChannel>('rcs'),\n tac.getChannel<MessagingChannel>('chat'),\n tac.getChannel<MessagingChannel>('whatsapp'),\n ] as (MessagingChannel | undefined)[]\n ).filter((ch): ch is MessagingChannel => ch != null);\n\n // Gather all channels that need webhook processing\n this.webhookChannels = [];\n if (this.voiceChannel) {\n this.webhookChannels.push(this.voiceChannel);\n }\n this.webhookChannels.push(...this.messagingChannels);\n\n if (this.webhookChannels.length === 0) {\n console.warn(\n 'TACServer: No channels configured for webhook processing. Register channels with TAC to enable webhooks.'\n );\n }\n // Use the user-supplied Fastify instance if provided; otherwise create\n // a default one with Pino logging.\n if (config.fastifyInstance) {\n this.fastify = config.fastifyInstance;\n } else {\n this.fastify = Fastify({\n logger: {\n level: process.env.TWILIO_LOG_LEVEL || 'info',\n },\n ...config.fastify,\n });\n }\n }\n\n /**\n * Validate `voiceCallEventPath`, the one path that isn't literal.\n *\n * Every other TAC path registers as configured, so a bad value is visible.\n * This one expands into three sub-paths, hiding a mistake the base path looks\n * innocent for: a sub-path colliding with another route while the base looks\n * unrelated (base `/hooks` vs `webhookPaths.twiml = '/hooks/status'`). Both\n * would register as POST routes and requests would reach the wrong handler.\n *\n * The leading-slash requirement is enforced by `TACConfigSchema` at parse\n * time, so it doesn't need re-checking here.\n */\n private validateCallEventPaths(): void {\n const cfg = this.tac.getConfig();\n\n const others: Record<string, string> = {\n [stripTrailingSlash(this.config.webhookPaths.twiml || '/twiml')]: 'webhookPaths.twiml',\n [stripTrailingSlash(cfg.voiceActionPath)]: 'TACConfig.voiceActionPath',\n [stripTrailingSlash(this.config.webhookPaths.conversation || '/webhook')]:\n 'webhookPaths.conversation',\n };\n if (this.config.webhookPaths.cintel) {\n others[stripTrailingSlash(this.config.webhookPaths.cintel)] = 'webhookPaths.cintel';\n }\n\n for (const kind of CALL_EVENT_KINDS) {\n const path = cfg.callEventPath(kind);\n const clash = others[stripTrailingSlash(path)];\n if (clash !== undefined) {\n throw new Error(\n `TACConfig.voiceCallEventPath expands to '${path}', which collides with ` +\n `${clash}. Both would register as POST routes and requests would ` +\n 'reach the wrong handler.'\n );\n }\n }\n }\n\n private getForwardedProto(request: FastifyRequest): string {\n const raw = request.headers['x-forwarded-proto'] as string | undefined;\n return raw?.split(',')[0]?.trim() || 'https';\n }\n\n private getForwardedHost(request: FastifyRequest): string {\n const raw = (request.headers['x-forwarded-host'] as string | undefined) || request.headers.host;\n return raw?.split(',')[0]?.trim() || '';\n }\n\n /**\n * Get the full URL for webhook validation\n * Handles X-Forwarded-* headers for proxy/ngrok scenarios\n */\n private getWebhookUrl(request: FastifyRequest): string {\n const proto = this.getForwardedProto(request);\n const host = this.getForwardedHost(request);\n return `${proto}://${host}${request.url}`;\n }\n\n /**\n * Validate the Twilio signature on an HTTP request. On failure, sends a 403\n * reply (Fastify halts the request once `reply.send` is called in a\n * `preHandler`, so the route handler won't run). Scoped to TAC-registered\n * webhook routes — does not run on user-added routes registered on\n * `server.fastify`.\n */\n private async validateRequestSignature(\n request: FastifyRequest,\n reply: FastifyReply\n ): Promise<void> {\n const signature = request.headers['x-twilio-signature'] as string;\n const url = this.getWebhookUrl(request);\n const authToken = this.tac.getConfig().authToken;\n\n let isValid: boolean;\n if (request.url.includes('bodySHA256=')) {\n const body = (request as FastifyRequest & { rawBody?: string }).rawBody ?? '';\n isValid = twilio.validateRequestWithBody(authToken, signature, url, body);\n } else {\n const params = (request.body as Record<string, string>) || {};\n isValid = twilio.validateRequest(authToken, signature, url, params);\n }\n\n if (!isValid) {\n this.fastify.log.warn({ url, hasSignature: !!signature }, 'Invalid Twilio webhook signature');\n await reply.code(403).send({ error: 'Invalid webhook signature' });\n }\n }\n\n /**\n * Setup routes\n */\n private async setupRoutes(): Promise<void> {\n const validateSignature = {\n preHandler: async (request: FastifyRequest, reply: FastifyReply): Promise<void> => {\n await this.validateRequestSignature(request, reply);\n },\n };\n\n // Conversation Orchestrator webhook — fan out to all enabled channels\n if (this.webhookChannels.length > 0) {\n this.fastify.post(\n this.config.webhookPaths.conversation || '/webhook',\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n const rawHeader = request.headers['i-twilio-idempotency-token'];\n const idempotencyToken = Array.isArray(rawHeader) ? rawHeader[0] : rawHeader;\n\n // Fan out to all channels\n for (const channel of this.webhookChannels) {\n channel.processWebhook(request.body, idempotencyToken).catch((err: unknown) => {\n this.fastify.log.error(\n { err, channel: channel.channelType },\n 'Webhook processing error'\n );\n });\n }\n\n await reply.code(200).send({ status: 'ok' });\n }\n );\n }\n\n // Voice webhook (POST - Twilio calls this when an incoming call arrives)\n this.fastify.post(\n this.config.webhookPaths.twiml || '/twiml',\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n if (!this.voiceChannel) {\n await reply.code(500).send({ error: 'Voice channel not available' });\n return;\n }\n\n const voiceChannel = this.voiceChannel;\n\n // Parse the Twilio webhook form into a framework-neutral TwiMLRequest\n // and hand it to the channel. The channel derives the WebSocket and\n // action URLs from TACConfig (voicePublicDomain + paths), layers in\n // VoiceChannelConfig.defaultTwimlOptions, and runs any per-call\n // customizer registered via voiceChannel.onInboundCallTwiml(...).\n const formDict = (request.body as Record<string, string>) ?? {};\n const twimlRequest = twiMLRequestFromForm(formDict);\n\n const twiml = await voiceChannel.handleIncomingCall(twimlRequest);\n\n await reply.type('application/xml').send(twiml);\n } catch (error) {\n this.fastify.log.error(\n 'TwiML generation error: ' + (error instanceof Error ? error.message : String(error))\n );\n await reply.code(500).send({\n error: 'Internal server error',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n // ConversationRelay callback endpoint. Path lives on TACConfig because the\n // voice channel derives the action URL from it too.\n this.fastify.post(\n this.tac.getConfig().voiceActionPath,\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n if (!this.voiceChannel) {\n await reply.code(500).send({ error: 'Voice channel not available' });\n return;\n }\n\n const voiceChannel = this.voiceChannel;\n\n // Parse form data into payload\n const formData = request.body as Record<string, string>;\n const parseResult = ConversationRelayCallbackPayloadSchema.safeParse(formData);\n\n if (!parseResult.success) {\n this.fastify.log.error(\n { errors: parseResult.error.issues },\n 'Invalid ConversationRelay callback payload'\n );\n await reply.code(400).send({ error: 'Invalid payload' });\n return;\n }\n\n const result = await voiceChannel.handleConversationRelayCallback(parseResult.data);\n\n await reply.code(result.status).type(result.contentType).send(result.content);\n } catch (error) {\n this.fastify.log.error(\n 'ConversationRelay callback error: ' +\n (error instanceof Error ? error.message : String(error))\n );\n await reply.code(500).send({ error: 'Internal server error' });\n }\n }\n );\n\n // One route per Twilio call callback — the route is the discriminator, so\n // each handler parses its own typed event with no payload sniffing. Paths\n // live on TACConfig because the voice channel derives the callback URLs it\n // hands to the Calls API from the same base.\n const callEventHandlers: Record<\n (typeof CALL_EVENT_KINDS)[number],\n (channel: VoiceChannel, form: Record<string, string>) => Promise<CallEventResult>\n > = {\n status: (channel, form) => channel.handleCallStatusEvent(form),\n amd: (channel, form) => channel.handleAmdEvent(form),\n recording: (channel, form) => channel.handleRecordingEvent(form),\n };\n\n for (const kind of CALL_EVENT_KINDS) {\n const handle = callEventHandlers[kind];\n this.fastify.post(\n this.tac.getConfig().callEventPath(kind),\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n if (!this.voiceChannel) {\n await reply.code(500).send({ error: 'Voice channel not available' });\n return;\n }\n\n const formData = (request.body as Record<string, string>) ?? {};\n const result = await handle(this.voiceChannel, formData);\n\n await reply.code(result.status).type(result.contentType).send(result.content);\n } catch (error) {\n this.fastify.log.error(\n `Call ${kind} callback error: ` +\n (error instanceof Error ? error.message : String(error))\n );\n await reply.code(500).send({ error: 'Internal server error' });\n }\n }\n );\n }\n\n // Voice WebSocket endpoint. Path lives on TACConfig because the voice\n // channel derives the WebSocket URL from it too.\n await this.fastify.register(fastify => {\n fastify.get(\n this.tac.getConfig().voiceWebsocketPath,\n { websocket: true },\n (socket: WebSocket, request: FastifyRequest) => {\n const signature = request.headers['x-twilio-signature'] as string;\n const authToken = this.tac.getConfig().authToken;\n\n const proto = this.getForwardedProto(request);\n const host = this.getForwardedHost(request);\n\n if (!host) {\n this.fastify.log.warn('WebSocket connection rejected: missing host header');\n socket.close(1008, 'Invalid request');\n return;\n }\n\n const wsProto = proto === 'https' ? 'wss' : 'ws';\n const fullUrl = new URL(`${wsProto}://${host}${request.url}`);\n const params: Record<string, string> = {};\n fullUrl.searchParams.forEach((value, key) => {\n params[key] = value;\n });\n const url = fullUrl.origin + fullUrl.pathname;\n\n const isValid = twilio.validateRequest(authToken, signature, url, params);\n\n if (!isValid) {\n this.fastify.log.warn(\n { url, hasSignature: !!signature },\n 'WebSocket connection rejected: invalid Twilio signature'\n );\n socket.close(1008, 'Invalid signature');\n return;\n }\n\n if (!this.voiceChannel) {\n socket.terminate();\n return;\n }\n\n this.voiceChannel.handleWebSocketConnection(socket);\n }\n );\n });\n\n // Conversation Intelligence webhook endpoint (optional - only if path is configured)\n if (this.config.webhookPaths.cintel) {\n this.fastify.post(\n this.config.webhookPaths.cintel,\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n if (!this.tac.isCintelEnabled()) {\n await reply.code(400).send({\n error: 'Conversation Intelligence is not enabled',\n message:\n 'Set TWILIO_TAC_CI_CONFIGURATION_ID and memory credentials to enable CI processing',\n });\n return;\n }\n\n try {\n this.fastify.log.info('Processing Conversation Intelligence webhook');\n const result = await this.tac.processCintelEvent(request.body);\n\n if (result.success) {\n if (result.skipped) {\n this.fastify.log.debug({ reason: result.skipReason }, 'CI event skipped');\n } else {\n this.fastify.log.info(\n { eventType: result.eventType, createdCount: result.createdCount },\n 'CI event processed'\n );\n }\n } else {\n this.fastify.log.error({ error: result.error }, 'CI event processing failed');\n }\n\n await reply.send(result);\n } catch (error) {\n this.fastify.log.error(\n 'CI webhook error: ' + (error instanceof Error ? error.message : String(error))\n );\n await reply.code(500).send({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n }\n }\n\n /**\n * Start the server\n */\n public async start(): Promise<void> {\n try {\n // Register required plugins, guarding against users who pre-registered\n // them on a supplied `fastifyInstance` (duplicate registration throws).\n if (!this.fastify.hasContentTypeParser('application/x-www-form-urlencoded')) {\n await this.fastify.register(formbody);\n }\n if (!this.fastify.hasDecorator('websocketServer')) {\n await this.fastify.register(websocket);\n }\n if (!this.fastify.hasDecorator('gracefulShutdown')) {\n await this.fastify.register(gracefulShutdown);\n }\n\n // Replace the default JSON parser with one that stores the raw body string,\n // needed by validateRequestWithBody for bodySHA256 signature validation.\n const defaultJsonParser = this.fastify.getDefaultJsonParser('error', 'error');\n if (this.fastify.hasContentTypeParser('application/json')) {\n this.fastify.removeContentTypeParser('application/json');\n }\n this.fastify.addContentTypeParser(\n 'application/json',\n { parseAs: 'string' },\n (request, body: string, done) => {\n (request as FastifyRequest & { rawBody?: string }).rawBody = body;\n void defaultJsonParser(request, body, done);\n }\n );\n\n // Set up routes (must be after plugin registration)\n // Signature validation is applied per-route as a `preHandler` so it only\n // runs on TAC-registered webhook routes, not on user-added routes on\n // `server.fastify`.\n await this.setupRoutes();\n\n // Configure graceful shutdown to wait for WebSocket connections\n this.fastify.gracefulShutdown(async (signal: string) => {\n this.fastify.log.info({ signal }, 'Received shutdown signal');\n\n // Wait for WebSocket connections to close naturally\n await this.waitForWebSocketsToClose();\n\n // Shutdown TAC (cleans up channel state)\n this.tac.shutdown();\n });\n\n // Start Fastify server\n await this.fastify.listen({\n host: this.config.host,\n port: this.config.port,\n });\n\n this.fastify.log.info(\n {\n host: this.config.host,\n port: this.config.port,\n conversation_webhook: this.config.webhookPaths.conversation,\n twiml_webhook: this.config.webhookPaths.twiml,\n ws_websocket: this.tac.getConfig().voiceWebsocketPath,\n conversation_relay_callback: this.tac.getConfig().voiceActionPath,\n ...(this.voiceChannel && {\n call_event_callbacks: CALL_EVENT_KINDS.map(kind =>\n this.tac.getConfig().callEventPath(kind)\n ),\n }),\n ...(this.config.webhookPaths.cintel && {\n cintel_webhook: this.config.webhookPaths.cintel,\n }),\n },\n 'TAC Server started'\n );\n } catch (error) {\n this.fastify.log.error({ err: error }, 'Failed to start TAC Server');\n throw error;\n }\n }\n\n /**\n * Wait for all WebSocket connections to close\n */\n private async waitForWebSocketsToClose(timeoutMs = 30000): Promise<void> {\n const wsServer = this.fastify.websocketServer;\n if (!wsServer || wsServer.clients.size === 0) {\n return;\n }\n\n this.fastify.log.info(\n { websocket_count: wsServer.clients.size },\n 'Waiting for WebSocket connections to close...'\n );\n\n const startTime = Date.now();\n\n return new Promise<void>(resolve => {\n const checkInterval = setInterval(() => {\n const clientCount = wsServer.clients.size;\n\n if (clientCount === 0) {\n clearInterval(checkInterval);\n this.fastify.log.info('All WebSocket connections closed');\n resolve();\n return;\n }\n\n // Check for timeout\n if (Date.now() - startTime >= timeoutMs) {\n clearInterval(checkInterval);\n this.fastify.log.warn(\n { remaining_websockets: clientCount },\n 'Timeout waiting for WebSockets to close, proceeding with shutdown'\n );\n resolve();\n return;\n }\n\n this.fastify.log.info(\n { remaining_websockets: clientCount },\n 'Waiting for WebSockets to close...'\n );\n }, 5000);\n });\n }\n\n /**\n * Stop the server gracefully\n */\n public async stop(): Promise<void> {\n try {\n await this.fastify.close();\n this.fastify.log.info('TAC Server stopped');\n } catch (error) {\n this.fastify.log.error({ err: error }, 'Error stopping TAC Server');\n throw error;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../packages/core/src/types/config.ts","../packages/core/src/types/handoff.ts","../packages/core/src/types/conversation.ts","../packages/core/src/types/tac.ts","../packages/core/src/lib/tac-memory-response.ts","../packages/core/src/types/memory.ts","../packages/core/src/types/crelay.ts","../packages/core/src/types/tools.ts","../packages/core/src/types/cintel.ts","../packages/core/src/types/knowledge.ts","../packages/core/src/lib/config.ts","../packages/core/src/util/log-redaction.ts","../packages/core/src/lib/logger.ts","../package.json","../packages/core/src/clients/base.ts","../packages/core/src/clients/memory.ts","../packages/core/src/clients/conversation.ts","../packages/core/src/clients/knowledge.ts","../packages/core/src/lib/operator-result-processor.ts","../packages/core/src/lib/tac.ts","../packages/core/src/channels/base.ts","../packages/core/src/channels/messaging.ts","../packages/core/src/channels/sms.ts","../packages/core/src/channels/rcs.ts","../packages/core/src/channels/whatsapp.ts","../packages/core/src/channels/chat.ts","../packages/core/src/util/handoff-urls.ts","../packages/core/src/channels/voice.ts","../packages/core/src/lib/conversation-session-helpers.ts","../packages/core/src/adapters/options.ts","../packages/core/src/adapters/prompt-builder.ts","../packages/tools/src/lib/builder.ts","../packages/tools/src/built-in/memory.ts","../packages/tools/src/built-in/messaging.ts","../packages/tools/src/built-in/handoff.ts","../packages/tools/src/built-in/knowledge.ts","../packages/server/src/lib/server.ts"],"names":["z","record","axios","session","Twilio"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\n/**\n * Channel types supported by the framework\n */\nexport const ChannelTypeSchema = z.enum(['sms', 'voice', 'chat', 'rcs', 'whatsapp']);\nexport type ChannelType = z.infer<typeof ChannelTypeSchema>;\n\n/**\n * Twilio Memory configuration schema\n */\nexport const TwilioMemoryConfigSchema = z.object({\n traitGroups: z.array(z.string()).optional(),\n observationsLimit: z.number().int().min(0).max(100).default(20),\n summariesLimit: z.number().int().min(0).max(100).default(5),\n // 0 matches the Memory API and Python SDK. Above 0, Memory requires a\n // conversationId on every /Recall, forcing the query expansion that\n // `memoryMode: \"once\"` exists to avoid.\n communicationsLimit: z.number().int().min(0).max(100).default(0),\n relevanceThreshold: z.number().min(0.0).max(1.0).default(0.0),\n /**\n * Trait group name that holds the phone identifier on newly created profiles.\n * Must match the promoted-to-identifier configuration of the Conversation Memory store.\n */\n phoneTraitGroup: z.string().default('Contact'),\n /** Trait field name within `phoneTraitGroup` that holds the phone identifier. */\n phoneTraitField: z.string().default('phone'),\n});\n\nexport type TwilioMemoryConfig = z.infer<typeof TwilioMemoryConfigSchema>;\n\n/**\n * Schema for a voice route path (e.g. voiceWebsocketPath). Trims whitespace,\n * maps an empty string to undefined so the `.default` applies, and requires a\n * leading '/' so path concatenation onto the domain can't produce a malformed\n * URL (e.g. `wss://example.comws`).\n */\nconst voicePathSchema = (defaultPath: string): z.ZodType<string> =>\n z.preprocess(v => {\n if (typeof v !== 'string') return v;\n const trimmed = v.trim();\n return trimmed.length === 0 ? undefined : trimmed;\n }, z.string().startsWith('/', 'Path must start with \"/\"').default(defaultPath));\n\n/** The three Twilio call callbacks TAC serves, one route per kind. */\nexport const CallEventKindSchema = z.enum(['status', 'amd', 'recording']);\n\nexport type CallEventKind = z.infer<typeof CallEventKindSchema>;\n\n/** Iterable form of {@link CallEventKind}, for registering every route. */\nexport const CALL_EVENT_KINDS: readonly CallEventKind[] = CallEventKindSchema.options;\n\n/**\n * TAC configuration schema\n */\nexport const TACConfigSchema = z.object({\n accountSid: z.string().min(1, 'Twilio Account SID is required'),\n authToken: z.string().min(1, 'Twilio Auth Token is required'),\n apiKey: z.string().min(1, 'Twilio API Key is required'),\n apiSecret: z.string().min(1, 'Twilio API Secret is required'),\n phoneNumber: z.string().min(1, 'Twilio Phone Number is required'),\n rcsSenderId: z\n .string()\n .regex(\n /^rcs:.+$/,\n 'RCS sender ID must be in format: rcs:<sender-id-or-phone> (e.g., rcs:brand_acme_agent or rcs:+1234567890)'\n )\n .optional(),\n whatsappNumber: z\n .string()\n .regex(/^whatsapp:\\+\\d+$/, 'WhatsApp number must be in format: whatsapp:+1234567890')\n .optional(),\n memoryConfig: TwilioMemoryConfigSchema.prefault({}),\n conversationConfigurationId: z\n .string()\n .regex(/^conv_configuration_[0-9a-z]{26}$/, 'Invalid Conversation Configuration ID format')\n .optional(),\n /**\n * Public domain where voice routes are reachable, optionally including a port\n * and/or base path (e.g. \"example.ngrok.app\", \"example.ngrok.app:8080\",\n * or \"example.com/server1\"). Used by VoiceChannel to construct the public\n * WebSocket URL and ConversationRelay action URL. Required when using the Voice channel.\n *\n * Whitespace, schemes (https://, wss://), and trailing slashes are stripped\n * automatically; anything else is passed through as given. Mirrors the Python\n * SDK's `_normalize_voice_public_domain` — keep the two in step.\n */\n voicePublicDomain: z\n .preprocess(v => {\n if (typeof v !== 'string') return v;\n let s = v.trim();\n if (s.length === 0) return undefined;\n for (const scheme of ['https://', 'http://', 'wss://', 'ws://']) {\n if (s.toLowerCase().startsWith(scheme)) {\n s = s.slice(scheme.length);\n break;\n }\n }\n s = s.replace(/\\/+$/, '');\n return s.length === 0 ? undefined : s;\n }, z.string().optional())\n .optional(),\n\n /**\n * Path the voice WebSocket is served at. Combined with voicePublicDomain to\n * build the public WebSocket URL the voice channel hands to Twilio in TwiML;\n * TACServer also registers its WebSocket route at this path. Override only if\n * you mount the route at a non-default path. Must start with '/'.\n */\n voiceWebsocketPath: voicePathSchema('/ws'),\n\n /**\n * Path the ConversationRelay action callback is served at. Same role as\n * voiceWebsocketPath but for the `<Connect action=...>` cleanup callback.\n * Must start with '/'.\n */\n voiceActionPath: voicePathSchema('/conversation-relay-callback'),\n\n /**\n * Base path for the call-event callbacks (status, async AMD, recording).\n * TACServer registers one route per callback under it — `<base>/status`,\n * `<base>/amd`, `<base>/recording` — so the route identifies the event. Same\n * role as voiceActionPath. Must start with '/'.\n */\n voiceCallEventPath: voicePathSchema('/twilio/call-events'),\n cintelConfigurationId: z.string().optional(),\n cintelSummaryOperatorSid: z.string().optional(),\n region: z\n .string()\n .max(63, 'Invalid Twilio region format (must be a valid DNS label)')\n .regex(\n /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/,\n 'Invalid Twilio region format (must be a valid DNS label)'\n )\n .optional(),\n /**\n * Twilio Studio Flow SID (FWxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) for handoff.\n * TAC derives both the digital-handoff Studio Executions URL and the voice\n * `<Connect action>` webhook URL from this SID.\n */\n studioHandoffFlowSid: z\n .string()\n .regex(\n /^FW[0-9a-f]{32}$/,\n 'Invalid Studio Flow SID format (expected FW followed by 32 hex chars)'\n )\n .optional(),\n});\n\nexport type TACConfigData = z.infer<typeof TACConfigSchema>;\n\n/**\n * Environment variable mapping for configuration\n */\nexport const EnvironmentVariables = {\n TWILIO_ACCOUNT_SID: 'TWILIO_ACCOUNT_SID',\n TWILIO_AUTH_TOKEN: 'TWILIO_AUTH_TOKEN',\n TWILIO_API_KEY: 'TWILIO_API_KEY',\n TWILIO_API_SECRET: 'TWILIO_API_SECRET',\n TWILIO_PHONE_NUMBER: 'TWILIO_PHONE_NUMBER',\n TWILIO_RCS_SENDER_ID: 'TWILIO_RCS_SENDER_ID',\n TWILIO_WHATSAPP_NUMBER: 'TWILIO_WHATSAPP_NUMBER',\n TWILIO_MEMORY_PROFILE_TRAIT_GROUPS: 'TWILIO_MEMORY_PROFILE_TRAIT_GROUPS',\n TWILIO_MEMORY_OBSERVATIONS_LIMIT: 'TWILIO_MEMORY_OBSERVATIONS_LIMIT',\n TWILIO_MEMORY_SUMMARIES_LIMIT: 'TWILIO_MEMORY_SUMMARIES_LIMIT',\n TWILIO_MEMORY_COMMUNICATIONS_LIMIT: 'TWILIO_MEMORY_COMMUNICATIONS_LIMIT',\n TWILIO_MEMORY_RELEVANCE_THRESHOLD: 'TWILIO_MEMORY_RELEVANCE_THRESHOLD',\n TWILIO_MEMORY_PHONE_TRAIT_GROUP: 'TWILIO_MEMORY_PHONE_TRAIT_GROUP',\n TWILIO_MEMORY_PHONE_TRAIT_FIELD: 'TWILIO_MEMORY_PHONE_TRAIT_FIELD',\n TWILIO_CONVERSATION_CONFIGURATION_ID: 'TWILIO_CONVERSATION_CONFIGURATION_ID',\n TWILIO_VOICE_PUBLIC_DOMAIN: 'TWILIO_VOICE_PUBLIC_DOMAIN',\n TWILIO_VOICE_WEBSOCKET_PATH: 'TWILIO_VOICE_WEBSOCKET_PATH',\n TWILIO_VOICE_ACTION_PATH: 'TWILIO_VOICE_ACTION_PATH',\n TWILIO_VOICE_CALL_EVENT_PATH: 'TWILIO_VOICE_CALL_EVENT_PATH',\n TWILIO_TAC_CI_CONFIGURATION_ID: 'TWILIO_TAC_CI_CONFIGURATION_ID',\n TWILIO_TAC_CI_SUMMARY_OPERATOR_SID: 'TWILIO_TAC_CI_SUMMARY_OPERATOR_SID',\n TWILIO_REGION: 'TWILIO_REGION',\n TWILIO_STUDIO_HANDOFF_FLOW_SID: 'TWILIO_STUDIO_HANDOFF_FLOW_SID',\n} as const;\n","import { z } from 'zod';\n\n/**\n * Structured payload generated during a handoff.\n *\n * Contains conversation context and developer-defined attributes\n * for routing to the target system (e.g., Flex TaskRouter).\n *\n * Serialized with camelCase aliases (conversationId/storeId/profileId)\n * for the Studio Executions wire format.\n */\nexport const HandoffPayloadSchema = z.object({\n conversationId: z.string(),\n storeId: z.string(),\n profileId: z.string(),\n attributes: z.record(z.string(), z.unknown()).default({}),\n});\n\nexport type HandoffPayload = z.infer<typeof HandoffPayloadSchema>;\n\n/**\n * ConversationRelay WebSocket ``end`` message carrying a handoff payload.\n *\n * ``handoffData`` is a JSON *string* (not a nested object) — ConversationRelay\n * forwards it verbatim in the POST body to the ``<Connect action>`` URL.\n */\nexport const PendingHandoffDataSchema = z.object({\n type: z.literal('end').default('end'),\n handoffData: z.string(),\n});\n\nexport type PendingHandoffData = z.infer<typeof PendingHandoffDataSchema>;\n","import { z } from 'zod';\nimport { ChannelTypeSchema } from './config';\nimport { PendingHandoffDataSchema } from './handoff';\nimport type { TACMemoryResponse } from '../lib/tac-memory-response';\n\n/**\n * Participant address type for different communication channels\n */\nexport const ParticipantAddressTypeSchema = z.enum([\n 'VOICE',\n 'SMS',\n 'RCS',\n 'EMAIL',\n 'WHATSAPP',\n 'CHAT',\n 'API',\n 'SYSTEM',\n]);\nexport type ParticipantAddressType = z.infer<typeof ParticipantAddressTypeSchema>;\n\n/**\n * Participant address containing channel and address\n */\nexport const ParticipantAddressSchema = z.object({\n channel: ParticipantAddressTypeSchema,\n address: z.string().min(1, 'Address is required'),\n channelId: z.string().nullable().optional(),\n});\n\nexport type ParticipantAddress = z.infer<typeof ParticipantAddressSchema>;\n\n/**\n * Communication participant for Conversations Service API (Conversation Orchestrator).\n *\n * Note: participantId is required for SDK validation when creating communications.\n */\nexport const CommunicationParticipantSchema = z.object({\n address: z.string().max(254),\n channel: ParticipantAddressTypeSchema,\n participantId: z.string(),\n deliveryStatus: z\n .enum(['INITIATED', 'IN_PROGRESS', 'DELIVERED', 'COMPLETED', 'FAILED'])\n .optional(),\n});\n\nexport type CommunicationParticipant = z.infer<typeof CommunicationParticipantSchema>;\n\n/**\n * Word-level transcription data with timing information.\n */\nexport const TranscriptionWordSchema = z.object({\n text: z.string(),\n startTime: z.string().optional(),\n endTime: z.string().optional(),\n});\n\nexport type TranscriptionWord = z.infer<typeof TranscriptionWordSchema>;\n\n/**\n * Transcription metadata for communication content.\n */\nexport const TranscriptionSchema = z.object({\n channel: z.number().optional(),\n confidence: z.number().min(0).max(1).optional(),\n engine: z.string().optional(),\n words: z.array(TranscriptionWordSchema).optional(),\n});\n\nexport type Transcription = z.infer<typeof TranscriptionSchema>;\n\n/**\n * Communication content (ContentText or ContentTranscription).\n *\n * Note: In the Conversation Orchestrator API, both `type` and `text` are required fields.\n */\nexport const CommunicationContentSchema = z.object({\n type: z.enum(['TEXT', 'TRANSCRIPTION']),\n text: z.string().max(8388608),\n transcription: TranscriptionSchema.optional(),\n});\n\nexport type CommunicationContent = z.infer<typeof CommunicationContentSchema>;\n\n/**\n * Communication from Conversations Service API (Conversation Orchestrator).\n *\n * Note: `createdAt` is optional per API spec.\n */\nexport const CommunicationSchema = z.object({\n id: z.string(),\n conversationId: z.string(),\n accountId: z.string(),\n author: CommunicationParticipantSchema,\n content: CommunicationContentSchema,\n recipients: z.array(CommunicationParticipantSchema),\n channelId: z.string().nullable().optional(),\n createdAt: z.string().nullable().optional(),\n updatedAt: z.string().nullable().optional(),\n occurredAt: z.string().nullable().optional(),\n});\n\nexport type Communication = z.infer<typeof CommunicationSchema>;\n\n/**\n * List communications response\n */\nexport const ListCommunicationsResponseSchema = z.object({\n communications: z.array(CommunicationSchema),\n});\n\nexport type ListCommunicationsResponse = z.infer<typeof ListCommunicationsResponseSchema>;\n\n/**\n * Participant reference for the Actions API (`from`/`to` entries).\n *\n * Either `participantId` or `address` must be supplied; `channel` is always required.\n * When both are provided, Conversation Orchestrator uses `participantId` and\n * `channel` disambiguates which of the participant's addresses to use.\n */\nexport const ActionParticipantRefSchema = z\n .object({\n participantId: z.string().min(1).optional(),\n address: z.string().min(1).max(254).optional(),\n channel: ParticipantAddressTypeSchema,\n })\n .refine(v => Boolean(v.participantId) || Boolean(v.address), {\n message: 'ActionParticipantRef requires at least `participantId` or `address`',\n });\n\nexport type ActionParticipantRef = z.infer<typeof ActionParticipantRefSchema>;\n\n/**\n * Plain-text content for a SEND_MESSAGE action.\n */\nexport const ActionTextContentSchema = z.object({\n text: z.string().max(8388608),\n});\n\nexport type ActionTextContent = z.infer<typeof ActionTextContentSchema>;\n\n/**\n * Channel-specific settings forwarded to the downstream backend.\n *\n * Open pass-through: any field not explicitly modeled here (e.g.\n * `messagingServiceSid`, `statusCallback`, `Attributes`) can be set by callers and\n * will be forwarded as-is.\n */\nexport const ActionChannelSettingsSchema = z.looseObject({\n channelId: z.string().optional(),\n});\n\nexport type ActionChannelSettings = z.infer<typeof ActionChannelSettingsSchema>;\n\n/**\n * Inner payload for a SEND_MESSAGE action.\n */\nexport const SendMessageActionPayloadSchema = z.object({\n from: ActionParticipantRefSchema,\n to: z.array(ActionParticipantRefSchema).min(1),\n content: ActionTextContentSchema,\n channelSettings: ActionChannelSettingsSchema.optional(),\n});\n\nexport type SendMessageActionPayload = z.infer<typeof SendMessageActionPayloadSchema>;\n\n/**\n * Request for POST /v2/Conversations/{id}/Actions with type=SEND_MESSAGE.\n *\n * Body is discriminated by `type` with the action-specific fields under `payload`.\n */\nexport const SendMessageActionRequestSchema = z.object({\n type: z.literal('SEND_MESSAGE').default('SEND_MESSAGE'),\n payload: SendMessageActionPayloadSchema,\n});\n\nexport type SendMessageActionRequest = z.infer<typeof SendMessageActionRequestSchema>;\n\n/**\n * Response from POST /v2/Conversations/{id}/Actions (202 Accepted).\n *\n * Listen for COMMUNICATION_CREATED webhook to get the full Communication.\n */\nexport const ActionResponseSchema = z.object({\n id: z.string(),\n // Kept as string (not enum) to tolerate future action types. Known: SEND_MESSAGE.\n type: z.string(),\n // Kept as string (not enum) to tolerate future statuses. Known: PENDING, COMPLETED, FAILED.\n status: z.string(),\n conversationId: z.string(),\n createdAt: z.string().nullish(),\n});\n\nexport type ActionResponse = z.infer<typeof ActionResponseSchema>;\n\n/**\n * Author information for a conversation session\n */\nexport const AuthorInfoSchema = z.object({\n address: z.string(),\n participantId: z.string().optional(),\n});\n\nexport type AuthorInfo = z.infer<typeof AuthorInfoSchema>;\n\n/**\n * Profile information for a conversation participant\n */\nexport interface Profile {\n profileId: string;\n traits?: Record<string, unknown>;\n}\n\n/**\n * Conversation session context\n */\nexport const ConversationSessionSchema = z.object({\n conversationId: z.string().min(1, 'Conversation ID is required'),\n /**\n * Twilio Call SID on the Voice channel, unset on messaging. The correlation\n * key for call events (`VoiceChannel.onCallStatus` / `onAmd` / `onRecording`)\n * and `endCall`. Equals `conversationId` in relay-only mode; look the session\n * up the other way with `VoiceChannel.getConversationSessionByCallSid`.\n */\n callSid: z.string().optional(),\n profileId: z.string().optional(),\n serviceId: z.string().optional(),\n channel: ChannelTypeSchema,\n startedAt: z.date(),\n authorInfo: AuthorInfoSchema.optional(),\n /**\n * Agent-side participant info stashed by inbound reconciliation or outbound\n * initiation. `sendResponse` reads this to avoid re-listing participants at\n * send time.\n */\n aiAgentInfo: AuthorInfoSchema.optional(),\n profile: z.custom<Profile>().optional(),\n metadata: z.record(z.string(), z.unknown()).optional().default({}),\n /**\n * Pending handoff payload set by the handoff tool. Voice channel sends\n * this as a WS \"end\" message after the LLM's final response.\n */\n pendingHandoffData: PendingHandoffDataSchema.optional(),\n /**\n * Cached memory for \"once\" mode. Set on the first retrieval, cleared when\n * the conversation becomes INACTIVE. Not persisted/serialized.\n */\n cachedMemory: z.custom<TACMemoryResponse>().optional(),\n});\n\nexport type ConversationSession = z.infer<typeof ConversationSessionSchema>;\n\n/**\n * Branded types for type safety\n */\nexport type ConversationId = string & { readonly _brand: 'ConversationId' };\nexport type ProfileId = string & { readonly _brand: 'ProfileId' };\nexport type ParticipantId = string & { readonly _brand: 'ParticipantId' };\n\n/**\n * Type guards for branded types\n */\nexport function isConversationId(value: string): value is ConversationId {\n return value.length > 0;\n}\n\nexport function isProfileId(value: string): value is ProfileId {\n return value.length > 0;\n}\n\nexport function isParticipantId(value: string): value is ParticipantId {\n return value.length > 0;\n}\n\n/**\n * Conversation response from Conversations Service API\n */\nexport const ConversationResponseSchema = z.object({\n id: z.string(),\n accountId: z.string(),\n status: z.string().optional(),\n name: z.string().nullish(), // API returns null when not set\n configurationId: z.string().optional(),\n createdAt: z.string().optional(),\n updatedAt: z.string().optional(),\n});\n\nexport type ConversationResponse = z.infer<typeof ConversationResponseSchema>;\n\n/**\n * List conversations response\n */\nexport const ListConversationsResponseSchema = z.object({\n conversations: z.array(ConversationResponseSchema),\n});\n\nexport type ListConversationsResponse = z.infer<typeof ListConversationsResponseSchema>;\n\n/**\n * Participant address from Conversations Service API (camelCase format)\n */\nexport const ConversationAddressSchema = z.object({\n channel: ParticipantAddressTypeSchema,\n address: z.string(),\n channelId: z.string().nullish(), // API returns null when not set\n});\n\nexport type ConversationAddress = z.infer<typeof ConversationAddressSchema>;\n\n/**\n * Participant response from Conversations Service API\n */\nexport const ConversationParticipantSchema = z.object({\n id: z.string(),\n conversationId: z.string(),\n accountId: z.string(),\n name: z.string().optional(),\n type: z.enum(['HUMAN_AGENT', 'CUSTOMER', 'AI_AGENT', 'AGENT', 'UNKNOWN']).optional(),\n profileId: z.string().nullable().optional(),\n addresses: z.array(ConversationAddressSchema).default([]),\n createdAt: z.string().optional(),\n updatedAt: z.string().optional(),\n});\n\nexport type ConversationParticipant = z.infer<typeof ConversationParticipantSchema>;\n\n/**\n * List participants response\n */\nexport const ListParticipantsResponseSchema = z.object({\n participants: z.array(ConversationParticipantSchema),\n});\n\nexport type ListParticipantsResponse = z.infer<typeof ListParticipantsResponseSchema>;\n\n/**\n * Timeout settings for channel status transitions\n */\nexport const StatusTimeoutsSchema = z.object({\n inactive: z.number().int().gte(1).nullable().optional(),\n closed: z.number().int().gte(1),\n});\n\nexport type StatusTimeouts = z.infer<typeof StatusTimeoutsSchema>;\n\n/**\n * Capture rule with from/to addresses and optional metadata\n */\nexport const CaptureRuleSchema = z.object({\n from: z.string(),\n to: z.string(),\n metadata: z.record(z.string(), z.string()).nullable().optional(),\n});\n\nexport type CaptureRule = z.infer<typeof CaptureRuleSchema>;\n\n/**\n * Configuration settings for a specific channel type\n */\nexport const ChannelSettingsSchema = z.object({\n statusTimeouts: StatusTimeoutsSchema.nullable().optional(),\n captureRules: z.array(CaptureRuleSchema).nullable().optional(),\n});\n\nexport type ChannelSettings = z.infer<typeof ChannelSettingsSchema>;\n\n/**\n * Webhook configuration for status callbacks\n */\nexport const StatusCallbackSchema = z.object({\n url: z.url(),\n method: z.enum(['POST', 'GET', 'PUT', 'DELETE', 'PATCH']).optional().default('POST'),\n});\n\nexport type StatusCallback = z.infer<typeof StatusCallbackSchema>;\n\n/**\n * Conversation grouping type\n *\n * - `GROUP_BY_PROFILE`: Groups communications by participant profile. Communications\n * with the same profile go to the same conversation, regardless of the channel or address.\n * - `GROUP_BY_PARTICIPANT_ADDRESSES`: Groups communications by participant addresses\n * across all channels. A customer using +15551234567 will be in the same conversation\n * whether they contact via SMS, WhatsApp, or RCS.\n * - `GROUP_BY_PARTICIPANT_ADDRESSES_AND_CHANNEL_TYPE`: Groups communications by both\n * participant addresses AND channel. A customer using +15551234567 via SMS will be in\n * a different conversation than the same customer via WhatsApp.\n */\nexport const ConversationGroupingTypeSchema = z.enum([\n 'GROUP_BY_PROFILE',\n 'GROUP_BY_PARTICIPANT_ADDRESSES',\n 'GROUP_BY_PARTICIPANT_ADDRESSES_AND_CHANNEL_TYPE',\n]);\n\nexport type ConversationGroupingType = z.infer<typeof ConversationGroupingTypeSchema>;\n\n/**\n * Configuration settings for a conversation\n */\nexport const ConversationConfigurationSchema = z.object({\n id: z.string(),\n displayName: z\n .string()\n .max(32)\n .regex(/^[a-zA-Z0-9-_ ]+$/)\n .nullable()\n .optional(),\n description: z.string(),\n conversationGroupingType: ConversationGroupingTypeSchema,\n memoryStoreId: z\n .string()\n .regex(/^mem_(store|service)_[0-7][0-9a-z]{25}$/, 'Invalid Memory Store ID format'),\n channelSettings: z.record(z.string(), ChannelSettingsSchema).nullable().optional(),\n statusCallbacks: z.array(StatusCallbackSchema).max(20).nullable().optional(),\n intelligenceConfigurationIds: z.array(z.string()).max(5).nullable().optional(),\n createdAt: z.string().nullable().optional(),\n updatedAt: z.string().nullable().optional(),\n version: z.number().int().nullable().optional(),\n});\n\nexport type ConversationConfiguration = z.infer<typeof ConversationConfigurationSchema>;\n\n// =========================================================================\n// Outbound Conversation Types\n// =========================================================================\n\n/**\n * Options for initiating an outbound SMS conversation.\n *\n * The sender is always TAC's configured `config.phoneNumber`. Multi-sender\n * deployments should run one TAC instance per sender so inbound webhook\n * routing, memory scoping, and configuration stay in sync.\n */\nexport const InitiateMessagingConversationOptionsSchema = z.object({\n to: z.string().min(1, 'Recipient address is required'),\n message: z.string().min(1, 'Initial message is required'),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type InitiateMessagingConversationOptions = z.infer<\n typeof InitiateMessagingConversationOptionsSchema\n>;\n\n/**\n * Result of initiating an outbound conversation\n */\nexport interface InitiateConversationResult {\n conversationId: ConversationId;\n session: ConversationSession;\n}\n\n/**\n * Result of initiating an outbound voice conversation.\n * Note: conversationId is not included because the conversation is created by\n * Conversation Orchestrator during passive hydration — the SDK discovers it by\n * callSid, in the background from WebSocket setup.\n */\nexport interface InitiateVoiceConversationResult {\n callSid: string;\n}\n\n/**\n * Webhook payload structure from Twilio Conversation Orchestrator.\n * This structure is used by all channels (messaging and voice) for webhook events.\n */\nexport interface ConversationWebhookPayload {\n eventType: string;\n timestamp?: string;\n data?: {\n id?: string;\n conversationId?: string;\n accountId?: string;\n serviceId?: string;\n status?: string;\n participantType?: string;\n profileId?: string;\n channelId?: string;\n author?: {\n address?: string;\n channel?: string;\n participantId?: string;\n };\n content?: {\n type?: string;\n text?: string;\n };\n recipients?: Array<{\n address?: string;\n channel?: string;\n participantId?: string;\n deliveryStatus?: string;\n }>;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n","import { z } from 'zod';\nimport { TranscriptionSchema } from './conversation';\n\n/**\n * Channel type for communications\n */\nexport const TACChannelTypeSchema = z.enum([\n 'VOICE',\n 'SMS',\n 'RCS',\n 'EMAIL',\n 'WHATSAPP',\n 'CHAT',\n 'API',\n 'SYSTEM',\n]);\nexport type TACChannelType = z.infer<typeof TACChannelTypeSchema>;\n\n/**\n * Delivery status for communications\n */\nexport const TACDeliveryStatusSchema = z.enum([\n 'INITIATED',\n 'IN_PROGRESS',\n 'DELIVERED',\n 'COMPLETED',\n 'FAILED',\n]);\nexport type TACDeliveryStatus = z.infer<typeof TACDeliveryStatusSchema>;\n\n/**\n * Participant type\n */\nexport const TACParticipantTypeSchema = z.enum(['HUMAN_AGENT', 'CUSTOMER', 'AI_AGENT', 'AGENT']);\nexport type TACParticipantType = z.infer<typeof TACParticipantTypeSchema>;\n\n/**\n * Unified author model with all fields from both Memory and Conversation Orchestrator APIs.\n *\n * Fields not available from a particular API will be undefined.\n */\nexport const TACCommunicationAuthorSchema = z.object({\n // Common fields (both APIs)\n address: z.string(),\n channel: TACChannelTypeSchema,\n\n // Conversation Orchestrator-only fields\n participantId: z.string().optional(),\n deliveryStatus: TACDeliveryStatusSchema.optional(),\n\n // Memory-only fields\n id: z.string().optional(),\n name: z.string().optional(),\n type: TACParticipantTypeSchema.optional(),\n profileId: z.string().nullable().optional(),\n});\n\nexport type TACCommunicationAuthor = z.infer<typeof TACCommunicationAuthorSchema>;\n\n/**\n * Unified content model with all fields from both Memory and Conversation Orchestrator APIs.\n */\nexport const TACCommunicationContentSchema = z.object({\n // Conversation Orchestrator-only: content type discriminator\n type: z.enum(['TEXT', 'TRANSCRIPTION']).optional(),\n // Both APIs: message text (optional in unified model to handle both)\n text: z.string().optional(),\n // Conversation Orchestrator-only: transcription metadata\n transcription: TranscriptionSchema.optional(),\n});\n\nexport type TACCommunicationContent = z.infer<typeof TACCommunicationContentSchema>;\n\n/**\n * Unified communication model with all fields from both Memory and Conversation Orchestrator APIs.\n *\n * Provides complete access to all communication fields regardless of the source.\n * Fields not available from a particular API will be undefined.\n */\nexport const TACCommunicationSchema = z.object({\n // Common fields (both APIs)\n id: z.string(),\n author: TACCommunicationAuthorSchema,\n content: TACCommunicationContentSchema,\n recipients: z.array(TACCommunicationAuthorSchema).default([]),\n channelId: z.string().nullable().optional(),\n createdAt: z.string().optional(),\n updatedAt: z.string().optional(),\n\n // Conversation Orchestrator-only fields\n conversationId: z.string().optional(),\n accountId: z.string().optional(),\n});\n\nexport type TACCommunication = z.infer<typeof TACCommunicationSchema>;\n","import { Communication } from '../types/conversation';\nimport { MemoryRetrievalResponse, ObservationInfo, SummaryInfo } from '../types/memory';\nimport { TACCommunication, TACCommunicationSchema } from '../types/tac';\n\n/**\n * Type guard to check if data is MemoryRetrievalResponse.\n */\nfunction isMemoryRetrievalResponse(\n data: MemoryRetrievalResponse | Communication[]\n): data is MemoryRetrievalResponse {\n return !Array.isArray(data);\n}\n\n/**\n * Unified response wrapper for TAC.retrieveMemory().\n *\n * Provides a consistent interface for accessing memory data regardless of whether\n * Memory API is configured or falling back to Conversation Orchestrator Communications API.\n *\n * Memory configured:\n * - observations, summaries, communications all populated\n * - communications include Memory-specific fields (author id, name, type, profileId)\n *\n * Conversation Orchestrator fallback:\n * - observations and summaries are empty arrays\n * - communications include Conversation Orchestrator-specific fields (conversationId, accountId, etc.)\n */\nexport class TACMemoryResponse {\n private readonly _data: MemoryRetrievalResponse | Communication[];\n private readonly _communications: TACCommunication[];\n\n /**\n * Initialize wrapper with either Memory or Conversation Orchestrator data.\n *\n * @param data - Either MemoryRetrievalResponse (Memory) or Communication[] (Conversation Orchestrator)\n */\n constructor(data: MemoryRetrievalResponse | Communication[]) {\n this._data = data;\n\n if (isMemoryRetrievalResponse(data)) {\n this._communications = (data.communications ?? []).map(comm =>\n TACCommunicationSchema.parse(comm)\n );\n } else {\n this._communications = data.map(comm => TACCommunicationSchema.parse(comm));\n }\n }\n\n /**\n * Get observation memories.\n *\n * @returns List of observations if Memory is configured, empty array for Conversation Orchestrator fallback\n */\n get observations(): ObservationInfo[] {\n if (isMemoryRetrievalResponse(this._data)) {\n return this._data.observations;\n }\n return [];\n }\n\n /**\n * Get summary memories.\n *\n * @returns List of summaries if Memory is configured, empty array for Conversation Orchestrator fallback\n */\n get summaries(): SummaryInfo[] {\n if (isMemoryRetrievalResponse(this._data)) {\n return this._data.summaries;\n }\n return [];\n }\n\n /**\n * Get communications in unified format with all available fields.\n *\n * Communications are converted to a common format during initialization that includes\n * all fields from both Memory and Conversation Orchestrator APIs. Fields not available from a particular\n * API will be undefined.\n *\n * @returns List of unified communications with all available fields\n */\n get communications(): TACCommunication[] {\n return this._communications;\n }\n\n /**\n * Check if Memory API is configured and providing full features.\n *\n * @returns true if Memory is configured (observations/summaries available),\n * false if using Conversation Orchestrator fallback (only communications available)\n */\n get hasMemoryFeatures(): boolean {\n return isMemoryRetrievalResponse(this._data);\n }\n\n /**\n * Access raw underlying data for advanced use cases.\n *\n * Use this when you need access to all fields from the original API responses,\n * not just the unified common fields.\n *\n * @returns Either MemoryRetrievalResponse or Communication[] depending on configuration\n */\n get rawData(): MemoryRetrievalResponse | Communication[] {\n return this._data;\n }\n\n /**\n * Build formatted prompt sections from available memory data.\n *\n * Generates markdown-formatted sections for observations, summaries, and communications\n * that can be injected into LLM prompts. Each section includes a heading and formatted content.\n * Sections with no data are omitted from the result.\n *\n * @returns Array of formatted prompt sections, empty array if no memory data available\n */\n buildMemoryPrompts(): string[] {\n const sections: string[] = [];\n\n const observationsSection = this.buildObservationsPrompt();\n if (observationsSection) {\n sections.push(observationsSection);\n }\n\n const summariesSection = this.buildSummariesPrompt();\n if (summariesSection) {\n sections.push(summariesSection);\n }\n\n const communicationsSection = this.buildCommunicationsPrompt();\n if (communicationsSection) {\n sections.push(communicationsSection);\n }\n\n return sections;\n }\n\n private buildObservationsPrompt(): string | null {\n if (this.observations.length === 0) {\n return null;\n }\n\n const lines = [\n '## Key Observations',\n 'Important notes about the customer from previous interactions:',\n ];\n\n for (const obs of this.observations) {\n lines.push(`- ${obs.content}`);\n }\n\n return lines.join('\\n');\n }\n\n private buildSummariesPrompt(): string | null {\n if (this.summaries.length === 0) {\n return null;\n }\n\n const lines = [\n '## Past Conversation Summaries',\n 'Summaries of previous conversations with this customer:',\n ];\n\n for (const summary of this.summaries) {\n lines.push(`- ${summary.content}`);\n }\n\n return lines.join('\\n');\n }\n\n private buildCommunicationsPrompt(): string | null {\n if (this.communications.length === 0) {\n return null;\n }\n\n const lines = ['## Recent Message History', 'Recent messages exchanged with this customer:'];\n\n for (const comm of this.communications) {\n const content = comm.content?.text;\n if (typeof content !== 'string' || content.trim().length === 0) {\n continue;\n }\n // Determine role - defaults to \"Assistant\" for undefined or non-CUSTOMER authors\n const role = comm.author?.type === 'CUSTOMER' ? 'User' : 'Assistant';\n lines.push(`${role}: ${content}`);\n }\n\n return lines.length > 2 ? lines.join('\\n') : null;\n }\n}\n","import { z } from 'zod';\n\n/**\n * Memory retrieval mode for channels.\n *\n * - \"always\": Fetch memory with the message as query on every inbound message.\n * - \"once\": Fetch memory once at conversation start with no query (and no\n * conversation id, skipping query expansion) and cache it. The cache is\n * invalidated when the conversation becomes INACTIVE.\n * - \"never\": Never automatically fetch memory (default).\n */\nexport const MemoryModeSchema = z.enum(['always', 'never', 'once']);\nexport type MemoryMode = z.infer<typeof MemoryModeSchema>;\n\n/**\n * Message direction in a conversation\n */\nexport const MessageDirectionSchema = z.enum(['inbound', 'outbound']);\nexport type MessageDirection = z.infer<typeof MessageDirectionSchema>;\n\n/**\n * Channel type for Memory communications\n */\nexport const MemoryChannelTypeSchema = z.enum([\n 'VOICE',\n 'SMS',\n 'RCS',\n 'EMAIL',\n 'WHATSAPP',\n 'CHAT',\n 'API',\n 'SYSTEM',\n]);\nexport type MemoryChannelType = z.infer<typeof MemoryChannelTypeSchema>;\n\n/**\n * Participant type in Memory API\n */\nexport const MemoryParticipantTypeSchema = z.enum([\n 'HUMAN_AGENT',\n 'CUSTOMER',\n 'AI_AGENT',\n 'AGENT',\n 'UNKNOWN',\n]);\nexport type MemoryParticipantType = z.infer<typeof MemoryParticipantTypeSchema>;\n\n/**\n * Delivery status for Memory communications\n */\nexport const MemoryDeliveryStatusSchema = z.enum([\n 'INITIATED',\n 'IN_PROGRESS',\n 'DELIVERED',\n 'COMPLETED',\n 'FAILED',\n]);\nexport type MemoryDeliveryStatus = z.infer<typeof MemoryDeliveryStatusSchema>;\n\n/**\n * Participant in a Memory communication (author or recipient).\n *\n * Memory API has different field requirements than Conversation Orchestrator:\n * - Uses `id` and `name` instead of just `participant_id`\n * - Includes `type` and `profileId` fields\n */\nexport const MemoryParticipantSchema = z.object({\n id: z.string(),\n name: z.string().max(256),\n address: z.string().max(254),\n channel: MemoryChannelTypeSchema,\n type: MemoryParticipantTypeSchema.optional(),\n profileId: z.string().nullable().optional(),\n deliveryStatus: MemoryDeliveryStatusSchema.optional(),\n});\n\nexport type MemoryParticipant = z.infer<typeof MemoryParticipantSchema>;\n\n/**\n * Content of a Memory communication.\n *\n * Memory API content is simpler than Conversation Orchestrator - no type discriminator field.\n * The `text` field is optional in Memory API models.\n */\nexport const MemoryCommunicationContentSchema = z.object({\n text: z.string().max(8388608).optional(),\n});\n\nexport type MemoryCommunicationContent = z.infer<typeof MemoryCommunicationContentSchema>;\n\n/**\n * A communication from Memory API (historical conversation data).\n *\n * Memory API has different field requirements than Conversation Orchestrator:\n * - No `conversationId`, `accountId`, or `content.type` fields\n * - Participants use `id`, `name`, `type`, `profileId`\n */\nexport const MemoryCommunicationSchema = z.object({\n id: z.string(),\n author: MemoryParticipantSchema,\n content: MemoryCommunicationContentSchema,\n recipients: z.array(MemoryParticipantSchema).max(100),\n channelId: z.string().max(256).nullable().optional(),\n createdAt: z.string(),\n updatedAt: z.string().optional(),\n});\n\nexport type MemoryCommunication = z.infer<typeof MemoryCommunicationSchema>;\n\n/**\n * Individual session message\n */\nexport const SessionMessageSchema = z.object({\n direction: MessageDirectionSchema,\n channel: z.string(),\n from_address: z.string().optional(),\n to_address: z.string().optional(),\n content: z.string(),\n timestamp: z.iso.datetime(),\n});\n\nexport type SessionMessage = z.infer<typeof SessionMessageSchema>;\n\n/**\n * Session information containing conversation history\n */\nexport const SessionInfoSchema = z.object({\n session_id: z.string(),\n started_at: z.iso.datetime(),\n ended_at: z.iso.datetime().optional(),\n channel: z.string(),\n messages: z.array(SessionMessageSchema),\n});\n\nexport type SessionInfo = z.infer<typeof SessionInfoSchema>;\n\n/**\n * Individual observation extracted from conversations\n */\nexport const ObservationInfoSchema = z.object({\n id: z.string(),\n content: z.string(),\n createdAt: z.iso.datetime(),\n occurredAt: z.iso.datetime().optional(),\n updatedAt: z.iso.datetime().optional(),\n conversationIds: z.array(z.string()).nullable().optional(),\n source: z.string().optional(),\n});\n\nexport type ObservationInfo = z.infer<typeof ObservationInfoSchema>;\n\n/**\n * Conversation summary information\n */\nexport const SummaryInfoSchema = z.object({\n id: z.string(),\n content: z.string(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime().optional(),\n conversationIds: z.array(z.string()).optional(),\n});\n\nexport type SummaryInfo = z.infer<typeof SummaryInfoSchema>;\n\n/**\n * Memory retrieval request parameters.\n *\n * Defaults match the Memory API server defaults. The SDK-level defaults in\n * TwilioMemoryConfigSchema may differ (e.g. communicationsLimit defaults to 10\n * in the SDK config for a better out-of-box experience, vs 0 on the API).\n */\nexport const MemoryRetrievalRequestSchema = z.object({\n conversationId: z.string().optional(),\n query: z.string().optional(),\n beginDate: z.iso.datetime().optional(),\n endDate: z.iso.datetime().optional(),\n observationsLimit: z.number().int().min(0).max(100).optional(),\n summariesLimit: z.number().int().min(0).max(100).optional(),\n communicationsLimit: z.number().int().min(0).max(100).optional(),\n relevanceThreshold: z.number().min(0.0).max(1.0).optional(),\n});\n\nexport type MemoryRetrievalRequest = z.infer<typeof MemoryRetrievalRequestSchema>;\n\n/**\n * Memory retrieval response from the Memory API /Recall endpoint.\n *\n * Contains observations, summaries, and communications from Memory API.\n */\nexport const MemoryRetrievalResponseSchema = z.object({\n observations: z.array(ObservationInfoSchema),\n summaries: z.array(SummaryInfoSchema),\n communications: z.array(MemoryCommunicationSchema).optional().default([]),\n meta: z\n .object({\n queryTime: z.number().optional(),\n })\n .optional(),\n});\n\nexport type MemoryRetrievalResponse = z.infer<typeof MemoryRetrievalResponseSchema>;\n\n/**\n * Profile lookup response\n */\nexport const ProfileLookupResponseSchema = z.object({\n normalizedValue: z.string().max(255),\n profiles: z\n .array(z.string())\n .max(100)\n .nullable()\n .transform(v => v ?? []),\n});\n\nexport type ProfileLookupResponse = z.infer<typeof ProfileLookupResponseSchema>;\n\n/**\n * Profile response with traits\n */\nexport const ProfileResponseSchema = z.object({\n id: z.string(),\n createdAt: z.string(),\n traits: z.record(z.string(), z.unknown()),\n});\n\nexport type ProfileResponse = z.infer<typeof ProfileResponseSchema>;\n\n/**\n * Empty memory response for error fallback\n */\nexport const EMPTY_MEMORY_RESPONSE: MemoryRetrievalResponse = {\n observations: [],\n summaries: [],\n communications: [],\n};\n\n/**\n * A single observation in a create request.\n *\n * `occurredAt` is required by the Memory API and formatted as ISO 8601.\n */\nexport const ObservationCreateRequestSchema = z.object({\n content: z.string(),\n source: z.string(),\n occurredAt: z.string(),\n conversationIds: z.array(z.string()).optional(),\n});\n\nexport type ObservationCreateRequest = z.infer<typeof ObservationCreateRequestSchema>;\n\n/**\n * Request body for the Memory API Observations endpoint.\n *\n * The endpoint is a batch create that wraps observations in an array.\n */\nexport const CreateObservationsRequestSchema = z.object({\n observations: z.array(ObservationCreateRequestSchema),\n});\n\nexport type CreateObservationsRequest = z.infer<typeof CreateObservationsRequestSchema>;\n\n/**\n * Response from creating an observation.\n *\n * The Memory API Observations endpoint is a batch create that returns a\n * confirmation message rather than the persisted observation.\n */\nexport const CreateObservationResponseSchema = z.object({\n message: z.string(),\n});\n\nexport type CreateObservationResponse = z.infer<typeof CreateObservationResponseSchema>;\n\n/**\n * Response from creating conversation summaries\n */\nexport const CreateConversationSummariesResponseSchema = z.object({\n message: z.string(),\n});\n\nexport type CreateConversationSummariesResponse = z.infer<\n typeof CreateConversationSummariesResponseSchema\n>;\n","import { z } from 'zod';\nimport type VoiceResponse from 'twilio/lib/twiml/VoiceResponse.js';\nimport type { CallListInstanceCreateOptions } from 'twilio/lib/rest/api/v2010/account/call.js';\n\n/**\n * ConversationRelay API Types\n *\n * Zod schemas are the single source of truth for runtime validation. Types are\n * inferred from schemas via z.infer. Compile-time drift guards (type assertions\n * against VoiceResponse.ConversationRelayAttributes / LanguageAttributes) ensure\n * that if the Twilio SDK types change, `npm run typecheck` will fail immediately.\n *\n * @see https://www.twilio.com/docs/voice/conversationrelay\n * @see https://www.twilio.com/docs/voice/conversationrelay/conversationrelay-noun\n */\n\n/**\n * Language configuration for multi-language ConversationRelay support\n * @see https://www.twilio.com/docs/voice/conversationrelay/conversationrelay-noun#language-attributes\n */\nexport const LanguageAttributesSchema = z.object({\n /** Language code (e.g., 'en-US', 'es-ES', 'en-AU') */\n code: z.string(),\n /** TTS provider for this language */\n ttsProvider: z.string().optional(),\n /** TTS voice for this language */\n voice: z.string().optional(),\n /** TTS language (may differ from code) */\n ttsLanguage: z.string().optional(),\n /** Transcription provider for this language */\n transcriptionProvider: z.string().optional(),\n /** Speech model for transcription */\n speechModel: z.string().optional(),\n /** Transcription language (may differ from code) */\n transcriptionLanguage: z.string().optional(),\n});\n\nexport type LanguageAttributes = z.infer<typeof LanguageAttributesSchema>;\n\n/**\n * ConversationRelay attributes for TwiML configuration\n * @see https://www.twilio.com/docs/voice/conversationrelay/conversationrelay-noun\n */\nexport const ConversationRelayAttributesSchema = z.object({\n /** WebSocket URL for ConversationRelay (required) */\n url: z.url(),\n\n // Welcome greeting settings\n /** Initial greeting to play when call connects */\n welcomeGreeting: z.string().optional(),\n /** Whether welcome greeting can be interrupted */\n welcomeGreetingInterruptible: z.enum(['any', 'speech', 'none']).optional(),\n\n // Transcription settings\n /** Transcription provider (e.g., 'Deepgram', 'Google') */\n transcriptionProvider: z.string().optional(),\n /** Language for transcription (e.g., 'en-US') */\n transcriptionLanguage: z.string().optional(),\n /** Speech model for transcription (e.g., 'nova-3-general') */\n speechModel: z.string().optional(),\n\n // TTS settings\n /** Text-to-speech provider (e.g., 'Google', 'ElevenLabs') */\n ttsProvider: z.string().optional(),\n /** Language for TTS (e.g., 'en-US') */\n ttsLanguage: z.string().optional(),\n /** Voice identifier for TTS (e.g., 'en-US-Journey-O') */\n voice: z.string().optional(),\n /** ElevenLabs text normalization setting */\n elevenlabsTextNormalization: z.string().optional(),\n\n // Interaction settings\n /** When agent speech can be interrupted */\n interruptible: z.enum(['any', 'speech', 'none']).optional(),\n /** Interrupt detection sensitivity */\n interruptSensitivity: z.enum(['low', 'medium', 'high']).optional(),\n /** Enable DTMF tone detection */\n dtmfDetection: z.boolean().optional(),\n /** Recognition hints for domain-specific vocabulary */\n hints: z.string().optional(),\n /** Whether prompts should be reported when TTS is playing and interrupt is disabled */\n reportInputDuringAgentSpeech: z.boolean().optional(),\n\n // Advanced settings\n /** Enable partial prompts (streaming) */\n partialPrompts: z.boolean().optional(),\n /** Enable profanity filtering */\n profanityFilter: z.boolean().optional(),\n /** Allow preemption of agent speech */\n preemptible: z.boolean().optional(),\n /** Default language code */\n language: z.string().optional(),\n /** Debug options for troubleshooting (string per SDK, not boolean) */\n debug: z.string().optional(),\n\n // Intelligence service\n /** Conversational Intelligence Service ID or unique name */\n intelligenceService: z.string().optional(),\n\n // Conversation orchestrator\n /** Twilio Conversation Orchestrator configuration ID */\n conversationConfiguration: z.string().optional(),\n});\n\nexport type ConversationRelayAttributes = z.infer<typeof ConversationRelayAttributesSchema>;\n\n/**\n * @internal Compile-time SDK drift guards — do not use directly.\n * If the Twilio SDK updates VoiceResponse.ConversationRelayAttributes or\n * VoiceResponse.LanguageAttributes, these checks will fail during typecheck,\n * signaling that our Zod schemas need to be updated to match.\n */\nexport type _SDKDriftGuards = {\n langCompat: LanguageAttributes extends VoiceResponse.LanguageAttributes ? true : never;\n langKeys: keyof VoiceResponse.LanguageAttributes extends keyof LanguageAttributes ? true : never;\n crelayCompat: ConversationRelayAttributes extends VoiceResponse.ConversationRelayAttributes\n ? true\n : never;\n crelayKeys: keyof VoiceResponse.ConversationRelayAttributes extends keyof ConversationRelayAttributes\n ? true\n : never;\n};\n\n/**\n * Custom parameters passed via TwiML\n * Can contain any key-value pairs with unknown values\n */\nexport const CustomParametersSchema = z.record(z.string(), z.unknown());\n\nexport type CustomParameters = z.infer<typeof CustomParametersSchema>;\n\n/**\n * WebSocket setup message from ConversationRelay\n */\nexport const SetupMessageSchema = z.object({\n type: z.literal('setup'),\n sessionId: z.string(),\n callSid: z.string(),\n parentCallSid: z.string().optional(),\n from: z.string(),\n to: z.string(),\n forwardedFrom: z.string().optional(),\n callerName: z.string().optional(),\n direction: z.string(),\n callType: z.string(),\n callStatus: z.string(),\n accountSid: z.string(),\n customParameters: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type SetupMessage = z.infer<typeof SetupMessageSchema>;\n\n/**\n * WebSocket prompt message (user speech)\n */\nexport const PromptMessageSchema = z.object({\n type: z.literal('prompt'),\n voicePrompt: z.string(),\n lang: z.string().optional(),\n last: z.boolean().optional(),\n agentSpeaking: z.string().optional(),\n});\n\nexport type PromptMessage = z.infer<typeof PromptMessageSchema>;\n\n/**\n * WebSocket interrupt message (user interruption)\n */\nexport const InterruptMessageSchema = z.object({\n type: z.literal('interrupt'),\n utteranceUntilInterrupt: z.string().optional(),\n durationUntilInterruptMs: z.number().int().nonnegative().optional(),\n});\n\nexport type InterruptMessage = z.infer<typeof InterruptMessageSchema>;\n\n/**\n * WebSocket DTMF message (caller pressed a key).\n *\n * Only sent when `dtmfDetection` is enabled on `<ConversationRelay>`, and one\n * message per keypress — digits are never batched.\n *\n * @see https://www.twilio.com/docs/voice/conversationrelay/websocket-messages#dtmf-message\n */\nexport const DtmfMessageSchema = z.object({\n type: z.literal('dtmf'),\n /** The key pressed: `0`-`9`, `*`, `#`, or `A`-`D`. */\n digit: z.string(),\n});\n\nexport type DtmfMessage = z.infer<typeof DtmfMessageSchema>;\n\n/**\n * Union of all WebSocket message types\n */\nexport const WebSocketMessageSchema = z.union([\n SetupMessageSchema,\n PromptMessageSchema,\n InterruptMessageSchema,\n DtmfMessageSchema,\n]);\n\nexport type WebSocketMessage = z.infer<typeof WebSocketMessageSchema>;\n\n/**\n * Text Token Message to send back via WebSocket\n * @see https://www.twilio.com/docs/voice/conversationrelay/websocket-messages#text-tokens-message\n */\nexport const TextTokenMessageSchema = z.object({\n type: z.literal('text'),\n token: z.string(),\n last: z.boolean().optional().default(true),\n});\n\nexport type TextTokenMessage = z.infer<typeof TextTokenMessageSchema>;\n\n/**\n * Extended ConversationRelay configuration that includes child elements.\n * Includes all ConversationRelayAttributes fields plus support for languages array.\n *\n * Note: The type is defined as an explicit interface and the schema is annotated\n * with z.ZodType<ConversationRelayConfig> to prevent TypeScript's type inference\n * from collapsing to `any` when resolving complex Zod generics with many optional\n * fields (especially under exactOptionalPropertyTypes).\n */\nexport interface ConversationRelayConfig extends ConversationRelayAttributes {\n /** Optional language configurations as child <Language> elements */\n languages?: LanguageAttributes[] | undefined;\n}\n\nexport const ConversationRelayConfigSchema: z.ZodType<ConversationRelayConfig> =\n ConversationRelayAttributesSchema.extend({\n /** Optional language configurations as child <Language> elements */\n languages: z.array(LanguageAttributesSchema).optional(),\n });\n\n// =========================================================================\n// TwiML customization layer\n// =========================================================================\n\n/**\n * Twilio uses the same four-value enum for several attributes that control\n * what caller input (DTMF, speech, both, neither) triggers a given behavior.\n */\nexport const InterruptModeSchema = z.enum(['none', 'dtmf', 'speech', 'any']);\nexport type InterruptMode = z.infer<typeof InterruptModeSchema>;\n\n/**\n * A single `<Language>` child for multi-language ConversationRelay setups.\n *\n * Maps to the `<Language>` element documented at\n * https://www.twilio.com/docs/voice/twiml/connect/conversationrelay#language-element\n *\n * Distinct from {@link LanguageAttributes} (the Twilio-SDK-shaped type used by\n * `connectConversationRelay`): this is the customization-facing model used in\n * {@link TwiMLOptions}, mirroring the Python SDK's `LanguageConfig`.\n */\nexport const LanguageConfigSchema = z.object({\n /**\n * Language code, e.g. 'es-MX'. Can be 'multi' for automatic language\n * detection (requires ElevenLabs TTS and Deepgram STT).\n */\n code: z.string(),\n /** TTS voice name for this language */\n voice: z.string().optional(),\n /** TTS provider, e.g. 'google' */\n ttsProvider: z.string().optional(),\n /** Transcription provider, e.g. 'deepgram' */\n transcriptionProvider: z.string().optional(),\n /** Speech model for STT. Choices vary by transcriptionProvider. */\n speechModel: z.string().optional(),\n});\n\nexport type LanguageConfig = z.infer<typeof LanguageConfigSchema>;\n\n/**\n * Options for the TwiML inside `<ConversationRelay>` (plus the\n * `<Connect action>` URL).\n *\n * Fields map to the attributes documented at\n * https://www.twilio.com/docs/voice/twiml/connect/conversationrelay . All\n * fields are optional. `VoiceChannel.handleIncomingCall` merges these values\n * over TAC defaults per-field — only fields explicitly present on the object\n * override lower layers (see `VoiceChannel`'s overlay logic).\n *\n * This is the customization-facing counterpart to {@link ConversationRelayConfig}\n * (which is the Twilio-SDK-shaped emit model and carries the required `url`).\n * Mirrors the Python SDK's `TwiMLOptions`.\n */\nexport const TwiMLOptionsSchema = z\n .object({\n /** Custom parameters to pass to ConversationRelay as `<Parameter>` children */\n customParameters: CustomParametersSchema.optional(),\n /** Initial greeting message for the caller */\n welcomeGreeting: z.string().optional(),\n /**\n * What caller input can interrupt the welcome greeting.\n * Defaults to 'any' on Twilio.\n */\n welcomeGreetingInterruptible: InterruptModeSchema.optional(),\n /**\n * URL for Twilio to request when the call ends (`<Connect action>`). Set to\n * a non-empty URL, or leave unset. An explicit `undefined` suppresses the\n * action entirely (see `VoiceChannel`'s actionUrl resolution); an empty\n * string is rejected so it can't silently drop the action.\n */\n actionUrl: z.string().min(1, 'actionUrl must not be empty').optional(),\n /**\n * Conversation Service SID. When set, ConversationRelay will manage\n * conversation creation and participants.\n */\n conversationConfiguration: z.string().optional(),\n /**\n * ConversationRelay WebSocket URL (the `<ConversationRelay url=...>`\n * attribute). Leave unset (the default) to use the URL the channel derives\n * from `TACConfig.voicePublicDomain` + `voiceWebsocketPath`. Set it only for\n * a per-call URL — e.g. an affinity-routed host that appends a token to the\n * upgrade URL — typically from an `onInboundCallTwiml` customizer. Layers\n * per-field like every other field. Must be non-empty when set.\n */\n websocketUrl: z.string().min(1, 'websocketUrl must not be empty').optional(),\n\n // Language, TTS, STT\n /**\n * Language for both STT and TTS, e.g. 'en-US'. Equivalent to setting both\n * ttsLanguage and transcriptionLanguage.\n */\n language: z.string().optional(),\n /** TTS language code; overrides `language` for TTS. */\n ttsLanguage: z.string().optional(),\n /**\n * STT language code; overrides `language` for transcription. Can be\n * 'multi' for automatic language detection (Deepgram only).\n */\n transcriptionLanguage: z.string().optional(),\n /** TTS voice name (choices vary by ttsProvider) */\n voice: z.string().optional(),\n /** TTS provider: 'Google', 'Amazon', or 'ElevenLabs'. Defaults to 'ElevenLabs'. */\n ttsProvider: z.string().optional(),\n /**\n * STT provider: 'Google' or 'Deepgram'. Defaults to 'Deepgram' (or 'Google'\n * for accounts that used ConversationRelay before 2025-09-12).\n */\n transcriptionProvider: z.string().optional(),\n /** Speech model for STT. Choices vary by transcriptionProvider. */\n speechModel: z.string().optional(),\n /**\n * Text normalization for ElevenLabs TTS. Defaults to 'off'. 'auto' behaves\n * like 'off' for ConversationRelay calls.\n */\n elevenlabsTextNormalization: z.enum(['on', 'auto', 'off']).optional(),\n\n // Turn detection / interruption\n /**\n * Confidence required to finish a turn. Only applies with Deepgram + flux\n * speech model. Twilio enforces the accepted range — see ConversationRelay docs.\n */\n eotThreshold: z.number().optional(),\n /**\n * Send unfinalized prompts and eager end-of-turn events (last=false). Only\n * applies with Deepgram + flux speech model.\n */\n partialPrompts: z.boolean().optional(),\n /**\n * Use Deepgram Smart Format for transcription output. Defaults to true when\n * transcriptionProvider='Deepgram'.\n */\n deepgramSmartFormat: z.boolean().optional(),\n /**\n * Silence (ms) after speech before finalizing the prompt. Integer\n * milliseconds or the literal 'auto' (the platform default). Twilio enforces\n * the accepted range — see ConversationRelay docs.\n */\n speechTimeout: z.union([z.number().int(), z.literal('auto')]).optional(),\n /**\n * What caller input interrupts TTS playback. Boolean accepted for backward\n * compat: true='any', false='none'. Defaults to 'any'.\n */\n interruptible: z.union([InterruptModeSchema, z.boolean()]).optional(),\n /** How easily caller speech triggers an interrupt. Defaults to 'high'. */\n interruptSensitivity: z.enum(['high', 'medium', 'low']).optional(),\n /**\n * What caller input gets reported while the agent is speaking (independent\n * of whether playback is interrupted). Defaults to 'none' since May 2025.\n */\n reportInputDuringAgentSpeech: InterruptModeSchema.optional(),\n /**\n * Filter short conversational feedback ('yeah', 'uh-huh', …) so it doesn't\n * interrupt the agent. Defaults to false.\n */\n ignoreBackchannel: z.boolean().optional(),\n /**\n * Allow text tokens from the next talk cycle to interrupt the current one.\n * Defaults to false.\n */\n preemptible: z.boolean().optional(),\n /** Emit DTMF keypress events over the WebSocket. */\n dtmfDetection: z.boolean().optional(),\n\n // Recognition hints / events / debug / intelligence\n /**\n * Comma-separated words/phrases likely to appear in speech. Capitalize\n * proper nouns.\n */\n hints: z.string().optional(),\n /** Space-separated event subscriptions, e.g. 'speaker-events tokens-played'. */\n events: z.string().optional(),\n /**\n * Debug subscription, e.g. 'debugging'. Note: 'speaker-events' and\n * 'tokens-played' have moved to the `events` attribute — only use them here\n * for backward compatibility.\n */\n debug: z.string().optional(),\n /**\n * Conversation Intelligence (classic) Service SID or unique name for\n * persisting transcripts and running Language Operators.\n */\n intelligenceService: z.string().optional(),\n\n // Nested <Language> children\n /** Additional `<Language>` children for multi-language support */\n languages: z.array(LanguageConfigSchema).optional(),\n\n /**\n * Escape hatch for ConversationRelay attributes not yet typed on this model.\n * Keys are emitted as-is on `<ConversationRelay>`; Twilio's SDK converts\n * snake_case to camelCase, lowercases bools to 'true'/'false', and\n * stringifies numbers. Prefer a typed field when one exists — use `extra`\n * only for newly-added Twilio attributes not yet in this SDK.\n */\n extra: z.record(z.string(), z.union([z.string(), z.boolean(), z.number()])).optional(),\n })\n // Forbid unknown keys so a typo in a field name fails loudly rather than\n // being silently dropped from the emitted TwiML.\n .strict()\n // Fail fast when `extra` includes a key that has a typed field on this model.\n // Without this, the user's value would be silently dropped by the TwiML\n // serializer in favor of the typed default — a footgun.\n .superRefine((value, ctx) => {\n if (!value.extra) return;\n const typed = new Set(Object.keys(TwiMLOptionsShape).filter(k => k !== 'extra'));\n const shadowed = Object.keys(value.extra)\n .filter(k => typed.has(k))\n .sort();\n if (shadowed.length > 0) {\n ctx.addIssue({\n code: 'custom',\n path: ['extra'],\n message:\n `TwiMLOptions.extra keys [${shadowed.join(', ')}] shadow typed fields. ` +\n 'Set the typed field directly instead of using `extra`.',\n });\n }\n });\n\n/**\n * @internal Field names of {@link TwiMLOptionsSchema}, used by the shadow-guard\n * refinement above. Declared separately because `.strict().superRefine(...)`\n * erases the object shape on the schema instance.\n */\nconst TwiMLOptionsShape = {\n customParameters: true,\n welcomeGreeting: true,\n welcomeGreetingInterruptible: true,\n actionUrl: true,\n conversationConfiguration: true,\n websocketUrl: true,\n language: true,\n ttsLanguage: true,\n transcriptionLanguage: true,\n voice: true,\n ttsProvider: true,\n transcriptionProvider: true,\n speechModel: true,\n elevenlabsTextNormalization: true,\n eotThreshold: true,\n partialPrompts: true,\n deepgramSmartFormat: true,\n speechTimeout: true,\n interruptible: true,\n interruptSensitivity: true,\n reportInputDuringAgentSpeech: true,\n ignoreBackchannel: true,\n preemptible: true,\n dtmfDetection: true,\n hints: true,\n events: true,\n debug: true,\n intelligenceService: true,\n languages: true,\n extra: true,\n} as const;\n\nexport type TwiMLOptions = z.infer<typeof TwiMLOptionsSchema>;\n\n/**\n * Framework-neutral view of the Twilio TwiML webhook form.\n *\n * Populated by `TACServer` from the incoming Twilio webhook, then passed to a\n * customizer registered via `VoiceChannel.onInboundCallTwiml(...)` so the\n * application can produce per-call {@link TwiMLOptions} overrides without\n * depending on Fastify types. Mirrors the Python SDK's `TwiMLRequest`.\n */\nexport const TwiMLRequestSchema = z.object({\n from: z.string().optional(),\n to: z.string().optional(),\n callSid: z.string().optional(),\n callerCountry: z.string().optional(),\n callerState: z.string().optional(),\n callerCity: z.string().optional(),\n direction: z.string().optional(),\n /**\n * Any other fields from the Twilio webhook not captured above. Values are\n * always strings here (webhook form fields are url-encoded), unlike\n * TwiMLOptions.extra which accepts string | boolean | number for emitted\n * TwiML attributes.\n */\n extra: z.record(z.string(), z.string()).default({}),\n});\n\nexport type TwiMLRequest = z.infer<typeof TwiMLRequestSchema>;\n\n/**\n * Map from Twilio webhook form field names to {@link TwiMLRequest} keys.\n * Fields not in this map are bucketed into `extra` by {@link twiMLRequestFromForm}.\n */\nconst TWIML_REQUEST_FORM_ALIASES: Record<string, keyof Omit<TwiMLRequest, 'extra'>> = {\n From: 'from',\n To: 'to',\n CallSid: 'callSid',\n CallerCountry: 'callerCountry',\n CallerState: 'callerState',\n CallerCity: 'callerCity',\n Direction: 'direction',\n};\n\n/**\n * Build a {@link TwiMLRequest} from a raw Twilio form dict, bucketing unknown\n * keys into `extra`. Mirrors the Python SDK's `TwiMLRequest.from_form`.\n */\nexport function twiMLRequestFromForm(form: Record<string, string>): TwiMLRequest {\n const known: Record<string, string> = {};\n const extra: Record<string, string> = {};\n for (const [key, value] of Object.entries(form)) {\n const alias = TWIML_REQUEST_FORM_ALIASES[key];\n if (alias) {\n known[alias] = value;\n } else {\n extra[key] = value;\n }\n }\n return TwiMLRequestSchema.parse({ ...known, extra });\n}\n\n/**\n * Voice channel specific events\n */\nexport interface VoiceChannelEvents {\n setup: SetupMessage;\n prompt: PromptMessage;\n interrupt: InterruptMessage;\n dtmf: DtmfMessage;\n error: Error;\n}\n\n/**\n * ConversationRelay callback payload from Twilio webhook\n *\n * Sent when a ConversationRelay session ends or transitions state.\n * Includes standard voice webhook parameters plus ConversationRelay-specific fields.\n *\n * @see https://www.twilio.com/docs/voice/twiml#request-parameters\n * @see https://www.twilio.com/docs/voice/conversationrelay/conversationrelay-noun#statuscallback\n */\nexport const ConversationRelayCallbackPayloadSchema = z.object({\n // Core Twilio identifiers (required)\n AccountSid: z.string(),\n CallSid: z.string(),\n\n /** Call status with strict type checking for all valid Twilio call states */\n CallStatus: z.enum([\n 'queued',\n 'initiated',\n 'ringing',\n 'in-progress',\n 'completed',\n 'busy',\n 'no-answer',\n 'failed',\n 'canceled',\n ]),\n\n // Call participants (required)\n From: z.string(),\n To: z.string(),\n\n /** Direction of the call */\n Direction: z.enum(['inbound', 'outbound-api', 'outbound-dial']),\n\n // Standard voice webhook parameters (optional)\n ApiVersion: z.string().optional(),\n ForwardedFrom: z.string().optional(),\n CallerName: z.string().optional(),\n ParentCallSid: z.string().optional(),\n ApplicationSid: z.string().optional(),\n\n // ConversationRelay session information (optional)\n SessionId: z.string().optional(),\n SessionStatus: z.string().optional(),\n SessionDuration: z.string().optional(),\n});\n\nexport type ConversationRelayCallbackPayload = z.infer<\n typeof ConversationRelayCallbackPayloadSchema\n>;\n\n// =========================================================================\n// Call Events (status callback, async AMD, recording status)\n// =========================================================================\n\n/**\n * Split a Twilio webhook form into aliased fields and everything else.\n *\n * Unknown keys — including fields that belong to a different call event — are\n * bucketed rather than dropped, so a handler can still reach them via `extra`.\n */\nfunction splitCallEventForm(\n form: Record<string, string>,\n aliases: Record<string, string>\n): { known: Record<string, string>; extra: Record<string, string> } {\n const known: Record<string, string> = {};\n const extra: Record<string, string> = {};\n for (const [key, value] of Object.entries(form)) {\n const alias = aliases[key];\n if (alias) {\n known[alias] = value;\n } else {\n extra[key] = value;\n }\n }\n return { known, extra };\n}\n\n/**\n * Fields shared by the three Twilio call-webhook events.\n *\n * `callSid` is the correlation key across every surface — it matches\n * `ConversationSession.callSid` and the SID from\n * `initiateOutboundConversation`. It's required: every real call webhook\n * carries one, and defaulting it would hand handlers an empty SID to act on\n * (`endCall('')` is a Twilio 404). Missing or blank fails validation, which the\n * channel turns into a 400.\n */\nconst CallEventBaseShape = {\n callSid: z.string().min(1, 'CallSid is required'),\n accountSid: z.string().optional(),\n /** Any other Twilio webhook fields not surfaced above. */\n extra: z.record(z.string(), z.string()).default({}),\n};\n\nconst CALL_EVENT_BASE_ALIASES = {\n CallSid: 'callSid',\n AccountSid: 'accountSid',\n} as const;\n\n/**\n * Call statuses that mean the call ended without reaching the callee — i.e.\n * worth a retry.\n */\nconst UNREACHED_CALL_STATUSES: readonly string[] = ['busy', 'no-answer', 'failed', 'canceled'];\n\n/**\n * A Twilio `statusCallback` webhook — call progress and disposition.\n *\n * By default Twilio sends only the terminal event, which covers every\n * disposition (`completed` / `busy` / `no-answer` / `failed` / `canceled`); set\n * `CallOptions.statusCallbackEvent` for the intermediate ones. Register a\n * handler via `VoiceChannel.onCallStatus`.\n *\n * `isUnreached` is computed at parse time so application code doesn't have to\n * match disposition strings itself.\n */\nexport const CallStatusEventSchema = z\n .object({\n ...CallEventBaseShape,\n callStatus: z.string().optional(),\n callDuration: z.string().optional(),\n sipResponseCode: z.string().optional(),\n })\n .transform(event => ({\n ...event,\n /** Call ended without reaching the callee — i.e. worth a retry. */\n isUnreached: UNREACHED_CALL_STATUSES.includes(event.callStatus ?? ''),\n }));\n\nexport type CallStatusEvent = z.infer<typeof CallStatusEventSchema>;\n\nconst CALL_STATUS_EVENT_ALIASES: Record<string, string> = {\n ...CALL_EVENT_BASE_ALIASES,\n CallStatus: 'callStatus',\n CallDuration: 'callDuration',\n SipResponseCode: 'sipResponseCode',\n};\n\n/** Build a {@link CallStatusEvent} from a raw Twilio webhook form. */\nexport function callStatusEventFromForm(form: Record<string, string>): CallStatusEvent {\n const { known, extra } = splitCallEventForm(form, CALL_STATUS_EVENT_ALIASES);\n return CallStatusEventSchema.parse({ ...known, extra });\n}\n\n/**\n * A Twilio `asyncAmdStatusCallback` webhook — answering machine detection.\n *\n * Fires at most once per call, and only when the call set both\n * `CallOptions.machineDetection` and `asyncAmd`.\n *\n * `answeredBy` is mode-dependent — `machine_start` under `'Enable'`,\n * `machine_end_beep` / `machine_end_silence` / `machine_end_other` under\n * `'DetectMessageEnd'`, plus `human` / `fax` / `unknown` in both. Use\n * `isMachine` rather than matching those yourself. Register a handler via\n * `VoiceChannel.onAmd`.\n */\nexport const AmdEventSchema = z\n .object({\n ...CallEventBaseShape,\n answeredBy: z.string().optional(),\n machineDetectionDuration: z.string().optional(),\n })\n .transform(event => ({\n ...event,\n /**\n * A machine answered — any `machine_*` value, either mode. `unknown`\n * (detection timed out) is false, so a call is never hung up on a guess.\n */\n isMachine: (event.answeredBy ?? '').startsWith('machine'),\n }));\n\nexport type AmdEvent = z.infer<typeof AmdEventSchema>;\n\nconst AMD_EVENT_ALIASES: Record<string, string> = {\n ...CALL_EVENT_BASE_ALIASES,\n AnsweredBy: 'answeredBy',\n MachineDetectionDuration: 'machineDetectionDuration',\n};\n\n/** Build an {@link AmdEvent} from a raw Twilio webhook form. */\nexport function amdEventFromForm(form: Record<string, string>): AmdEvent {\n const { known, extra } = splitCallEventForm(form, AMD_EVENT_ALIASES);\n return AmdEventSchema.parse({ ...known, extra });\n}\n\n/**\n * A Twilio `recordingStatusCallback` webhook — a recording became available.\n *\n * Fires when the recording is ready (`recordingUrl` accessible), only when\n * recording is enabled. Register a handler via `VoiceChannel.onRecording`.\n */\nexport const RecordingEventSchema = z.object({\n ...CallEventBaseShape,\n recordingSid: z.string().optional(),\n recordingUrl: z.string().optional(),\n recordingStatus: z.string().optional(),\n recordingDuration: z.string().optional(),\n});\n\nexport type RecordingEvent = z.infer<typeof RecordingEventSchema>;\n\nconst RECORDING_EVENT_ALIASES: Record<string, string> = {\n ...CALL_EVENT_BASE_ALIASES,\n RecordingSid: 'recordingSid',\n RecordingUrl: 'recordingUrl',\n RecordingStatus: 'recordingStatus',\n RecordingDuration: 'recordingDuration',\n};\n\n/** Build a {@link RecordingEvent} from a raw Twilio webhook form. */\nexport function recordingEventFromForm(form: Record<string, string>): RecordingEvent {\n const { known, extra } = splitCallEventForm(form, RECORDING_EVENT_ALIASES);\n return RecordingEventSchema.parse({ ...known, extra });\n}\n\n// =========================================================================\n// Calls API parameters (calls.create passthrough)\n// =========================================================================\n\n/**\n * Every parameter `client.calls.create()` accepts, as of the pinned Twilio SDK.\n *\n * Unlike Python's `inspect.signature`, TypeScript has no runtime view of a\n * function's accepted keys, so the set is listed here and pinned to the SDK by\n * {@link _CallsCreateDriftGuards} at typecheck time. It's needed at runtime\n * because the Node SDK builds its request body from an explicit whitelist —\n * an unrecognized key is **silently dropped**, not an error, so without this a\n * typo would look like it worked.\n */\nconst CALLS_CREATE_PARAMS = [\n 'applicationSid',\n 'asyncAmd',\n 'asyncAmdStatusCallback',\n 'asyncAmdStatusCallbackMethod',\n 'byoc',\n 'callerId',\n 'callReason',\n 'callToken',\n 'clientNotificationUrl',\n 'fallbackMethod',\n 'fallbackUrl',\n 'from',\n 'machineDetection',\n 'machineDetectionSilenceTimeout',\n 'machineDetectionSpeechEndThreshold',\n 'machineDetectionSpeechThreshold',\n 'machineDetectionTimeout',\n 'method',\n 'record',\n 'recordingChannels',\n 'recordingStatusCallback',\n 'recordingStatusCallbackEvent',\n 'recordingStatusCallbackMethod',\n 'recordingTrack',\n 'sendDigits',\n 'sipAuthPassword',\n 'sipAuthUsername',\n 'statusCallback',\n 'statusCallbackEvent',\n 'statusCallbackMethod',\n 'timeLimit',\n 'timeout',\n 'to',\n 'trim',\n 'twiml',\n 'url',\n] as const;\n\n/**\n * `calls.create` parameters TAC owns — it builds the call and its TwiML, so a\n * caller setting these would either be overwritten or break the call.\n */\nconst RESERVED_CALL_PARAMS = ['to', 'from', 'twiml', 'url', 'applicationSid'] as const;\n\ntype ReservedCallParam = (typeof RESERVED_CALL_PARAMS)[number];\n\n/**\n * The `calls.create` parameters TAC types explicitly — the ones outbound\n * ConversationRelay reaches for. Everything else the SDK accepts is still\n * forwarded, typed by the SDK itself via {@link CallOptions}.\n */\nexport interface TypedCallOptions {\n /**\n * Enables AMD. `'Enable'` reports as soon as it can tell human from machine\n * (to hang up on voicemail); `'DetectMessageEnd'` waits out the greeting (to\n * leave a message). Required, together with `asyncAmd`, for `onAmd` to fire.\n */\n machineDetection?: 'Enable' | 'DetectMessageEnd' | undefined;\n /**\n * Detect in the background. Required for `onAmd`: with it off, `AnsweredBy`\n * comes back on the TwiML request, which inline TwiML can't receive.\n *\n * Twilio's API types this as a string; a boolean is serialized for you.\n */\n asyncAmd?: boolean | string | undefined;\n asyncAmdStatusCallback?: string | undefined;\n asyncAmdStatusCallbackMethod?: string | undefined;\n machineDetectionTimeout?: number | undefined;\n machineDetectionSpeechThreshold?: number | undefined;\n machineDetectionSpeechEndThreshold?: number | undefined;\n machineDetectionSilenceTimeout?: number | undefined;\n\n /** Required for `onRecording`. */\n record?: boolean | undefined;\n recordingStatusCallback?: string | undefined;\n recordingStatusCallbackEvent?: string[] | undefined;\n recordingChannels?: string | undefined;\n recordingTrack?: string | undefined;\n\n statusCallback?: string | undefined;\n /**\n * Lifecycle events to report. Omitted, Twilio sends only `'completed'` —\n * which covers busy/canceled/failed/no-answer. Set it for ringing/answered.\n */\n statusCallbackEvent?: string[] | undefined;\n statusCallbackMethod?: string | undefined;\n /** Seconds to ring before giving up. Twilio defaults to 60. */\n timeout?: number | undefined;\n}\n\n/**\n * Parameters for Twilio's `client.calls.create()`.\n *\n * {@link TypedCallOptions} covers the ones outbound ConversationRelay reaches\n * for; any other parameter `calls.create()` accepts is forwarded too, typed by\n * the Twilio SDK. TAC-owned parameters (`to`, `from`, `twiml`, `url`,\n * `applicationSid`) are excluded — TAC builds the call and its TwiML.\n *\n * Unknown keys are rejected at validation, so a typo fails at\n * `initiateOutboundConversation` rather than being silently dropped by the SDK.\n *\n * @example\n * ```typescript\n * const callOptions: CallOptions = {\n * machineDetection: 'Enable',\n * asyncAmd: true,\n * record: true,\n * };\n * ```\n */\nexport type CallOptions = TypedCallOptions &\n Omit<CallListInstanceCreateOptions, ReservedCallParam | keyof TypedCallOptions>;\n\n/**\n * @internal Fails typecheck unless instantiated with `true`. A conditional type\n * that merely resolves to `never` is not an error on its own, so the assertion\n * has to be a constraint violation to be load-bearing.\n */\ntype _AssertTrue<T extends true> = T;\n\n/**\n * @internal Compile-time SDK drift guards — do not use directly.\n * If the Twilio SDK adds, removes, or renames a `calls.create` parameter these\n * checks fail during `npm run typecheck`, signaling that\n * {@link CALLS_CREATE_PARAMS} needs updating. Without the `complete` direction a\n * newly added SDK parameter would be rejected at runtime as unknown.\n */\nexport type _CallsCreateDriftGuards = {\n known: _AssertTrue<\n (typeof CALLS_CREATE_PARAMS)[number] extends keyof CallListInstanceCreateOptions ? true : false\n >;\n complete: _AssertTrue<\n keyof CallListInstanceCreateOptions extends (typeof CALLS_CREATE_PARAMS)[number] ? true : false\n >;\n typedAreRealParams: _AssertTrue<\n keyof TypedCallOptions extends keyof CallListInstanceCreateOptions ? true : false\n >;\n reservedAreRealParams: _AssertTrue<\n ReservedCallParam extends keyof CallListInstanceCreateOptions ? true : false\n >;\n};\n\nconst ACCEPTED_CALL_PARAMS: ReadonlySet<string> = new Set(CALLS_CREATE_PARAMS);\n\n/**\n * Whether an `asyncAmd` value actually turns background detection on.\n *\n * Accepts the boolean TAC serializes for callers and the string Twilio's API\n * types the parameter as, so `'false'` reads as off rather than as a non-empty\n * (therefore truthy) string.\n */\nfunction isAsyncAmdEnabled(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.trim().toLowerCase() === 'true';\n return false;\n}\n\n/**\n * Runtime validation for {@link CallOptions}.\n *\n * Loose rather than strict so untyped-but-real Calls API parameters pass\n * through; `superRefine` then rejects TAC-owned and unknown keys explicitly so\n * the message says which mistake was made.\n */\nconst CallOptionsObjectSchema = z\n .looseObject({\n machineDetection: z.enum(['Enable', 'DetectMessageEnd']).optional(),\n asyncAmd: z.union([z.boolean(), z.string()]).optional(),\n asyncAmdStatusCallback: z.string().optional(),\n asyncAmdStatusCallbackMethod: z.string().optional(),\n machineDetectionTimeout: z.number().int().optional(),\n machineDetectionSpeechThreshold: z.number().int().optional(),\n machineDetectionSpeechEndThreshold: z.number().int().optional(),\n machineDetectionSilenceTimeout: z.number().int().optional(),\n\n record: z.boolean().optional(),\n recordingStatusCallback: z.string().optional(),\n recordingStatusCallbackEvent: z.array(z.string()).optional(),\n recordingChannels: z.string().optional(),\n recordingTrack: z.string().optional(),\n\n statusCallback: z.string().optional(),\n statusCallbackEvent: z.array(z.string()).optional(),\n statusCallbackMethod: z.string().optional(),\n timeout: z.number().int().optional(),\n })\n .superRefine((value, ctx) => {\n const supplied = Object.keys(value);\n\n const conflict = supplied.filter(key =>\n (RESERVED_CALL_PARAMS as readonly string[]).includes(key)\n );\n if (conflict.length > 0) {\n ctx.addIssue({\n code: 'custom',\n message:\n `callOptions may not set TAC-owned call parameters: ${conflict.sort().join(', ')}. ` +\n 'TAC builds the call and its TwiML.',\n });\n }\n\n const unknown = supplied.filter(key => !ACCEPTED_CALL_PARAMS.has(key));\n if (unknown.length > 0) {\n ctx.addIssue({\n code: 'custom',\n message:\n \"callOptions has parameters Twilio's calls.create() does not accept: \" +\n `${unknown.sort().join(', ')}. Check for a typo, or upgrade the twilio package.`,\n });\n }\n\n // AMD needs both flags. machineDetection turns detection on; asyncAmd\n // delivers AnsweredBy to a callback. Without asyncAmd, Twilio returns it on\n // the TwiML request instead — unreachable, since TAC sends inline TwiML.\n //\n // asyncAmd is checked by value, not truthiness: Twilio's API types it as a\n // string, and `Boolean('false')` is true — so a plain truthiness test would\n // wave through `asyncAmd: 'false'` and silently deliver no AMD event.\n if (Boolean(value.machineDetection) !== isAsyncAmdEnabled(value.asyncAmd)) {\n ctx.addIssue({\n code: 'custom',\n message:\n 'AMD requires both machineDetection and asyncAmd; got ' +\n `machineDetection=${JSON.stringify(value.machineDetection)}, ` +\n `asyncAmd=${JSON.stringify(value.asyncAmd)}.`,\n });\n }\n });\n\n/**\n * Validates {@link CallOptions}. The parsed value is re-widened to `CallOptions`\n * because the loose object's inferred index signature would otherwise erase the\n * SDK-derived parameter types.\n */\nexport const CallOptionsSchema: z.ZodType<CallOptions, unknown> = CallOptionsObjectSchema.transform(\n value => value as CallOptions\n);\n\n/**\n * Serialize {@link CallOptions} into the argument object for\n * `client.calls.create()`, dropping unset keys.\n *\n * `asyncAmd` is coerced to a string because Twilio's SDK types it as one,\n * unlike `record`.\n */\nexport function callOptionsToCreateParams(options: CallOptions): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(options)) {\n if (value === undefined) continue;\n params[key] = key === 'asyncAmd' && typeof value === 'boolean' ? String(value) : value;\n }\n return params;\n}\n\n// =========================================================================\n// Outbound Voice Conversation Types\n// =========================================================================\n\n/**\n * Options for initiating an outbound voice conversation.\n *\n * The caller identity is always TAC's configured `config.phoneNumber`.\n * Multi-number deployments should run one TAC instance per line.\n *\n * TwiML for the outbound call is built by merging per-field, highest precedence\n * first:\n * 1. This call's `twimlOptions` (per-call overrides)\n * 2. `VoiceChannelConfig.defaultTwimlOptions` (channel-wide defaults)\n * 3. TAC defaults (welcome greeting, conversationConfiguration, actionUrl\n * resolved via Studio handoff if configured, else derived from\n * `TACConfig.voicePublicDomain` + `voiceActionPath`)\n *\n * Fields you don't set at a layer fall through to lower layers — so\n * `twimlOptions: { voice: 'es-MX-Neural2-A' }` on this call overrides only\n * `voice`; `language`, `interruptible`, etc. from the channel config still apply.\n */\nexport interface InitiateVoiceConversationOptions {\n to: string;\n /**\n * Public WebSocket URL for ConversationRelay (e.g. 'wss://your-domain.ngrok.app/ws').\n * Optional — defaults to the URL derived from `TACConfig.voicePublicDomain` +\n * `voiceWebsocketPath`. Pass it here only to override the URL for a specific call.\n */\n websocketUrl?: string | undefined;\n /**\n * Per-call overrides for the TwiML inside `<ConversationRelay>`. Merged over\n * `VoiceChannelConfig.defaultTwimlOptions` and TAC defaults.\n */\n twimlOptions?: TwiMLOptions | undefined;\n /**\n * Parameters for Twilio's `calls.create()` — AMD, recording, status\n * callbacks, timeout (see {@link CallOptions}). Callback URLs auto-wire when\n * the matching handler is registered; an explicit URL wins.\n */\n callOptions?: CallOptions | undefined;\n}\n\nexport const InitiateVoiceConversationOptionsSchema: z.ZodType<InitiateVoiceConversationOptions> = z\n .object({\n to: z.string().min(1, 'Recipient phone number is required'),\n websocketUrl: z.url().optional(),\n twimlOptions: TwiMLOptionsSchema.optional(),\n callOptions: CallOptionsSchema.optional(),\n })\n // Reject removed flat fields (welcomeGreeting, actionUrl, customParameters,\n // conversationRelayConfig) so callers upgrading from older TAC versions get\n // a clear error instead of having their values silently dropped.\n .strict();\n","import { z } from 'zod';\n\n/**\n * JSON Schema definition for tool parameters\n */\nexport const JSONSchemaSchema = z.object({\n type: z.enum(['object', 'string', 'number', 'boolean', 'array']),\n properties: z.record(z.string(), z.any()).optional(),\n required: z.array(z.string()).optional(),\n items: z.any().optional(),\n enum: z.array(z.any()).optional(),\n description: z.string().optional(),\n});\n\nexport type JSONSchema = z.infer<typeof JSONSchemaSchema>;\n\n/**\n * Tool function signature\n */\nexport type ToolFunction<TParams = unknown, TResult = unknown> = (\n params: TParams\n) => Promise<TResult> | TResult;\n\n/**\n * Core tool definition\n */\nexport interface TACTool<TParams = unknown, TResult = unknown> {\n name: string;\n description: string;\n parameters: JSONSchema;\n implementation: ToolFunction<TParams, TResult>;\n}\n\n/**\n * OpenAI tool format\n */\nexport const OpenAIToolSchema = z.object({\n type: z.literal('function'),\n function: z.object({\n name: z.string(),\n description: z.string(),\n parameters: JSONSchemaSchema,\n }),\n});\n\nexport type OpenAITool = z.infer<typeof OpenAIToolSchema>;\n\n/**\n * Anthropic tool format\n */\nexport const AnthropicToolSchema = z.object({\n name: z.string(),\n description: z.string(),\n input_schema: JSONSchemaSchema,\n});\n\nexport type AnthropicTool = z.infer<typeof AnthropicToolSchema>;\n\n/**\n * Tool execution context\n */\nexport interface ToolContext {\n conversationId?: string;\n profileId?: string;\n channel?: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Tool execution result\n */\nexport const ToolExecutionResultSchema = z.object({\n success: z.boolean(),\n data: z.any().optional(),\n error: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type ToolExecutionResult = z.infer<typeof ToolExecutionResultSchema>;\n\n/**\n * Built-in tool types\n */\nexport const BuiltInTools = {\n RETRIEVE_MEMORY: 'retrieve_profile_memory',\n SEND_MESSAGE: 'send_message',\n HANDOFF: 'handoff',\n SEARCH_KNOWLEDGE: 'search_knowledge',\n} as const;\n\nexport type BuiltInToolName = (typeof BuiltInTools)[keyof typeof BuiltInTools];\n","import { z } from 'zod';\n\n/**\n * Conversation Intelligence Types\n *\n * These types represent the webhook payloads and configuration for\n * processing Conversation Intelligence operator results.\n */\n\n/**\n * Participant in operator execution (e.g., CUSTOMER, AGENT)\n */\nexport const CintelParticipantSchema = z.object({\n type: z.string(),\n profileId: z.string().optional(),\n mediaParticipantId: z.string().optional(),\n});\n\nexport type CintelParticipant = z.infer<typeof CintelParticipantSchema>;\n\n/**\n * Execution details for an operator result\n */\nexport const ExecutionDetailsSchema = z.object({\n participants: z.array(CintelParticipantSchema).optional(),\n});\n\nexport type ExecutionDetails = z.infer<typeof ExecutionDetailsSchema>;\n\n/**\n * Operator metadata\n */\nexport const OperatorSchema = z.object({\n id: z.string(),\n name: z.string().optional(),\n});\n\nexport type Operator = z.infer<typeof OperatorSchema>;\n\n/**\n * Individual operator result from Conversation Intelligence\n */\nexport const OperatorResultSchema = z.object({\n id: z.string(),\n operator: OperatorSchema,\n outputFormat: z.string(),\n result: z.unknown(),\n dateCreated: z.string(),\n referenceIds: z.array(z.string()).optional().default([]),\n executionDetails: ExecutionDetailsSchema.optional(),\n});\n\nexport type OperatorResult = z.infer<typeof OperatorResultSchema>;\n\n/**\n * Intelligence configuration metadata\n */\nexport const IntelligenceConfigurationSchema = z.object({\n id: z.string(),\n friendlyName: z.string().optional(),\n});\n\nexport type IntelligenceConfiguration = z.infer<typeof IntelligenceConfigurationSchema>;\n\n/**\n * Full webhook payload for operator result events\n */\nexport const OperatorResultEventSchema = z.object({\n accountId: z.string(),\n conversationId: z.string(),\n memoryStoreId: z.string().optional(),\n intelligenceConfiguration: IntelligenceConfigurationSchema,\n operatorResults: z.array(OperatorResultSchema),\n});\n\nexport type OperatorResultEvent = z.infer<typeof OperatorResultEventSchema>;\n\n/**\n * Result of processing an operator result event\n */\nexport const OperatorProcessingResultSchema = z.object({\n success: z.boolean(),\n eventType: z.string().optional(),\n skipped: z.boolean().default(false),\n skipReason: z.string().optional(),\n error: z.string().optional(),\n createdCount: z.number().default(0),\n});\n\nexport type OperatorProcessingResult = z.infer<typeof OperatorProcessingResultSchema>;\n\n/**\n * Conversation Intelligence configuration for TAC\n */\nexport const ConversationIntelligenceConfigSchema = z.object({\n configurationId: z.string(),\n summaryOperatorSid: z.string().optional(),\n});\n\nexport type ConversationIntelligenceConfig = z.infer<typeof ConversationIntelligenceConfigSchema>;\n\n/**\n * Summary item for batch creation\n */\nexport const ConversationSummaryItemSchema = z.object({\n content: z.string(),\n conversationId: z.string(),\n occurredAt: z.string(),\n source: z.string().optional(),\n});\n\nexport type ConversationSummaryItem = z.infer<typeof ConversationSummaryItemSchema>;\n","import { z } from 'zod';\n\n/**\n * Knowledge base status enum\n */\nexport const KnowledgeBaseStatusSchema = z.enum([\n 'QUEUED',\n 'PROVISIONING',\n 'ACTIVE',\n 'FAILED',\n 'DELETING',\n]);\n\nexport type KnowledgeBaseStatus = z.infer<typeof KnowledgeBaseStatusSchema>;\n\n/**\n * Knowledge base metadata (from GET endpoint)\n */\nexport const KnowledgeBaseSchema = z.object({\n id: z.string(),\n displayName: z.string(),\n description: z.string(),\n status: KnowledgeBaseStatusSchema,\n createdAt: z.string(),\n updatedAt: z.string(),\n version: z.number(),\n});\n\nexport type KnowledgeBase = z.infer<typeof KnowledgeBaseSchema>;\n\n/**\n * Search result chunk (from POST search endpoint)\n */\nexport const KnowledgeChunkResultSchema = z.object({\n content: z.string(),\n knowledgeId: z.string(),\n createdAt: z.string(),\n score: z.number().optional(),\n});\n\nexport type KnowledgeChunkResult = z.infer<typeof KnowledgeChunkResultSchema>;\n\n/**\n * Search response wrapper\n */\nexport const KnowledgeSearchResponseSchema = z.object({\n chunks: z.array(KnowledgeChunkResultSchema),\n});\n\nexport type KnowledgeSearchResponse = z.infer<typeof KnowledgeSearchResponseSchema>;\n","import { TACConfigData, TACConfigSchema, EnvironmentVariables } from '../types/index';\nimport type { CallEventKind } from '../types/index';\nimport { z } from 'zod';\n\n/**\n * TAC Configuration class with Python-like static factory methods\n *\n * Example usage:\n * ```typescript\n * // Load from environment variables\n * const config = TACConfig.fromEnv();\n *\n * // Or create manually\n * const config = new TACConfig({\n * accountSid: 'ACxxxx',\n * // ...\n * });\n * ```\n */\nexport class TACConfig {\n public readonly accountSid: string;\n public readonly authToken: string;\n public readonly apiKey: string;\n public readonly apiSecret: string;\n public readonly phoneNumber: string;\n public readonly rcsSenderId?: string;\n public readonly whatsappNumber?: string;\n public readonly memoryConfig: TACConfigData['memoryConfig'];\n public readonly conversationConfigurationId?: string;\n public readonly voicePublicDomain?: string;\n /** Path the voice WebSocket is served at (default '/ws'). */\n public readonly voiceWebsocketPath: string;\n /** Path the ConversationRelay action callback is served at (default '/conversation-relay-callback'). */\n public readonly voiceActionPath: string;\n /** Base path the call-event callbacks are served under (default '/twilio/call-events'). */\n public readonly voiceCallEventPath: string;\n public readonly cintelConfigurationId?: string;\n public readonly cintelSummaryOperatorSid?: string;\n /** Optional Twilio region subdomain for API routing (e.g. transforms base URLs to `https://{product}.{region}.twilio.com`) */\n public readonly region?: string;\n /**\n * Twilio Studio Flow SID for handoff. TAC derives both the digital-handoff\n * Studio Executions URL (`studio.twilio.com/v2/Flows/{SID}/Executions`) and\n * the voice `<Connect action>` webhook URL\n * (`webhooks.twilio.com/v1/Accounts/{AccountSid}/Flows/{SID}?Trigger=incomingCall`)\n * from this SID.\n */\n public readonly studioHandoffFlowSid?: string;\n constructor(data: TACConfigData | z.input<typeof TACConfigSchema>) {\n // Validate the configuration data\n const validatedConfig = TACConfigSchema.parse(data);\n\n // Assign all properties\n this.accountSid = validatedConfig.accountSid;\n this.authToken = validatedConfig.authToken;\n this.apiKey = validatedConfig.apiKey;\n this.apiSecret = validatedConfig.apiSecret;\n this.phoneNumber = validatedConfig.phoneNumber;\n if (validatedConfig.rcsSenderId) {\n this.rcsSenderId = validatedConfig.rcsSenderId;\n }\n if (validatedConfig.whatsappNumber) {\n this.whatsappNumber = validatedConfig.whatsappNumber;\n }\n // Assign the validated memory config directly; schema parsing already validates shape and applies defaults\n this.memoryConfig = validatedConfig.memoryConfig;\n if (validatedConfig.conversationConfigurationId) {\n this.conversationConfigurationId = validatedConfig.conversationConfigurationId;\n }\n if (validatedConfig.voicePublicDomain) {\n this.voicePublicDomain = validatedConfig.voicePublicDomain;\n }\n // voiceWebsocketPath / voiceActionPath / voiceCallEventPath always have schema defaults\n this.voiceWebsocketPath = validatedConfig.voiceWebsocketPath;\n this.voiceActionPath = validatedConfig.voiceActionPath;\n this.voiceCallEventPath = validatedConfig.voiceCallEventPath;\n if (validatedConfig.cintelConfigurationId) {\n this.cintelConfigurationId = validatedConfig.cintelConfigurationId;\n }\n if (validatedConfig.cintelSummaryOperatorSid) {\n this.cintelSummaryOperatorSid = validatedConfig.cintelSummaryOperatorSid;\n }\n if (validatedConfig.region) {\n this.region = validatedConfig.region;\n }\n if (validatedConfig.studioHandoffFlowSid) {\n this.studioHandoffFlowSid = validatedConfig.studioHandoffFlowSid;\n }\n }\n\n /**\n * Create TACConfig from environment variables.\n *\n * Required environment variables:\n * - TWILIO_ACCOUNT_SID: Twilio Account SID\n * - TWILIO_AUTH_TOKEN: Twilio Auth Token for API authentication\n * - TWILIO_API_KEY: Twilio API Key SID (starts with SK)\n * - TWILIO_API_SECRET: Twilio API Secret for API Key authentication\n * - TWILIO_PHONE_NUMBER: Phone number for voice and SMS channels\n *\n * Optional environment variables:\n * - TWILIO_WHATSAPP_NUMBER: WhatsApp number for WhatsApp channel (e.g., 'whatsapp:+1234567890')\n * - TWILIO_CONVERSATION_CONFIGURATION_ID: Conversation Orchestrator configuration ID (enables orchestrated mode)\n * - TWILIO_VOICE_PUBLIC_DOMAIN: Public domain for voice routes (required for voice; a port and/or base path are allowed, e.g., 'abc123.ngrok.app', 'example.ngrok.app:8080', or 'example.com/server1')\n * - TWILIO_VOICE_WEBSOCKET_PATH: Path for the voice WebSocket (default: /ws)\n * - TWILIO_VOICE_ACTION_PATH: Path for the ConversationRelay action callback (default: /conversation-relay-callback)\n * - TWILIO_VOICE_CALL_EVENT_PATH: Base path for the call-event callbacks — status, async AMD, recording (default: /twilio/call-events)\n * - TWILIO_REGION: Twilio region subdomain for API routing (e.g. transforms base URLs to `https://{product}.{region}.twilio.com`)\n * - TWILIO_STUDIO_HANDOFF_FLOW_SID: Studio Flow SID used by createStudioHandoffTool for human handoff\n * - TWILIO_RCS_SENDER_ID: RCS Sender ID for the RCS channel\n *\n * Memory Configuration (defaults defined in TwilioMemoryConfigSchema):\n * - TWILIO_MEMORY_PROFILE_TRAIT_GROUPS: Trait groups to include (comma-separated, e.g., \"Contact,Preferences\")\n * - TWILIO_MEMORY_OBSERVATIONS_LIMIT: Max observations in memory retrieval\n * - TWILIO_MEMORY_SUMMARIES_LIMIT: Max summaries in memory retrieval\n * - TWILIO_MEMORY_COMMUNICATIONS_LIMIT: Max communications in memory retrieval\n * - TWILIO_MEMORY_RELEVANCE_THRESHOLD: Min relevance score (0.0-1.0)\n * - TWILIO_MEMORY_PHONE_TRAIT_GROUP: Trait group that holds the phone identifier on new profiles (default \"Contact\")\n * - TWILIO_MEMORY_PHONE_TRAIT_FIELD: Trait field within phoneTraitGroup (default \"phone\")\n *\n * @throws Error if required environment variables are not set or invalid\n *\n * @example\n * ```typescript\n * // Ensure env vars are set before calling (e.g. via dotenv, Docker, CI, etc.)\n * const config = TACConfig.fromEnv();\n *\n * // Use in TAC initialization\n * const tac = new TAC({ config });\n * ```\n */\n public static fromEnv(): TACConfig {\n // Check for required environment variables\n const requiredVars = [\n { key: EnvironmentVariables.TWILIO_ACCOUNT_SID, name: 'TWILIO_ACCOUNT_SID' },\n { key: EnvironmentVariables.TWILIO_AUTH_TOKEN, name: 'TWILIO_AUTH_TOKEN' },\n { key: EnvironmentVariables.TWILIO_API_KEY, name: 'TWILIO_API_KEY' },\n { key: EnvironmentVariables.TWILIO_API_SECRET, name: 'TWILIO_API_SECRET' },\n { key: EnvironmentVariables.TWILIO_PHONE_NUMBER, name: 'TWILIO_PHONE_NUMBER' },\n ];\n\n // Throw error for missing required variables (like Python's KeyError)\n for (const { key, name } of requiredVars) {\n if (!process.env[key]) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n }\n\n // Parse memory configuration from environment variables\n const traitGroupsStr = process.env[EnvironmentVariables.TWILIO_MEMORY_PROFILE_TRAIT_GROUPS];\n // Parse trait groups, filtering out empty strings from malformed CSV (e.g., \"A,,B,\")\n // Treat empty/whitespace-only strings and delimiter-only inputs as undefined for consistency\n const trimmedTraitGroups = traitGroupsStr?.trim();\n const parsedTraitGroups =\n trimmedTraitGroups && trimmedTraitGroups.length > 0\n ? trimmedTraitGroups\n .split(',')\n .map(g => g.trim())\n .filter(g => g.length > 0)\n : undefined;\n const traitGroups =\n parsedTraitGroups && parsedTraitGroups.length > 0 ? parsedTraitGroups : undefined;\n\n // Helper to parse integer from env var with validation and bounds checking.\n // Returns undefined when the env var is not set, letting the Zod schema apply defaults.\n const parseIntEnv = (\n envVarName: string,\n value: string | undefined,\n min: number,\n max: number\n ): number | undefined => {\n if (!value) return undefined;\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n\n const parsed = Number(trimmed);\n if (!Number.isFinite(parsed)) {\n throw new Error(`Invalid ${envVarName}: expected an integer, got \"${value}\"`);\n }\n if (!Number.isInteger(parsed)) {\n throw new Error(`Invalid ${envVarName}: expected an integer, got \"${value}\"`);\n }\n if (parsed < min || parsed > max) {\n throw new Error(`Invalid ${envVarName}: must be between ${min} and ${max}, got ${parsed}`);\n }\n return parsed;\n };\n\n // Helper to parse float from env var with validation and bounds checking.\n // Returns undefined when the env var is not set, letting the Zod schema apply defaults.\n const parseFloatEnv = (\n envVarName: string,\n value: string | undefined,\n min: number,\n max: number\n ): number | undefined => {\n if (!value) return undefined;\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n\n const parsed = Number(trimmed);\n if (!Number.isFinite(parsed)) {\n throw new Error(`Invalid ${envVarName}: expected a number, got \"${value}\"`);\n }\n if (parsed < min || parsed > max) {\n throw new Error(`Invalid ${envVarName}: must be between ${min} and ${max}, got ${parsed}`);\n }\n return parsed;\n };\n\n const rawConfig = {\n accountSid: process.env[EnvironmentVariables.TWILIO_ACCOUNT_SID]!,\n authToken: process.env[EnvironmentVariables.TWILIO_AUTH_TOKEN]!,\n apiKey: process.env[EnvironmentVariables.TWILIO_API_KEY]!,\n apiSecret: process.env[EnvironmentVariables.TWILIO_API_SECRET]!,\n phoneNumber: process.env[EnvironmentVariables.TWILIO_PHONE_NUMBER]!,\n rcsSenderId: process.env[EnvironmentVariables.TWILIO_RCS_SENDER_ID],\n whatsappNumber: process.env[EnvironmentVariables.TWILIO_WHATSAPP_NUMBER] || undefined,\n memoryConfig: {\n traitGroups,\n observationsLimit: parseIntEnv(\n 'TWILIO_MEMORY_OBSERVATIONS_LIMIT',\n process.env[EnvironmentVariables.TWILIO_MEMORY_OBSERVATIONS_LIMIT],\n 0,\n 100\n ),\n summariesLimit: parseIntEnv(\n 'TWILIO_MEMORY_SUMMARIES_LIMIT',\n process.env[EnvironmentVariables.TWILIO_MEMORY_SUMMARIES_LIMIT],\n 0,\n 100\n ),\n communicationsLimit: parseIntEnv(\n 'TWILIO_MEMORY_COMMUNICATIONS_LIMIT',\n process.env[EnvironmentVariables.TWILIO_MEMORY_COMMUNICATIONS_LIMIT],\n 0,\n 100\n ),\n relevanceThreshold: parseFloatEnv(\n 'TWILIO_MEMORY_RELEVANCE_THRESHOLD',\n process.env[EnvironmentVariables.TWILIO_MEMORY_RELEVANCE_THRESHOLD],\n 0.0,\n 1.0\n ),\n phoneTraitGroup:\n process.env[EnvironmentVariables.TWILIO_MEMORY_PHONE_TRAIT_GROUP] || undefined,\n phoneTraitField:\n process.env[EnvironmentVariables.TWILIO_MEMORY_PHONE_TRAIT_FIELD] || undefined,\n },\n conversationConfigurationId:\n process.env[EnvironmentVariables.TWILIO_CONVERSATION_CONFIGURATION_ID] || undefined,\n voicePublicDomain: process.env[EnvironmentVariables.TWILIO_VOICE_PUBLIC_DOMAIN],\n voiceWebsocketPath:\n process.env[EnvironmentVariables.TWILIO_VOICE_WEBSOCKET_PATH] || undefined,\n voiceActionPath: process.env[EnvironmentVariables.TWILIO_VOICE_ACTION_PATH] || undefined,\n voiceCallEventPath:\n process.env[EnvironmentVariables.TWILIO_VOICE_CALL_EVENT_PATH] || undefined,\n cintelConfigurationId: process.env[EnvironmentVariables.TWILIO_TAC_CI_CONFIGURATION_ID],\n cintelSummaryOperatorSid:\n process.env[EnvironmentVariables.TWILIO_TAC_CI_SUMMARY_OPERATOR_SID],\n region: process.env[EnvironmentVariables.TWILIO_REGION],\n studioHandoffFlowSid: process.env[EnvironmentVariables.TWILIO_STUDIO_HANDOFF_FLOW_SID],\n };\n\n return new TACConfig(rawConfig);\n }\n\n /**\n * Path a call-event callback is served at.\n *\n * Single source of truth: the voice channel builds callback URLs from this\n * and TACServer registers routes at it, so the two can't drift.\n */\n public callEventPath(kind: CallEventKind): string {\n return `${this.voiceCallEventPath.replace(/\\/+$/, '')}/${kind}`;\n }\n\n /**\n * Public URL for a call-event callback, or `undefined` without a public domain.\n */\n public callEventUrl(kind: CallEventKind): string | undefined {\n if (!this.voicePublicDomain) {\n return undefined;\n }\n return `https://${this.voicePublicDomain}${this.callEventPath(kind)}`;\n }\n\n /**\n * Whether Conversation Orchestrator is configured.\n * Returns false in voice-only mode (no conversationConfigurationId).\n *\n * @internal\n */\n public isOrchestratorEnabled(): boolean {\n return this.conversationConfigurationId !== undefined;\n }\n\n /**\n * Get basic auth credentials for Twilio APIs\n */\n public getBasicAuthCredentials(): { username: string; password: string } {\n return {\n username: this.accountSid,\n password: this.authToken,\n };\n }\n}\n","function scrubPhoneMatch(match: string): string {\n const digits = match.replace(/[\\s\\-()]/g, '');\n if (digits.length < 8) return '***';\n return `${digits.slice(0, 2)}***${digits.slice(-4)}`;\n}\n\nfunction scrubEmailMatch(match: string): string {\n const atIndex = match.indexOf('@');\n if (atIndex <= 0) return '***';\n return `${match[0]}***${match.slice(atIndex)}`;\n}\n\nexport function scrubPii(value: string): string {\n // Fresh RegExp each call — avoids lastIndex state bugs from the g flag\n const phoneRe = /\\+\\d[\\d\\s()-]{6,}\\d/g;\n const emailRe = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g;\n return value.replace(phoneRe, scrubPhoneMatch).replace(emailRe, scrubEmailMatch);\n}\n\nexport function scrubObject(obj: unknown, seen?: WeakSet<object>): unknown {\n if (typeof obj === 'string') return scrubPii(obj);\n if (obj === null || typeof obj !== 'object') return obj;\n\n const visited = seen ?? new WeakSet<object>();\n if (visited.has(obj)) return '[Circular]';\n visited.add(obj);\n\n if (obj instanceof Error) {\n const record = obj as unknown as Record<string, unknown>;\n const scrubbed = Object.create(Object.getPrototypeOf(obj) as object) as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n scrubbed[key] = scrubObject(record[key], visited);\n }\n const result = scrubbed as unknown as Error;\n if (!Object.prototype.hasOwnProperty.call(scrubbed, 'message')) {\n result.message = scrubPii(obj.message);\n }\n if (!Object.prototype.hasOwnProperty.call(scrubbed, 'name')) {\n result.name = obj.name;\n }\n if (obj.stack && !Object.prototype.hasOwnProperty.call(scrubbed, 'stack')) {\n result.stack = scrubPii(obj.stack);\n }\n return result;\n }\n\n if (Array.isArray(obj)) return obj.map(item => scrubObject(item, visited));\n\n // Only deep-scrub plain objects; leave class instances (Date, URL, Map, etc.) unchanged\n if (Object.getPrototypeOf(obj) !== Object.prototype) return obj;\n\n const record = obj as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(record)) {\n out[key] = scrubObject(record[key], visited);\n }\n return out;\n}\n\nexport function maskPhone(phone: string): string {\n if (!phone || !phone.startsWith('+') || phone.length < 8) {\n return '***';\n }\n return `${phone.slice(0, 2)}***${phone.slice(-4)}`;\n}\n\nexport function maskEmail(email: string): string {\n const atIndex = email.indexOf('@');\n if (atIndex <= 0) {\n return '***';\n }\n return `${email[0]}***${email.slice(atIndex)}`;\n}\n\nexport function maskAddress(address: string): string {\n if (!address) return '***';\n if (address.includes('@')) return maskEmail(address);\n if (address.startsWith('+')) return maskPhone(address);\n if (address.length <= 1) return '***';\n return `${address[0]}***`;\n}\n\n/**\n * Mask `<Parameter value=\"...\">` contents in TwiML, keeping the names.\n *\n * `<Parameter>` children carry whatever the developer put in\n * `customParameters` — profile IDs, caller names. Names stay because knowing\n * which parameters were sent is the point of logging the TwiML.\n *\n * Handles either quote style. TAC's own TwiML comes from the Twilio SDK, which\n * always double-quotes, but this takes a plain string and shouldn't depend on\n * that to stay safe.\n */\nexport function redactTwimlParameters(twiml: string | undefined | null): string {\n if (!twiml) return '';\n // Fresh RegExp each call — avoids lastIndex state bugs from the g flag.\n const parameterValueRe = /(<Parameter\\b[^>]*?\\bvalue=)([\"'])(.*?)\\2/gi;\n return twiml.replace(parameterValueRe, (_match, prefix: string, quote: string) => {\n return `${prefix}${quote}***${quote}`;\n });\n}\n","import pino from 'pino';\nimport { scrubObject } from '../util/log-redaction';\n\n/**\n * Logger type that can be either Pino logger or Fastify's logger\n */\nexport type Logger = pino.Logger;\n\nfunction piiLogMethod(this: pino.Logger, args: unknown[], method: pino.LogFn): void {\n const scrubbed = args.map(arg =>\n typeof arg === 'string'\n ? scrubObject(arg)\n : typeof arg === 'object' && arg !== null\n ? scrubObject(arg)\n : arg\n );\n return method.apply(this, scrubbed as Parameters<pino.LogFn>);\n}\n\nexport function createLogger(options?: { level?: string; name?: string }): Logger {\n const level = options?.level || process.env.TWILIO_LOG_LEVEL || 'info';\n\n return pino({\n level,\n ...(options?.name && { name: options.name }),\n hooks: { logMethod: piiLogMethod },\n });\n}\n","{\n \"name\": \"twilio-agent-connect\",\n \"version\": \"2.3.0\",\n \"description\": \"Twilio Agent Connect - A TypeScript framework for building intelligent agents\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"clean\": \"rimraf dist packages/*/dist\",\n \"test\": \"vitest --run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest --coverage\",\n \"lint\": \"eslint packages/*/src/**/*.ts src/**/*.ts\",\n \"lint:fix\": \"eslint packages/*/src/**/*.ts src/**/*.ts --fix\",\n \"format\": \"prettier --write packages/*/src/**/*.ts src/**/*.ts getting_started/**/*.ts\",\n \"format:check\": \"prettier --check packages/*/src/**/*.ts src/**/*.ts getting_started/**/*.ts\",\n \"typecheck\": \"tsc --noEmit\",\n \"docs\": \"typedoc\",\n \"docs:watch\": \"typedoc --watch\",\n \"example:getting-started\": \"cd getting_started/examples/openai && npm install && npm run dev\",\n \"example:chat\": \"cd getting_started/examples/chat && npm install && npm run dev\"\n },\n \"keywords\": [\n \"twilio\",\n \"ai\",\n \"agents\",\n \"framework\",\n \"typescript\"\n ],\n \"author\": \"Twilio\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/twilio/twilio-agent-connect-typescript.git\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.0.0\",\n \"@shipgirl/typedoc-plugin-versions\": \"^0.3.2\",\n \"@types/node\": \"^22.0.0\",\n \"@types/ws\": \"^8.18.1\",\n \"@vitest/coverage-v8\": \"^4.1.2\",\n \"axios-mock-adapter\": \"^2.1.0\",\n \"eslint\": \"^9.0.0\",\n \"globals\": \"^15.0.0\",\n \"prettier\": \"^3.0.0\",\n \"rimraf\": \"^5.0.0\",\n \"tsup\": \"^8.5.1\",\n \"typedoc\": \"^0.28.20\",\n \"typedoc-material-theme\": \"^1.4.1\",\n \"typescript\": \"^5.0.0\",\n \"typescript-eslint\": \"^8.0.0\",\n \"vitest\": \"^4.1.2\"\n },\n \"dependencies\": {\n \"@fastify/formbody\": \"^8.0.2\",\n \"@fastify/websocket\": \"^11.2.0\",\n \"axios\": \"^1.15.2\",\n \"axios-retry\": \"^4.5.0\",\n \"dotenv\": \"^16.4.7\",\n \"fastify\": \"^5.8.5\",\n \"fastify-graceful-shutdown\": \"^5.0.0\",\n \"pino\": \"^9.0.0\",\n \"twilio\": \"^5.10.7\",\n \"ws\": \"^8.19.0\",\n \"zod\": \"^4.0.0\"\n },\n \"peerDependencies\": {\n \"@openai/agents\": \"^0.8.0\"\n },\n \"peerDependenciesMeta\": {\n \"@openai/agents\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=22.13.0\",\n \"npm\": \">=9.0.0\"\n }\n}\n","import { Logger, createLogger } from '../lib/logger';\nimport { TACConfig } from '../lib/config';\nimport packageJson from '../../../../package.json' with { type: 'json' };\nimport axios, { AxiosInstance } from 'axios';\nimport axiosRetry from 'axios-retry';\n\nfunction buildUserAgent(): string {\n return `twilio-agent-connect-typescript/${packageJson.version}`;\n}\n\n/**\n * Base HTTP client for Twilio API services\n *\n * Features:\n * - Automatic Basic Auth using Twilio API credentials\n * - User-Agent header injection\n * - 30-second request timeout\n * - HTTP redirect following (up to 5 redirects) with auth preservation\n * - Automatic retry (up to 3 retries / 4 total attempts with exponential backoff)\n * - Error logging for failed requests\n * - Automatic JSON serialization/deserialization\n */\nexport abstract class BaseClient {\n protected readonly baseUrl: string;\n protected readonly logger: Logger;\n protected readonly axiosInstance: AxiosInstance;\n\n constructor(baseUrl: string, config: TACConfig, logger?: Logger) {\n this.baseUrl = baseUrl;\n this.logger = logger || createLogger({ name: this.constructor.name });\n\n // Create Authorization header for Basic Auth\n const authHeader =\n 'Basic ' + Buffer.from(`${config.apiKey}:${config.apiSecret}`).toString('base64');\n\n // Extract origin from baseUrl for same-origin check\n const baseOrigin = new URL(baseUrl).origin;\n\n this.axiosInstance = axios.create({\n baseURL: baseUrl,\n timeout: 30000,\n maxRedirects: 5,\n headers: {\n 'User-Agent': buildUserAgent(),\n Authorization: authHeader,\n },\n beforeRedirect: (options, _responseDetails) => {\n // Preserve auth header for same-origin redirects only (prevents credential leaks)\n const redirectUrl = new URL(\n String(options.path || ''),\n `${String(options.protocol)}//${String(options.host)}`\n );\n if (redirectUrl.origin === baseOrigin && options.headers) {\n (options.headers as Record<string, string>).Authorization = authHeader;\n }\n },\n });\n\n axiosRetry(this.axiosInstance, {\n retries: 3,\n retryDelay: retryCount => axiosRetry.exponentialDelay(retryCount),\n retryCondition: error => {\n // Retry network/no-response errors for any method, and retry 5xx/429 responses only for idempotent methods\n // (which helps prevent duplicate side effects on non-idempotent requests such as POST)\n return axiosRetry.isNetworkOrIdempotentRequestError(error);\n },\n });\n\n // Response interceptor for error logging\n this.axiosInstance.interceptors.response.use(\n response => response,\n error => {\n if (axios.isAxiosError(error)) {\n const status = error.response?.status;\n const logContext = {\n error: error.message,\n method: error.config?.method,\n url: error.config?.url,\n status,\n };\n // Log 4xx as warn (client errors, may be expected/handled)\n // Log 5xx/network as error (server/infrastructure failures)\n if (status !== undefined && status >= 400 && status < 500) {\n this.logger.warn(logContext, 'HTTP request client error');\n } else {\n this.logger.error(logContext, 'HTTP request error');\n }\n }\n throw error;\n }\n );\n }\n\n /**\n * Make an HTTP request with automatic header injection and error handling\n *\n * @param url - The URL path (relative to baseURL)\n * @param method - HTTP method (GET, POST, etc.)\n * @param data - Optional request body (will be automatically serialized to JSON)\n * @param params - Optional query string parameters\n * @returns Promise resolving to the response data (already parsed from JSON)\n * @throws Error on timeout, HTTP errors, or network failures\n */\n protected async makeRequest<TResponse = unknown>(\n url: string,\n method: string,\n data?: unknown,\n params?: Record<string, string>\n ): Promise<TResponse> {\n const response = await this.axiosInstance.request<TResponse>({\n url,\n method,\n data,\n params,\n });\n\n return response.data;\n }\n}\n","import { z } from 'zod';\nimport {\n MemoryRetrievalRequest,\n MemoryRetrievalRequestSchema,\n MemoryRetrievalResponse,\n EMPTY_MEMORY_RESPONSE,\n ObservationInfoSchema,\n SummaryInfoSchema,\n MemoryCommunicationSchema,\n ProfileLookupResponse,\n ProfileLookupResponseSchema,\n ProfileResponse,\n ProfileResponseSchema,\n ObservationCreateRequest,\n CreateObservationsRequest,\n CreateObservationResponse,\n CreateObservationResponseSchema,\n CreateConversationSummariesResponse,\n CreateConversationSummariesResponseSchema,\n} from '../types';\nimport { TACConfig } from '../lib/config';\nimport { Logger } from '../lib/logger';\nimport { BaseClient } from './base';\n\n/**\n * Memory client for interacting with Twilio Memory Service\n */\nexport class MemoryClient extends BaseClient {\n private readonly storeId: string;\n\n constructor(config: TACConfig, storeId: string, logger?: Logger) {\n const baseUrl = config.region\n ? `https://memory.${config.region}.twilio.com`\n : 'https://memory.twilio.com';\n super(baseUrl, config, logger);\n this.storeId = storeId;\n }\n\n /**\n * Get the store ID this client is configured for\n */\n public getStoreId(): string {\n return this.storeId;\n }\n\n /**\n * Retrieve memories for a specific profile\n *\n * @param profileId - The profile ID to retrieve memories for\n * @param request - Optional request parameters for filtering results\n * @returns Promise containing memory retrieval response\n */\n public async retrieveMemories(\n profileId: string,\n request: Partial<MemoryRetrievalRequest> = {}\n ): Promise<MemoryRetrievalResponse> {\n try {\n const url = `/v1/Stores/${this.storeId}/Profiles/${profileId}/Recall`;\n\n this.logger.debug(\n {\n memory_store_id: this.storeId,\n profile_id: profileId,\n request,\n },\n 'Retrieving memories'\n );\n\n // Validate and apply defaults through schema\n const validatedRequest = MemoryRetrievalRequestSchema.parse(request);\n\n // Serialize request to Memory API wire format (camelCase)\n const requestBody = {\n conversationId: validatedRequest.conversationId,\n query: validatedRequest.query,\n beginDate: validatedRequest.beginDate,\n endDate: validatedRequest.endDate,\n observationsLimit: validatedRequest.observationsLimit,\n summariesLimit: validatedRequest.summariesLimit,\n communicationsLimit: validatedRequest.communicationsLimit,\n relevanceThreshold: validatedRequest.relevanceThreshold,\n };\n\n // Remove undefined values\n const cleanedBody = Object.fromEntries(\n Object.entries(requestBody).filter(([_, value]) => value !== undefined)\n );\n\n const data = await this.makeRequest<MemoryRetrievalResponse>(url, 'POST', cleanedBody);\n\n this.logger.debug(\n {\n memory_store_id: this.storeId,\n profile_id: profileId,\n },\n 'Raw memory response received'\n );\n\n if (data === null || typeof data !== 'object') {\n this.logger.warn(\n {\n profile_id: profileId,\n memory_store_id: this.storeId,\n },\n 'Invalid memory response format'\n );\n return EMPTY_MEMORY_RESPONSE;\n }\n\n // Parse each item independently so a single malformed entry (e.g. an\n // unrecognized enum value) doesn't discard the entire response.\n const response = data as Record<string, unknown>;\n const observations = this.parseItems(\n response.observations,\n ObservationInfoSchema,\n 'observation',\n profileId\n );\n const summaries = this.parseItems(\n response.summaries,\n SummaryInfoSchema,\n 'summary',\n profileId\n );\n const communications = this.parseItems(\n response.communications,\n MemoryCommunicationSchema,\n 'communication',\n profileId\n );\n\n this.logger.debug(\n {\n memory_store_id: this.storeId,\n profile_id: profileId,\n observation_count: observations.length,\n summary_count: summaries.length,\n communication_count: communications.length,\n // Server-side query time; dominates /Recall when expansion runs.\n query_time_ms: (response.meta as { queryTime?: number } | undefined)?.queryTime,\n },\n 'Memory retrieval succeeded'\n );\n\n return { observations, summaries, communications };\n } catch (error) {\n this.logger.warn(\n {\n error: error instanceof Error ? error.message : String(error),\n profile_id: profileId,\n memory_store_id: this.storeId,\n },\n 'Memory retrieval error'\n );\n return EMPTY_MEMORY_RESPONSE;\n }\n }\n\n /** Cap on per-item validation warnings logged per response, to avoid flooding logs. */\n private static readonly MAX_INVALID_ITEM_LOGS = 10;\n\n /**\n * Validate an array of memory items one at a time, dropping (and logging)\n * any that fail validation while keeping the rest.\n *\n * Per-item warnings are capped at {@link MemoryClient.MAX_INVALID_ITEM_LOGS}\n * and followed by a single summary warning with the total `invalid_count`.\n */\n private parseItems<T>(\n value: unknown,\n schema: z.ZodType<T, unknown>,\n itemType: string,\n profileId: string\n ): T[] {\n if (value === undefined) {\n return [];\n }\n\n if (!Array.isArray(value)) {\n this.logger.warn(\n {\n profile_id: profileId,\n memory_store_id: this.storeId,\n item_type: itemType,\n received_type: typeof value,\n },\n 'Expected an array of memory items but received a non-array value'\n );\n return [];\n }\n\n const parsed: T[] = [];\n let invalidCount = 0;\n for (const [index, item] of value.entries()) {\n const result = schema.safeParse(item);\n if (result.success) {\n parsed.push(result.data);\n continue;\n }\n\n invalidCount += 1;\n if (invalidCount <= MemoryClient.MAX_INVALID_ITEM_LOGS) {\n this.logger.warn(\n {\n profile_id: profileId,\n memory_store_id: this.storeId,\n item_type: itemType,\n item_index: index,\n validation_errors: result.error.issues,\n },\n 'Dropping invalid memory item'\n );\n }\n }\n\n if (invalidCount > 0) {\n this.logger.warn(\n {\n profile_id: profileId,\n memory_store_id: this.storeId,\n item_type: itemType,\n invalid_count: invalidCount,\n total_count: value.length,\n },\n 'Dropped invalid memory items'\n );\n }\n\n return parsed;\n }\n\n /**\n * Find profiles that contain a specific identifier value\n *\n * @param idType - Identifier type (e.g., 'phone', 'email')\n * @param value - Raw value captured for the identifier\n * @returns Promise containing profile lookup response with normalized value and matching profile IDs\n */\n public async lookupProfile(idType: string, value: string): Promise<ProfileLookupResponse> {\n const url = `/v1/Stores/${this.storeId}/Profiles/Lookup`;\n\n const requestBody = {\n idType,\n value,\n };\n\n try {\n const data = await this.makeRequest<ProfileLookupResponse>(url, 'POST', requestBody);\n return ProfileLookupResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to lookup profile: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create a profile via identity resolution (upsert).\n *\n * Conversation Memory runs identity resolution on the submitted traits: if an identifier\n * match is found, the existing canonical profile ID is returned; otherwise a\n * new profile is minted. The body must contain at least one\n * trait-promoted-to-identifier per the store's identity resolution settings,\n * else resolution fails with 400.\n *\n * The write is queued (202 Accepted) — the canonical profile ID is returned\n * synchronously in the response body, but downstream traits may not be fully\n * persisted immediately.\n *\n * @param traits - Trait-group → field → value mapping (e.g. `{\"Contact\": {\"phone\": \"+13175551234\"}}`)\n * @returns Canonical profile ID (`mem_profile_…`)\n * @throws Error if the API request fails or the response is missing an `id` field\n */\n public async createProfile(traits: Record<string, Record<string, unknown>>): Promise<string> {\n const url = `/v1/Stores/${this.storeId}/Profiles`;\n const requestBody = { traits };\n\n let data: unknown;\n try {\n data = await this.makeRequest<unknown>(url, 'POST', requestBody);\n } catch (error) {\n throw new Error(\n `Failed to create profile: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n\n const profileId =\n data && typeof data === 'object' && 'id' in data ? (data as { id: unknown }).id : undefined;\n if (typeof profileId !== 'string') {\n throw new Error(`CreateProfile response missing 'id' field: ${JSON.stringify(data)}`);\n }\n return profileId;\n }\n\n /**\n * Fetch profile information with traits\n *\n * @param profileId - The profile ID to fetch\n * @param traitGroups - Optional list of trait group names to include\n * @returns Promise containing profile response with ID, created timestamp, and traits\n */\n public async getProfile(profileId: string, traitGroups?: string[]): Promise<ProfileResponse> {\n const url = `/v1/Stores/${this.storeId}/Profiles/${profileId}`;\n\n const params: Record<string, string> = {};\n if (traitGroups && traitGroups.length > 0) {\n params.traitGroups = traitGroups.join(',');\n }\n\n try {\n const data = await this.makeRequest<ProfileResponse>(\n url,\n 'GET',\n undefined,\n Object.keys(params).length > 0 ? params : undefined\n );\n return ProfileResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to get profile: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create an observation for a profile.\n *\n * The Memory API Observations endpoint is a batch create: the observation is\n * wrapped in an `observations` array and `occurredAt` is required, so it\n * defaults to the current time (ISO 8601) when omitted or blank.\n *\n * @param profileId - The profile ID to create the observation for\n * @param content - The observation content\n * @param source - Source of the observation (default: 'conversation-intelligence')\n * @param conversationIds - Optional array of conversation IDs associated with this observation\n * @param occurredAt - Timestamp when the observation occurred (ISO 8601); defaults to now when omitted or blank\n * @returns Promise containing the API confirmation message\n */\n public async createObservation(\n profileId: string,\n content: string,\n source: string = 'conversation-intelligence',\n conversationIds?: string[],\n occurredAt?: string\n ): Promise<CreateObservationResponse> {\n const url = `/v1/Stores/${this.storeId}/Profiles/${profileId}/Observations`;\n\n const observation: ObservationCreateRequest = {\n content,\n source,\n occurredAt: occurredAt && occurredAt.trim() ? occurredAt : new Date().toISOString(),\n };\n\n if (conversationIds && conversationIds.length > 0) {\n observation.conversationIds = conversationIds;\n }\n\n const requestBody: CreateObservationsRequest = { observations: [observation] };\n\n try {\n const data = await this.makeRequest<CreateObservationResponse>(url, 'POST', requestBody);\n return CreateObservationResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to create observation: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create conversation summaries for a profile\n *\n * @param profileId - The profile ID to create summaries for\n * @param summaries - Array of summary items to create\n * @returns Promise containing a success message for the created conversation summaries\n */\n public async createConversationSummaries(\n profileId: string,\n summaries: Array<{\n content: string;\n conversationId: string;\n occurredAt: string;\n source?: string;\n }>\n ): Promise<CreateConversationSummariesResponse> {\n const url = `/v1/Stores/${this.storeId}/Profiles/${profileId}/ConversationSummaries`;\n\n const requestBody = {\n summaries: summaries.map(s => ({\n content: s.content,\n conversationId: s.conversationId,\n occurredAt: s.occurredAt,\n source: s.source ?? 'conversation-intelligence',\n })),\n };\n\n try {\n const data = await this.makeRequest<CreateConversationSummariesResponse>(\n url,\n 'POST',\n requestBody\n );\n return CreateConversationSummariesResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to create conversation summaries: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n}\n","import {\n ActionResponse,\n ActionResponseSchema,\n Communication,\n ConversationResponse,\n ConversationResponseSchema,\n ConversationAddress,\n ConversationParticipant,\n ConversationParticipantSchema,\n SendMessageActionRequest,\n ConversationConfiguration,\n ConversationConfigurationSchema,\n ListCommunicationsResponse,\n ListCommunicationsResponseSchema,\n ListParticipantsResponse,\n ListParticipantsResponseSchema,\n ListConversationsResponse,\n ListConversationsResponseSchema,\n} from '../types';\nimport axios from 'axios';\nimport { TACConfig } from '../lib/config';\nimport { Logger } from '../lib/logger';\nimport { BaseClient } from './base';\n\n/**\n * Conversation client for interacting with Twilio Conversations Service\n */\nexport class ConversationClient extends BaseClient {\n private readonly conversationConfigurationId: string;\n\n constructor(config: TACConfig, logger?: Logger) {\n const baseUrl = config.region\n ? `https://conversations.${config.region}.twilio.com`\n : 'https://conversations.twilio.com';\n super(baseUrl, config, logger);\n if (!config.conversationConfigurationId) {\n throw new Error('conversationConfigurationId is required to create ConversationClient');\n }\n this.conversationConfigurationId = config.conversationConfigurationId;\n }\n\n /**\n * Create an action on a conversation via the Conversation Orchestrator Actions API.\n *\n * Currently supports SEND_MESSAGE actions. Returns 202 Accepted; the action is\n * processed asynchronously and delivered via COMMUNICATION_CREATED webhook.\n *\n * @param conversationId - The conversation ID\n * @param request - The action request ({type, payload})\n * @returns Promise containing the ActionResponse\n */\n public async createAction(\n conversationId: string,\n request: SendMessageActionRequest\n ): Promise<ActionResponse> {\n const url = `/v2/Conversations/${conversationId}/Actions`;\n\n try {\n const data = await this.makeRequest<ActionResponse>(url, 'POST', request);\n return ActionResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to create action: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * List communications for a conversation\n *\n * @param conversationId - The conversation ID\n * @returns Promise containing array of communications\n */\n public async listCommunications(conversationId: string): Promise<Communication[]> {\n const url = `/v2/Conversations/${conversationId}/Communications`;\n\n try {\n const data = await this.makeRequest<ListCommunicationsResponse>(url, 'GET');\n const validated = ListCommunicationsResponseSchema.parse(data);\n return validated.communications;\n } catch (error) {\n throw new Error(\n `Failed to list communications: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create a new conversation, optionally with inline participants.\n *\n * When participants are provided, CO creates them atomically with the\n * conversation. If an active conversation with the same participant\n * addresses already exists (respecting the configuration's group-by\n * rules), CO returns 409 with a pointer to the existing conversation.\n */\n public async createConversation(options?: {\n name?: string;\n participants?: Array<{\n type: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT';\n addresses: ConversationAddress[];\n }>;\n }): Promise<ConversationResponse> {\n const url = `/v2/Conversations`;\n\n const requestBody: Record<string, unknown> = {\n configurationId: this.conversationConfigurationId,\n };\n\n if (options?.name) {\n requestBody.name = options.name;\n }\n\n if (options?.participants) {\n requestBody.participants = options.participants;\n }\n\n try {\n const data = await this.makeRequest<ConversationResponse>(url, 'POST', requestBody);\n return ConversationResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to create conversation: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Create a conversation with inline participants, reusing an existing active\n * conversation if CO returns 409 (group-by dedup).\n *\n * On 409 CO returns the existing conversation ID in the\n * X-Conflicting-Resource-Id response header.\n */\n public async createOrReuseConversation(\n participants: Array<{\n type: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT';\n addresses: ConversationAddress[];\n }>\n ): Promise<{ conversation: { id: string }; reused: boolean }> {\n try {\n const conversation = await this.createConversation({ participants });\n return { conversation, reused: false };\n } catch (error) {\n const existingId = this.extractConversationIdFrom409(error);\n if (existingId) {\n this.logger.info(\n { conversation_id: existingId },\n 'Reusing existing active conversation (409 dedup)'\n );\n return { conversation: { id: existingId }, reused: true };\n }\n throw error;\n }\n }\n\n /**\n * Extract conversation ID from a 409 response's X-Conflicting-Resource-Id header.\n */\n private extractConversationIdFrom409(error: unknown): string | null {\n // Unwrap: createConversation wraps the axios error in a generic Error\n const cause = error instanceof Error ? (error.cause ?? error) : error;\n if (!axios.isAxiosError(cause) || cause.response?.status !== 409) {\n return null;\n }\n\n const headers = cause.response.headers as Record<string, string> | undefined;\n const conflictId = headers?.['x-conflicting-resource-id'];\n return typeof conflictId === 'string' && conflictId.length > 0 ? conflictId : null;\n }\n\n /**\n * Add a participant to a conversation.\n *\n * @param conversationId - The conversation ID\n * @param addresses - Array of participant addresses\n * @param participantType - Type of participant (CUSTOMER, AI_AGENT, HUMAN_AGENT, AGENT)\n * @returns Promise containing participant response\n */\n public async addParticipant(\n conversationId: string,\n addresses: ConversationAddress[],\n participantType: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT' | 'AGENT'\n ): Promise<ConversationParticipant> {\n const url = `/v2/Conversations/${conversationId}/Participants`;\n\n const requestBody = {\n type: participantType,\n addresses,\n };\n\n try {\n const data = await this.makeRequest<ConversationParticipant>(url, 'POST', requestBody);\n return ConversationParticipantSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to add participant: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Replace an existing participant.\n *\n * PUT is a full resource replacement per the Conversation Orchestrator spec —\n * any field omitted from the body is cleared on the server. Callers must pass\n * the current `addresses` (and `name` if set) to preserve them.\n *\n * @param conversationId - Conversation ID containing the participant\n * @param participantId - Participant ID to update\n * @param participantType - New participant type\n * @param addresses - Current participant addresses (required to avoid wiping)\n * @param options.name - Current participant display name (optional)\n * @param options.profileId - Conversation Memory profile ID to attach (optional)\n * @returns Promise containing the updated participant\n */\n public async updateParticipant(\n conversationId: string,\n participantId: string,\n participantType: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT' | 'AGENT',\n addresses: ConversationAddress[],\n options?: { name?: string; profileId?: string }\n ): Promise<ConversationParticipant> {\n const url = `/v2/Conversations/${conversationId}/Participants/${participantId}`;\n\n const requestBody: Record<string, unknown> = {\n type: participantType,\n addresses,\n };\n if (options?.name !== undefined) {\n requestBody.name = options.name;\n }\n if (options?.profileId !== undefined) {\n requestBody.profileId = options.profileId;\n }\n\n try {\n const data = await this.makeRequest<ConversationParticipant>(url, 'PUT', requestBody);\n return ConversationParticipantSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to update participant: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * List participants in a conversation\n *\n * @param conversationId - The conversation ID\n * @returns Promise containing array of participants\n */\n public async listParticipants(conversationId: string): Promise<ConversationParticipant[]> {\n const url = `/v2/Conversations/${conversationId}/Participants`;\n\n try {\n const data = await this.makeRequest<ListParticipantsResponse>(url, 'GET');\n const validated = ListParticipantsResponseSchema.parse(data);\n return validated.participants;\n } catch (error) {\n throw new Error(\n `Failed to list participants: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * List conversations with optional filters\n *\n * @param filters - Optional filters (channelId, status)\n * @returns Promise containing array of conversations\n */\n public async listConversations(filters?: {\n channelId?: string;\n status?: string[];\n }): Promise<ConversationResponse[]> {\n const url = `/v2/Conversations`;\n\n const params: Record<string, string> = {};\n if (filters?.channelId) {\n params.channelId = filters.channelId;\n }\n if (filters?.status && filters.status.length > 0) {\n params.status = filters.status.join(',');\n }\n\n try {\n const data = await this.makeRequest<ListConversationsResponse>(\n url,\n 'GET',\n undefined,\n Object.keys(params).length > 0 ? params : undefined\n );\n const validated = ListConversationsResponseSchema.parse(data);\n return validated.conversations;\n } catch (error) {\n throw new Error(\n `Failed to list conversations: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Clear statusCallbacks on a conversation's instance configuration.\n *\n * This stops the conversation from sending webhook events to TAC,\n * which is needed during handoff so the receiving system can take over.\n *\n * @param conversationId - The conversation ID to update\n */\n public async clearStatusCallbacks(conversationId: string): Promise<void> {\n const url = `/v2/Conversations/${conversationId}`;\n\n try {\n await this.makeRequest<unknown>(url, 'PATCH', {\n configuration: { statusCallbacks: [] },\n });\n } catch (error) {\n throw new Error(\n `Failed to clear status callbacks: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Update conversation status\n *\n * @param conversationId - The conversation ID\n * @param status - New status (ACTIVE, INACTIVE, CLOSED)\n * @returns Promise containing updated conversation\n */\n public async updateConversation(\n conversationId: string,\n status: 'ACTIVE' | 'INACTIVE' | 'CLOSED'\n ): Promise<ConversationResponse> {\n const url = `/v2/Conversations/${conversationId}`;\n\n const requestBody = { status };\n\n try {\n const data = await this.makeRequest<ConversationResponse>(url, 'PUT', requestBody);\n return ConversationResponseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to update conversation: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Retrieve the details for a single configuration\n *\n * @param configurationId - The configuration ID to retrieve\n * @returns Promise containing configuration details\n */\n public async getConfiguration(configurationId: string): Promise<ConversationConfiguration> {\n const url = `/v2/ControlPlane/Configurations/${configurationId}`;\n\n try {\n const data = await this.makeRequest<ConversationConfiguration>(url, 'GET');\n return ConversationConfigurationSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to get configuration: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n}\n","import {\n KnowledgeBase,\n KnowledgeBaseSchema,\n KnowledgeChunkResult,\n KnowledgeSearchResponse,\n KnowledgeSearchResponseSchema,\n} from '../types';\nimport { TACConfig } from '../lib/config';\nimport { Logger } from '../lib/logger';\nimport { BaseClient } from './base';\n\n/**\n * Knowledge client for interacting with Twilio Knowledge Service\n */\nexport class KnowledgeClient extends BaseClient {\n constructor(config: TACConfig, logger?: Logger) {\n const baseUrl = config.region\n ? `https://knowledge.${config.region}.twilio.com`\n : 'https://knowledge.twilio.com';\n super(baseUrl, config, logger);\n }\n\n /**\n * Get knowledge base metadata\n *\n * @param knowledgeBaseId - The knowledge base ID (format: know_knowledgebase_*)\n * @returns Promise containing knowledge base metadata\n */\n public async getKnowledgeBase(knowledgeBaseId: string): Promise<KnowledgeBase> {\n const url = `/v2/ControlPlane/KnowledgeBases/${knowledgeBaseId}`;\n\n try {\n const data = await this.makeRequest<KnowledgeBase>(url, 'GET');\n return KnowledgeBaseSchema.parse(data);\n } catch (error) {\n throw new Error(\n `Failed to get knowledge base: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n\n /**\n * Search knowledge base for relevant content\n *\n * @param knowledgeBaseId - The knowledge base ID (format: know_knowledgebase_*)\n * @param query - Search query (max 2048 characters)\n * @param topK - Maximum number of results to return (default: 5, max: 20)\n * @param knowledgeIds - Optional list of knowledge IDs to filter results\n * @returns Promise containing array of search result chunks\n */\n public async searchKnowledgeBase(\n knowledgeBaseId: string,\n query: string,\n topK: number = 5,\n knowledgeIds?: string[]\n ): Promise<KnowledgeChunkResult[]> {\n const url = `/v2/KnowledgeBases/${knowledgeBaseId}/Search`;\n\n const requestBody: Record<string, unknown> = {\n query,\n top: Math.min(Math.max(topK, 1), 20), // Clamp to 1-20\n };\n\n if (knowledgeIds && knowledgeIds.length > 0) {\n requestBody.knowledgeIds = knowledgeIds;\n }\n\n try {\n const data = await this.makeRequest<KnowledgeSearchResponse>(url, 'POST', requestBody);\n const validated = KnowledgeSearchResponseSchema.parse(data);\n return validated.chunks;\n } catch (error) {\n throw new Error(\n `Failed to search knowledge base: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error }\n );\n }\n }\n}\n","import {\n OperatorResultEvent,\n OperatorResultEventSchema,\n OperatorResult,\n OperatorProcessingResult,\n ConversationIntelligenceConfig,\n} from '../types/index';\nimport { MemoryClient } from '../clients/memory';\nimport { Logger, createLogger } from './logger';\n\n/**\n * Extract profile IDs from operator result execution details\n *\n * @param operatorResult - The operator result to extract profile IDs from\n * @returns Array of profile IDs found in participants\n */\nfunction extractProfileIds(operatorResult: OperatorResult): string[] {\n const profileIds: string[] = [];\n\n if (operatorResult.executionDetails?.participants) {\n for (const participant of operatorResult.executionDetails.participants) {\n if (participant.profileId) {\n profileIds.push(participant.profileId);\n }\n }\n }\n\n return profileIds;\n}\n\n/**\n * Generate content string from operator result\n *\n * @param operatorResult - The operator result to generate content from\n * @returns Content string or undefined if result is empty\n */\nfunction generateContent(operatorResult: OperatorResult): string | undefined {\n const result = operatorResult.result;\n\n if (result === null || result === undefined) {\n return undefined;\n }\n\n if (typeof result === 'string') {\n return result.trim() || undefined;\n }\n\n // For objects/arrays, stringify them\n const jsonString = JSON.stringify(result);\n return jsonString === '{}' || jsonString === '[]' ? undefined : jsonString;\n}\n\n/**\n * Parse summaries content from JSON result\n *\n * Expects format: { \"summaries\": [\"summary1\", \"summary2\", ...] }\n *\n * @param jsonContent - JSON string to parse\n * @returns Array of summary strings\n */\nfunction parseSummariesContent(jsonContent: string): string[] {\n try {\n const parsed = JSON.parse(jsonContent) as unknown;\n\n if (typeof parsed === 'object' && parsed !== null && 'summaries' in parsed) {\n const summaries = (parsed as { summaries: unknown }).summaries;\n if (Array.isArray(summaries)) {\n return summaries.filter((s): s is string => typeof s === 'string' && s.trim() !== '');\n }\n }\n\n return [];\n } catch {\n return [];\n }\n}\n\n/**\n * Processor for Conversation Intelligence operator result webhooks\n *\n * Processes operator results from CI and creates conversation summaries in the\n * Memory service based on the operator configuration.\n */\nexport class OperatorResultProcessor {\n private readonly memoryClient: MemoryClient;\n private readonly config: ConversationIntelligenceConfig;\n private readonly logger: Logger;\n\n constructor(memoryClient: MemoryClient, config: ConversationIntelligenceConfig, logger?: Logger) {\n this.memoryClient = memoryClient;\n this.config = config;\n this.logger = logger ?? createLogger({ name: 'cintel-processor' });\n }\n\n /**\n * Process an operator result event webhook payload\n *\n * @param payload - The raw webhook payload\n * @returns Processing result indicating success/failure and details\n */\n public async processEvent(payload: unknown): Promise<OperatorProcessingResult> {\n // Validate the payload\n const parseResult = OperatorResultEventSchema.safeParse(payload);\n\n if (!parseResult.success) {\n this.logger.warn(\n { validation_errors: parseResult.error.issues },\n 'Invalid operator result event payload'\n );\n return {\n success: false,\n skipped: false,\n error: `Invalid payload: ${parseResult.error.message}`,\n createdCount: 0,\n };\n }\n\n const event = parseResult.data;\n\n // Check if this event is from the configured CI configuration\n if (event.intelligenceConfiguration.id !== this.config.configurationId) {\n this.logger.debug(\n {\n received_config_id: event.intelligenceConfiguration.id,\n expected_config_id: this.config.configurationId,\n },\n 'Skipping event from different CI configuration'\n );\n return {\n success: true,\n skipped: true,\n skipReason: `Event from different CI configuration: ${event.intelligenceConfiguration.id}`,\n createdCount: 0,\n };\n }\n\n // Check for memory store ID and verify it matches the client's store ID\n if (!event.memoryStoreId) {\n this.logger.warn({ conversation_id: event.conversationId }, 'No memory store ID in event');\n return {\n success: false,\n skipped: false,\n error: 'No memory store ID provided in event',\n createdCount: 0,\n };\n }\n\n const clientStoreId = this.memoryClient.getStoreId();\n if (event.memoryStoreId !== clientStoreId) {\n this.logger.debug(\n {\n conversation_id: event.conversationId,\n event_store_id: event.memoryStoreId,\n client_store_id: clientStoreId,\n },\n 'Skipping event from different memory store'\n );\n return {\n success: true,\n skipped: true,\n skipReason: `Event from different memory store: ${event.memoryStoreId} (expected ${clientStoreId})`,\n createdCount: 0,\n };\n }\n\n // Process each operator result\n const results: OperatorProcessingResult[] = [];\n\n for (const operatorResult of event.operatorResults) {\n const result = await this.processOperatorResult(event, operatorResult);\n results.push(result);\n }\n\n // Aggregate results\n const successCount = results.filter(r => r.success && !r.skipped).length;\n const skippedCount = results.filter(r => r.skipped).length;\n const errorCount = results.filter(r => !r.success).length;\n const totalCreated = results.reduce((sum, r) => sum + r.createdCount, 0);\n\n // Determine overall event type\n const eventTypes = results\n .filter(r => r.success && !r.skipped && r.eventType)\n .map(r => r.eventType);\n const uniqueEventTypes = [...new Set(eventTypes)];\n const eventType =\n uniqueEventTypes.length === 1\n ? uniqueEventTypes[0]\n : uniqueEventTypes.length > 1\n ? 'mixed'\n : undefined;\n\n if (errorCount > 0) {\n const errors = results.filter(r => !r.success).map(r => r.error);\n return {\n success: false,\n eventType,\n skipped: false,\n error: `${errorCount} operator(s) failed: ${errors.join('; ')}`,\n createdCount: totalCreated,\n };\n }\n\n if (skippedCount === results.length) {\n return {\n success: true,\n skipped: true,\n skipReason: 'All operator results were skipped',\n createdCount: 0,\n };\n }\n\n this.logger.info(\n {\n conversation_id: event.conversationId,\n success_count: successCount,\n skipped_count: skippedCount,\n created_count: totalCreated,\n event_type: eventType,\n },\n 'Processed operator result event'\n );\n\n return {\n success: true,\n eventType,\n skipped: false,\n createdCount: totalCreated,\n };\n }\n\n /**\n * Process an individual operator result\n */\n private async processOperatorResult(\n event: OperatorResultEvent,\n operatorResult: OperatorResult\n ): Promise<OperatorProcessingResult> {\n const operatorSid = operatorResult.operator.id;\n\n // Check if this is a configured operator\n const isSummaryOperator = this.config.summaryOperatorSid === operatorSid;\n\n if (!isSummaryOperator) {\n this.logger.debug(\n {\n operator_sid: operatorSid,\n summary_operator_sid: this.config.summaryOperatorSid,\n },\n 'Skipping unconfigured operator'\n );\n return {\n success: true,\n skipped: true,\n skipReason: `Operator ${operatorSid} is not configured for processing`,\n createdCount: 0,\n };\n }\n\n // Generate content from operator result\n const content = generateContent(operatorResult);\n\n if (!content) {\n this.logger.debug(\n { operator_sid: operatorSid },\n 'Skipping operator result with empty content'\n );\n return {\n success: true,\n skipped: true,\n skipReason: 'Operator result has empty content',\n createdCount: 0,\n };\n }\n\n // Extract profile IDs from execution details\n const profileIds = extractProfileIds(operatorResult);\n\n if (profileIds.length === 0) {\n this.logger.warn(\n { operator_sid: operatorSid, conversation_id: event.conversationId },\n 'No profile IDs found in operator result'\n );\n return {\n success: true,\n skipped: true,\n skipReason: 'No profile IDs found in operator result execution details',\n createdCount: 0,\n };\n }\n\n return this.processSummaryEvent(event, operatorResult, content, profileIds);\n }\n\n /**\n * Process a summary operator result\n */\n private async processSummaryEvent(\n event: OperatorResultEvent,\n operatorResult: OperatorResult,\n content: string,\n profileIds: string[]\n ): Promise<OperatorProcessingResult> {\n // Parse summaries from JSON content\n const summaries = parseSummariesContent(content);\n\n if (summaries.length === 0) {\n this.logger.debug(\n { operator_sid: operatorResult.operator.id },\n 'No summaries found in content'\n );\n return {\n success: true,\n eventType: 'summary',\n skipped: true,\n skipReason: 'No summaries found in operator result content',\n createdCount: 0,\n };\n }\n\n let createdCount = 0;\n\n // Create summaries for each profile\n for (const profileId of profileIds) {\n try {\n const summaryItems = summaries.map(summaryContent => ({\n content: summaryContent,\n conversationId: event.conversationId,\n occurredAt: operatorResult.dateCreated,\n source: 'conversation-intelligence',\n }));\n\n await this.memoryClient.createConversationSummaries(profileId, summaryItems);\n createdCount += summaries.length;\n\n this.logger.debug(\n {\n profile_id: profileId,\n conversation_id: event.conversationId,\n summary_count: summaries.length,\n },\n 'Created conversation summaries'\n );\n } catch (error) {\n this.logger.error(\n {\n err: error,\n profile_id: profileId,\n conversation_id: event.conversationId,\n },\n 'Failed to create conversation summaries'\n );\n return {\n success: false,\n eventType: 'summary',\n skipped: false,\n error: `Failed to create summaries: ${error instanceof Error ? error.message : String(error)}`,\n createdCount,\n };\n }\n }\n\n return {\n success: true,\n eventType: 'summary',\n skipped: false,\n createdCount,\n };\n }\n}\n","import {\n TACConfigData,\n ConversationSession,\n ConversationId,\n ProfileId,\n ProfileResponse,\n ChannelType,\n OperatorProcessingResult,\n} from '../types';\nimport { TACMemoryResponse } from './tac-memory-response';\nimport { TACConfig } from './config';\nimport { MemoryClient } from '../clients/memory';\nimport { ConversationClient } from '../clients/conversation';\nimport { KnowledgeClient } from '../clients/knowledge';\nimport { BaseChannel } from '../channels/base';\nimport { Logger, createLogger } from './logger';\nimport { maskAddress } from '../util/log-redaction';\nimport { OperatorResultProcessor } from './operator-result-processor';\n\nexport interface TACOptions {\n config?: TACConfig | TACConfigData;\n logger?: Logger;\n}\n\n/**\n * Callback function signatures for TAC events\n */\nexport type MessageReadyCallback = (params: {\n conversationId: ConversationId;\n profileId: ProfileId | undefined;\n message: string;\n author: string;\n memory: TACMemoryResponse | undefined;\n session: ConversationSession;\n channel: ChannelType;\n abortSignal?: AbortSignal;\n}) => Promise<string | null | void> | string | null | void;\n\nexport type InterruptCallback = (params: {\n conversationId: ConversationId;\n utteranceUntilInterrupt: string | undefined;\n durationUntilInterruptMs: number | undefined;\n session: ConversationSession;\n}) => Promise<void> | void;\n\nexport type ConversationEndedCallback = (params: {\n session: ConversationSession;\n}) => Promise<void> | void;\n\n/**\n * Main Twilio Agent Connect class\n *\n * Central orchestrator that manages configuration, channels (SMS, WhatsApp, Chat, Voice),\n * callbacks, and coordinates between memory, conversations, and LLM integrations.\n */\nexport class TAC {\n private static readonly FACTORY_TOKEN = Symbol('TAC.create');\n\n private readonly config: TACConfig;\n public readonly logger: Logger;\n private memoryClient: MemoryClient | null = null;\n private knowledgeClient: KnowledgeClient | null = null;\n private conversationClient: ConversationClient | null = null;\n private readonly channels: Map<ChannelType, BaseChannel>;\n private cintelProcessor?: OperatorResultProcessor;\n\n private memoryStoreId: string | undefined;\n\n // Callback registrations\n private messageReadyCallback?: MessageReadyCallback;\n private interruptCallback?: InterruptCallback;\n private conversationEndedCallback?: ConversationEndedCallback;\n\n private constructor(token: symbol, options: TACOptions = {}) {\n if (token !== TAC.FACTORY_TOKEN) {\n throw new Error('TAC constructor is private. Use TAC.create() instead of new TAC().');\n }\n // Handle config resolution:\n // - If it's already a TACConfig instance, use it\n // - If it's data, create a new TACConfig\n // - If not provided, load from environment variables\n const finalConfig = options.config\n ? options.config instanceof TACConfig\n ? options.config\n : new TACConfig(options.config)\n : TACConfig.fromEnv();\n const finalLogger = options.logger ?? createLogger({ name: 'tac' });\n\n this.config = finalConfig;\n this.logger = finalLogger;\n this.channels = new Map();\n }\n\n public static async create(options: TACOptions = {}): Promise<TAC> {\n const tac = new TAC(TAC.FACTORY_TOKEN, options);\n\n if (!tac.config.isOrchestratorEnabled()) {\n tac.logger.info(\n 'Voice-only mode: conversationConfigurationId not set, skipping Conversation Orchestrator initialization'\n );\n return tac;\n }\n\n try {\n tac.conversationClient = new ConversationClient(\n tac.config,\n tac.logger.child({ component: 'conversation' })\n );\n\n // Safe: we already returned early if !isOrchestratorEnabled(), so conversationConfigurationId is defined\n const conversationConfig = await tac.conversationClient.getConfiguration(\n tac.config.conversationConfigurationId!\n );\n\n tac.memoryStoreId = conversationConfig.memoryStoreId;\n tac.memoryClient = new MemoryClient(\n tac.config,\n conversationConfig.memoryStoreId,\n tac.logger.child({ component: 'memory' })\n );\n\n tac.knowledgeClient = new KnowledgeClient(\n tac.config,\n tac.logger.child({ component: 'knowledge' })\n );\n\n if (tac.config.cintelConfigurationId) {\n tac.cintelProcessor = new OperatorResultProcessor(\n tac.memoryClient,\n {\n configurationId: tac.config.cintelConfigurationId,\n summaryOperatorSid: tac.config.cintelSummaryOperatorSid,\n },\n tac.logger.child({ component: 'cintel' })\n );\n }\n\n return tac;\n } catch (error) {\n tac.logger.error({ err: error }, 'TAC initialization failed');\n throw error;\n }\n }\n\n /**\n * Register a channel with the framework\n */\n public registerChannel(channel: BaseChannel): void {\n this.logger.info({ channel: channel.channelType }, 'Registering channel');\n\n // Remove existing channel of same type\n const existingChannel = this.channels.get(channel.channelType);\n if (existingChannel) {\n this.logger.info({ channel: channel.channelType }, 'Replacing existing channel registration');\n existingChannel.shutdown();\n }\n\n this.channels.set(channel.channelType, channel);\n\n // Set up channel event listeners\n this.setupChannelEventListeners(channel);\n\n this.logger.info({ channel: channel.channelType }, 'Channel registration complete');\n }\n\n /**\n * Set up event listeners for a channel\n */\n private setupChannelEventListeners(channel: BaseChannel): void {\n // Handle channel errors directly\n channel.on(\n 'error',\n ({ error, context }: { error: Error; context?: Record<string, unknown> }) => {\n this.logger.error({ err: error, ...context }, 'Channel error');\n }\n );\n\n // Handle message received events for SMS channels\n channel.on(\n 'messageReceived',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises -- Intentionally async callback\n async (data: {\n conversationId: ConversationId;\n profileId: ProfileId | undefined;\n message: string;\n author: string;\n userMemory: TACMemoryResponse | undefined;\n }): Promise<void> => {\n await this.handleMessageReady({ ...data, channelType: channel.channelType });\n }\n );\n\n // Handle voice prompt events\n channel.on(\n 'prompt',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises -- Intentionally async callback\n async ({\n conversationId,\n transcript,\n userMemory,\n session,\n abortSignal,\n }: {\n conversationId: ConversationId;\n transcript: string;\n userMemory?: TACMemoryResponse;\n session?: ConversationSession;\n abortSignal: AbortSignal;\n }): Promise<void> => {\n // Use session from event if available, otherwise get from channel\n const eventSession = session || channel.getConversationSession(conversationId);\n if (eventSession) {\n await this.handleMessageReady({\n conversationId,\n profileId: eventSession.profileId ? (eventSession.profileId as ProfileId) : undefined,\n message: transcript,\n author: 'user',\n userMemory,\n channelType: channel.channelType,\n abortSignal,\n });\n }\n }\n );\n\n // Handle voice interrupt events\n channel.on(\n 'interrupt',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises -- Intentionally async event handler\n async ({\n conversationId,\n utteranceUntilInterrupt,\n durationUntilInterruptMs,\n }: {\n conversationId: ConversationId;\n utteranceUntilInterrupt: string | undefined;\n durationUntilInterruptMs: number | undefined;\n }) => {\n const session = channel.getConversationSession(conversationId);\n if (session && this.interruptCallback) {\n try {\n await this.interruptCallback({\n conversationId,\n utteranceUntilInterrupt,\n durationUntilInterruptMs,\n session,\n });\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: conversationId },\n 'Interrupt callback error'\n );\n }\n }\n }\n );\n\n // Handle conversation ended events\n channel.on(\n 'conversationEnded',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises -- Intentionally async event handler\n async ({ session }: { session: ConversationSession }) => {\n if (this.conversationEndedCallback) {\n try {\n await this.conversationEndedCallback({ session });\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: session.conversationId },\n 'Conversation ended callback error'\n );\n }\n }\n }\n );\n }\n\n /**\n * Handle message ready event from channels\n */\n private async handleMessageReady(data: {\n conversationId: ConversationId;\n profileId: ProfileId | undefined;\n message: string;\n author: string;\n userMemory: TACMemoryResponse | undefined;\n channelType: ChannelType;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n this.logger.debug(\n {\n conversation_id: data.conversationId,\n profile_id: data.profileId,\n author: maskAddress(data.author),\n message_length: data.message.length,\n channel: data.channelType,\n operation: 'handle_message_ready',\n },\n 'Handling message ready'\n );\n\n if (!this.messageReadyCallback) {\n this.logger.warn('No message ready callback registered');\n return;\n }\n\n try {\n // Use the channel type passed from the event handler, not lookup by conversation ID\n // This ensures voice prompts use voice channel even if SMS also has this conversation\n const channel = this.channels.get(data.channelType);\n if (!channel) {\n throw new Error(`No channel found for type ${data.channelType}`);\n }\n\n this.logger.debug(\n { conversation_id: data.conversationId, channel: channel.channelType },\n 'Using channel for message'\n );\n\n const session = channel.getConversationSession(data.conversationId);\n if (!session) {\n throw new Error(`No session found for conversation ${data.conversationId}`);\n }\n\n // Memory is now fetched by channels based on their memoryMode configuration\n const memory = data.userMemory;\n\n // Execute callback\n this.logger.debug(\n { conversation_id: data.conversationId },\n 'Executing message ready callback'\n );\n try {\n const response = await this.messageReadyCallback({\n conversationId: data.conversationId,\n profileId: data.profileId,\n message: data.message,\n author: data.author,\n memory: memory ?? undefined,\n session,\n channel: channel.channelType,\n ...(data.abortSignal !== undefined && { abortSignal: data.abortSignal }),\n });\n this.logger.debug(\n { conversation_id: data.conversationId },\n 'Message ready callback completed'\n );\n\n // Auto-send if callback returned a string\n if (typeof response === 'string') {\n if (response === '') {\n this.logger.warn(\n { conversation_id: data.conversationId },\n 'Callback returned empty string, skipping auto-send'\n );\n } else {\n try {\n await channel.sendResponse(data.conversationId, response);\n } catch (sendError) {\n this.logger.error(\n { err: sendError, conversation_id: data.conversationId },\n 'Failed to auto-send callback response'\n );\n }\n }\n }\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: data.conversationId },\n 'Message ready callback error'\n );\n }\n\n this.logger.debug({ conversation_id: data.conversationId }, 'Message handling completed');\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: data.conversationId },\n 'Message handling error'\n );\n }\n }\n\n /**\n * Register callback for when messages are ready to be processed.\n * Return a string to auto-send, or null/void for manual handling.\n */\n public onMessageReady(callback: MessageReadyCallback): void {\n this.messageReadyCallback = callback;\n }\n\n /**\n * Register callback for when user interrupts (voice channel)\n */\n public onInterrupt(callback: InterruptCallback): void {\n this.interruptCallback = callback;\n }\n\n /**\n * Register callback for when a conversation ends.\n *\n * The callback is triggered by channels when a conversation is closed\n * (e.g., SMS conversation status changed to CLOSED, or voice WebSocket\n * disconnected). The callback receives the full ConversationSession before\n * it is cleaned up.\n */\n public onConversationEnded(callback: ConversationEndedCallback): void {\n this.conversationEndedCallback = callback;\n }\n\n /**\n * Whether Conversation Orchestrator is configured.\n * Returns false in voice-only mode.\n *\n * @internal\n */\n public isOrchestratorEnabled(): boolean {\n return this.config.isOrchestratorEnabled();\n }\n\n /**\n * Get registered channel by type\n */\n public getChannel<T extends BaseChannel>(channelType: ChannelType): T | undefined {\n return this.channels.get(channelType) as T | undefined;\n }\n\n /**\n * Get configuration\n */\n public getConfig(): TACConfig {\n return this.config;\n }\n\n /**\n * Get memory client for advanced memory operations.\n * Returns null in voice-only mode.\n */\n public getMemoryClient(): MemoryClient | null {\n return this.memoryClient;\n }\n\n /**\n * Get the memory store ID resolved from the ConversationConfiguration at startup.\n * Returns undefined in voice-only mode.\n */\n public getMemoryStoreId(): string | undefined {\n return this.memoryStoreId;\n }\n\n /**\n * Get knowledge client for knowledge base operations.\n * Returns null in voice-only mode.\n */\n public getKnowledgeClient(): KnowledgeClient | null {\n return this.knowledgeClient;\n }\n\n /**\n * Get conversation client for advanced conversation operations.\n * Returns null in voice-only mode.\n */\n public getConversationClient(): ConversationClient | null {\n return this.conversationClient;\n }\n\n /**\n * Check if Conversation Intelligence processing is enabled\n *\n * @returns true if CI processor is initialized, false otherwise\n */\n public isCintelEnabled(): boolean {\n return this.cintelProcessor !== undefined;\n }\n\n /**\n * Process a Conversation Intelligence operator result webhook event\n *\n * @param payload - The raw webhook payload from CI\n * @returns Promise containing the processing result\n * @throws Error if CI processor is not initialized\n */\n public async processCintelEvent(payload: unknown): Promise<OperatorProcessingResult> {\n if (!this.cintelProcessor) {\n throw new Error(\n 'Conversation Intelligence processor is not initialized. ' +\n 'Ensure cintelConfigurationId is provided in TAC configuration.'\n );\n }\n return this.cintelProcessor.processEvent(payload);\n }\n\n /**\n * Retrieve memories from Memory API with automatic fallback to Conversations API\n *\n * @param session - Conversation session context\n * @param query - Optional semantic search query\n * @param conversationId - Passed through to `/Recall` as-is. Sending one\n * without a `query` makes Memory infer one from that conversation's history\n * — an expensive server-side step — so leave it unset when there is no\n * per-turn topic (e.g. `\"once\"` mode's cache-priming fetch).\n * @returns Promise containing TACMemoryResponse wrapper providing unified access to memory data.\n *\n * Attempts to retrieve from Memory API first:\n * - observations, summaries, and communications available\n * - communications include author name and type\n *\n * Falls back to Conversations API on error:\n * - observations and summaries are empty arrays\n * - communications have basic fields only (no author name/type)\n */\n public async retrieveMemory(\n session: ConversationSession,\n query?: string,\n conversationId?: string\n ): Promise<TACMemoryResponse> {\n if (!this.isOrchestratorEnabled()) {\n return new TACMemoryResponse([]);\n }\n\n try {\n // If profileId is missing, try to lookup profile using address\n if (!session.profileId) {\n // Check if authorInfo and address are available\n if (!session.authorInfo || !session.authorInfo.address) {\n throw new Error(\n 'profileId is required for memory retrieval but was not found in ' +\n 'conversation context. Additionally, authorInfo.address is not available ' +\n 'for profile lookup. Ensure either profileId or authorInfo.address is ' +\n 'provided when creating the ConversationSession.'\n );\n }\n\n // Determine identity type based on address format\n // Email addresses contain '@', phone numbers start with '+'\n const address = session.authorInfo.address;\n let identityType: 'email' | 'phone';\n if (address.includes('@')) {\n identityType = 'email';\n } else if (address.startsWith('+')) {\n identityType = 'phone';\n } else {\n throw new Error(\n `Unsupported authorInfo.address format '${maskAddress(address)}'. ` +\n \"Expected an email address containing '@' or a phone number starting with '+'.\"\n );\n }\n this.logger.debug(\n { identityType, address: maskAddress(address), channel: session.channel },\n 'profileId not found, attempting to lookup profile'\n );\n\n if (!this.memoryClient) {\n throw new Error('Memory client is not available');\n }\n\n // Lookup profile using appropriate identity type\n const lookupResponse = await this.memoryClient.lookupProfile(\n identityType,\n session.authorInfo.address\n );\n\n // Check if any profiles were found\n if (!lookupResponse.profiles || lookupResponse.profiles.length === 0) {\n throw new Error(\n `No profile found for ${identityType} ${maskAddress(session.authorInfo.address)}. ` +\n 'Profile lookup returned no results. Ensure the identity ' +\n 'is registered in the identity resolution system.'\n );\n }\n\n // Use the first profile ID\n session.profileId = lookupResponse.profiles[0];\n }\n\n if (!session.profileId) {\n throw new Error('Profile ID is required but was not resolved');\n }\n\n if (!this.memoryClient) {\n throw new Error('Memory client is not available');\n }\n\n const memoryResponse = await this.memoryClient.retrieveMemories(session.profileId, {\n conversationId,\n query,\n observationsLimit: this.config.memoryConfig.observationsLimit,\n summariesLimit: this.config.memoryConfig.summariesLimit,\n communicationsLimit: this.config.memoryConfig.communicationsLimit,\n relevanceThreshold: this.config.memoryConfig.relevanceThreshold,\n });\n return new TACMemoryResponse(memoryResponse);\n } catch (error) {\n this.logger.warn(\n { err: error },\n 'Failed to retrieve memory from Memory API, falling back to Conversations API'\n );\n\n try {\n if (!this.conversationClient) {\n throw new Error('Conversation client is not available');\n }\n const communications = await this.conversationClient.listCommunications(\n session.conversationId\n );\n\n return new TACMemoryResponse(communications);\n } catch (fallbackError) {\n this.logger.error({ err: fallbackError }, 'Failed to retrieve communications');\n throw fallbackError;\n }\n }\n }\n\n /**\n * Fetch profile information with traits\n *\n * @param profileId - Profile ID to fetch\n * @returns Promise containing profile response or undefined if not available\n */\n public async fetchProfile(profileId: string): Promise<ProfileResponse | undefined> {\n if (!profileId) {\n this.logger.warn('profile_id is required for profile fetching but was not provided');\n return undefined;\n }\n\n if (!this.memoryClient) {\n this.logger.warn('Memory client is not available (voice-only mode)');\n return undefined;\n }\n\n try {\n const traitGroups = this.config.memoryConfig.traitGroups;\n const profileResponse = await this.memoryClient.getProfile(profileId, traitGroups);\n return profileResponse;\n } catch (error) {\n this.logger.error({ err: error }, `Failed to fetch profile for ${profileId}`);\n return undefined;\n }\n }\n\n /**\n * Shutdown TAC and cleanup resources\n */\n public shutdown(): void {\n for (const channel of this.channels.values()) {\n this.logger.debug({ channel: channel.channelType }, 'Shutting down channel');\n channel.shutdown();\n }\n\n this.channels.clear();\n this.logger.info('TAC shutdown complete');\n }\n}\n","import {\n ConversationSession,\n ChannelType,\n ConversationId,\n ConversationWebhookPayload,\n ProfileId,\n MemoryMode,\n MemoryModeSchema,\n isConversationId,\n isProfileId,\n} from '../types/index';\nimport { TACConfig } from '../lib/config';\nimport { ConversationClient } from '../clients/conversation';\nimport { Logger } from '../lib/logger';\nimport type { TAC } from '../lib/tac';\nimport { TACMemoryResponse } from '../lib/tac-memory-response';\n\n/**\n * Base channel event callbacks\n */\nexport interface BaseChannelEvents {\n onConversationStarted?: (data: { session: ConversationSession }) => void;\n onConversationEnded?: (data: { session: ConversationSession }) => Promise<void> | void;\n onError?: (data: { error: Error; context?: Record<string, unknown> }) => void;\n}\n\n/**\n * Base channel options\n */\nexport interface BaseChannelOptions {\n /**\n * Memory retrieval mode for this channel. Default is \"never\".\n *\n * - \"never\": Memory is not automatically retrieved. Use the memory TAC tool or manually call `tac.retrieveMemory()` in callbacks for conditional retrieval.\n * - \"always\": Memory is automatically retrieved (using the message as query) for every inbound message and available in `onMessageReady` callback.\n * - \"once\": Memory is retrieved once at conversation start with no query (and no conversation id) and cached on the session. Subsequent messages reuse the cache until the conversation becomes INACTIVE.\n */\n memoryMode?: MemoryMode;\n\n /**\n * Maximum number of idempotency tokens to track for webhook deduplication.\n * Default is 10000. Must be a positive integer.\n */\n dedupCapacity?: number;\n}\n\n/**\n * Abstract base class for all channel implementations\n *\n * Provides common functionality for:\n * - Conversation lifecycle management and session tracking\n * - Webhook deduplication using Twilio idempotency tokens\n * - Event filtering to prevent cross-channel fanout\n * - Memory retrieval integration\n * - Error handling and logging\n *\n * Subclasses must implement channel-specific webhook processing and message sending.\n */\nexport abstract class BaseChannel {\n protected readonly tac: TAC;\n protected readonly config: TACConfig;\n protected readonly logger: Logger;\n protected readonly conversationClient: ConversationClient | null;\n protected readonly activeConversations: Map<ConversationId, ConversationSession>;\n protected readonly callbacks: BaseChannelEvents;\n protected readonly memoryMode: MemoryMode;\n private readonly processedWebhookTokens: Set<string>;\n private readonly maxTrackedTokens: number;\n\n constructor(tac: TAC, options?: BaseChannelOptions) {\n this.tac = tac;\n this.config = tac.getConfig();\n this.logger = tac.logger.child({ component: 'channel' });\n this.conversationClient = tac.getConversationClient();\n this.activeConversations = new Map();\n this.callbacks = {};\n\n // Validate memoryMode with runtime check for JS consumers\n const providedMode = options?.memoryMode;\n const modeToValidate = providedMode === undefined ? 'never' : providedMode;\n const parseResult = MemoryModeSchema.safeParse(modeToValidate);\n if (!parseResult.success) {\n throw new Error(\n `Invalid memoryMode: \"${modeToValidate}\". Must be \"always\", \"once\", or \"never\".`\n );\n }\n this.memoryMode = parseResult.data;\n\n // Validate and set deduplication capacity\n const capacity = options?.dedupCapacity ?? 10000;\n if (capacity < 1 || !Number.isInteger(capacity)) {\n throw new Error('dedupCapacity must be a positive integer');\n }\n this.maxTrackedTokens = capacity;\n this.processedWebhookTokens = new Set();\n }\n\n /**\n * Get the channel type (implemented by subclasses)\n */\n public abstract get channelType(): ChannelType;\n\n /**\n * Register event callbacks\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic event callback needs to accept any args\n public on(event: string, callback: (...args: any[]) => void): void {\n switch (event) {\n case 'conversationStarted':\n this.callbacks.onConversationStarted = callback;\n break;\n case 'conversationEnded':\n this.callbacks.onConversationEnded = callback;\n break;\n case 'error':\n this.callbacks.onError = callback;\n break;\n }\n }\n\n /**\n * Process incoming webhook data (implemented by subclasses)\n */\n public abstract processWebhook(payload: unknown): Promise<void>;\n\n /**\n * Send a response back to the user (implemented by subclasses)\n */\n public abstract sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void>;\n\n /**\n * Start a new conversation session\n */\n protected startConversation(\n conversationId: ConversationId,\n profileId?: ProfileId,\n serviceId?: string\n ): ConversationSession {\n if (this.activeConversations.has(conversationId)) {\n this.logger.debug(\n {\n conversation_id: conversationId,\n profile_id: this.activeConversations.get(conversationId)?.profileId,\n service_id: this.activeConversations.get(conversationId)?.serviceId,\n },\n 'Conversation already active'\n );\n return this.activeConversations.get(conversationId)!;\n }\n\n const session: ConversationSession = {\n conversationId: conversationId,\n profileId: profileId,\n serviceId: serviceId,\n channel: this.channelType,\n startedAt: new Date(),\n metadata: {},\n };\n\n this.activeConversations.set(conversationId, session);\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n profile_id: profileId,\n service_id: serviceId,\n channel: this.channelType,\n },\n 'Conversation started'\n );\n\n if (this.callbacks.onConversationStarted) {\n this.callbacks.onConversationStarted({ session });\n }\n\n return session;\n }\n\n /**\n * End a conversation session.\n *\n * Triggers the onConversationEnded callback BEFORE removing the session,\n * so the callback receives the full ConversationSession data.\n * Errors in the callback do not prevent session cleanup.\n */\n protected async endConversation(conversationId: ConversationId): Promise<void> {\n const session = this.activeConversations.get(conversationId);\n\n if (session) {\n // Trigger callback BEFORE deleting the session\n if (this.callbacks.onConversationEnded) {\n try {\n await this.callbacks.onConversationEnded({ session });\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: conversationId },\n 'Error in conversation ended callback'\n );\n }\n }\n\n this.activeConversations.delete(conversationId);\n this.logger.debug(\n {\n conversation_id: conversationId,\n channel: this.channelType,\n service_id: session.serviceId,\n },\n 'Conversation ended'\n );\n } else {\n this.logger.debug(\n { conversation_id: conversationId, channel: this.channelType },\n 'Conversation end requested but no active session found'\n );\n }\n }\n\n /**\n * Get an active conversation session\n */\n public getConversationSession(conversationId: ConversationId): ConversationSession | undefined {\n return this.activeConversations.get(conversationId);\n }\n\n /**\n * Check if a conversation is active\n */\n public isConversationActive(conversationId: ConversationId): boolean {\n return this.activeConversations.has(conversationId);\n }\n\n /**\n * Handle errors with proper context\n */\n protected handleError(error: Error, context?: Record<string, unknown>): void {\n this.logger.error({ err: error }, 'Channel error');\n\n if (this.callbacks.onError) {\n if (context) {\n this.callbacks.onError({ error, context });\n } else {\n this.callbacks.onError({ error });\n }\n }\n }\n\n /**\n * Check if a webhook has already been processed using Twilio's idempotency token.\n * Uses a sliding window with fixed capacity to track tokens (FIFO eviction).\n *\n * This is intentionally a single synchronous check-and-record to prevent race conditions\n * where a duplicate arrives while the first request is still awaiting async work.\n */\n protected isDuplicateWebhook(idempotencyToken: string): boolean {\n if (this.processedWebhookTokens.has(idempotencyToken)) {\n return true;\n }\n\n if (this.processedWebhookTokens.size >= this.maxTrackedTokens) {\n const oldest = this.processedWebhookTokens.values().next().value!;\n this.processedWebhookTokens.delete(oldest);\n }\n\n this.processedWebhookTokens.add(idempotencyToken);\n return false;\n }\n\n /**\n * Remove an idempotency token from the deduplication cache.\n * Used when webhook processing fails and retries should not be blocked.\n */\n protected removeWebhookToken(idempotencyToken: string): void {\n this.processedWebhookTokens.delete(idempotencyToken);\n }\n\n /**\n * Self-filtering: check if webhook event belongs to this channel.\n *\n * - COMMUNICATION_CREATED: require author.channel matches this channel type\n * - CONVERSATION_UPDATED: only process if conversation is tracked locally\n * - Other events: pass through\n */\n protected isEventForThisChannel(webhookData: ConversationWebhookPayload): boolean {\n const eventType = webhookData.eventType;\n const authorChannel = webhookData.data?.author?.channel;\n\n // COMMUNICATION_CREATED: require author.channel for safe filtering\n // Reject events without channel to prevent fanout crosstalk\n if (eventType === 'COMMUNICATION_CREATED') {\n if (!authorChannel) {\n return false;\n }\n return authorChannel === this.channelType.toUpperCase();\n }\n\n // CONVERSATION_UPDATED: only process if this channel tracks the conversation\n if (eventType === 'CONVERSATION_UPDATED') {\n const conversationId = this.extractConversationId(webhookData);\n if (conversationId && !this.activeConversations.has(conversationId)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Validate webhook payload (override in subclasses for specific validation)\n */\n protected validateWebhookPayload(payload: unknown): boolean {\n return payload !== null && payload !== undefined;\n }\n\n /**\n * Preprocess webhook before handling event-specific logic.\n * Handles deduplication, validation, filtering, and data extraction.\n *\n * @param payload - Raw webhook payload from Twilio\n * @param idempotencyToken - Optional idempotency token for deduplication\n * @returns Preprocessed webhook data, or null if webhook should be skipped\n */\n protected preprocessWebhook(\n payload: unknown,\n idempotencyToken: string | undefined\n ): {\n webhookData: ConversationWebhookPayload;\n eventType: string;\n conversationId: string | undefined;\n } | null {\n this.logger.debug({ operation: 'webhook_processing' }, 'Processing webhook');\n\n if (idempotencyToken && this.isDuplicateWebhook(idempotencyToken)) {\n this.logger.debug({ idempotency_token: idempotencyToken }, 'Skipping duplicate webhook');\n return null;\n }\n\n if (!this.validateWebhookPayload(payload)) {\n throw new Error('Invalid webhook payload');\n }\n\n const webhookData = payload as ConversationWebhookPayload;\n const eventType = webhookData.eventType;\n const conversationId = webhookData.data?.conversationId || webhookData.data?.id;\n\n // Self-filter: ignore events meant for other channel types\n if (!this.isEventForThisChannel(webhookData)) {\n this.logger.debug(\n { event_type: eventType, channel: this.channelType, conversation_id: conversationId },\n 'Ignoring event for different channel type'\n );\n return null;\n }\n\n return { webhookData, eventType, conversationId };\n }\n\n /**\n * Extract conversation ID from webhook payload with type validation.\n *\n * Extracts conversationId from webhookData.data?.conversationId || webhookData.data?.id,\n * validates the value is a non-empty string, and ensures it passes isConversationId check.\n *\n * This prevents invalid IDs from causing downstream issues like incorrect Map key\n * matching in CONVERSATION_UPDATED self-filtering or propagating malformed IDs.\n */\n protected extractConversationId(payload: unknown): ConversationId | null {\n if (!payload || typeof payload !== 'object') {\n return null;\n }\n\n const webhookData = payload as ConversationWebhookPayload;\n const conversationId = webhookData.data?.conversationId || webhookData.data?.id;\n\n // Validate type and format before casting to ConversationId\n if (conversationId && typeof conversationId === 'string' && isConversationId(conversationId)) {\n return conversationId;\n }\n\n return null;\n }\n\n /**\n * Extract profile ID from webhook payload with type validation.\n *\n * Extracts profileId from webhookData.data?.profileId,\n * validates the value is a non-empty string, and ensures it passes isProfileId check.\n *\n * This prevents invalid IDs from propagating downstream and ensures consistent\n * validation across all channel types.\n */\n protected extractProfileId(payload: unknown): ProfileId | null {\n if (!payload || typeof payload !== 'object') {\n return null;\n }\n\n const webhookData = payload as ConversationWebhookPayload;\n const profileId = webhookData.data?.profileId;\n\n // Validate type and format before casting to ProfileId\n if (profileId && typeof profileId === 'string' && isProfileId(profileId)) {\n return profileId;\n }\n\n return null;\n }\n\n /**\n * Retrieve memory according to the channel's memoryMode.\n *\n * This method handles the common logic for memory retrieval across all channels,\n * including error handling and debug logging.\n *\n * Modes:\n * - \"always\": Fetch with the provided query on every message.\n * - \"once\": Fetch once with neither a query nor a conversation id (skipping\n * query expansion) and cache the result on the session. Subsequent calls\n * reuse the cache until it is invalidated on the INACTIVE transition.\n * - \"never\": Skip retrieval.\n *\n * Memory retrieval failures are logged and swallowed so message processing\n * continues without memory context.\n */\n protected async retrieveMemoryIfEnabled(\n session: ConversationSession,\n query?: string\n ): Promise<TACMemoryResponse | undefined> {\n // \"never\" and any unexpected value: no automatic retrieval\n if (this.memoryMode !== 'always' && this.memoryMode !== 'once') {\n return undefined;\n }\n\n // \"once\" mode reuses cached memory across messages.\n if (this.memoryMode === 'once' && session.cachedMemory !== undefined) {\n this.logger.debug({ conversation_id: session.conversationId }, 'Reusing cached memory');\n return session.cachedMemory;\n }\n\n try {\n // \"always\" sends query + conversation id so Memory ranks by relevance.\n // \"once\" sends neither: with no query, a conversation id only buys\n // Memory's expensive server-side query expansion.\n const isAlways = this.memoryMode === 'always';\n const memory = await this.tac.retrieveMemory(\n session,\n isAlways ? query : undefined,\n isAlways ? session.conversationId : undefined\n );\n if (this.memoryMode === 'once') {\n session.cachedMemory = memory;\n }\n this.logger.debug(\n { conversation_id: session.conversationId, memory_mode: this.memoryMode },\n 'Memory retrieved'\n );\n return memory;\n } catch (error) {\n this.logger.warn(\n { err: error, conversation_id: session.conversationId },\n 'Failed to retrieve memory, continuing without memory context'\n );\n // Continue without memory rather than failing entire message processing\n return undefined;\n }\n }\n\n /**\n * Invalidate cached memory for \"once\" mode when a conversation becomes\n * INACTIVE. Conversation Orchestrator updates memory on the INACTIVE\n * transition, so the next message re-fetches fresh memory. No-op for other\n * memory modes.\n */\n protected invalidateCachedMemory(conversationId: ConversationId): void {\n if (this.memoryMode !== 'once') {\n return;\n }\n\n const session = this.activeConversations.get(conversationId);\n if (session?.cachedMemory !== undefined) {\n session.cachedMemory = undefined;\n this.logger.debug(\n { conversation_id: conversationId },\n 'Invalidated cached memory on INACTIVE status'\n );\n }\n }\n\n /**\n * Cleanup resources when shutting down\n */\n public shutdown(): void {\n this.activeConversations.clear();\n delete this.callbacks.onConversationStarted;\n delete this.callbacks.onConversationEnded;\n delete this.callbacks.onError;\n }\n}\n","import {\n ActionChannelSettings,\n ConversationAddress,\n ConversationId,\n ConversationParticipant,\n ConversationWebhookPayload,\n InitiateConversationResult,\n ProfileId,\n SendMessageActionRequest,\n isConversationId,\n} from '../types/index';\nimport axios from 'axios';\nimport { BaseChannel, BaseChannelEvents, BaseChannelOptions } from './base';\nimport { ConversationClient } from '../clients/conversation';\nimport type { TAC } from '../lib/tac';\nimport { maskAddress } from '../util/log-redaction';\n\n/**\n * Participant types that represent TAC itself at TAC's (channel, address).\n *\n * `AI_AGENT` is the canonical type; `AGENT` is the legacy Conversation\n * Orchestrator form. A participant typed either way at TAC's address is\n * recognized as TAC and not overwritten; anything else (HUMAN_AGENT,\n * CUSTOMER, …) is someone else's assignment.\n */\nconst AGENT_TYPES = new Set<string>(['AGENT', 'AI_AGENT']);\n\n/**\n * Memory identifier type to use when looking up / creating a profile for a\n * channel's customer address. Channels absent from this map skip profile\n * resolution during participant reconciliation.\n */\nconst CHANNEL_IDENTITY_TYPES: Record<string, string> = {\n SMS: 'phone',\n VOICE: 'phone',\n RCS: 'rcs',\n WHATSAPP: 'whatsapp',\n};\n\n/**\n * Messaging channel configuration options.\n * Alias for BaseChannelOptions that can be extended by specific channel implementations.\n */\nexport type MessagingChannelConfig = BaseChannelOptions;\n\n/**\n * Messaging channel event callbacks extending base callbacks\n */\nexport interface MessagingChannelEvents extends BaseChannelEvents {\n onMessageReceived?: (data: {\n conversationId: ConversationId;\n profileId: ProfileId | undefined;\n message: string;\n author: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Memory structure is dynamic and defined by user\n userMemory: any;\n }) => void;\n}\n\n/**\n * Abstract Messaging Channel base class for SMS and Chat channels\n *\n * Provides shared webhook processing logic for messaging channels\n * (SMS and Chat) that use the Conversations Service webhooks.\n *\n * Subclasses must implement:\n * - `isDefaultAgentAddress`: fast-path check for the channel's default agent address\n * - `getAgentAddress`: return the agent's `ConversationAddress` for a conversation\n * - `sendResponse`: send messages back through the channel\n *\n * Subclass flags:\n * - `reconcileCustomerType`: if `true` (default), reconciliation will also\n * promote a channel-matching UNKNOWN participant (not owning the agent\n * address) to CUSTOMER. Set `false` for channels where the customer is\n * identified author-driven (e.g. chat).\n */\nexport abstract class MessagingChannel extends BaseChannel {\n protected override readonly conversationClient: ConversationClient;\n protected readonly messagingCallbacks: MessagingChannelEvents;\n\n /**\n * Controls whether reconciliation promotes an UNKNOWN customer-side\n * participant to CUSTOMER. Subclasses override to opt out (e.g. chat).\n */\n protected reconcileCustomerType: boolean = true;\n\n constructor(tac: TAC, config?: MessagingChannelConfig) {\n super(tac, config);\n if (!tac.isOrchestratorEnabled()) {\n throw new Error(\n 'Messaging channels require conversationConfigurationId to be configured. ' +\n 'Voice-only mode does not support SMS or Chat channels.'\n );\n }\n // Safe: orchestrator is enabled so conversationClient is guaranteed non-null\n this.conversationClient = tac.getConversationClient() as ConversationClient;\n this.messagingCallbacks = {};\n }\n\n /**\n * Fast-path check: is the author address this channel's default agent address?\n * (e.g., config.phoneNumber for SMS, agentAddress for Chat)\n */\n protected abstract isDefaultAgentAddress(authorAddress: string): boolean;\n\n /**\n * Return the agent-side ConversationAddress for this conversation.\n *\n * Used by `reconcileParticipants` to identify which participant (by channel\n * + address) represents the agent. May read from session state (e.g. chat's\n * per-conversation channelId) to build the address.\n */\n protected abstract getAgentAddress(conversationId: ConversationId): ConversationAddress;\n\n /**\n * Check if a message is from the bot itself (2-tier).\n *\n * 1. Default agent address (stateless, no API call)\n * 2. API fallback via listParticipants (cross-process / multi-worker)\n */\n private async isOwnMessage(\n authorAddress: string,\n conversationId: ConversationId,\n authorParticipantId: string | undefined\n ): Promise<boolean> {\n if (this.isDefaultAgentAddress(authorAddress)) return true;\n\n if (authorParticipantId) {\n try {\n const participants = await this.conversationClient.listParticipants(conversationId);\n const authorParticipant = participants.find(p => p.id === authorParticipantId);\n if (authorParticipant) {\n if (authorParticipant.type === undefined) {\n this.logger.warn(\n { conversation_id: conversationId, participant_id: authorParticipantId },\n 'Participant type is undefined — cannot determine if this is an agent message'\n );\n }\n if (authorParticipant.type && AGENT_TYPES.has(authorParticipant.type)) {\n return true;\n }\n }\n } catch (error) {\n this.logger.warn(\n { err: error, conversation_id: conversationId, participant_id: authorParticipantId },\n 'Failed to look up participant type for self-message check; falling through'\n );\n }\n }\n\n return false;\n }\n\n /**\n * Register event callbacks (override for messaging-specific events)\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic event callback needs to accept any args\n public override on(event: string, callback: (...args: any[]) => void): void {\n if (event === 'messageReceived') {\n this.messagingCallbacks.onMessageReceived = callback;\n } else {\n // Delegate to parent for base events\n super.on(event, callback);\n }\n }\n\n /**\n * Process messaging channel webhook from Conversation Orchestrator\n */\n public async processWebhook(payload: unknown, idempotencyToken?: string): Promise<void> {\n try {\n const result = this.preprocessWebhook(payload, idempotencyToken);\n if (!result) {\n return;\n }\n\n const { webhookData, eventType, conversationId } = result;\n\n switch (eventType) {\n case 'CONVERSATION_CREATED':\n this.logger.debug(\n { conversation_id: conversationId, profile_id: webhookData.data?.profileId },\n 'Handling CONVERSATION_CREATED'\n );\n this.handleConversationCreated(webhookData);\n break;\n\n case 'COMMUNICATION_CREATED':\n this.logger.debug({ conversation_id: conversationId }, 'Handling COMMUNICATION_CREATED');\n await this.handleCommunicationCreated(webhookData);\n break;\n\n case 'CONVERSATION_UPDATED':\n this.logger.debug(\n { conversation_id: conversationId, status: webhookData.data?.status },\n 'Handling CONVERSATION_UPDATED'\n );\n await this.handleConversationUpdated(webhookData);\n break;\n\n default:\n this.logger.warn(\n {\n event_type: eventType,\n raw_event_type: webhookData.eventType,\n conversation_id: conversationId,\n },\n 'Unhandled event type - this event will be ignored'\n );\n }\n\n this.logger.debug({ event_type: eventType }, 'Webhook processing completed');\n } catch (error) {\n // Remove the token so retries are not blocked\n if (idempotencyToken) {\n this.removeWebhookToken(idempotencyToken);\n }\n this.handleError(error instanceof Error ? error : new Error(String(error)), { payload });\n }\n }\n\n /**\n * Handle conversation creation event\n */\n private handleConversationCreated(payload: ConversationWebhookPayload): void {\n const conversationId = this.extractConversationId(payload);\n const profileId = this.extractProfileId(payload);\n\n if (!conversationId) {\n this.logger.warn(\n { operation: 'handle_conversation_created' },\n 'Missing conversation ID in conversation.created event'\n );\n throw new Error('Missing conversation ID in conversation.created event');\n }\n\n this.startConversation(conversationId, profileId ?? undefined, payload.data?.serviceId);\n }\n\n /**\n * Handle new communication event (incoming message)\n */\n private async handleCommunicationCreated(payload: ConversationWebhookPayload): Promise<void> {\n const conversationId = this.extractConversationId(payload);\n const profileId = this.extractProfileId(payload);\n // Extract message text from data.content.text\n const message = payload.data?.content?.text?.trim();\n // Author is in data.author.address\n const author = payload.data?.author?.address || 'unknown';\n\n this.logger.info(\n {\n conversation_id: conversationId,\n profile_id: profileId,\n author: maskAddress(author),\n message_length: message?.length,\n operation: 'handle_communication_created',\n },\n 'Handling communication.created'\n );\n\n if (!conversationId) {\n this.logger.warn(\n { operation: 'handle_communication_created' },\n 'Missing conversation ID in communication.created event'\n );\n throw new Error('Missing conversation ID in communication.created event');\n }\n\n if (!message) {\n this.logger.info({ conversation_id: conversationId }, 'Ignoring empty message');\n return;\n }\n\n // Per-conversation communication ID dedup stored in the in-memory\n // ConversationSession metadata. This only prevents duplicate processing\n // within the current process/session lifetime; it does not deduplicate\n // across horizontally-scaled instances or after a restart.\n const communicationId = payload.data?.id;\n if (communicationId) {\n const session = this.getConversationSession(conversationId);\n if (session?.metadata?.lastCommunicationId === communicationId) {\n this.logger.debug(\n { conversation_id: conversationId, communication_id: communicationId },\n 'Skipping already-processed communication'\n );\n return;\n }\n }\n\n // Filter out messages from the bot itself\n if (await this.isOwnMessage(author, conversationId, payload.data?.author?.participantId)) {\n this.logger.info(\n {\n conversation_id: conversationId,\n author_address: maskAddress(author),\n },\n 'Ignoring message from AI agent'\n );\n return;\n }\n\n // Initialize conversation if not already active\n if (!this.isConversationActive(conversationId)) {\n this.logger.debug({ conversation_id: conversationId }, 'Starting new conversation');\n this.startConversation(conversationId, profileId ?? undefined, payload.data?.serviceId);\n } else if (payload.data?.serviceId) {\n const session = this.getConversationSession(conversationId);\n if (session && session.serviceId !== payload.data.serviceId) {\n this.logger.debug(\n {\n conversation_id: conversationId,\n old_service_id: session.serviceId,\n new_service_id: payload.data.serviceId,\n },\n 'Updating conversation configuration ID from communication.created'\n );\n session.serviceId = payload.data.serviceId;\n }\n }\n\n // Get session and update with author info for profile lookup\n const session = this.getConversationSession(conversationId);\n if (session) {\n session.authorInfo = {\n address: author,\n participantId: payload.data?.author?.participantId,\n };\n\n // Store channelId (Chat Channel SID) in session metadata for reply sending\n if (payload.data?.channelId) {\n if (!session.metadata) {\n session.metadata = {};\n }\n session.metadata.channelId = payload.data.channelId;\n this.logger.debug(\n { conversation_id: conversationId, channel_id: payload.data.channelId },\n 'Stored channelId in session metadata'\n );\n }\n\n // Track communication ID for cross-process dedup\n if (communicationId) {\n if (!session.metadata) {\n session.metadata = {};\n }\n session.metadata.lastCommunicationId = communicationId;\n }\n\n // Reconcile participant types pre-LLM so v1-bridge's UNKNOWN gets\n // promoted, and to stash both participant ids on the session for\n // sendResponse. Reconcile failure means the reply would fail too —\n // skip the callback so the LLM doesn't waste a turn on an\n // un-replyable conversation.\n //\n // Gate on `aiAgentInfo` (persistent across turns) — `authorInfo` is\n // overwritten from every webhook so it's not a reliable \"already\n // reconciled\" signal.\n if (!session.aiAgentInfo) {\n const resolved = await this.reconcileParticipants(conversationId);\n if (!resolved) {\n // Surface via handleError (logs at error level AND fires the app's\n // onError callback) rather than a bare warn — otherwise the dropped\n // inbound is invisible to the app and can't be observed or retried.\n // Set a stable error.name and error_code so consumers can classify\n // this condition programmatically without string-matching the message.\n const error = new Error(\n `Participant reconciliation failed for conversation ${conversationId}; ` +\n 'inbound message dropped because no sendable participants could be resolved.'\n );\n error.name = 'ParticipantReconciliationError';\n this.handleError(error, {\n conversation_id: conversationId,\n channel: this.channelType,\n dropped_inbound: true,\n error_code: 'participant_reconciliation_failed',\n });\n return;\n }\n\n const [agentParticipant, customerParticipant] = resolved;\n const agentAddress = this.getAgentAddress(conversationId);\n session.aiAgentInfo = {\n address: agentAddress.address,\n participantId: agentParticipant.id,\n };\n // When reconcile resolved a customer (SMS path — chat disables customer\n // reconciliation and uses the authorInfo captured from the webhook\n // above), use its authoritative participant id and lift any resolved\n // profile.\n if (customerParticipant && session.authorInfo) {\n session.authorInfo.participantId = customerParticipant.id;\n if (customerParticipant.profileId && !session.profileId) {\n session.profileId = customerParticipant.profileId;\n }\n }\n }\n }\n\n // Retrieve user memory if enabled via memoryMode\n const userMemory = session ? await this.retrieveMemoryIfEnabled(session, message) : undefined;\n\n // Invoke message received callback with memory context\n if (this.messagingCallbacks.onMessageReceived) {\n this.logger.debug({ conversation_id: conversationId }, 'Invoking message received callback');\n this.messagingCallbacks.onMessageReceived({\n conversationId,\n profileId: (session?.profileId as ProfileId | undefined) ?? profileId ?? undefined,\n message,\n author,\n userMemory,\n });\n }\n }\n\n /**\n * Handle conversation updated event\n */\n private async handleConversationUpdated(payload: ConversationWebhookPayload): Promise<void> {\n const conversationId = this.extractConversationId(payload);\n\n if (!conversationId) {\n throw new Error('Missing conversation ID in conversation.updated event');\n }\n\n // Check if conversation is closed\n if (payload.data?.status === 'CLOSED') {\n this.logger.debug(\n { conversation_id: conversationId, status: payload.data.status },\n 'Conversation closed, cleaning up'\n );\n await this.endConversation(conversationId);\n } else if (payload.data?.status === 'INACTIVE') {\n // Invalidate cached memory (\"once\" mode) when the conversation becomes\n // inactive. Memory is updated by Conversation Orchestrator on the\n // INACTIVE transition, so the next message re-fetches fresh memory.\n this.invalidateCachedMemory(conversationId);\n }\n }\n\n /**\n * Validate messaging channel webhook payload structure\n */\n protected override validateWebhookPayload(payload: unknown): boolean {\n if (!super.validateWebhookPayload(payload)) {\n return false;\n }\n\n const webhookData = payload as ConversationWebhookPayload;\n return (\n typeof webhookData === 'object' &&\n typeof webhookData.eventType === 'string' &&\n webhookData.eventType.length > 0\n );\n }\n\n /**\n * Reconcile Conversation Orchestrator's participants to the types TAC\n * needs for sending.\n *\n * v1-bridge capture can leave TAC's agent participant as `UNKNOWN` (wrong\n * type at our address), or omit it entirely (customer-only conversation).\n * This pass fixes those cases; it refuses to rewrite anything else at our\n * address. Decision matrix:\n *\n * | Agent side | Customer side | Action |\n * |----------------------|---------------------|-------------------------------|\n * | AGENT / AI_AGENT | CUSTOMER | Use as-is (no profile work). |\n * | AGENT / AI_AGENT | UNKNOWN, no CUST | Resolve profile, PUT → CUST. |\n * | UNKNOWN at our addr | CUSTOMER | PUT agent → AI_AGENT. |\n * | UNKNOWN at our addr | UNKNOWN, no CUST | PUT agent; resolve, PUT CUST. |\n * | other at our addr | any | Return null (log ERROR). |\n * | none at our addr | CUSTOMER or UNKNOWN | POST AI_AGENT, then proceed. |\n * | any | no resolvable cust | Return null (caller WARNs). |\n *\n * TAC recognizes both `AGENT` and `AI_AGENT` at its address as itself.\n * `HUMAN_AGENT` is NOT treated as TAC (a real human is a separate\n * participant — TAC must not speak on their behalf); it falls into the\n * \"other at our addr\" row and causes the reconcile to bail.\n *\n * Customer-side reconciliation is gated by `reconcileCustomerType`. Chat\n * sets it to `false` because chat identifies the customer author-driven\n * (via `session.authorInfo.participantId`), so promoting some other\n * `UNKNOWN` CHAT participant could pick the wrong recipient.\n *\n * @returns `[agent, customerOrNull]` on success. `customer` is `null` when\n * `reconcileCustomerType` is `false`. `null` overall when either the agent\n * or the customer cannot be resolved — the caller treats `null` as a hard\n * stop and skips the message-ready callback.\n */\n protected async reconcileParticipants(\n conversationId: ConversationId\n ): Promise<[ConversationParticipant, ConversationParticipant | null] | null> {\n const agentAddress = this.getAgentAddress(conversationId);\n\n let participants: ConversationParticipant[];\n try {\n participants = await this.conversationClient.listParticipants(conversationId);\n } catch (error) {\n this.logger.error(\n { err: error, conversation_id: conversationId },\n 'Failed to list participants for reconciliation'\n );\n return null;\n }\n\n const channel = agentAddress.channel;\n\n const ownsAgentAddress = (p: ConversationParticipant): boolean =>\n Array.isArray(p.addresses) &&\n p.addresses.some(a => a.channel === channel && a.address === agentAddress.address);\n\n const matchesChannel = (p: ConversationParticipant): boolean =>\n Array.isArray(p.addresses) && p.addresses.some(a => a.channel === channel);\n\n let agentCandidate = participants.find(ownsAgentAddress);\n if (!agentCandidate) {\n const created = await this.addAgentParticipant(conversationId, agentAddress);\n if (!created) return null;\n agentCandidate = created;\n } else if (agentCandidate.type === 'UNKNOWN') {\n // Only promote UNKNOWN — an already-typed participant at TAC's address\n // that isn't AGENT/AI_AGENT (e.g., CUSTOMER, HUMAN_AGENT) is someone\n // else's assignment and must not be overwritten.\n const promoted = await this.promoteParticipant(conversationId, agentCandidate, 'AI_AGENT');\n if (!promoted) return null;\n agentCandidate = promoted;\n } else if (!agentCandidate.type || !AGENT_TYPES.has(agentCandidate.type)) {\n this.logger.error(\n {\n conversation_id: conversationId,\n participant_id: agentCandidate.id,\n participant_type: agentCandidate.type,\n },\n \"Participant at TAC's address has a conflicting type; refusing to overwrite. \" +\n 'Check Conversation Orchestrator participant state — a non-agent participant is holding ' +\n \"TAC's (channel, address).\"\n );\n return null;\n }\n\n if (!this.reconcileCustomerType) {\n return [agentCandidate, null];\n }\n\n const customer = participants.find(\n p => p.type === 'CUSTOMER' && matchesChannel(p) && !ownsAgentAddress(p)\n );\n if (customer) {\n return [agentCandidate, customer];\n }\n\n const customerUnknown = participants.find(\n p => p.type === 'UNKNOWN' && matchesChannel(p) && !ownsAgentAddress(p)\n );\n if (customerUnknown) {\n const profileId = await this.resolveCustomerProfile(customerUnknown, channel);\n const promotedCustomer = await this.promoteParticipant(\n conversationId,\n customerUnknown,\n 'CUSTOMER',\n profileId\n );\n if (promotedCustomer) {\n return [agentCandidate, promotedCustomer];\n }\n }\n\n this.logger.warn(\n { conversation_id: conversationId, channel },\n 'No customer participant resolvable; skipping webhook'\n );\n return null;\n }\n\n /**\n * Find or mint a Conversation Memory profile for a customer being promoted from UNKNOWN.\n *\n * Only resolves for phone-based channels (SMS, VOICE, RCS, WHATSAPP). Looks\n * up by the channel's identifier type (`phone` for SMS/VOICE, `rcs` for\n * RCS, `whatsapp` for WHATSAPP) first; on miss, creates a new profile\n * using the configured phone trait group/field. Returns undefined on any\n * failure — the caller still promotes the participant, just without a\n * `profileId` attached.\n */\n private async resolveCustomerProfile(\n customer: ConversationParticipant,\n channel: string\n ): Promise<string | undefined> {\n const identityType = CHANNEL_IDENTITY_TYPES[channel];\n if (!identityType) return undefined;\n\n const memoryClient = this.tac.getMemoryClient();\n if (!memoryClient || !this.tac.getMemoryStoreId()) return undefined;\n\n const phoneAddress = Array.isArray(customer.addresses)\n ? (customer.addresses.find(a => a.channel === channel && !!a.address)?.address ?? undefined)\n : undefined;\n if (!phoneAddress) return undefined;\n\n try {\n const lookup = await memoryClient.lookupProfile(identityType, phoneAddress);\n if (lookup.profiles && lookup.profiles.length > 0) {\n return lookup.profiles[0];\n }\n } catch (error) {\n this.logger.warn(\n { err: error, conversation_id: customer.conversationId },\n 'Profile lookup failed during reconciliation; falling back to create'\n );\n }\n\n const memoryConfig = this.config.memoryConfig;\n const traitGroup = memoryConfig.phoneTraitGroup;\n const traitField = memoryConfig.phoneTraitField;\n\n try {\n return await memoryClient.createProfile({\n [traitGroup]: { [traitField]: phoneAddress },\n });\n } catch (error) {\n this.logger.warn(\n { err: error, conversation_id: customer.conversationId },\n 'Profile creation failed during reconciliation; promoting without profile'\n );\n return undefined;\n }\n }\n\n /**\n * PUT a participant to `newType`.\n *\n * Conversation Orchestrator's PUT is a full-resource replacement, so we\n * pass the existing `name` and `addresses` back unchanged to avoid wiping\n * them. `profileId` defaults to the participant's current value; pass a\n * non-undefined override to attach a newly resolved profile during CUSTOMER\n * reconciliation.\n *\n * Returns undefined on any error (including 409). A 409 from Conversation\n * Orchestrator here means the promotion is structurally blocked — stop and\n * surface it; don't retry.\n */\n private async promoteParticipant(\n conversationId: ConversationId,\n participant: ConversationParticipant,\n newType: 'CUSTOMER' | 'AI_AGENT' | 'HUMAN_AGENT' | 'AGENT',\n profileId?: string\n ): Promise<ConversationParticipant | undefined> {\n const effectiveProfileId = profileId !== undefined ? profileId : participant.profileId;\n const updateOptions: { name?: string; profileId?: string } = {};\n if (participant.name !== undefined) updateOptions.name = participant.name;\n if (effectiveProfileId !== null && effectiveProfileId !== undefined) {\n updateOptions.profileId = effectiveProfileId;\n }\n\n try {\n const updated = await this.conversationClient.updateParticipant(\n conversationId,\n participant.id,\n newType,\n participant.addresses,\n updateOptions\n );\n this.logger.debug(\n {\n conversation_id: conversationId,\n participant_id: participant.id,\n from_type: participant.type,\n to_type: newType,\n },\n 'Promoted participant'\n );\n return updated;\n } catch (error) {\n if (this.isConflictError(error)) {\n this.logger.warn(\n {\n conversation_id: conversationId,\n participant_id: participant.id,\n target_type: newType,\n conflicting_resource_id: this.extractConflictingResourceId(error),\n },\n 'Conversation Orchestrator returned 409 on participant promotion; skipping — ' +\n 'likely a conflicting conversation or grouping constraint. Check ' +\n 'Conversation Orchestrator for duplicate active conversations.'\n );\n return undefined;\n }\n this.logger.error(\n {\n err: error,\n conversation_id: conversationId,\n participant_id: participant.id,\n target_type: newType,\n },\n 'Failed to promote participant'\n );\n return undefined;\n }\n }\n\n /**\n * POST an `AI_AGENT` participant owning `agentAddress`.\n *\n * Returns undefined on any error (including 409). A 409 here means the\n * address is already owned or the conversation's participant set can't\n * accept a new AI_AGENT — stop and surface it; don't retry.\n */\n private async addAgentParticipant(\n conversationId: ConversationId,\n agentAddress: ConversationAddress\n ): Promise<ConversationParticipant | undefined> {\n try {\n const created = await this.conversationClient.addParticipant(\n conversationId,\n [agentAddress],\n 'AI_AGENT'\n );\n this.logger.debug(\n { conversation_id: conversationId, participant_id: created.id },\n 'Added AI_AGENT participant'\n );\n return created;\n } catch (error) {\n if (this.isConflictError(error)) {\n this.logger.warn(\n {\n conversation_id: conversationId,\n conflicting_resource_id: this.extractConflictingResourceId(error),\n },\n 'Conversation Orchestrator returned 409 on AI_AGENT participant add; skipping — ' +\n \"address is already owned or the conversation can't accept a new AI_AGENT. \" +\n 'Check Conversation Orchestrator participant state.'\n );\n return undefined;\n }\n this.logger.error(\n { err: error, conversation_id: conversationId },\n 'Failed to add AI_AGENT participant'\n );\n return undefined;\n }\n }\n\n private isConflictError(error: unknown): boolean {\n const cause = error instanceof Error ? (error.cause ?? error) : error;\n return axios.isAxiosError(cause) && cause.response?.status === 409;\n }\n\n private extractConflictingResourceId(error: unknown): string | undefined {\n const cause = error instanceof Error ? (error.cause ?? error) : error;\n if (!axios.isAxiosError(cause)) return undefined;\n const headers = cause.response?.headers as Record<string, string> | undefined;\n const id = headers?.['x-conflicting-resource-id'];\n return typeof id === 'string' && id.length > 0 ? id : undefined;\n }\n\n /**\n * Shared outbound conversation initiation for messaging channels (SMS/RCS/Chat/WhatsApp).\n *\n * Handles the full flow: create conversation → find participants → start\n * session → send initial message → error cleanup.\n */\n protected async initiateOutboundMessagingConversation(params: {\n channel: 'SMS' | 'CHAT' | 'RCS' | 'WHATSAPP';\n to: string;\n from: string;\n message: string;\n metadata?: Record<string, unknown>;\n channelId?: string;\n channelSettings?: ActionChannelSettings;\n }): Promise<InitiateConversationResult> {\n const {\n channel,\n to,\n from: fromAddress,\n message,\n metadata,\n channelId,\n channelSettings,\n } = params;\n\n let conversationId: string | undefined;\n let conversationReused = false;\n\n try {\n const customerAddress: ConversationAddress = {\n channel,\n address: to,\n ...(channelId ? { channelId } : {}),\n };\n const agentAddress: ConversationAddress = {\n channel,\n address: fromAddress,\n ...(channelId ? { channelId } : {}),\n };\n\n const result = await this.conversationClient.createOrReuseConversation([\n { type: 'CUSTOMER', addresses: [customerAddress] },\n { type: 'AI_AGENT', addresses: [agentAddress] },\n ]);\n conversationId = result.conversation.id;\n conversationReused = result.reused;\n\n if (!isConversationId(conversationId)) {\n throw new Error(`Invalid conversation ID returned: ${conversationId}`);\n }\n\n const participants = await this.conversationClient.listParticipants(conversationId);\n\n const customerParticipant = participants.find(\n p =>\n p.type === 'CUSTOMER' &&\n Array.isArray(p.addresses) &&\n p.addresses.some(\n a =>\n a.channel === channel &&\n a.address === to &&\n (channelId === undefined || a.channelId === channelId)\n )\n );\n if (!customerParticipant) {\n throw new Error('Customer participant not found after conversation creation');\n }\n\n const agentParticipant = participants.find(\n p =>\n p.type !== undefined &&\n AGENT_TYPES.has(p.type) &&\n Array.isArray(p.addresses) &&\n p.addresses.some(\n a =>\n a.channel === channel &&\n a.address === fromAddress &&\n (channelId === undefined || a.channelId === channelId)\n )\n );\n if (!agentParticipant) {\n throw new Error('Agent participant not found after conversation creation');\n }\n\n // Start local session BEFORE sending the initial message so the\n // COMMUNICATION_CREATED webhook (triggered by createAction) finds a\n // correctly-configured session instead of auto-starting one with wrong\n // metadata.\n const session = this.startConversation(conversationId);\n session.authorInfo = {\n address: to,\n participantId: customerParticipant.id,\n };\n session.aiAgentInfo = {\n address: fromAddress,\n participantId: agentParticipant.id,\n };\n session.metadata = {\n ...session.metadata,\n ...(metadata ?? {}),\n direction: 'outbound',\n ...(channelId ? { channelId } : {}),\n };\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: { channel, participantId: agentParticipant.id },\n to: [{ channel, participantId: customerParticipant.id }],\n content: { text: message },\n ...(channelSettings ? { channelSettings } : {}),\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n { conversation_id: conversationId, to: maskAddress(to) },\n `Outbound ${channel} conversation initiated`\n );\n\n return { conversationId, session };\n } catch (error) {\n if (conversationId) {\n this.activeConversations.delete(conversationId as ConversationId);\n }\n if (conversationId && !conversationReused) {\n await this.conversationClient\n .updateConversation(conversationId, 'CLOSED')\n .catch(closeErr => {\n this.logger.warn(\n { err: closeErr, conversation_id: conversationId },\n 'Failed to close orphaned conversation after initiation error'\n );\n });\n }\n this.logger.error(\n { err: error, to: maskAddress(to) },\n `Failed to initiate outbound ${channel}`\n );\n this.handleError(error instanceof Error ? error : new Error(String(error)), { to });\n throw error;\n }\n }\n}\n","import {\n ChannelType,\n ConversationAddress,\n ConversationId,\n SendMessageActionRequest,\n InitiateMessagingConversationOptions,\n InitiateMessagingConversationOptionsSchema,\n InitiateConversationResult,\n} from '../types/index';\nimport { MessagingChannel } from './messaging';\nimport { maskAddress } from '../util/log-redaction';\n\n/**\n * SMS Channel implementation for Twilio Conversations Service\n *\n * Handles SMS conversations through webhook events from Twilio.\n * Automatically retrieves user memory and manages conversation lifecycle.\n */\nexport class SMSChannel extends MessagingChannel {\n public get channelType(): ChannelType {\n return 'sms';\n }\n\n protected isDefaultAgentAddress(authorAddress: string): boolean {\n return authorAddress === this.config.phoneNumber;\n }\n\n protected getAgentAddress(_conversationId: ConversationId): ConversationAddress {\n return { channel: 'SMS', address: this.config.phoneNumber };\n }\n\n /**\n * Send SMS response using the Conversation Orchestrator Actions API (SEND_MESSAGE).\n *\n * Reads the agent and customer participant ids stashed on the session by\n * inbound reconciliation or outbound initiation. Missing ids are a misuse —\n * `sendResponse` is only expected to be called after an inbound webhook\n * (COMMUNICATION_CREATED → reconcile) or after `initiateOutboundConversation`,\n * both of which populate the session.\n */\n public async sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_length: message.length,\n operation: 'send_response',\n },\n 'Sending SMS response'\n );\n\n try {\n const session = this.getConversationSession(conversationId);\n\n if (!session || !session.authorInfo || !session.aiAgentInfo) {\n throw new Error(\n `Unable to send SMS: sendResponse called without a reconciled session for ` +\n `conversation ${conversationId}. Wait for an inbound webhook or call ` +\n `initiateOutboundConversation first.`\n );\n }\n\n const customerParticipantId = session.authorInfo.participantId;\n const agentParticipantId = session.aiAgentInfo.participantId;\n if (!customerParticipantId || !agentParticipantId) {\n throw new Error(\n `Unable to send SMS: session for conversation ${conversationId} is missing ` +\n `participant ids.`\n );\n }\n\n const channelId =\n typeof session.metadata?.channelId === 'string' ? session.metadata.channelId : undefined;\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n recipient_participant_id: customerParticipantId,\n agent_participant_id: agentParticipantId,\n },\n 'Sending SMS via Actions API'\n );\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: {\n channel: 'SMS',\n participantId: agentParticipantId,\n },\n to: [\n {\n channel: 'SMS',\n participantId: customerParticipantId,\n },\n ],\n content: { text: message },\n ...(channelId ? { channelSettings: { channelId } } : {}),\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n },\n 'SMS sent successfully via Actions API'\n );\n } catch (error) {\n this.logger.error({ err: error, conversation_id: conversationId }, 'Send response error');\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Initiate an outbound SMS conversation\n *\n * Creates a conversation via Conversation Orchestrator, adds customer and\n * agent participants, then sends the initial message via the Actions API.\n * The sender is always `config.phoneNumber`.\n */\n public async initiateOutboundConversation(\n options: InitiateMessagingConversationOptions\n ): Promise<InitiateConversationResult> {\n const validated = InitiateMessagingConversationOptionsSchema.parse(options);\n\n this.logger.info(\n { to: maskAddress(validated.to), message_length: validated.message.length },\n 'Initiating outbound SMS conversation'\n );\n\n return this.initiateOutboundMessagingConversation({\n channel: 'SMS',\n to: validated.to,\n from: this.config.phoneNumber,\n message: validated.message,\n ...(validated.metadata ? { metadata: validated.metadata } : {}),\n });\n }\n}\n","import {\n ChannelType,\n ConversationAddress,\n ConversationId,\n SendMessageActionRequest,\n InitiateMessagingConversationOptions,\n InitiateMessagingConversationOptionsSchema,\n InitiateConversationResult,\n} from '../types/index';\nimport { MessagingChannel, MessagingChannelConfig } from './messaging';\nimport { maskAddress } from '../util/log-redaction';\nimport type { TAC } from '../lib/tac';\n\n/**\n * RCS Channel implementation for Twilio Conversations Service\n *\n * Handles RCS (Rich Communication Services) conversations through webhook\n * events from Twilio. The RCS Sender ID is configured on `TACConfig` via\n * `TWILIO_RCS_SENDER_ID`. Follows the same pattern as SMS (sender from\n * TAC config) for consistency with other messaging channels.\n */\nexport class RCSChannel extends MessagingChannel {\n constructor(tac: TAC, config?: MessagingChannelConfig) {\n super(tac, config);\n\n if (!this.config.rcsSenderId) {\n throw new Error(\n 'rcsSenderId is required for RCS channel. ' +\n 'Please set TWILIO_RCS_SENDER_ID environment variable or provide rcsSenderId in TACConfig.'\n );\n }\n }\n\n public get channelType(): ChannelType {\n return 'rcs';\n }\n\n protected isDefaultAgentAddress(authorAddress: string): boolean {\n return authorAddress === this.config.rcsSenderId;\n }\n\n protected getAgentAddress(_conversationId: ConversationId): ConversationAddress {\n if (!this.config.rcsSenderId) {\n throw new Error('rcsSenderId is required for RCS channel.');\n }\n return { channel: 'RCS', address: this.config.rcsSenderId };\n }\n\n /**\n * Send RCS response using the Conversation Orchestrator Actions API (SEND_MESSAGE).\n *\n * Reads the agent and customer participant ids stashed on the session by\n * inbound reconciliation or outbound initiation. Missing ids are a misuse —\n * `sendResponse` is only expected to be called after an inbound webhook\n * (COMMUNICATION_CREATED → reconcile) or after `initiateOutboundConversation`,\n * both of which populate the session.\n */\n public async sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_length: message.length,\n operation: 'send_response',\n },\n 'Sending RCS response'\n );\n\n try {\n const session = this.getConversationSession(conversationId);\n\n if (!session || !session.authorInfo || !session.aiAgentInfo) {\n throw new Error(\n `Unable to send RCS: sendResponse called without a reconciled session for ` +\n `conversation ${conversationId}. Wait for an inbound webhook or call ` +\n `initiateOutboundConversation first.`\n );\n }\n\n const customerParticipantId = session.authorInfo.participantId;\n const agentParticipantId = session.aiAgentInfo.participantId;\n if (!customerParticipantId || !agentParticipantId) {\n throw new Error(\n `Unable to send RCS: session for conversation ${conversationId} is missing ` +\n `participant ids.`\n );\n }\n\n const channelId =\n typeof session.metadata?.channelId === 'string' ? session.metadata.channelId : undefined;\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n recipient_participant_id: customerParticipantId,\n agent_participant_id: agentParticipantId,\n },\n 'Sending RCS via Actions API'\n );\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: {\n channel: 'RCS',\n participantId: agentParticipantId,\n },\n to: [\n {\n channel: 'RCS',\n participantId: customerParticipantId,\n },\n ],\n content: { text: message },\n ...(channelId ? { channelSettings: { channelId } } : {}),\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n },\n 'RCS sent successfully via Actions API'\n );\n } catch (error) {\n this.logger.error({ err: error, conversation_id: conversationId }, 'Send response error');\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Initiate an outbound RCS conversation\n *\n * Creates a conversation via Conversation Orchestrator, adds customer and\n * agent participants, then sends the initial message via the Actions API.\n * The sender is always `config.rcsSenderId`.\n */\n public async initiateOutboundConversation(\n options: InitiateMessagingConversationOptions\n ): Promise<InitiateConversationResult> {\n const validated = InitiateMessagingConversationOptionsSchema.parse(options);\n\n if (!this.config.rcsSenderId) {\n throw new Error('rcsSenderId is required for RCS channel.');\n }\n\n this.logger.info(\n { to: maskAddress(validated.to), message_length: validated.message.length },\n 'Initiating outbound RCS conversation'\n );\n\n return this.initiateOutboundMessagingConversation({\n channel: 'RCS',\n to: validated.to,\n from: this.config.rcsSenderId,\n message: validated.message,\n ...(validated.metadata ? { metadata: validated.metadata } : {}),\n });\n }\n}\n","import {\n ChannelType,\n ConversationAddress,\n ConversationId,\n SendMessageActionRequest,\n InitiateMessagingConversationOptions,\n InitiateMessagingConversationOptionsSchema,\n InitiateConversationResult,\n} from '../types/index';\nimport { MessagingChannel } from './messaging';\nimport { maskAddress } from '../util/log-redaction';\n\n/**\n * WhatsApp Channel implementation for Twilio Conversations Service\n *\n * Handles WhatsApp conversations through webhook events from Twilio.\n * Automatically retrieves user memory and manages conversation lifecycle.\n *\n * WhatsApp uses WhatsApp sender phone numbers configured in TACConfig\n * (via TWILIO_WHATSAPP_NUMBER). Address format: whatsapp:+1234567890\n */\nexport class WhatsAppChannel extends MessagingChannel {\n public get channelType(): ChannelType {\n return 'whatsapp';\n }\n\n protected isDefaultAgentAddress(authorAddress: string): boolean {\n if (!this.config.whatsappNumber) {\n throw new Error(\n 'whatsappNumber is required for WhatsApp channel. ' +\n 'Please set TWILIO_WHATSAPP_NUMBER environment variable or ' +\n 'provide whatsappNumber in TACConfig.'\n );\n }\n return authorAddress === this.config.whatsappNumber;\n }\n\n protected getAgentAddress(_conversationId: ConversationId): ConversationAddress {\n if (!this.config.whatsappNumber) {\n throw new Error(\n 'whatsappNumber is required for WhatsApp channel. ' +\n 'Please set TWILIO_WHATSAPP_NUMBER environment variable or ' +\n 'provide whatsappNumber in TACConfig.'\n );\n }\n return { channel: 'WHATSAPP', address: this.config.whatsappNumber };\n }\n\n /**\n * Send WhatsApp response using the Conversation Orchestrator Actions API (SEND_MESSAGE).\n *\n * Reads the agent and customer participant ids stashed on the session by\n * inbound reconciliation or outbound initiation. Missing ids are a misuse —\n * `sendResponse` is only expected to be called after an inbound webhook\n * (COMMUNICATION_CREATED → reconcile) or after `initiateOutboundConversation`,\n * both of which populate the session.\n */\n public async sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_length: message.length,\n operation: 'send_response',\n },\n 'Sending WhatsApp response'\n );\n\n try {\n const session = this.getConversationSession(conversationId);\n\n if (!session || !session.authorInfo || !session.aiAgentInfo) {\n throw new Error(\n `Unable to send WhatsApp: sendResponse called without a reconciled session for ` +\n `conversation ${conversationId}. Wait for an inbound webhook or call ` +\n `initiateOutboundConversation first.`\n );\n }\n\n const customerParticipantId = session.authorInfo.participantId;\n const agentParticipantId = session.aiAgentInfo.participantId;\n if (!customerParticipantId || !agentParticipantId) {\n throw new Error(\n `Unable to send WhatsApp: session for conversation ${conversationId} is missing ` +\n `participant ids.`\n );\n }\n\n const channelId =\n typeof session.metadata?.channelId === 'string' ? session.metadata.channelId : undefined;\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n recipient_participant_id: customerParticipantId,\n agent_participant_id: agentParticipantId,\n },\n 'Sending WhatsApp via Actions API'\n );\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: {\n channel: 'WHATSAPP',\n participantId: agentParticipantId,\n },\n to: [\n {\n channel: 'WHATSAPP',\n participantId: customerParticipantId,\n },\n ],\n content: { text: message },\n ...(channelId ? { channelSettings: { channelId } } : {}),\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n {\n conversation_id: conversationId,\n recipient_address: maskAddress(session.authorInfo.address),\n },\n 'WhatsApp sent successfully via Actions API'\n );\n } catch (error) {\n this.logger.error({ err: error, conversation_id: conversationId }, 'Send response error');\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Initiate an outbound WhatsApp conversation\n *\n * Creates a conversation via Conversation Orchestrator, adds customer and\n * agent participants, then sends the initial message via the Actions API.\n * The sender is always `config.whatsappNumber`.\n */\n public async initiateOutboundConversation(\n options: InitiateMessagingConversationOptions\n ): Promise<InitiateConversationResult> {\n const validated = InitiateMessagingConversationOptionsSchema.parse(options);\n\n if (!this.config.whatsappNumber) {\n throw new Error(\n 'whatsappNumber is required for WhatsApp channel. ' +\n 'Please set TWILIO_WHATSAPP_NUMBER environment variable or ' +\n 'provide whatsappNumber in TACConfig.'\n );\n }\n\n this.logger.info(\n { to: maskAddress(validated.to), message_length: validated.message.length },\n 'Initiating outbound WhatsApp conversation'\n );\n\n return this.initiateOutboundMessagingConversation({\n channel: 'WHATSAPP',\n to: validated.to,\n from: this.config.whatsappNumber,\n message: validated.message,\n ...(validated.metadata ? { metadata: validated.metadata } : {}),\n });\n }\n}\n","import {\n ActionChannelSettings,\n ChannelType,\n ConversationAddress,\n ConversationId,\n SendMessageActionRequest,\n InitiateConversationResult,\n} from '../types/index';\nimport { z } from 'zod';\nimport { MessagingChannel, MessagingChannelConfig } from './messaging';\nimport type { TAC } from '../lib/tac';\nimport { maskAddress } from '../util/log-redaction';\n\n/**\n * Options for initiating an outbound chat conversation.\n *\n * The sender is always the channel's configured `agentAddress`. Multi-sender\n * deployments should run one TAC instance per sender.\n */\nexport const InitiateChatConversationOptionsSchema = z.object({\n to: z.string().min(1, 'Recipient identity is required'),\n channelId: z.string().min(1, 'Chat Channel SID is required'),\n message: z.string().min(1, 'Initial message is required'),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type InitiateChatConversationOptions = z.infer<typeof InitiateChatConversationOptionsSchema>;\n\n/**\n * Chat channel configuration options\n */\nexport interface ChatChannelConfig extends MessagingChannelConfig {\n /** Chat agent identity string (defaults to 'ai-assistant') */\n agentAddress?: string;\n}\n\n/**\n * Chat Channel implementation for Twilio Conversations Service\n *\n * Handles web chat conversations through webhook events from Twilio.\n * Uses identity-based addressing instead of phone numbers.\n * Automatically creates AI_AGENT participant if needed and manages conversation lifecycle.\n */\nexport class ChatChannel extends MessagingChannel {\n private readonly agentAddress: string;\n\n // Chat identifies the customer author-driven from the webhook's\n // `author.participantId`; promoting some other channel-matching UNKNOWN\n // CHAT participant could pick the wrong recipient.\n protected override reconcileCustomerType: boolean = false;\n\n constructor(tac: TAC, config?: ChatChannelConfig) {\n super(tac, config);\n this.agentAddress = config?.agentAddress ?? 'ai-assistant';\n }\n\n public get channelType(): ChannelType {\n return 'chat';\n }\n\n protected isDefaultAgentAddress(authorAddress: string): boolean {\n return authorAddress === this.agentAddress;\n }\n\n protected getAgentAddress(conversationId: ConversationId): ConversationAddress {\n const session = this.getConversationSession(conversationId);\n const channelId =\n session && typeof session.metadata?.channelId === 'string'\n ? session.metadata.channelId\n : undefined;\n return {\n channel: 'CHAT',\n address: this.agentAddress,\n ...(channelId ? { channelId } : {}),\n };\n }\n\n /**\n * Send chat response using the Conversation Orchestrator Actions API (SEND_MESSAGE).\n *\n * Reads the agent and customer participant ids stashed on the session by\n * inbound reconciliation or outbound initiation. Missing ids are a misuse —\n * `sendResponse` is only expected to be called after an inbound webhook\n * (COMMUNICATION_CREATED → reconcile) or after `initiateOutboundConversation`,\n * both of which populate the session.\n */\n public async sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_length: message.length,\n operation: 'send_response',\n },\n 'Sending chat response'\n );\n\n try {\n const session = this.getConversationSession(conversationId);\n\n if (!session || !session.authorInfo || !session.aiAgentInfo) {\n throw new Error(\n `Unable to send chat message: sendResponse called without a reconciled session ` +\n `for conversation ${conversationId}. Wait for an inbound webhook or call ` +\n `initiateOutboundConversation first.`\n );\n }\n\n const customerParticipantId = session.authorInfo.participantId;\n const agentParticipantId = session.aiAgentInfo.participantId;\n if (!customerParticipantId || !agentParticipantId) {\n throw new Error(\n `Unable to send chat message: session for conversation ${conversationId} is ` +\n `missing participant ids.`\n );\n }\n\n // channelId (Chat Channel SID) is required for CHAT delivery — the V1\n // Chat backend uses it to pick the destination thread. Inbound webhooks\n // always populate it, so a missing value here is a misuse.\n const chatChannelSid =\n typeof session.metadata?.channelId === 'string' ? session.metadata.channelId : undefined;\n\n if (!chatChannelSid) {\n throw new Error(\n \"Missing required session.metadata['channelId'] for chat sendResponse; \" +\n 'this is normally populated by an inbound webhook. Ensure an inbound ' +\n 'message has been processed before calling sendResponse, or set ' +\n \"session.metadata['channelId'] explicitly in advanced usage.\"\n );\n }\n\n const channelSettings: ActionChannelSettings = {\n channelId: chatChannelSid,\n };\n\n this.logger.debug(\n {\n conversation_id: conversationId,\n recipient_participant_id: customerParticipantId,\n agent_participant_id: agentParticipantId,\n channel_id: chatChannelSid,\n },\n 'Sending chat message via Actions API'\n );\n\n const actionRequest: SendMessageActionRequest = {\n type: 'SEND_MESSAGE',\n payload: {\n from: {\n channel: 'CHAT',\n participantId: agentParticipantId,\n },\n to: [\n {\n channel: 'CHAT',\n participantId: customerParticipantId,\n },\n ],\n content: { text: message },\n channelSettings,\n },\n };\n\n await this.conversationClient.createAction(conversationId, actionRequest);\n\n this.logger.info(\n { conversation_id: conversationId, channel_id: chatChannelSid },\n 'Chat message sent successfully via Actions API'\n );\n } catch (error) {\n this.logger.error({ err: error, conversation_id: conversationId }, 'Send response error');\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Initiate an outbound chat conversation\n *\n * Creates a conversation via Conversation Orchestrator, adds customer and\n * agent participants, then sends the initial message via the Actions API.\n * The sender is always this channel's configured `agentAddress`.\n */\n public async initiateOutboundConversation(\n options: InitiateChatConversationOptions\n ): Promise<InitiateConversationResult> {\n const validated = InitiateChatConversationOptionsSchema.parse(options);\n\n this.logger.info(\n { to: maskAddress(validated.to), channel_id: validated.channelId },\n 'Initiating outbound chat conversation'\n );\n\n return this.initiateOutboundMessagingConversation({\n channel: 'CHAT',\n to: validated.to,\n from: this.agentAddress,\n message: validated.message,\n ...(validated.metadata ? { metadata: validated.metadata } : {}),\n channelId: validated.channelId,\n channelSettings: {\n channelId: validated.channelId,\n },\n });\n }\n}\n","/**\n * URL builders for Twilio Studio handoff.\n *\n * Shared between the tools package (digital handoff POSTs) and the server\n * package (voice `<Connect action>` URL).\n */\n\n/**\n * Build the Twilio Studio Flow Executions URL for a given Flow SID.\n *\n * Used for digital (messaging/chat) handoff — POST the handoff payload\n * to this URL to start a Studio flow execution.\n */\nexport function studioExecutionsUrl(flowSid: string): string {\n return `https://studio.twilio.com/v2/Flows/${flowSid}/Executions`;\n}\n\n/**\n * Build the Twilio Studio Flow voice webhook URL for a given Flow SID.\n *\n * Used as the `<Connect action=...>` URL in TwiML for voice handoff,\n * so that when ConversationRelay ends the session Twilio triggers the\n * Studio flow for an incoming call.\n */\nexport function studioVoiceHandoffUrl(accountSid: string, flowSid: string): string {\n return `https://webhooks.twilio.com/v1/Accounts/${accountSid}/Flows/${flowSid}?Trigger=incomingCall`;\n}\n","import { WebSocket } from 'ws';\nimport VoiceResponse from 'twilio/lib/twiml/VoiceResponse.js';\nimport Twilio from 'twilio';\nimport {\n ChannelType,\n ConversationId,\n ConversationSession,\n ProfileId,\n WebSocketMessageSchema,\n PromptMessage,\n InterruptMessage,\n DtmfMessage,\n TextTokenMessage,\n CustomParameters,\n ConversationRelayConfig,\n ConversationRelayConfigSchema,\n ConversationRelayCallbackPayload,\n InitiateVoiceConversationOptions,\n InitiateVoiceConversationOptionsSchema,\n TwiMLOptions,\n TwiMLRequest,\n ConversationWebhookPayload,\n CallOptions,\n CallEventKind,\n CallStatusEvent,\n AmdEvent,\n RecordingEvent,\n CallOptionsSchema,\n callOptionsToCreateParams,\n callStatusEventFromForm,\n amdEventFromForm,\n recordingEventFromForm,\n} from '../types/index';\nimport type { InitiateVoiceConversationResult } from '../types/conversation';\nimport { BaseChannel, BaseChannelEvents, BaseChannelOptions } from './base';\nimport type { TAC } from '../lib/tac';\nimport { TACMemoryResponse } from '../lib/tac-memory-response';\nimport { maskAddress, redactTwimlParameters } from '../util/log-redaction';\nimport { studioVoiceHandoffUrl } from '../util/handoff-urls';\n\n/** Fixed default welcome greeting applied when no layer sets one. */\nconst DEFAULT_WELCOME_GREETING = 'Hello! How can I assist you today?';\n\n/** Poll window from call-connect: 10 attempts, 250ms doubling to a 1.5s cap (~11s). */\nconst POLL_ATTEMPTS = 10;\nconst POLL_BASE_DELAY_MS = 250;\nconst POLL_MAX_DELAY_MS = 1500;\n\n/**\n * Configuration for the Voice channel.\n *\n * `defaultTwimlOptions` is one of several TwiML layers that merge per-field;\n * see `handleIncomingCall` (inbound) and `initiateOutboundConversation`\n * (outbound) for the full precedence order.\n */\nexport interface VoiceChannelConfig extends BaseChannelOptions {\n /**\n * Static `TwiMLOptions` applied to every call (inbound and outbound).\n * Controls the TwiML inside `<ConversationRelay>` — voice, language,\n * transcription provider, welcomeGreeting, `<Language>` children, etc. Use\n * this when the same ConversationRelay configuration is correct for every call.\n *\n * Per-call inbound customization is registered via\n * `VoiceChannel.onInboundCallTwiml(...)` (not on this config).\n *\n * Note: `customParameters` and `languages` replace wholesale when a\n * higher-priority layer sets them.\n */\n defaultTwimlOptions?: TwiMLOptions;\n\n /**\n * Static {@link CallOptions} applied to every outbound call — the\n * `calls.create` parameters, including the call-event callback URLs. This is\n * the layer to use for a custom server or non-default routes: URLs set here\n * override the ones TAC would derive from `voicePublicDomain` +\n * `voiceCallEventPath`.\n */\n defaultCallOptions?: CallOptions;\n}\n\n/**\n * Callback that produces per-call overrides for the TwiML inside\n * `<ConversationRelay>` on inbound calls. Receives a framework-neutral\n * {@link TwiMLRequest} and returns {@link TwiMLOptions}.\n */\nexport type InboundCallTwimlHandler = (req: TwiMLRequest) => Promise<TwiMLOptions>;\n\n/** Handler for Twilio `statusCallback` webhooks. */\nexport type CallStatusHandler = (event: CallStatusEvent) => Promise<void> | void;\n\n/** Handler for Twilio `asyncAmdStatusCallback` webhooks. */\nexport type AmdHandler = (event: AmdEvent) => Promise<void> | void;\n\n/** Handler for Twilio `recordingStatusCallback` webhooks. */\nexport type RecordingHandler = (event: RecordingEvent) => Promise<void> | void;\n\n/** One ConversationRelay keypress, as delivered to a {@link DtmfHandler}. */\nexport interface DtmfEvent {\n /**\n * Undefined only when the keypress beat conversation setup: `dtmf` before\n * ConversationRelay's `setup`, or an orchestrated-mode lookup that failed.\n */\n conversationId: ConversationId | undefined;\n /** Undefined only before ConversationRelay's `setup` message. */\n callSid: string | undefined;\n /** The key pressed: `0`-`9`, `*`, `#`, or `A`-`D`. */\n digit: string;\n /** Present whenever `conversationId` is. */\n session?: ConversationSession;\n}\n\n/** Handler for ConversationRelay `dtmf` messages (caller keypresses). */\nexport type DtmfHandler = (event: DtmfEvent) => Promise<void> | void;\n\n/**\n * Stringify a custom-parameter value for emission as a `<Parameter value=...>`.\n * Parameter values are scalars in practice; objects are JSON-encoded rather\n * than producing '[object Object]'.\n */\nfunction stringifyParameterValue(value: unknown): string {\n if (typeof value === 'object') {\n return JSON.stringify(value);\n }\n // string | number | boolean | bigint | symbol — all safely stringifiable.\n return String(value as string | number | boolean | bigint);\n}\n\n/**\n * Voice channel event callbacks extending base callbacks\n */\nexport interface VoiceChannelEvents extends BaseChannelEvents {\n onSetup?: (data: {\n callSid: string;\n from: string;\n to: string;\n customParameters: Record<string, unknown> | undefined;\n }) => void;\n onPrompt?: (data: {\n conversationId: ConversationId;\n transcript: string;\n userMemory?: TACMemoryResponse;\n session?: ConversationSession;\n abortSignal: AbortSignal;\n }) => Promise<void> | void;\n onInterrupt?: (data: {\n conversationId: ConversationId;\n utteranceUntilInterrupt: string | undefined;\n durationUntilInterruptMs: number | undefined;\n }) => void;\n /** Caller keypress. See {@link VoiceChannel.onDtmf}. */\n onDtmf?: DtmfHandler;\n /**\n * Fired once the session and WebSocket registration exist — in orchestrated\n * mode possibly before the first prompt, since the lookup starts at setup.\n */\n onWebSocketConnected?: (data: { conversationId: ConversationId }) => void;\n onWebSocketDisconnected?: (data: { conversationId: ConversationId }) => void;\n}\n\n/**\n * Voice Channel implementation for Twilio ConversationRelay\n *\n * Handles voice conversations through WebSocket connections.\n * Manages real-time audio streaming and conversation state.\n */\nexport interface StreamTask {\n controller: AbortController;\n hasSentTokens: boolean;\n}\n\nexport class VoiceChannel extends BaseChannel {\n private readonly webSocketConnections: Map<ConversationId, WebSocket>;\n private readonly voiceCallbacks: VoiceChannelEvents;\n private readonly streamTasks: Map<ConversationId, StreamTask>;\n private readonly promptQueues: Map<ConversationId, Promise<void>>;\n private readonly initializationRetries: Map<string, number>;\n private readonly callSidToConversationId: Map<string, ConversationId>;\n private readonly MAX_INITIALIZATION_RETRIES = 3;\n private twilioClient: ReturnType<typeof Twilio> | undefined;\n private readonly voiceConfig: VoiceChannelConfig;\n private onInboundCallTwimlHandler: InboundCallTwimlHandler | undefined;\n private onCallStatusHandler: CallStatusHandler | undefined;\n private onAmdHandler: AmdHandler | undefined;\n private onRecordingHandler: RecordingHandler | undefined;\n\n constructor(tac: TAC, options?: VoiceChannelConfig) {\n super(tac, options);\n this.voiceConfig = options ?? {};\n this.webSocketConnections = new Map();\n this.voiceCallbacks = {};\n this.streamTasks = new Map();\n this.promptQueues = new Map();\n this.initializationRetries = new Map();\n this.callSidToConversationId = new Map();\n }\n\n /**\n * Register a callback that produces per-call overrides for the TwiML inside\n * `<ConversationRelay>` on inbound calls.\n *\n * The callback receives a framework-neutral {@link TwiMLRequest} (parsed from\n * the Twilio webhook form) and returns {@link TwiMLOptions}. Fields the\n * callback explicitly sets override `defaultTwimlOptions` and TAC defaults;\n * unset fields fall through.\n *\n * @example\n * ```typescript\n * voiceChannel.onInboundCallTwiml(async req => {\n * if (req.callerCountry === 'MX') {\n * return { language: 'es-MX', welcomeGreeting: '¡Hola!' };\n * }\n * return {};\n * });\n * ```\n *\n * Outbound calls don't use this — pass per-call TwiML via\n * `InitiateVoiceConversationOptions.twimlOptions` directly.\n */\n public onInboundCallTwiml(callback: InboundCallTwimlHandler): void {\n this.onInboundCallTwimlHandler = callback;\n }\n\n /**\n * Register a handler for Twilio `statusCallback` webhooks.\n *\n * This is the Calls-API status callback (call disposition), not the\n * ConversationRelay session callback — see\n * {@link handleConversationRelayCallback}.\n *\n * Registering does two things: it stores the handler, and it makes later\n * outbound calls pass `statusCallback` to `calls.create`. With no handler\n * registered TAC omits that parameter, so Twilio has nowhere to post and the\n * event never arrives.\n *\n * Twilio reports only the terminal event by default, which covers every\n * disposition; set `CallOptions.statusCallbackEvent` for ringing/answered.\n *\n * @example\n * ```typescript\n * voiceChannel.onCallStatus(async event => {\n * if (event.isUnreached) {\n * // queue a retry\n * }\n * });\n * ```\n */\n public onCallStatus(callback: CallStatusHandler): void {\n this.onCallStatusHandler = callback;\n }\n\n /**\n * Register a handler for Twilio `asyncAmdStatusCallback` webhooks.\n *\n * Registering makes later outbound calls pass `asyncAmdStatusCallback` to\n * `calls.create`; without a handler TAC omits it and Twilio has nowhere to\n * post the result. It does not enable detection — that's per-call, via\n * `CallOptions.machineDetection` and `asyncAmd`, both of which are required\n * for this to fire (at most once per call).\n *\n * @example\n * ```typescript\n * voiceChannel.onAmd(async event => {\n * if (event.isMachine) {\n * await voiceChannel.endCall(event.callSid); // voicemail → hang up\n * }\n * });\n * ```\n */\n public onAmd(callback: AmdHandler): void {\n this.onAmdHandler = callback;\n }\n\n /**\n * Register a handler for Twilio `recordingStatusCallback` webhooks.\n *\n * Registering makes later outbound calls pass `recordingStatusCallback` to\n * `calls.create`; without a handler TAC omits it and Twilio has nowhere to\n * post. It does not start recording — that's `CallOptions.record`, which is\n * required for this to fire.\n *\n * @example\n * ```typescript\n * voiceChannel.onRecording(async event => {\n * if (event.recordingStatus === 'completed') {\n * // store event.recordingUrl\n * }\n * });\n * ```\n */\n public onRecording(callback: RecordingHandler): void {\n this.onRecordingHandler = callback;\n }\n\n /**\n * Register a handler for DTMF keypresses, called once per key in order.\n *\n * Requires `dtmfDetection: true` on the ConversationRelay config — without it\n * Twilio sends nothing and this never fires. Digits aren't buffered, so\n * accumulating a multi-digit entry is the handler's job.\n *\n * A keypress initializes the conversation just as a prompt does, since a\n * caller can type without ever speaking; if that fails the digit still\n * arrives, with `conversationId` and `session` undefined. Keypresses don't\n * cancel in-flight streaming on their own — that's a separate `interrupt`\n * message, sent when `interruptible` includes `dtmf`.\n *\n * @example\n * ```typescript\n * const digits = new Map<string, string>();\n *\n * voiceChannel.onDtmf(({ conversationId, digit }) => {\n * if (!conversationId) return;\n * digits.set(conversationId, (digits.get(conversationId) ?? '') + digit);\n * });\n * ```\n */\n public onDtmf(callback: DtmfHandler): void {\n this.voiceCallbacks.onDtmf = callback;\n }\n\n /**\n * Resolve the public WebSocket URL from `TACConfig.voicePublicDomain` +\n * `TACConfig.voiceWebsocketPath`. Throws if `voicePublicDomain` isn't set.\n */\n private resolveWebsocketUrl(action: string): string {\n if (this.config.voicePublicDomain) {\n return `wss://${this.config.voicePublicDomain}${this.config.voiceWebsocketPath}`;\n }\n throw new Error(\n `${action} needs a WebSocket URL. Set TWILIO_VOICE_PUBLIC_DOMAIN ` +\n '(or TACConfig.voicePublicDomain).'\n );\n }\n\n /**\n * Resolve the default `<Connect action=...>` cleanup URL.\n *\n * Returns undefined if `voicePublicDomain` isn't set; that's fine because\n * actionUrl has higher-priority layers (customizer, twimlOptions, Studio\n * handoff) above this fallback.\n */\n private resolveDefaultActionUrl(): string | undefined {\n if (this.config.voicePublicDomain) {\n return `https://${this.config.voicePublicDomain}${this.config.voiceActionPath}`;\n }\n return undefined;\n }\n\n private getTwilioClient(): ReturnType<typeof Twilio> {\n if (!this.twilioClient) {\n this.twilioClient = Twilio(this.config.apiKey, this.config.apiSecret, {\n accountSid: this.config.accountSid,\n });\n }\n return this.twilioClient;\n }\n\n public get channelType(): ChannelType {\n return 'voice';\n }\n\n /**\n * Register event callbacks (override for Voice-specific events)\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic event callback needs to accept any args\n public override on(event: string, callback: (...args: any[]) => void): void {\n switch (event) {\n case 'setup':\n this.voiceCallbacks.onSetup = callback;\n break;\n case 'prompt':\n this.voiceCallbacks.onPrompt = callback;\n break;\n case 'interrupt':\n this.voiceCallbacks.onInterrupt = callback;\n break;\n case 'dtmf':\n this.voiceCallbacks.onDtmf = callback;\n break;\n case 'webSocketConnected':\n this.voiceCallbacks.onWebSocketConnected = callback;\n break;\n case 'webSocketDisconnected':\n this.voiceCallbacks.onWebSocketDisconnected = callback;\n break;\n default:\n // Delegate to parent for base events\n super.on(event, callback);\n break;\n }\n }\n\n /**\n * Process conversation webhooks for cleanup.\n *\n * Voice channel processes CONVERSATION_UPDATED events:\n * - CLOSED status: Clean up local session state\n *\n * Note: Conversation tracking uses instance-local memory. In multi-instance\n * deployments, webhooks may route to a different instance, preventing cleanup.\n *\n * @param payload - Raw webhook event data from Twilio\n * @param idempotencyToken - Optional Twilio idempotency token from request headers\n */\n public async processWebhook(payload: unknown, idempotencyToken?: string): Promise<void> {\n try {\n const result = this.preprocessWebhook(payload, idempotencyToken);\n if (!result) {\n return;\n }\n\n const { webhookData, eventType, conversationId } = result;\n\n switch (eventType) {\n case 'CONVERSATION_UPDATED':\n this.logger.debug(\n { conversation_id: conversationId, status: webhookData.data?.status },\n 'Handling CONVERSATION_UPDATED'\n );\n await this.handleConversationUpdated(webhookData);\n break;\n\n default:\n this.logger.debug(\n {\n event_type: eventType,\n raw_event_type: webhookData.eventType,\n conversation_id: conversationId,\n },\n 'Unhandled event type - this event will be ignored'\n );\n }\n\n this.logger.debug({ event_type: eventType }, 'Webhook processing completed');\n } catch (error) {\n // Remove the token so retries are not blocked\n if (idempotencyToken) {\n this.removeWebhookToken(idempotencyToken);\n }\n this.handleError(error instanceof Error ? error : new Error(String(error)), { payload });\n }\n }\n\n /**\n * Handle conversation updated event\n */\n private async handleConversationUpdated(payload: ConversationWebhookPayload): Promise<void> {\n const conversationId = this.extractConversationId(payload);\n\n if (!conversationId) {\n throw new Error('Missing conversation ID in conversation.updated event');\n }\n\n // Check if conversation is closed\n if (payload.data?.status === 'CLOSED') {\n this.logger.debug(\n { conversation_id: conversationId, status: payload.data.status },\n 'Conversation closed, cleaning up'\n );\n await this.endConversation(conversationId);\n } else if (payload.data?.status === 'INACTIVE') {\n // \"once\" mode: drop the cache so the next message re-fetches.\n this.invalidateCachedMemory(conversationId);\n }\n }\n\n /**\n * Get active WebSocket connection for a conversation\n */\n public getWebsocket(conversationId: ConversationId): WebSocket | null {\n return this.webSocketConnections.get(conversationId) || null;\n }\n\n /**\n * Poll Conversation Orchestrator for the conversation ConversationRelay\n * created for `callSid`, then register the local session and WebSocket.\n * Runs in the background from `setup`, so those can exist before the\n * caller speaks.\n */\n private async initializeOrchestratedConversation(\n callSid: string,\n fromNumber: string | null,\n ws: WebSocket\n ): Promise<ConversationId> {\n if (!this.conversationClient) {\n throw new Error('Conversation client is required in orchestrated mode');\n }\n\n let conversations: Awaited<ReturnType<typeof this.conversationClient.listConversations>> = [];\n\n for (let attempt = 0; attempt < POLL_ATTEMPTS; attempt++) {\n // ACTIVE only: a stale conversation on the same CallSid would break the\n // \"exactly 1\" check below.\n conversations = await this.conversationClient.listConversations({\n channelId: callSid,\n status: ['ACTIVE'],\n });\n if (conversations.length === 1) break;\n if (attempt < POLL_ATTEMPTS - 1) {\n this.logger.debug(\n { call_sid: callSid, attempt: attempt + 1, found: conversations.length },\n 'Conversation not ready yet, polling again'\n );\n const delayMs = Math.min(POLL_BASE_DELAY_MS * 2 ** attempt, POLL_MAX_DELAY_MS);\n await new Promise(resolve => setTimeout(resolve, delayMs));\n }\n }\n\n if (conversations.length !== 1) {\n throw new Error(\n `Expected exactly 1 conversation for callSid ${callSid}, ` +\n `but found ${conversations.length} after ${POLL_ATTEMPTS} attempts`\n );\n }\n\n const conversation = conversations[0]!;\n const conversationId = conversation.id as ConversationId;\n\n const participants = await this.conversationClient.listParticipants(conversationId);\n\n const customerParticipant = participants.find(p => p.type === 'CUSTOMER');\n const customerAddress =\n customerParticipant?.addresses?.find(a => a.channel === 'VOICE')?.address ??\n fromNumber ??\n undefined;\n const profileId: ProfileId | undefined = customerParticipant?.profileId\n ? (customerParticipant.profileId as ProfileId)\n : undefined;\n\n this.webSocketConnections.set(conversationId, ws);\n this.callSidToConversationId.set(callSid, conversationId);\n const session = this.startConversation(conversationId, profileId);\n // conversationId is the Orchestrator's, so record the CallSid too —\n // out-of-band call webhooks resolve via getConversationSessionByCallSid.\n session.callSid = callSid;\n\n if (customerAddress) {\n session.authorInfo = {\n address: customerAddress,\n };\n }\n\n if (this.voiceCallbacks.onWebSocketConnected) {\n this.voiceCallbacks.onWebSocketConnected({ conversationId });\n }\n\n return conversationId;\n }\n\n /**\n * Handle WebSocket connection from ConversationRelay\n */\n public handleWebSocketConnection(ws: WebSocket): void {\n let conversationId: ConversationId | null = null;\n let callSid: string | null = null;\n let fromNumber: string | null = null;\n let initializationFailed = false;\n // Background conversation lookup started on `setup`; cleared once claimed,\n // by the first message that needs a conversation or by the close handler.\n let initPromise: Promise<ConversationId> | null = null;\n\n /**\n * Resolve this connection's conversation, creating it on first use.\n *\n * Shared by `prompt` and `dtmf` because either can be the first message\n * that needs a conversation — a caller can press a digit before speaking,\n * and until the session and WebSocket are registered a handler has no way\n * to respond. Returns null when `setup` hasn't arrived yet (no callSid);\n * rejects when initialization fails, after recording the attempt so a\n * later message can retry up to MAX_INITIALIZATION_RETRIES.\n */\n const ensureConversation = async (): Promise<ConversationId | null> => {\n if (conversationId) {\n return conversationId;\n }\n const sid = callSid;\n if (!sid) {\n return null;\n }\n\n // Check retry limit before attempting initialization\n const retryCount = this.initializationRetries.get(sid) ?? 0;\n if (retryCount >= this.MAX_INITIALIZATION_RETRIES) {\n throw new Error(\n `Cannot process message - conversation initialization failed after ${retryCount} attempts for callSid ${sid}`\n );\n }\n\n try {\n if (initializationFailed) {\n this.logger.info(\n { call_sid: sid, retry_count: retryCount },\n 'Retrying conversation initialization after previous failure'\n );\n }\n\n if (!this.tac.isOrchestratorEnabled()) {\n // Voice-only mode: use callSid as conversationId directly\n conversationId = sid as ConversationId;\n this.webSocketConnections.set(conversationId, ws);\n this.callSidToConversationId.set(sid, conversationId);\n const session = this.startConversation(conversationId);\n // Relay-only: conversationId === callSid.\n session.callSid = sid;\n\n if (fromNumber) {\n session.authorInfo = { address: fromNumber };\n }\n\n if (this.voiceCallbacks.onWebSocketConnected) {\n this.voiceCallbacks.onWebSocketConnected({ conversationId });\n }\n } else {\n // Await the lookup from `setup` — usually already done.\n // Stays visible to the close handler while awaited, so a\n // hangup mid-lookup still cleans up; cleared after so a\n // retry starts fresh and `close` uses conversationId.\n initPromise ??= this.initializeOrchestratedConversation(sid, fromNumber, ws);\n try {\n conversationId = await initPromise;\n } finally {\n initPromise = null;\n }\n }\n\n // Success! Clear retry count and failed flag\n initializationFailed = false;\n this.initializationRetries.delete(sid);\n this.logger.info(\n { conversation_id: conversationId, call_sid: sid },\n 'Conversation initialization succeeded'\n );\n return conversationId;\n } catch (err) {\n initializationFailed = true;\n this.initializationRetries.set(sid, retryCount + 1);\n this.logger.error(\n { err, call_sid: sid, retry_count: retryCount + 1 },\n 'Conversation initialization failed'\n );\n throw err;\n }\n };\n\n ws.on('message', (data: Buffer) => {\n (async (): Promise<void> => {\n try {\n const messageData = JSON.parse(data.toString()) as unknown;\n const result = WebSocketMessageSchema.safeParse(messageData);\n\n if (!result.success) {\n this.logger.debug(\n {\n validation_errors: result.error.issues.map(issue => ({\n path: issue.path.join('.'),\n message: issue.message,\n })),\n },\n 'Invalid or unrecognized WebSocket message, skipping'\n );\n return;\n }\n\n const message = result.data;\n\n switch (message.type) {\n case 'setup':\n callSid = message.callSid;\n fromNumber = message.from;\n\n // ConversationRelay creates the conversation at call-connect, so\n // start the lookup now and let it overlap the wait for the\n // caller's first utterance instead of delaying it.\n if (this.tac.isOrchestratorEnabled()) {\n this.logger.debug(\n { call_sid: callSid },\n 'Starting background conversation initialization'\n );\n initPromise = this.initializeOrchestratedConversation(callSid, fromNumber, ws);\n // Marks it handled; whoever claims it still sees the rejection.\n void initPromise.catch(() => undefined);\n }\n\n if (this.voiceCallbacks.onSetup) {\n this.voiceCallbacks.onSetup({\n callSid,\n from: message.from,\n to: message.to,\n customParameters: message.customParameters,\n });\n }\n break;\n\n case 'prompt':\n await ensureConversation();\n\n if (conversationId) {\n const previousPrompt = this.promptQueues.get(conversationId) ?? Promise.resolve();\n const currentPrompt = previousPrompt\n .then(() => this.handlePromptMessage(conversationId!, message))\n .catch((err: unknown) => {\n this.handleError(err instanceof Error ? err : new Error(String(err)), {\n conversationId,\n message: data.toString(),\n });\n });\n this.promptQueues.set(conversationId, currentPrompt);\n } else {\n this.logger.warn('Received prompt before conversation initialized');\n }\n break;\n\n case 'interrupt':\n if (conversationId) {\n this.handleInterruptMessage(conversationId, message);\n }\n break;\n\n case 'dtmf':\n // A keypress can be the caller's first input, so initialize the\n // conversation the same way a prompt does — without it the handler\n // has no session and no WebSocket to respond on. Unlike a prompt, a\n // failure here is logged rather than thrown: the digit is still\n // worth delivering, just without a conversation.\n try {\n await ensureConversation();\n } catch (err) {\n this.logger.warn(\n { err, call_sid: callSid },\n 'Conversation initialization failed on DTMF keypress, delivering digit without a conversation'\n );\n }\n\n await this.handleDtmfMessage(conversationId, callSid, message);\n break;\n\n default:\n this.logger.debug(\n {\n conversation_id: conversationId,\n message_type: (messageData as Record<string, unknown>)?.type,\n },\n 'Unhandled WebSocket event type'\n );\n break;\n }\n } catch (error) {\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n callSid,\n message: data.toString(),\n });\n }\n })().catch((err: unknown) => {\n this.logger.error({ err }, 'Unhandled error in WebSocket message handler');\n });\n });\n\n ws.on('close', () => {\n // Call ended before any prompt claimed the lookup. A promise can't be\n // cancelled, so adopt what it registers and tear that down, or the\n // WebSocket registration leaks. The conversation stays tracked (CLOSED).\n const pendingInit = initPromise;\n initPromise = null;\n if (pendingInit && !conversationId) {\n void pendingInit\n .then(async adoptedId => {\n await this.handleWebSocketDisconnect(adoptedId);\n if (callSid) this.callSidToConversationId.delete(callSid);\n })\n // No prompt ever arrived to surface a lookup failure, so log here.\n .catch((err: unknown) => {\n this.logger.error(\n { err, call_sid: callSid },\n 'Background conversation initialization failed after the call ended'\n );\n });\n }\n\n if (conversationId) {\n void this.handleWebSocketDisconnect(conversationId).catch((err: unknown) => {\n this.logger.error(\n { err, conversation_id: conversationId },\n 'WebSocket disconnect handler error'\n );\n });\n }\n if (callSid) {\n this.initializationRetries.delete(callSid);\n this.callSidToConversationId.delete(callSid);\n }\n });\n\n ws.on('error', (error: Error) => {\n this.handleError(error, { conversationId });\n });\n }\n\n /**\n * Handle WebSocket prompt message (user speech)\n */\n private async handlePromptMessage(\n conversationId: ConversationId,\n message: PromptMessage\n ): Promise<void> {\n const transcript = message.voicePrompt;\n\n // Start a new stream task so the AbortSignal is available to handlers.\n // startStreamTask() cancels any existing task internally.\n const streamTask = this.startStreamTask(conversationId);\n\n // Get session for memory retrieval\n const session = this.getConversationSession(conversationId);\n\n // Retrieve memory if enabled via memoryMode\n const userMemory = session\n ? await this.retrieveMemoryIfEnabled(session, transcript)\n : undefined;\n\n if (this.voiceCallbacks.onPrompt) {\n await this.voiceCallbacks.onPrompt({\n conversationId,\n transcript,\n abortSignal: streamTask.controller.signal,\n ...(userMemory !== undefined && { userMemory }),\n ...(session !== undefined && { session }),\n });\n }\n }\n\n /**\n * Handle WebSocket interrupt message\n */\n private handleInterruptMessage(conversationId: ConversationId, message: InterruptMessage): void {\n const { utteranceUntilInterrupt, durationUntilInterruptMs } = message;\n\n // Check whether tokens were sent before cancelling (cancel deletes the entry)\n const streamTask = this.streamTasks.get(conversationId);\n const wasStreaming = streamTask?.hasSentTokens ?? false;\n\n // Cancel any in-flight stream task on interrupt\n const cancelled = this.cancelStreamTask(conversationId);\n if (cancelled) {\n this.logger.info(\n { conversation_id: conversationId },\n 'Cancelled stream task due to interrupt'\n );\n }\n\n // Finalize the interrupted token stream so ConversationRelay stops\n // waiting for more tokens. Only needed when tokens were actually sent;\n // sending last:true without a preceding stream creates a spurious empty turn.\n if (cancelled && wasStreaming) {\n const ws = this.webSocketConnections.get(conversationId);\n if (ws?.readyState === WebSocket.OPEN) {\n try {\n ws.send(JSON.stringify({ type: 'text', token: '', last: true }));\n } catch (err) {\n this.logger.debug(\n { conversation_id: conversationId, err },\n 'WebSocket closed before sending stream finalization'\n );\n }\n }\n }\n\n if (this.voiceCallbacks.onInterrupt) {\n this.voiceCallbacks.onInterrupt({\n conversationId,\n utteranceUntilInterrupt,\n durationUntilInterruptMs,\n });\n }\n }\n\n /**\n * Handle WebSocket DTMF message (caller keypress)\n */\n private async handleDtmfMessage(\n conversationId: ConversationId | null,\n callSid: string | null,\n message: DtmfMessage\n ): Promise<void> {\n const { digit } = message;\n\n // Never log the digit itself — callers type account numbers and PINs on the\n // keypad, and nothing downstream scrubs it.\n this.logger.debug({ conversation_id: conversationId, call_sid: callSid }, 'DTMF keypress');\n\n if (!this.voiceCallbacks.onDtmf) {\n return;\n }\n\n const session = conversationId ? this.getConversationSession(conversationId) : undefined;\n\n await this.voiceCallbacks.onDtmf({\n conversationId: conversationId ?? undefined,\n callSid: callSid ?? undefined,\n digit,\n ...(session !== undefined && { session }),\n });\n }\n\n /**\n * Handle WebSocket disconnection. In orchestrated mode the conversation stays\n * tracked until the CLOSED webhook (so a follow-up call can reuse it); in\n * voice-only mode there is no such webhook, so it ends here.\n */\n private async handleWebSocketDisconnect(conversationId: ConversationId): Promise<void> {\n this.cancelStreamTask(conversationId);\n this.webSocketConnections.delete(conversationId);\n this.promptQueues.delete(conversationId);\n\n if (this.voiceCallbacks.onWebSocketDisconnected) {\n this.voiceCallbacks.onWebSocketDisconnected({ conversationId });\n }\n\n if (!this.tac.isOrchestratorEnabled()) {\n await this.endConversation(conversationId);\n }\n }\n\n /**\n * Send voice response via WebSocket\n */\n public sendResponse(\n conversationId: ConversationId,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n try {\n const ws = this.webSocketConnections.get(conversationId);\n\n if (ws?.readyState !== WebSocket.OPEN) {\n throw new Error(`No active WebSocket connection for conversation ${conversationId}`);\n }\n\n const response: TextTokenMessage = {\n type: 'text',\n token: message,\n last: true,\n };\n\n ws.send(JSON.stringify(response));\n\n // If a handoff is pending, send the WS \"end\" message now that the\n // LLM's final response has been delivered to the caller.\n const session = this.getConversationSession(conversationId);\n if (session?.pendingHandoffData) {\n try {\n ws.send(JSON.stringify(session.pendingHandoffData));\n delete session.pendingHandoffData;\n } catch (err) {\n this.logger.warn(\n { err, conversation_id: conversationId },\n 'WebSocket closed before sending handoff end message; caller will not be transferred'\n );\n }\n }\n\n return Promise.resolve();\n } catch (error) {\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n message,\n metadata,\n });\n throw error;\n }\n }\n\n /**\n * Send a streaming voice response via WebSocket, token by token.\n *\n * Each chunk from the iterable is sent as a text token message with last: false.\n * After the iterable completes, a final empty marker with last: true is sent\n * only if at least one token was emitted. If the AbortSignal fires (e.g., user\n * interrupted), iteration stops and no final marker is sent (the interrupt\n * handler sends the finalization instead).\n *\n * @returns The accumulated full response text.\n */\n public async sendStreamingResponse(\n conversationId: ConversationId,\n stream: AsyncIterable<string>,\n options?: { signal?: AbortSignal }\n ): Promise<string> {\n const ws = this.webSocketConnections.get(conversationId);\n\n if (ws?.readyState !== WebSocket.OPEN) {\n throw new Error(`No active WebSocket connection for conversation ${conversationId}`);\n }\n\n const activeTask = this.streamTasks.get(conversationId);\n const signal = options?.signal ?? activeTask?.controller.signal;\n let fullResponse = '';\n let hasSentTokens = false;\n\n if (signal?.aborted) {\n return fullResponse;\n }\n\n try {\n for await (const chunk of stream) {\n if (signal?.aborted) {\n break;\n }\n\n if (ws.readyState !== WebSocket.OPEN) {\n this.logger.info(\n { conversation_id: conversationId },\n 'WebSocket closed during streaming'\n );\n break;\n }\n\n fullResponse += chunk;\n const tokenMessage: TextTokenMessage = {\n type: 'text',\n token: chunk,\n last: false,\n };\n ws.send(JSON.stringify(tokenMessage));\n hasSentTokens = true;\n if (activeTask) {\n activeTask.hasSentTokens = true;\n }\n }\n\n if (!signal?.aborted && hasSentTokens && ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: 'text', token: '', last: true }));\n }\n } catch (error) {\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n conversationId,\n });\n throw error;\n } finally {\n // Only clean up if we still own the active stream task.\n // A new prompt may have replaced it while we were unwinding.\n if (activeTask && this.streamTasks.get(conversationId) === activeTask) {\n this.completeStreamTask(conversationId);\n }\n }\n\n return fullResponse;\n }\n\n // =========================================================================\n // Incoming Call Handling\n // =========================================================================\n\n /**\n * Generate the TwiML response for an incoming voice call.\n *\n * ConversationRelay automatically handles conversation creation and\n * participant management via the `conversationConfiguration` parameter.\n *\n * The WebSocket URL and default session-cleanup action URL are derived from\n * `TACConfig.voicePublicDomain` + `TACConfig.voiceWebsocketPath` /\n * `voiceActionPath`.\n *\n * TwiML fields are merged per-field, highest precedence first:\n * 1. Output of the customizer registered via\n * `VoiceChannel.onInboundCallTwiml(...)` if configured and `twimlRequest`\n * is given. (Application-owned.)\n * 2. `VoiceChannelConfig.defaultTwimlOptions` — per-channel defaults.\n * 3. `hostTwimlOptions` — per-call transport facts supplied by the host (the\n * code owning the route), e.g. a per-call `websocketUrl` with an affinity\n * token.\n * 4. TAC defaults: a fixed default welcomeGreeting, `conversationConfiguration`\n * from `TACConfig`, `actionUrl` resolved via Studio handoff (when\n * `studioHandoffFlowSid` is configured), else derived from\n * `TACConfig.voicePublicDomain` + `voiceActionPath`, and the `websocketUrl`\n * derived from `TACConfig.voicePublicDomain` + `voiceWebsocketPath`.\n *\n * Fields not set at a layer fall through to lower layers. Arrays (`languages`)\n * and nested objects (`customParameters`) replace wholesale when set at a\n * higher-priority layer. `websocketUrl` falls back to the `TACConfig`-derived\n * URL if unset at every layer.\n *\n * @param twimlRequest - Parsed Twilio webhook fields. Passed to the customizer\n * if one is configured on the channel.\n * @param options - Additional per-call inputs.\n * @param options.hostTwimlOptions - Per-call TwiML supplied by a custom\n * in-process host (e.g. an affinity-routed deployment injecting a per-call\n * `websocketUrl`), layered below `defaultTwimlOptions` and the application\n * customizer but above the TAC defaults.\n * @returns TwiML XML string for call connection.\n */\n public async handleIncomingCall(\n twimlRequest?: TwiMLRequest,\n options?: { hostTwimlOptions?: TwiMLOptions }\n ): Promise<string> {\n let customized: TwiMLOptions | undefined;\n if (this.onInboundCallTwimlHandler && twimlRequest) {\n customized = await this.onInboundCallTwimlHandler(twimlRequest);\n }\n\n const merged = this.buildTwimlOptions(options?.hostTwimlOptions, customized);\n const websocketUrl = merged.websocketUrl ?? this.resolveWebsocketUrl('handleIncomingCall');\n return this.generateTwiml(websocketUrl, merged);\n }\n\n /**\n * Layer TwiML options, lowest precedence first: TAC defaults → `host`\n * (calling host's per-call values) → channel `defaultTwimlOptions` → `perCall`\n * (application customizer output for inbound, or\n * `InitiateVoiceConversationOptions.twimlOptions` for outbound).\n */\n private buildTwimlOptions(\n host: TwiMLOptions | undefined,\n perCall: TwiMLOptions | undefined\n ): TwiMLOptions {\n const merged: TwiMLOptions = {\n welcomeGreeting: DEFAULT_WELCOME_GREETING,\n ...(this.tac.isOrchestratorEnabled() && this.config.conversationConfigurationId !== undefined\n ? { conversationConfiguration: this.config.conversationConfigurationId }\n : {}),\n };\n const resolvedActionUrl = this.resolveActionUrl(host, perCall);\n if (resolvedActionUrl !== undefined) {\n merged.actionUrl = resolvedActionUrl;\n }\n if (host) {\n this.overlayFields(merged, host);\n }\n if (this.voiceConfig.defaultTwimlOptions) {\n this.overlayFields(merged, this.voiceConfig.defaultTwimlOptions);\n }\n if (perCall) {\n this.overlayFields(merged, perCall);\n }\n return merged;\n }\n\n /**\n * Apply fields explicitly present on `source` onto `target`.\n *\n * Nested objects (`customParameters`), arrays (`languages`), and dicts\n * (`extra`) replace wholesale — there's no per-key merging.\n *\n * `actionUrl` is skipped here on purpose — it's resolved once via\n * `resolveActionUrl` looking at every layer at once, and that resolved value\n * is written into `target` before this overlay runs. Letting it through here\n * would let a higher-priority layer that didn't set actionUrl silently clobber\n * a lower layer that did.\n *\n * \"Explicitly present\" is detected via key presence (`key in source`), which\n * mirrors Python's `model_fields_set`: a key set to `undefined` is still\n * \"present\" and overrides lower layers, while an absent key falls through.\n */\n private overlayFields(target: TwiMLOptions, source: TwiMLOptions): void {\n for (const key of Object.keys(source) as (keyof TwiMLOptions)[]) {\n if (key === 'actionUrl') {\n continue;\n }\n // Index assignment across a heterogeneous record; both sides are TwiMLOptions.\n (target as Record<string, unknown>)[key] = (source as Record<string, unknown>)[key];\n }\n }\n\n /**\n * Resolve the TwiML `<Connect action=...>` URL.\n *\n * Precedence (highest to lowest):\n * 1. application customizer\n * 2. channel `defaultTwimlOptions`\n * 3. `host` (calling host's per-call options)\n * 4. Studio handoff (when `studioHandoffFlowSid` is configured)\n * 5. Channel default — derived from `TACConfig.voicePublicDomain` +\n * `TACConfig.voiceActionPath`.\n *\n * User-expressed intent (Studio handoff is configured explicitly on\n * `TACConfig`) beats the SDK's generated cleanup default.\n *\n * Explicit `actionUrl: undefined` on a layer (key present, value undefined)\n * suppresses `<Connect action=...>` entirely — all lower layers are skipped.\n * `actionUrl` left absent (key not present) falls through to the next layer.\n */\n private resolveActionUrl(\n host: TwiMLOptions | undefined,\n customized: TwiMLOptions | undefined\n ): string | undefined {\n if (customized && 'actionUrl' in customized) {\n return customized.actionUrl;\n }\n if (\n this.voiceConfig.defaultTwimlOptions &&\n 'actionUrl' in this.voiceConfig.defaultTwimlOptions\n ) {\n return this.voiceConfig.defaultTwimlOptions.actionUrl;\n }\n if (host && 'actionUrl' in host) {\n return host.actionUrl;\n }\n if (this.config.studioHandoffFlowSid) {\n return studioVoiceHandoffUrl(this.config.accountSid, this.config.studioHandoffFlowSid);\n }\n return this.resolveDefaultActionUrl();\n }\n\n // =========================================================================\n // Outbound Call Handling\n // =========================================================================\n\n /**\n * Overlay `perCall` onto `VoiceChannelConfig.defaultCallOptions`.\n *\n * Per-field via key presence, the same convention {@link overlayFields} uses\n * for TwiML options — so a per-call `{ machineDetection: undefined }`\n * explicitly clears the channel default rather than falling through to it.\n *\n * The result is always validated, for two reasons: a combination only\n * reachable by layering — per-call clearing `machineDetection` while the\n * default set `asyncAmd` — must still fail instead of reaching Twilio, and\n * `VoiceChannelConfig` is a plain interface, so `defaultCallOptions` has had\n * no runtime validation of its own.\n */\n private mergeCallOptions(perCall: CallOptions | undefined): CallOptions | undefined {\n const defaults = this.voiceConfig.defaultCallOptions;\n if (!defaults && !perCall) {\n return undefined;\n }\n\n const merged: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(defaults ?? {})) {\n if (value !== undefined) {\n merged[key] = value;\n }\n }\n for (const key of Object.keys(perCall ?? {})) {\n merged[key] = (perCall as Record<string, unknown>)[key];\n }\n return CallOptionsSchema.parse(merged);\n }\n\n /**\n * Build the extra arguments for `client.calls.create`.\n *\n * Layers, highest precedence first: this call's `callOptions`,\n * `VoiceChannelConfig.defaultCallOptions`, then callback URLs derived from\n * `voicePublicDomain` + `voiceCallEventPath`.\n *\n * A URL is derived only when its handler is registered. That's a deliberate\n * deviation from `websocketUrl` / `actionUrl`, which derive unconditionally:\n * those are load-bearing, so a wrong one fails loudly on the first call,\n * whereas an unwanted call-event URL fails as silent 11200 alerts for a\n * feature nobody asked for. Set the URLs in `defaultCallOptions` when TAC\n * isn't serving the routes.\n */\n private buildCallParams(callOptions: CallOptions | undefined): Record<string, unknown> {\n const merged = this.mergeCallOptions(callOptions);\n const params = merged ? callOptionsToCreateParams(merged) : {};\n\n const wiring: [CallEventKind, string, unknown][] = [\n ['status', 'statusCallback', this.onCallStatusHandler],\n ['amd', 'asyncAmdStatusCallback', this.onAmdHandler],\n ['recording', 'recordingStatusCallback', this.onRecordingHandler],\n ];\n for (const [kind, param, handler] of wiring) {\n if (!handler) continue;\n const url = this.config.callEventUrl(kind);\n // An explicit URL from either options layer is never overwritten.\n if (url !== undefined && params[param] === undefined) {\n params[param] = url;\n }\n }\n\n return params;\n }\n\n /**\n * Initiate an outbound voice conversation\n *\n * Places an outbound call with inline TwiML that connects to ConversationRelay.\n * The conversationConfiguration attribute tells CO to create and manage the\n * conversation during passive hydration. The session is initialized when the\n * background callSid lookup started at WebSocket setup finds it.\n *\n * TwiML fields are merged per-field, highest precedence first:\n * 1. `options.twimlOptions` — per-call overrides\n * 2. `VoiceChannelConfig.defaultTwimlOptions` — channel-wide defaults\n * 3. TAC defaults: welcome greeting, `conversationConfiguration` from\n * `TACConfig`, and `actionUrl` from Studio handoff (if configured), else\n * derived from `TACConfig.voicePublicDomain` + `voiceActionPath`.\n *\n * Calls-API parameters merge the same way:\n * 1. `options.callOptions` — per-call overrides\n * 2. `VoiceChannelConfig.defaultCallOptions` — channel-wide defaults\n * 3. Callback URLs derived from `TACConfig.voicePublicDomain` +\n * `voiceCallEventPath`, for handlers that are registered\n *\n * The WebSocket URL is derived from `TACConfig.voicePublicDomain` +\n * `TACConfig.voiceWebsocketPath`, unless overridden per-call via\n * `options.websocketUrl`.\n */\n public async initiateOutboundConversation(\n options: InitiateVoiceConversationOptions\n ): Promise<InitiateVoiceConversationResult> {\n const validated = InitiateVoiceConversationOptionsSchema.parse(options);\n const fromNumber = this.config.phoneNumber;\n\n this.logger.info(\n { to: validated.to, from: fromNumber },\n 'Initiating outbound voice conversation'\n );\n\n try {\n // Outbound has no inbound customizer and no host layer; the per-call\n // override is options.twimlOptions.\n const merged = this.buildTwimlOptions(undefined, validated.twimlOptions);\n\n // `options.websocketUrl` is the dedicated per-call outbound override and\n // wins over any websocketUrl that came through the layered twimlOptions\n // merge; both fall back to the TACConfig-derived URL.\n const websocketUrl =\n validated.websocketUrl ??\n merged.websocketUrl ??\n this.resolveWebsocketUrl('initiateOutboundConversation');\n const twiml = this.generateTwiml(websocketUrl, merged);\n const callParams = this.buildCallParams(validated.callOptions);\n\n // The inline TwiML handed to Twilio, useful for debugging the\n // <Connect action> handoff target. customParameters values are masked —\n // they're arbitrary developer data (profile IDs, caller names), unlike\n // the WS/action URLs and conversation config.\n this.logger.debug(\n { twiml: redactTwimlParameters(twiml), to: maskAddress(validated.to) },\n 'Outbound call TwiML'\n );\n\n // Place the outbound call with inline TwiML\n const client = this.getTwilioClient();\n const call = await client.calls.create({\n to: validated.to,\n from: fromNumber,\n twiml,\n ...callParams,\n });\n\n this.logger.info(\n { call_sid: call.sid, to: maskAddress(validated.to) },\n 'Outbound voice call placed'\n );\n\n return { callSid: call.sid };\n } catch (error) {\n this.logger.error(\n { err: error, to: maskAddress(validated.to) },\n 'Failed to initiate outbound call'\n );\n this.handleError(error instanceof Error ? error : new Error(String(error)), {\n to: validated.to,\n });\n throw error;\n }\n }\n\n // =========================================================================\n // ConversationRelay Callback Handling\n // =========================================================================\n\n /**\n * Handle ConversationRelay callback from Twilio. Cleans up on call completion\n * in voice-only mode; in orchestrated mode the CO webhook owns cleanup.\n *\n * @param payload - Callback payload from Twilio\n * @returns Response with status, content, and content type\n */\n public async handleConversationRelayCallback(\n payload: ConversationRelayCallbackPayload\n ): Promise<{ status: number; content: string; contentType: string }> {\n this.logger.debug(\n { call_sid: payload.CallSid, call_status: payload.CallStatus },\n 'ConversationRelay callback received'\n );\n\n if (payload.AccountSid !== this.config.accountSid) {\n this.logger.warn(\n { expected: this.config.accountSid, received: payload.AccountSid },\n 'ConversationRelay callback AccountSid mismatch, ignoring'\n );\n return { status: 403, content: 'Forbidden', contentType: 'text/plain' };\n }\n\n if (payload.CallStatus === 'completed' && !this.tac.isOrchestratorEnabled()) {\n const conversationId = this.callSidToConversationId.get(payload.CallSid);\n if (conversationId) {\n this.callSidToConversationId.delete(payload.CallSid);\n await this.endConversation(conversationId);\n }\n }\n\n return { status: 200, content: 'OK', contentType: 'text/plain' };\n }\n\n // =========================================================================\n // Call Event Handling (status callback, async AMD, recording)\n // =========================================================================\n\n /**\n * Whether a call-webhook payload belongs to the configured account.\n *\n * Twilio signature validation already gates the route; this is defense in\n * depth. A payload with no `AccountSid` is allowed through.\n *\n * Subaccounts: events carry the SID the call was placed on, so configure TAC\n * with that account or its events get dropped here.\n */\n private callEventAccountOk(form: Record<string, string>): boolean {\n const accountSid = form['AccountSid'];\n if (accountSid && accountSid !== this.config.accountSid) {\n this.logger.warn(\n { expected: this.config.accountSid, received: accountSid },\n 'Call event AccountSid mismatch, ignoring'\n );\n return false;\n }\n return true;\n }\n\n /**\n * Parse a call-event webhook form and dispatch it to its handler.\n *\n * Returns 400 when the payload can't be parsed (no `CallSid`) or the handler\n * throws — better than handing Twilio a 200 for an event that wasn't\n * processed. Everything else, including no handler registered and an\n * account mismatch, is a 200 no-op.\n */\n private async dispatchCallEvent<T>(\n kind: CallEventKind,\n form: Record<string, string>,\n handler: ((event: T) => Promise<void> | void) | undefined,\n parse: (form: Record<string, string>) => T,\n logFields: (event: T) => Record<string, unknown>\n ): Promise<{ status: number; content: string; contentType: string }> {\n const ok = { status: 200, content: 'OK', contentType: 'text/plain' };\n if (!handler || !this.callEventAccountOk(form)) {\n return ok;\n }\n\n try {\n const event = parse(form);\n this.logger.debug(logFields(event), `Call ${kind} event received`);\n await handler(event);\n } catch (error) {\n this.logger.error({ err: error, kind }, 'Failed to process call event callback');\n return { status: 400, content: 'Bad Request', contentType: 'text/plain' };\n }\n return ok;\n }\n\n /**\n * Handle a Twilio `statusCallback` webhook.\n *\n * The developer routes the request here (`TACServer` does this automatically\n * for its `/status` call-event route). Parsed into a {@link CallStatusEvent}\n * and dispatched to the {@link onCallStatus} handler. No-op if no handler is\n * registered.\n *\n * @param form - Raw form data from the webhook request.\n */\n public async handleCallStatusEvent(\n form: Record<string, string>\n ): Promise<{ status: number; content: string; contentType: string }> {\n return this.dispatchCallEvent(\n 'status',\n form,\n this.onCallStatusHandler,\n callStatusEventFromForm,\n event => ({ call_sid: event.callSid, call_status: event.callStatus })\n );\n }\n\n /**\n * Handle a Twilio `asyncAmdStatusCallback` webhook.\n *\n * The developer routes the request here (`TACServer` does this automatically\n * for its `/amd` call-event route). Parsed into an {@link AmdEvent} and\n * dispatched to the {@link onAmd} handler. No-op if no handler is registered.\n *\n * @param form - Raw form data from the webhook request.\n */\n public async handleAmdEvent(\n form: Record<string, string>\n ): Promise<{ status: number; content: string; contentType: string }> {\n return this.dispatchCallEvent('amd', form, this.onAmdHandler, amdEventFromForm, event => ({\n call_sid: event.callSid,\n answered_by: event.answeredBy,\n }));\n }\n\n /**\n * Handle a Twilio `recordingStatusCallback` webhook.\n *\n * The developer routes the request here (`TACServer` does this automatically\n * for its `/recording` call-event route). Parsed into a\n * {@link RecordingEvent} and dispatched to the {@link onRecording} handler.\n * No-op if no handler is registered.\n *\n * @param form - Raw form data from the webhook request.\n */\n public async handleRecordingEvent(\n form: Record<string, string>\n ): Promise<{ status: number; content: string; contentType: string }> {\n return this.dispatchCallEvent(\n 'recording',\n form,\n this.onRecordingHandler,\n recordingEventFromForm,\n event => ({ call_sid: event.callSid, recording_status: event.recordingStatus })\n );\n }\n\n /**\n * Hang up a call and clean up its ConversationRelay session.\n *\n * Works on `callSid` alone, whether or not a session exists yet. No-ops the\n * session cleanup if none is tracked.\n *\n * Does not throw — hanging up an already-ended call is routine (the callee\n * hangs up while AMD is still resolving), and handlers shouldn't have to\n * guard against it.\n *\n * @param callSid - Twilio Call SID (from a call event, the outbound result, or\n * `ConversationSession.callSid`).\n * @returns True if Twilio accepted the hangup, false if it failed (logged).\n * Session cleanup runs either way.\n */\n public async endCall(callSid: string): Promise<boolean> {\n const client = this.getTwilioClient();\n let hungUp = true;\n try {\n await client.calls(callSid).update({ status: 'completed' });\n } catch (error) {\n hungUp = false;\n this.logger.error({ err: error, call_sid: callSid }, 'Failed to hang up call');\n }\n\n const session = this.getConversationSessionByCallSid(callSid);\n if (session) {\n await this.endConversation(session.conversationId as ConversationId);\n }\n return hungUp;\n }\n\n /**\n * Look up the active voice session for a Twilio Call SID.\n *\n * Out-of-band code holding a CallSid — a dashboard route, an operator action,\n * a call-event handler — can't reach the session-facing methods, which are\n * keyed by conversation id: the Orchestrator conversation id in orchestrator\n * mode, the CallSid only in ConversationRelay-only mode.\n *\n * Relay-only mode creates the session on the first prompt; orchestrated\n * mode creates it when the lookup started at setup finishes, so it may\n * exist before the caller speaks — including before `onAmd` fires. Treat it\n * as racy and hang up with {@link endCall}, which needs no session.\n *\n * At the other end, orchestrator mode keeps the session until Conversation\n * Orchestrator's CLOSED webhook, so it outlives the call and `onCallStatus` /\n * `onRecording` do resolve. Relay-only mode tears down on the\n * ConversationRelay callback instead, which races them.\n *\n * @example\n * ```typescript\n * async function nudge(callSid: string): Promise<void> {\n * const session = voiceChannel.getConversationSessionByCallSid(callSid);\n * if (session) {\n * await voiceChannel.sendResponse(session.conversationId, 'Still there?');\n * }\n * }\n * ```\n *\n * @param callSid - Twilio Call SID, e.g. from\n * `InitiateVoiceConversationResult.callSid` or a call event.\n * @returns The session, or `undefined` — not created yet, the call ended, or\n * it landed on another instance (see the horizontal-scaling note in\n * CLAUDE.md).\n */\n public getConversationSessionByCallSid(callSid: string): ConversationSession | undefined {\n for (const session of this.activeConversations.values()) {\n if (session.callSid === callSid) {\n return session;\n }\n }\n return undefined;\n }\n\n // =========================================================================\n // Stream Task Management\n // =========================================================================\n\n /**\n * Start tracking a streaming task for a conversation\n *\n * @param conversationId - The conversation ID\n * @returns The stream task with its AbortController\n */\n public startStreamTask(conversationId: ConversationId): StreamTask {\n // Cancel any existing task\n this.cancelStreamTask(conversationId);\n\n const task: StreamTask = { controller: new AbortController(), hasSentTokens: false };\n this.streamTasks.set(conversationId, task);\n\n this.logger.debug({ conversation_id: conversationId }, 'Started stream task');\n return task;\n }\n\n /**\n * Cancel an active streaming task\n *\n * @param conversationId - The conversation ID\n * @returns true if a task was cancelled, false otherwise\n */\n public cancelStreamTask(conversationId: ConversationId): boolean {\n const task = this.streamTasks.get(conversationId);\n if (task) {\n task.controller.abort();\n this.streamTasks.delete(conversationId);\n this.logger.debug({ conversation_id: conversationId }, 'Cancelled stream task');\n return true;\n }\n return false;\n }\n\n /**\n * Complete a streaming task (remove from tracking)\n *\n * @param conversationId - The conversation ID\n */\n public completeStreamTask(conversationId: ConversationId): void {\n this.streamTasks.delete(conversationId);\n this.logger.debug({ conversation_id: conversationId }, 'Completed stream task');\n }\n\n /**\n * Check if a stream task is active\n *\n * @param conversationId - The conversation ID\n * @returns true if an active task exists\n */\n public hasActiveStreamTask(conversationId: ConversationId): boolean {\n const task = this.streamTasks.get(conversationId);\n return task !== undefined && !task.controller.signal.aborted;\n }\n\n // =========================================================================\n // ConversationRelay TwiML Generation\n // =========================================================================\n\n /**\n * Field names on {@link TwiMLOptions} that map directly to `<ConversationRelay>`\n * attributes (camelCase, emitted as-is). Excludes the fields handled specially\n * by {@link generateTwiml}: websocketUrl (resolved through the layered merge and\n * emitted as the `url` attribute), actionUrl, languages, customParameters, extra.\n */\n private static readonly RELAY_ATTR_FIELDS: readonly (keyof TwiMLOptions)[] = [\n 'welcomeGreeting',\n 'welcomeGreetingInterruptible',\n 'conversationConfiguration',\n 'language',\n 'ttsLanguage',\n 'transcriptionLanguage',\n 'voice',\n 'ttsProvider',\n 'transcriptionProvider',\n 'speechModel',\n 'elevenlabsTextNormalization',\n 'eotThreshold',\n 'partialPrompts',\n 'deepgramSmartFormat',\n 'speechTimeout',\n 'interruptible',\n 'interruptSensitivity',\n 'reportInputDuringAgentSpeech',\n 'ignoreBackchannel',\n 'preemptible',\n 'dtmfDetection',\n 'hints',\n 'events',\n 'debug',\n 'intelligenceService',\n ];\n\n /**\n * Generate TwiML XML for ConversationRelay from a merged {@link TwiMLOptions}.\n *\n * This is the low-level emitter used by `handleIncomingCall` and\n * `initiateOutboundConversation` after layering. It mirrors the Python SDK's\n * `generate_twiml`. The WebSocket URL may be passed as `websocketUrl` or via\n * `options.websocketUrl` (the explicit argument wins when both are given), so a\n * channel-less caller can pass everything in one object.\n *\n * @param websocketUrl - Public WebSocket URL (e.g. 'wss://example.ngrok.app/ws').\n * Optional if `options.websocketUrl` is set.\n * @param options - Merged TwiMLOptions to emit.\n * @returns TwiML XML string ready to return to Twilio.\n * @throws {Error} if no WebSocket URL is provided via either source.\n */\n private generateTwiml(websocketUrl: string | undefined, options: TwiMLOptions): string {\n const resolvedWebsocketUrl = websocketUrl || options.websocketUrl;\n if (!resolvedWebsocketUrl) {\n throw new Error(\n 'generateTwiml requires a WebSocket URL — pass it explicitly or set options.websocketUrl.'\n );\n }\n\n const response = new VoiceResponse();\n\n // <Connect action=...> — actionUrl undefined means no action attribute.\n const connect = response.connect(options.actionUrl ? { action: options.actionUrl } : {});\n\n // Build ConversationRelay attributes. Keys on TwiMLOptions are already\n // camelCase; the Twilio SDK serializes booleans/numbers as TwiML attribute\n // values.\n const relayAttrs: Record<string, unknown> = { url: resolvedWebsocketUrl };\n for (const field of VoiceChannel.RELAY_ATTR_FIELDS) {\n let value = options[field];\n if (value === undefined) {\n continue;\n }\n // Twilio accepts true/false on `interruptible` for backward-compat but the\n // documented enum is none|dtmf|speech|any. Normalize so we emit canonical\n // values regardless of the SDK's bool serialization.\n if (field === 'interruptible' && typeof value === 'boolean') {\n value = value ? 'any' : 'none';\n }\n relayAttrs[field] = value;\n }\n\n // `extra` is the escape hatch for attributes not yet typed. The schema's\n // shadow-guard rejects keys colliding with typed fields, so pass them\n // through as-is — except `url`: it's not a TwiMLOptions field (invisible to\n // the shadow-guard) but IS the resolved WebSocket endpoint, so letting\n // `extra.url` through would silently point the call at the wrong socket.\n if (options.extra) {\n for (const [key, value] of Object.entries(options.extra)) {\n if (key === 'url') {\n this.logger.warn(\n 'Ignoring `url` in TwiMLOptions.extra; set `websocketUrl` to override the ConversationRelay URL.'\n );\n continue;\n }\n relayAttrs[key] = value;\n }\n }\n\n const relay = connect.conversationRelay(\n relayAttrs as Parameters<typeof connect.conversationRelay>[0]\n );\n\n // Emit <Language> children, if any.\n if (options.languages && options.languages.length > 0) {\n for (const lang of options.languages) {\n const langAttrs = this.filterUnsetValues(lang);\n relay.language(langAttrs as Parameters<typeof relay.language>[0]);\n }\n }\n\n // Emit custom parameters as <Parameter> children, skipping null/undefined.\n if (options.customParameters) {\n for (const [name, value] of Object.entries(options.customParameters)) {\n if (value !== null && value !== undefined) {\n relay.parameter({ name, value: stringifyParameterValue(value) });\n }\n }\n }\n\n return response.toString();\n }\n\n /**\n * Generate TwiML to connect a call to ConversationRelay.\n * Validates configuration with Zod before generating TwiML.\n *\n * @param config - ConversationRelay configuration (url, transcription, TTS, etc.)\n * @param options - Optional settings for parameters and the Connect verb\n * @returns TwiML XML string\n * @throws {Error} if config validation fails\n */\n public connectConversationRelay(\n config: ConversationRelayConfig,\n options?: { parameters?: CustomParameters; actionUrl?: string }\n ): string {\n // Validate configuration with Zod schema (consistent with project pattern)\n const validationResult = ConversationRelayConfigSchema.safeParse(config);\n\n if (!validationResult.success) {\n const errorMessage = validationResult.error.issues\n .map(issue => `${issue.path.join('.')}: ${issue.message}`)\n .join(', ');\n throw new Error(`Invalid ConversationRelay configuration: ${errorMessage}`);\n }\n\n const validatedConfig = validationResult.data;\n\n // Extract languages array (child elements, not attributes)\n const { languages, ...conversationRelayAttributes } = validatedConfig;\n\n // Filter out undefined values to keep TwiML clean\n const filteredConfig = this.filterUnsetValues(conversationRelayAttributes);\n\n // Build TwiML using SDK\n const response = new VoiceResponse();\n const connect = response.connect(options?.actionUrl ? { action: options.actionUrl } : {});\n const relay = connect.conversationRelay(filteredConfig);\n\n // Add language configurations as child <Language> elements\n if (languages && languages.length > 0) {\n for (const lang of languages) {\n // Filter out undefined values to satisfy exactOptionalPropertyTypes\n // Type assertion is safe here because we've already validated with Zod\n const filteredLang = this.filterUnsetValues(lang);\n relay.language(filteredLang as Parameters<typeof relay.language>[0]);\n }\n }\n\n // Add custom parameters as child <Parameter> elements\n if (options?.parameters) {\n for (const [name, value] of Object.entries(options.parameters)) {\n relay.parameter({ name, value: String(value) });\n }\n }\n\n return response.toString();\n }\n\n /**\n * Filter out undefined values from configuration object.\n * Keeps null, false, 0, and empty strings as they are valid values.\n */\n private filterUnsetValues(config: Record<string, unknown>): Record<string, unknown> {\n const filtered: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(config)) {\n if (value !== undefined) {\n filtered[key] = value;\n }\n }\n return filtered;\n }\n\n /**\n * Cleanup channel state on shutdown\n *\n * Note: WebSocket connections are managed by the server and closed there.\n * This method only cleans up internal channel state.\n */\n public override shutdown(): void {\n this.streamTasks.clear();\n this.webSocketConnections.clear();\n this.promptQueues.clear();\n this.initializationRetries.clear();\n this.callSidToConversationId.clear();\n super.shutdown();\n }\n}\n","import { ConversationSession } from '../types/conversation';\n\nfunction formatTraitValue(value: unknown): string {\n // For primitives (string, number, boolean, bigint), return as-is for readability\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n typeof value === 'bigint'\n ) {\n return String(value);\n }\n // For objects and arrays, use JSON.stringify with bigint replacer\n try {\n return (\n JSON.stringify(value, (_key, replacerValue: unknown) => {\n if (typeof replacerValue === 'bigint') {\n return String(replacerValue);\n }\n return replacerValue;\n }) ?? String(value)\n );\n } catch {\n return String(value);\n }\n}\n\n/**\n * Build a formatted profile prompt section from conversation session data.\n *\n * Generates a markdown-formatted Customer Profile section with trait information.\n * Each trait is displayed as a bulleted list item with the trait name and formatted value.\n * Primitive values (string, number, boolean, bigint) are shown without quotes for readability,\n * while objects and arrays are JSON-stringified.\n *\n * @param context - The conversation session containing profile data\n * @param traitGroups - Optional array of trait group names to include. If provided, only\n * these trait groups will be included in the output. If an empty array\n * is provided, returns null.\n * @returns Formatted profile section or null if no profile data or no traits match filter\n */\nexport function buildProfilePrompt(\n context: ConversationSession,\n traitGroups?: string[]\n): string | null {\n if (!context.profile || !context.profile.traits) {\n return null;\n }\n\n let filteredTraits: Record<string, unknown>;\n\n if (traitGroups !== undefined) {\n if (traitGroups.length === 0) {\n return null;\n }\n\n filteredTraits = Object.fromEntries(\n Object.entries(context.profile.traits).filter(\n ([key, value]) => traitGroups.includes(key) && value != null\n )\n );\n } else {\n filteredTraits = Object.fromEntries(\n Object.entries(context.profile.traits).filter(([, value]) => value != null)\n );\n }\n\n if (Object.keys(filteredTraits).length === 0) {\n return null;\n }\n\n const lines = ['## Customer Profile', 'Information about this customer:'];\n\n for (const [key, value] of Object.entries(filteredTraits)) {\n lines.push(`- ${key}: ${formatTraitValue(value)}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * Configuration options for adapter utilities like MemoryPromptBuilder.\n */\nexport interface AdapterOptions {\n /**\n * Optional array of profile trait group names to include in the output.\n *\n * - If undefined or not provided, all available trait groups are included\n * - If empty array ([]), no profile traits are included (profile section is omitted)\n * - If populated array, only the specified trait groups are included\n *\n * @example\n * ```typescript\n * // Include only Contact and Preferences traits\n * { profileTraits: ['Contact', 'Preferences'] }\n *\n * // Exclude all profile traits\n * { profileTraits: [] }\n *\n * // Include all traits (default)\n * { } // or undefined\n * ```\n */\n profileTraits?: string[];\n}\n\n/**\n * Extract and normalize profile trait groups from adapter options.\n *\n * This is an internal helper function used by MemoryPromptBuilder to handle trait filtering.\n * The returned array should be treated as immutable.\n *\n * @param options - Adapter options containing optional profileTraits configuration\n * @returns undefined if all traits should be included, empty array if traits should be\n * excluded, or the specified trait groups array. The array is returned by reference.\n * @internal\n */\nexport function getProfileTraits(options?: AdapterOptions): string[] | undefined {\n if (!options || options.profileTraits === undefined) {\n return undefined;\n }\n\n if (options.profileTraits.length === 0) {\n return [];\n }\n\n return options.profileTraits;\n}\n","import { TACMemoryResponse } from '../lib/tac-memory-response';\nimport { buildProfilePrompt } from '../lib/conversation-session-helpers';\nimport { ConversationSession } from '../types/conversation';\nimport { AdapterOptions, getProfileTraits } from './options';\n\n/**\n * Utility class for building formatted LLM prompts from TAC memory and profile data.\n *\n * Generates markdown-formatted prompt sections that can be injected into LLM system messages,\n * providing context about the customer from previous interactions.\n *\n * @example\n * ```typescript\n * // Simple usage with compose() - no if/else needed\n * const systemPrompt = MemoryPromptBuilder.compose(\n * 'You are a helpful assistant.',\n * memoryResponse,\n * session\n * );\n *\n * // Advanced usage with trait filtering\n * const systemPrompt = MemoryPromptBuilder.compose(\n * 'You are a helpful assistant.',\n * memoryResponse,\n * session,\n * { profileTraits: ['Contact', 'Preferences'] }\n * );\n * ```\n */\nexport class MemoryPromptBuilder {\n /**\n * Build a formatted memory prompt from available memory and profile data.\n *\n * **Note:** Most users should use `compose()` instead, which automatically handles\n * combining memory with your system prompt. Use `build()` only if you need the raw\n * memory content without a system prompt.\n *\n * Generates a structured prompt with up to four sections:\n * - **Customer Profile**: Profile traits (filtered by options if provided)\n * - **Key Observations**: Important notes from previous interactions\n * - **Past Conversation Summaries**: Summaries of previous conversations\n * - **Recent Message History**: Recent communications with the customer\n *\n * Sections with no data are omitted. If no data is available at all, returns an empty string.\n *\n * @param memoryResponse - Memory data from TAC.retrieveMemory() containing observations,\n * summaries, and communications. Optional.\n * @param context - Conversation session containing profile data. Optional.\n * @param options - Configuration options for filtering profile traits. If profileTraits is\n * provided, only those trait groups will be included in the output. If an\n * empty array is provided, profile section is omitted. Optional.\n * @returns Formatted markdown prompt string ready for injection into LLM system messages.\n * Returns empty string if no memory or profile data is available.\n *\n * @example\n * ```typescript\n * // Recommended: Use compose() for most cases\n * const prompt = MemoryPromptBuilder.compose(basePrompt, memory, session);\n *\n * // Advanced: Use build() only if you need raw memory content\n * const rawMemory = MemoryPromptBuilder.build(memory, session);\n * if (rawMemory) {\n * // Custom handling of memory content\n * }\n * ```\n */\n static build(\n memoryResponse?: TACMemoryResponse | null,\n context?: ConversationSession | null,\n options?: AdapterOptions\n ): string {\n if (!memoryResponse && (!context || !context.profile)) {\n return '';\n }\n\n const sections: string[] = [];\n\n if (context) {\n const traitGroups = getProfileTraits(options);\n const profileSection = buildProfilePrompt(context, traitGroups);\n if (profileSection) {\n sections.push(profileSection);\n }\n }\n\n if (memoryResponse) {\n const memorySections = memoryResponse.buildMemoryPrompts();\n sections.push(...memorySections);\n }\n\n if (sections.length === 0) {\n return '';\n }\n\n return this.assemblePrompt(sections);\n }\n\n /**\n * Compose system prompt with memory context.\n *\n * Appends memory to systemPrompt if available. Always returns a string.\n * Eliminates the need for manual if/else checks when combining prompts.\n *\n * **Note:** Empty strings and whitespace-only strings are treated as \"no system prompt\"\n * (same as null/undefined). Whitespace is automatically trimmed from systemPrompt.\n *\n * @param systemPrompt - Base system prompt for the LLM. Empty string, whitespace-only,\n * null, and undefined are all treated as \"no system prompt\". Optional.\n * @param memoryResponse - Memory data from TAC.retrieveMemory(). Optional.\n * @param context - Conversation session containing profile data. Optional.\n * @param options - Configuration options for filtering profile traits. Optional.\n * @returns Composed prompt with memory appended to systemPrompt. Returns empty string\n * if both systemPrompt and memory are empty/null/undefined.\n *\n * @example\n * ```typescript\n * // Before (manual if/else)\n * const memoryContext = MemoryPromptBuilder.build(memoryResponse, context);\n * const systemPrompt = basePrompt + (memoryContext ? `\\n\\n${memoryContext}` : '');\n *\n * // After (compose handles it)\n * const systemPrompt = MemoryPromptBuilder.compose(basePrompt, memoryResponse, context);\n *\n * // Empty strings and whitespace are treated as \"no prompt\"\n * MemoryPromptBuilder.compose('', memoryResponse, context); // Returns just memory\n * MemoryPromptBuilder.compose(' ', memoryResponse, context); // Returns just memory (trimmed)\n * MemoryPromptBuilder.compose(null, memoryResponse, context); // Returns just memory\n * ```\n */\n static compose(\n systemPrompt?: string | null,\n memoryResponse?: TACMemoryResponse | null,\n context?: ConversationSession | null,\n options?: AdapterOptions\n ): string {\n const memoryContent = this.build(memoryResponse, context, options);\n const trimmedPrompt = systemPrompt?.trim() || null;\n\n if (!trimmedPrompt && !memoryContent) {\n return '';\n }\n\n if (!trimmedPrompt) {\n return memoryContent;\n }\n\n if (!memoryContent) {\n return trimmedPrompt;\n }\n\n return `${trimmedPrompt}\\n\\n${memoryContent}`;\n }\n\n private static assemblePrompt(sections: string[]): string {\n const header = [\n '# Customer Context',\n 'You have access to the following information about this customer ' +\n 'from previous interactions:',\n '',\n ];\n\n const body = sections.join('\\n\\n');\n\n return header.join('\\n') + body;\n }\n}\n","import { ToolFunction, JSONSchema, OpenAITool, AnthropicTool } from '@twilio/tac-core';\n\n/**\n * TAC Tool class with helper methods for LLM integration\n *\n * Matches Python's TACTool dataclass with conversion methods.\n */\nexport class TACTool<TParams = unknown, TResult = unknown> {\n constructor(\n public readonly name: string,\n public readonly description: string,\n public readonly parameters: JSONSchema,\n public readonly implementation: ToolFunction<TParams, TResult>\n ) {}\n\n /**\n * Convert to OpenAI function calling format\n */\n toOpenAIFormat(): OpenAITool {\n return {\n type: 'function',\n function: {\n name: this.name,\n description: this.description,\n parameters: this.parameters,\n },\n };\n }\n\n /**\n * Convert to Anthropic tool calling format\n */\n toAnthropicFormat(): AnthropicTool {\n return {\n name: this.name,\n description: this.description,\n input_schema: this.parameters,\n };\n }\n\n /**\n * Convert to JSON string (OpenAI format by default)\n */\n toJSON(): string {\n return JSON.stringify(this.toOpenAIFormat(), null, 2);\n }\n\n /**\n * Convert this tool to an OpenAI Agents SDK `FunctionTool` instance.\n *\n * Unlike `toOpenAIFormat` and `toAnthropicFormat` (which return plain\n * objects consumed by HTTP APIs), the OpenAI Agents SDK dispatches on tool\n * *type*, so this returns a live `tool(...)` object with an invoke callback\n * that calls this tool and JSON-encodes the result.\n *\n * Requires the `@openai/agents` package:\n *\n * npm install @openai/agents\n *\n * @returns A FunctionTool ready to pass to `new Agent({ tools: [...] })`.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Return type depends on an optional peer dep we don't declare\n async toOpenAIAgentsSDKTool(): Promise<any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Optional peer dep: dynamic import, can't declare types\n let agentsModule: any;\n try {\n // Dynamic import of an optional peer dependency. The indirection via a\n // string variable keeps TypeScript from trying to resolve the module\n // at compile time (it isn't a declared dependency).\n const moduleSpec = '@openai/agents';\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- Dynamic optional-dep import\n agentsModule = await import(/* @vite-ignore */ moduleSpec);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new Error(\n 'toOpenAIAgentsSDKTool() failed to load @openai/agents. ' +\n 'Install with: npm install @openai/agents. ' +\n `Underlying error: ${cause}`,\n { cause: err }\n );\n }\n\n const impl = this.implementation;\n // The Agents SDK's `JsonObjectSchemaNonStrict` requires `additionalProperties: true`\n // (and `Strict` requires `: false`). Our schema sets neither by default, so normalize\n // for the non-strict path we're opting into.\n const parameters = {\n ...this.parameters,\n additionalProperties: true,\n };\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call -- Optional peer dep\n return agentsModule.tool({\n name: this.name,\n description: this.description,\n parameters,\n // Disable strict mode: the Agents SDK's strict JSON schema rejects\n // some features TAC emits (e.g. unions, top-level description).\n strict: false,\n execute: async (args: unknown): Promise<string> => {\n const result = await impl(args as TParams);\n return JSON.stringify(result);\n },\n });\n }\n}\n\n/**\n * Create a tool directly with all parameters\n *\n * Simplified approach matching Python's create_tool function.\n * No builder pattern - just a simple function call.\n */\nexport function defineTool<TParams = unknown, TResult = unknown>(\n name: string,\n description: string,\n parameters: JSONSchema,\n implementation: ToolFunction<TParams, TResult>\n): TACTool<TParams, TResult> {\n if (!name) {\n throw new Error('Tool name is required');\n }\n\n if (!description) {\n throw new Error('Tool description is required');\n }\n\n if (!parameters) {\n throw new Error('Tool parameters schema is required');\n }\n\n if (!implementation) {\n throw new Error('Tool implementation is required');\n }\n\n return new TACTool(name, description, parameters, implementation);\n}\n","import {\n MemoryRetrievalRequest,\n MemoryRetrievalResponse,\n BuiltInTools,\n MemoryClient,\n} from '@twilio/tac-core';\nimport { TACTool, defineTool } from '../lib/builder';\n\n/**\n * Parameters for memory retrieval tool\n */\ninterface MemoryRetrievalParams {\n query?: string;\n beginDate?: string;\n endDate?: string;\n observationsLimit?: number;\n summariesLimit?: number;\n communicationsLimit?: number;\n relevanceThreshold?: number;\n}\n\n/**\n * Create memory retrieval tool.\n *\n * @param memoryClient - Memory client instance (must be initialized with storeId)\n * @param profileId - Optional profile ID for memory retrieval\n * @param conversationId - Optional conversation ID for memory retrieval\n * @param options - Optional overrides for tool metadata.\n * @param options.name - Tool name exposed to the LLM. Defaults to `retrieve_profile_memory`.\n * @param options.description - Tool description exposed to the LLM. Defaults to a\n * generic \"retrieve memories\" prompt.\n */\nexport function createMemoryRetrievalTool(\n memoryClient: MemoryClient,\n profileId?: string,\n conversationId?: string,\n options: { name?: string; description?: string } = {}\n): TACTool<MemoryRetrievalParams, MemoryRetrievalResponse> {\n return defineTool(\n options.name ?? BuiltInTools.RETRIEVE_MEMORY,\n options.description ??\n 'Retrieve user memories including observations, summaries, and conversation history',\n {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Optional semantic search query to filter memories',\n },\n beginDate: {\n type: 'string',\n description: 'Optional start date for filtering memories (ISO 8601 format)',\n },\n endDate: {\n type: 'string',\n description: 'Optional end date for filtering memories (ISO 8601 format)',\n },\n observationsLimit: {\n type: 'integer',\n minimum: 0,\n maximum: 100,\n default: 20,\n description: 'Maximum number of observations to retrieve. Set to 0 to skip observations.',\n },\n summariesLimit: {\n type: 'integer',\n minimum: 0,\n maximum: 100,\n default: 5,\n description: 'Maximum number of summaries to retrieve. Set to 0 to skip summaries.',\n },\n communicationsLimit: {\n type: 'integer',\n minimum: 0,\n maximum: 100,\n default: 0,\n description:\n 'Maximum number of communications to retrieve. Set to 0 to skip communications.',\n },\n relevanceThreshold: {\n type: 'number',\n minimum: 0.0,\n maximum: 1.0,\n default: 0.0,\n description: 'Minimum relevance score threshold for observations and summaries.',\n },\n },\n required: [], // No required parameters\n description: 'Retrieve memories for the current user',\n },\n async (params: MemoryRetrievalParams) => {\n if (!profileId) {\n throw new Error('No profile ID available for memory retrieval');\n }\n\n const request = Object.fromEntries(\n Object.entries({\n conversationId,\n query: params.query,\n beginDate: params.beginDate,\n endDate: params.endDate,\n observationsLimit: params.observationsLimit,\n summariesLimit: params.summariesLimit,\n communicationsLimit: params.communicationsLimit,\n relevanceThreshold: params.relevanceThreshold,\n }).filter(([_, value]) => value !== undefined)\n ) as Partial<MemoryRetrievalRequest>;\n\n return memoryClient.retrieveMemories(profileId, request);\n }\n );\n}\n\n/**\n * Create factory function for memory tools\n *\n * @param memoryClient - Memory client instance (must be initialized with storeId)\n */\nexport function createMemoryTools(memoryClient: MemoryClient): {\n forProfile: (\n profileId: string,\n conversationId?: string\n ) => TACTool<MemoryRetrievalParams, MemoryRetrievalResponse>;\n forSession: (\n profileId?: string,\n conversationId?: string\n ) => TACTool<MemoryRetrievalParams, MemoryRetrievalResponse>;\n} {\n return {\n forProfile: (profileId: string, conversationId?: string) =>\n createMemoryRetrievalTool(memoryClient, profileId, conversationId),\n\n forSession: (profileId?: string, conversationId?: string) =>\n createMemoryRetrievalTool(memoryClient, profileId, conversationId),\n };\n}\n","import { BuiltInTools, ConversationId, BaseChannel } from '@twilio/tac-core';\nimport { TACTool, defineTool } from '../lib/builder';\n\n/**\n * Parameters for send message tool\n */\ninterface SendMessageParams {\n message: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Result from send message tool\n */\ninterface SendMessageResult {\n success: boolean;\n message_id?: string;\n error?: string;\n}\n\n/**\n * Create send message tool\n */\nexport function createSendMessageTool(\n channel: BaseChannel,\n conversationId: ConversationId\n): TACTool<SendMessageParams, SendMessageResult> {\n return defineTool(\n BuiltInTools.SEND_MESSAGE,\n 'Send a message to the user in the current conversation',\n {\n type: 'object',\n properties: {\n message: {\n type: 'string',\n description: 'The message content to send to the user',\n },\n metadata: {\n type: 'object',\n description: 'Optional metadata to include with the message',\n },\n },\n required: ['message'],\n description: 'Send a message to the user',\n },\n async (params: SendMessageParams) => {\n try {\n await channel.sendResponse(conversationId, params.message, params.metadata);\n\n return {\n success: true,\n message_id: `msg_${Date.now()}`, // Simple ID generation\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n );\n}\n\n/**\n * Create factory function for messaging tools\n */\nexport function createMessagingTools(): {\n forConversation: (\n channel: BaseChannel,\n conversationId: ConversationId\n ) => TACTool<SendMessageParams, SendMessageResult>;\n} {\n return {\n /**\n * Create send message tool for specific channel and conversation\n */\n forConversation: (channel: BaseChannel, conversationId: ConversationId) =>\n createSendMessageTool(channel, conversationId),\n };\n}\n","/**\n * Handoff tool for the Twilio Agent Connect.\n *\n * Generic Studio-backed handoff that routes a conversation to a human agent.\n * Produces a structured HandoffPayload and delivers it as a Twilio Studio\n * Execution (voice via `<Connect action>`, digital channels via direct POST).\n */\n\nimport axios, { AxiosError } from 'axios';\nimport {\n ConversationSession,\n HandoffPayload,\n PendingHandoffData,\n TAC,\n studioExecutionsUrl,\n studioVoiceHandoffUrl,\n} from '@twilio/tac-core';\nimport { TACTool, defineTool } from '../lib/builder';\n\n// Re-export URL helpers for backward compatibility with the Python factory surface.\nexport { studioExecutionsUrl, studioVoiceHandoffUrl };\n\n/**\n * Build a HandoffPayload from session context and attributes.\n *\n * Useful for custom handoff tools that want TAC's payload shape without\n * the Studio-specific delivery in `postStudioHandoff`.\n */\nexport function buildHandoffPayload(\n session: ConversationSession,\n memoryStoreId: string,\n attributes: Record<string, unknown>\n): HandoffPayload {\n return {\n conversationId: session.conversationId,\n storeId: memoryStoreId,\n profileId: session.profileId ?? '',\n attributes,\n };\n}\n\n/**\n * POST a handoff payload to a Twilio Studio Flow Executions endpoint.\n *\n * Emits the Twilio Studio Executions API wire format: form-encoded\n * `To` / `From` / `Parameters` fields with HTTP Basic auth.\n * `Parameters` is a JSON string keyed under `HandoffData` so Studio\n * can reference it via `{{flow.data.HandoffData.*}}`.\n */\nexport async function postStudioHandoff(\n payload: HandoffPayload,\n session: ConversationSession,\n options: {\n handoffUrl: string;\n fromAddress: string;\n apiKey: string;\n apiSecret: string;\n }\n): Promise<void> {\n const { handoffUrl, fromAddress, apiKey, apiSecret } = options;\n const toAddress = session.authorInfo?.address ?? '';\n\n const form = new URLSearchParams();\n form.append('To', toAddress);\n form.append('From', fromAddress);\n form.append('Parameters', JSON.stringify({ HandoffData: payload }));\n\n await axios.post(handoffUrl, form.toString(), {\n timeout: 10_000,\n auth: { username: apiKey, password: apiSecret },\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n });\n}\n\n/**\n * Result returned by the handoff tool.\n */\nexport interface HandoffResult {\n status: 'handoff_initiated' | 'handoff_failed';\n channel: string;\n error?: string;\n}\n\ninterface HandoffParams {\n reason: string;\n}\n\nconst DEFAULT_HANDOFF_TOOL_NAME = 'handoff';\nconst DEFAULT_HANDOFF_TOOL_DESCRIPTION =\n 'Hand off the conversation to a human agent. ' +\n 'Use this when the customer requests a human, or when you ' +\n 'cannot adequately handle the request.';\n\n/**\n * Create a handoff tool that delivers in the Twilio Studio Executions API shape.\n *\n * The returned tool exposes only `handoff({ reason })` to the LLM. All other\n * dependencies (TAC instance, session, static attributes) are captured in the\n * closure.\n *\n * On digital channels, the tool POSTs to the Studio Flow Executions endpoint\n * derived from `tac.getConfig().studioHandoffFlowSid`. For voice channels,\n * the payload is stored on the session and the voice channel automatically\n * sends the WS `end` message with `handoffData` after the LLM's final\n * response is delivered.\n *\n * The tool also sets the conversation to INACTIVE and clears status callbacks\n * to prevent further webhook events from being routed to TAC.\n *\n * **Not available in voice-only mode.** This tool requires Conversation\n * Orchestrator for conversation state management and Conversation Memory for\n * the handoff payload. In voice-only mode, implement your own handoff by\n * setting `session.pendingHandoffData` directly — the voice channel will\n * send the WS `end` message with your payload, and your `<Connect action>`\n * URL handler can route the call accordingly.\n *\n * @throws Error if `tac.getConfig().studioHandoffFlowSid` is unset, if\n * Conversation Orchestrator is not configured (voice-only mode), or if\n * the memory store ID was not resolved at startup.\n */\nexport function createStudioHandoffTool(\n tac: TAC,\n session: ConversationSession,\n options: {\n attributes?: Record<string, unknown>;\n name?: string;\n description?: string;\n } = {}\n): TACTool<HandoffParams, HandoffResult> {\n const config = tac.getConfig();\n if (!config.studioHandoffFlowSid) {\n throw new Error(\n 'createStudioHandoffTool requires tac.getConfig().studioHandoffFlowSid ' +\n '(set TWILIO_STUDIO_HANDOFF_FLOW_SID in your environment).'\n );\n }\n const flowSid = config.studioHandoffFlowSid;\n\n const coClient = tac.getConversationClient();\n if (!coClient) {\n throw new Error(\n 'createStudioHandoffTool requires Conversation Orchestrator ' +\n '(not available in voice-only mode)'\n );\n }\n const memoryStoreId = tac.getMemoryStoreId();\n if (!memoryStoreId) {\n throw new Error(\n 'createStudioHandoffTool requires a memory store ID ' +\n '(resolved from conversationConfigurationId at startup)'\n );\n }\n\n const staticAttributes = options.attributes ?? {};\n const toolName = options.name ?? DEFAULT_HANDOFF_TOOL_NAME;\n const toolDescription = options.description ?? DEFAULT_HANDOFF_TOOL_DESCRIPTION;\n\n return defineTool<HandoffParams, HandoffResult>(\n toolName,\n toolDescription,\n {\n type: 'object',\n properties: {\n reason: {\n type: 'string',\n description: 'The reason for handing off to a human agent',\n },\n },\n required: ['reason'],\n description: 'Hand off the conversation to a human agent',\n },\n async (params: HandoffParams): Promise<HandoffResult> => {\n const attributes = { ...staticAttributes, reason: params.reason };\n const payload = buildHandoffPayload(session, memoryStoreId, attributes);\n\n // 1. Set conversation to INACTIVE to trigger the CO-generated\n // conversation summary that Flex fetches on pickup. Downstream\n // (Studio/Flex) flips it back to ACTIVE on pickup and CLOSED on hangup —\n // we don't close it ourselves.\n try {\n await coClient.updateConversation(session.conversationId, 'INACTIVE');\n } catch (err) {\n tac.logger.warn(\n { err, conversation_id: session.conversationId },\n 'Failed to set conversation INACTIVE during handoff'\n );\n }\n\n // 2. Clear statusCallbacks so TAC stops receiving webhook events for\n // this conversation (Flex/human agent will handle it from here).\n try {\n await coClient.clearStatusCallbacks(session.conversationId);\n } catch (err) {\n tac.logger.warn(\n { err, conversation_id: session.conversationId },\n 'Failed to clear status callbacks during handoff'\n );\n }\n\n // 3. Deliver handoff payload.\n if (session.channel === 'voice') {\n // Voice: store on session for deferred delivery. The voice channel\n // sends the WS \"end\" message after the LLM's final response so the\n // caller hears a goodbye before transfer. handoffData is a JSON\n // *string* — ConversationRelay forwards it verbatim in the POST body\n // to the action URL.\n const pending: PendingHandoffData = {\n type: 'end',\n handoffData: JSON.stringify(payload),\n };\n session.pendingHandoffData = pending;\n } else {\n // Digital channels: POST handoff payload to the Studio Flow Executions\n // endpoint. If the POST fails (network, 4xx, 5xx, timeout), return\n // handoff_failed so the LLM can tell the user instead of claiming\n // success.\n try {\n await postStudioHandoff(payload, session, {\n handoffUrl: studioExecutionsUrl(flowSid),\n fromAddress: config.phoneNumber,\n apiKey: config.apiKey,\n apiSecret: config.apiSecret,\n });\n } catch (err) {\n const message =\n err instanceof AxiosError\n ? err.message\n : err instanceof Error\n ? err.message\n : String(err);\n tac.logger.error(\n { err, conversation_id: session.conversationId },\n 'Failed to deliver handoff payload'\n );\n return {\n status: 'handoff_failed',\n channel: session.channel,\n error: message,\n };\n }\n }\n\n return { status: 'handoff_initiated', channel: session.channel };\n }\n );\n}\n","import { KnowledgeClient, KnowledgeChunkResult } from '@twilio/tac-core';\nimport { TACTool, defineTool } from '../lib/builder';\n\n/**\n * Parameters for knowledge search tool (visible to LLM)\n */\ninterface KnowledgeSearchParams {\n query: string;\n}\n\n/**\n * Configuration for knowledge search tool\n */\ninterface KnowledgeToolConfig {\n name?: string;\n description?: string;\n topK?: number;\n}\n\n/**\n * Create knowledge search tool with explicit name and description\n *\n * @param knowledgeClient - The Knowledge client instance\n * @param knowledgeBaseId - The knowledge base ID to search\n * @param config - Configuration with required name and description\n * @returns TACTool configured for knowledge search\n */\nexport function createKnowledgeSearchTool(\n knowledgeClient: KnowledgeClient,\n knowledgeBaseId: string,\n config: { name: string; description: string; topK?: number }\n): TACTool<KnowledgeSearchParams, KnowledgeChunkResult[]> {\n const topK = config.topK ?? 5;\n\n return defineTool(\n config.name,\n config.description,\n {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'The search query to find relevant knowledge',\n },\n },\n required: ['query'],\n description: config.description,\n },\n async (params: KnowledgeSearchParams) => {\n return knowledgeClient.searchKnowledgeBase(knowledgeBaseId, params.query, topK);\n }\n );\n}\n\n/**\n * Create knowledge search tool with auto-fetched metadata from knowledge base\n *\n * This async version fetches the knowledge base metadata to auto-generate\n * the tool name and description if not provided.\n *\n * @param knowledgeClient - The Knowledge client instance\n * @param knowledgeBaseId - The knowledge base ID to search\n * @param config - Optional configuration (name/description auto-generated if not provided)\n * @returns Promise containing TACTool configured for knowledge search\n */\nexport async function createKnowledgeSearchToolAsync(\n knowledgeClient: KnowledgeClient,\n knowledgeBaseId: string,\n config?: KnowledgeToolConfig\n): Promise<TACTool<KnowledgeSearchParams, KnowledgeChunkResult[]>> {\n let name = config?.name;\n let description = config?.description;\n\n // Fetch knowledge base metadata if name or description not provided\n if (!name || !description) {\n const kb = await knowledgeClient.getKnowledgeBase(knowledgeBaseId);\n if (!name) {\n // Generate tool name from display name (normalized snake_case)\n const normalized = kb.displayName\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_+|_+$/g, '');\n\n name = normalized ? `search_${normalized}` : 'search_knowledge_base';\n }\n if (!description) {\n description = kb.description || `Search the ${kb.displayName} knowledge base`;\n }\n }\n\n const toolConfig: { name: string; description: string; topK?: number } = {\n name,\n description,\n };\n if (config?.topK !== undefined) {\n toolConfig.topK = config.topK;\n }\n return createKnowledgeSearchTool(knowledgeClient, knowledgeBaseId, toolConfig);\n}\n\n/**\n * Create factory for knowledge tools\n *\n * @param knowledgeClient - The Knowledge client instance\n * @returns Factory object with methods to create knowledge tools\n */\nexport function createKnowledgeTools(knowledgeClient: KnowledgeClient): {\n forKnowledgeBase: (\n knowledgeBaseId: string,\n config: { name: string; description: string; topK?: number }\n ) => TACTool<KnowledgeSearchParams, KnowledgeChunkResult[]>;\n forKnowledgeBaseAsync: (\n knowledgeBaseId: string,\n config?: KnowledgeToolConfig\n ) => Promise<TACTool<KnowledgeSearchParams, KnowledgeChunkResult[]>>;\n} {\n return {\n /**\n * Create knowledge search tool with explicit config\n */\n forKnowledgeBase: (\n knowledgeBaseId: string,\n config: { name: string; description: string; topK?: number }\n ) => createKnowledgeSearchTool(knowledgeClient, knowledgeBaseId, config),\n\n /**\n * Create knowledge search tool with auto-fetched metadata\n */\n forKnowledgeBaseAsync: (knowledgeBaseId: string, config?: KnowledgeToolConfig) =>\n createKnowledgeSearchToolAsync(knowledgeClient, knowledgeBaseId, config),\n };\n}\n","import Fastify, {\n FastifyInstance,\n FastifyServerOptions,\n FastifyRequest,\n FastifyReply,\n} from 'fastify';\nimport formbody from '@fastify/formbody';\nimport websocket from '@fastify/websocket';\nimport gracefulShutdown from 'fastify-graceful-shutdown';\nimport type { WebSocket } from 'ws';\nimport twilio from 'twilio';\n\nimport {\n ConversationRelayCallbackPayloadSchema,\n twiMLRequestFromForm,\n CALL_EVENT_KINDS,\n} from '@twilio/tac-core';\nimport { TAC, VoiceChannel, MessagingChannel } from '@twilio/tac-core';\n\n/**\n * Server configuration options\n */\nexport interface TACServerConfig {\n /** Fastify server options (ignored if `fastifyInstance` is provided) */\n fastify?: FastifyServerOptions;\n\n /**\n * Pre-configured Fastify instance to mount TAC routes onto.\n *\n * Use this to control construction-time settings (logger, `trustProxy`,\n * schema, ...) or to register your own plugins/hooks before TAC's\n * routes are set up. If provided, the `fastify` options field is\n * ignored.\n */\n fastifyInstance?: FastifyInstance;\n\n /** Host to bind the server to (default: '0.0.0.0') */\n host?: string;\n\n /** Port to bind the server to (default: 8000) */\n port?: number;\n\n /**\n * Custom server-only webhook paths. The voice WebSocket and ConversationRelay\n * action callback paths live on `TACConfig` (`voiceWebsocketPath` /\n * `voiceActionPath`) because they're consumed by the voice channel regardless\n * of which web framework is used; this server reads them from there.\n */\n webhookPaths?: {\n /**\n * @deprecated Use `conversation` instead. This field will be removed in a future version.\n * If both `messaging` and `conversation` are set, `conversation` takes precedence.\n */\n messaging?: string;\n conversation?: string;\n twiml?: string;\n /** Path for Conversation Intelligence webhook (optional - only registered if provided) */\n cintel?: string;\n };\n\n /** Voice channel instance (alternative to registering on TAC) */\n voiceChannel?: VoiceChannel;\n\n /** Messaging channel instances — webhooks are fanned out to all (alternative to registering on TAC) */\n messagingChannels?: MessagingChannel[];\n}\n\n/**\n * Default server configuration\n */\nconst DEFAULT_CONFIG = {\n host: '0.0.0.0',\n port: 8000,\n webhookPaths: {\n conversation: '/webhook',\n twiml: '/twiml',\n },\n} satisfies Omit<\n TACServerConfig,\n 'fastify' | 'fastifyInstance' | 'voiceChannel' | 'messagingChannels'\n>;\n\n/** Normalize a route path for comparison, so '/hooks' and '/hooks/' collide. */\nfunction stripTrailingSlash(path: string): string {\n return path.replace(/\\/+$/, '');\n}\n\n/** What the voice channel's webhook handlers hand back for a reply. */\ntype CallEventResult = { status: number; content: string; contentType: string };\n\n/**\n * Batteries-included Fastify server for TAC\n *\n * Provides out-of-the-box setup for SMS and Voice channels with\n * proper webhook handling, WebSocket support, and production-ready defaults.\n *\n * Customization:\n * - Pass your own Fastify instance via `config.fastifyInstance` to control\n * construction-time settings (logger, `trustProxy`, schema, ...) and to\n * register plugins/hooks before TAC's routes are set up.\n * - Or mutate `server.fastify` after construction to add routes,\n * decorators, or hooks — before calling `start()`.\n *\n * Example:\n * import Fastify from 'fastify';\n *\n * const app = Fastify({ logger: true, trustProxy: true });\n * const server = new TACServer(tac, { fastifyInstance: app });\n *\n * server.fastify.get('/health', async () => ({ status: 'ok' }));\n *\n * await server.start();\n */\nexport class TACServer {\n public readonly fastify: FastifyInstance;\n private readonly tac: TAC;\n private readonly config: Required<\n Omit<TACServerConfig, 'fastify' | 'fastifyInstance' | 'voiceChannel' | 'messagingChannels'>\n >;\n /** All enabled messaging channels */\n private readonly messagingChannels: MessagingChannel[];\n /** Voice channel instance */\n private readonly voiceChannel: VoiceChannel | undefined;\n /** All channels that need webhook processing (voice + messaging) */\n private readonly webhookChannels: (VoiceChannel | MessagingChannel)[];\n\n constructor(tac: TAC, config: TACServerConfig = {}) {\n this.tac = tac;\n\n // Handle deprecated `messaging` field: log warning and apply fallback if needed\n const webhookPaths = { ...DEFAULT_CONFIG.webhookPaths, ...config.webhookPaths };\n if (config.webhookPaths?.messaging) {\n console.warn(\n 'TACServer: The \"webhookPaths.messaging\" field is deprecated and will be removed in a future version. ' +\n 'Please update your configuration to use \"webhookPaths.conversation\" instead.'\n );\n // If conversation isn't explicitly set, use messaging value as fallback\n if (!config.webhookPaths.conversation) {\n webhookPaths.conversation = config.webhookPaths.messaging;\n }\n }\n\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n webhookPaths,\n };\n\n // Resolve channels: prefer explicit kwargs, fall back to tac.getChannel()\n this.voiceChannel = config.voiceChannel ?? tac.getChannel<VoiceChannel>('voice');\n\n // Fail fast at construction if a voice channel is attached but no public\n // URL is configured. Without this check, the misconfiguration would only\n // surface on the first inbound call as a 500 — easy to miss in CI or smoke\n // tests that don't hit voice. Custom adapters (Express/etc.) constructing\n // VoiceChannel directly still get the runtime error on first request.\n if (this.voiceChannel && !tac.getConfig().voicePublicDomain) {\n throw new Error(\n 'Voice channel is configured but TACConfig.voicePublicDomain is not set. ' +\n 'Set it directly or via the TWILIO_VOICE_PUBLIC_DOMAIN env var.'\n );\n }\n // Unconditional, because the call-event routes register unconditionally\n // (like the TwiML and ConversationRelay routes) — so the collision is real\n // whether or not a voice channel is attached.\n this.validateCallEventPaths();\n this.messagingChannels =\n config.messagingChannels ??\n (\n [\n tac.getChannel<MessagingChannel>('sms'),\n tac.getChannel<MessagingChannel>('rcs'),\n tac.getChannel<MessagingChannel>('chat'),\n tac.getChannel<MessagingChannel>('whatsapp'),\n ] as (MessagingChannel | undefined)[]\n ).filter((ch): ch is MessagingChannel => ch != null);\n\n // Gather all channels that need webhook processing\n this.webhookChannels = [];\n if (this.voiceChannel) {\n this.webhookChannels.push(this.voiceChannel);\n }\n this.webhookChannels.push(...this.messagingChannels);\n\n if (this.webhookChannels.length === 0) {\n console.warn(\n 'TACServer: No channels configured for webhook processing. Register channels with TAC to enable webhooks.'\n );\n }\n // Use the user-supplied Fastify instance if provided; otherwise create\n // a default one with Pino logging.\n if (config.fastifyInstance) {\n this.fastify = config.fastifyInstance;\n } else {\n this.fastify = Fastify({\n logger: {\n level: process.env.TWILIO_LOG_LEVEL || 'info',\n },\n ...config.fastify,\n });\n }\n }\n\n /**\n * Validate `voiceCallEventPath`, the one path that isn't literal.\n *\n * Every other TAC path registers as configured, so a bad value is visible.\n * This one expands into three sub-paths, hiding a mistake the base path looks\n * innocent for: a sub-path colliding with another route while the base looks\n * unrelated (base `/hooks` vs `webhookPaths.twiml = '/hooks/status'`). Both\n * would register as POST routes and requests would reach the wrong handler.\n *\n * The leading-slash requirement is enforced by `TACConfigSchema` at parse\n * time, so it doesn't need re-checking here.\n */\n private validateCallEventPaths(): void {\n const cfg = this.tac.getConfig();\n\n const others: Record<string, string> = {\n [stripTrailingSlash(this.config.webhookPaths.twiml || '/twiml')]: 'webhookPaths.twiml',\n [stripTrailingSlash(cfg.voiceActionPath)]: 'TACConfig.voiceActionPath',\n [stripTrailingSlash(this.config.webhookPaths.conversation || '/webhook')]:\n 'webhookPaths.conversation',\n };\n if (this.config.webhookPaths.cintel) {\n others[stripTrailingSlash(this.config.webhookPaths.cintel)] = 'webhookPaths.cintel';\n }\n\n for (const kind of CALL_EVENT_KINDS) {\n const path = cfg.callEventPath(kind);\n const clash = others[stripTrailingSlash(path)];\n if (clash !== undefined) {\n throw new Error(\n `TACConfig.voiceCallEventPath expands to '${path}', which collides with ` +\n `${clash}. Both would register as POST routes and requests would ` +\n 'reach the wrong handler.'\n );\n }\n }\n }\n\n private getForwardedProto(request: FastifyRequest): string {\n const raw = request.headers['x-forwarded-proto'] as string | undefined;\n return raw?.split(',')[0]?.trim() || 'https';\n }\n\n private getForwardedHost(request: FastifyRequest): string {\n const raw = (request.headers['x-forwarded-host'] as string | undefined) || request.headers.host;\n return raw?.split(',')[0]?.trim() || '';\n }\n\n /**\n * Get the full URL for webhook validation\n * Handles X-Forwarded-* headers for proxy/ngrok scenarios\n */\n private getWebhookUrl(request: FastifyRequest): string {\n const proto = this.getForwardedProto(request);\n const host = this.getForwardedHost(request);\n return `${proto}://${host}${request.url}`;\n }\n\n /**\n * Validate the Twilio signature on an HTTP request. On failure, sends a 403\n * reply (Fastify halts the request once `reply.send` is called in a\n * `preHandler`, so the route handler won't run). Scoped to TAC-registered\n * webhook routes — does not run on user-added routes registered on\n * `server.fastify`.\n */\n private async validateRequestSignature(\n request: FastifyRequest,\n reply: FastifyReply\n ): Promise<void> {\n const signature = request.headers['x-twilio-signature'] as string;\n const url = this.getWebhookUrl(request);\n const authToken = this.tac.getConfig().authToken;\n\n let isValid: boolean;\n if (request.url.includes('bodySHA256=')) {\n const body = (request as FastifyRequest & { rawBody?: string }).rawBody ?? '';\n isValid = twilio.validateRequestWithBody(authToken, signature, url, body);\n } else {\n const params = (request.body as Record<string, string>) || {};\n isValid = twilio.validateRequest(authToken, signature, url, params);\n }\n\n if (!isValid) {\n this.fastify.log.warn({ url, hasSignature: !!signature }, 'Invalid Twilio webhook signature');\n await reply.code(403).send({ error: 'Invalid webhook signature' });\n }\n }\n\n /**\n * Setup routes\n */\n private async setupRoutes(): Promise<void> {\n const validateSignature = {\n preHandler: async (request: FastifyRequest, reply: FastifyReply): Promise<void> => {\n await this.validateRequestSignature(request, reply);\n },\n };\n\n // Conversation Orchestrator webhook — fan out to all enabled channels\n if (this.webhookChannels.length > 0) {\n this.fastify.post(\n this.config.webhookPaths.conversation || '/webhook',\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n const rawHeader = request.headers['i-twilio-idempotency-token'];\n const idempotencyToken = Array.isArray(rawHeader) ? rawHeader[0] : rawHeader;\n\n // Fan out to all channels\n for (const channel of this.webhookChannels) {\n channel.processWebhook(request.body, idempotencyToken).catch((err: unknown) => {\n this.fastify.log.error(\n { err, channel: channel.channelType },\n 'Webhook processing error'\n );\n });\n }\n\n await reply.code(200).send({ status: 'ok' });\n }\n );\n }\n\n // Voice webhook (POST - Twilio calls this when an incoming call arrives)\n this.fastify.post(\n this.config.webhookPaths.twiml || '/twiml',\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n if (!this.voiceChannel) {\n await reply.code(500).send({ error: 'Voice channel not available' });\n return;\n }\n\n const voiceChannel = this.voiceChannel;\n\n // Parse the Twilio webhook form into a framework-neutral TwiMLRequest\n // and hand it to the channel. The channel derives the WebSocket and\n // action URLs from TACConfig (voicePublicDomain + paths), layers in\n // VoiceChannelConfig.defaultTwimlOptions, and runs any per-call\n // customizer registered via voiceChannel.onInboundCallTwiml(...).\n const formDict = (request.body as Record<string, string>) ?? {};\n const twimlRequest = twiMLRequestFromForm(formDict);\n\n const twiml = await voiceChannel.handleIncomingCall(twimlRequest);\n\n await reply.type('application/xml').send(twiml);\n } catch (error) {\n this.fastify.log.error(\n 'TwiML generation error: ' + (error instanceof Error ? error.message : String(error))\n );\n await reply.code(500).send({\n error: 'Internal server error',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n // ConversationRelay callback endpoint. Path lives on TACConfig because the\n // voice channel derives the action URL from it too.\n this.fastify.post(\n this.tac.getConfig().voiceActionPath,\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n if (!this.voiceChannel) {\n await reply.code(500).send({ error: 'Voice channel not available' });\n return;\n }\n\n const voiceChannel = this.voiceChannel;\n\n // Parse form data into payload\n const formData = request.body as Record<string, string>;\n const parseResult = ConversationRelayCallbackPayloadSchema.safeParse(formData);\n\n if (!parseResult.success) {\n this.fastify.log.error(\n { errors: parseResult.error.issues },\n 'Invalid ConversationRelay callback payload'\n );\n await reply.code(400).send({ error: 'Invalid payload' });\n return;\n }\n\n const result = await voiceChannel.handleConversationRelayCallback(parseResult.data);\n\n await reply.code(result.status).type(result.contentType).send(result.content);\n } catch (error) {\n this.fastify.log.error(\n 'ConversationRelay callback error: ' +\n (error instanceof Error ? error.message : String(error))\n );\n await reply.code(500).send({ error: 'Internal server error' });\n }\n }\n );\n\n // One route per Twilio call callback — the route is the discriminator, so\n // each handler parses its own typed event with no payload sniffing. Paths\n // live on TACConfig because the voice channel derives the callback URLs it\n // hands to the Calls API from the same base.\n const callEventHandlers: Record<\n (typeof CALL_EVENT_KINDS)[number],\n (channel: VoiceChannel, form: Record<string, string>) => Promise<CallEventResult>\n > = {\n status: (channel, form) => channel.handleCallStatusEvent(form),\n amd: (channel, form) => channel.handleAmdEvent(form),\n recording: (channel, form) => channel.handleRecordingEvent(form),\n };\n\n for (const kind of CALL_EVENT_KINDS) {\n const handle = callEventHandlers[kind];\n this.fastify.post(\n this.tac.getConfig().callEventPath(kind),\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n if (!this.voiceChannel) {\n await reply.code(500).send({ error: 'Voice channel not available' });\n return;\n }\n\n const formData = (request.body as Record<string, string>) ?? {};\n const result = await handle(this.voiceChannel, formData);\n\n await reply.code(result.status).type(result.contentType).send(result.content);\n } catch (error) {\n this.fastify.log.error(\n `Call ${kind} callback error: ` +\n (error instanceof Error ? error.message : String(error))\n );\n await reply.code(500).send({ error: 'Internal server error' });\n }\n }\n );\n }\n\n // Voice WebSocket endpoint. Path lives on TACConfig because the voice\n // channel derives the WebSocket URL from it too.\n await this.fastify.register(fastify => {\n fastify.get(\n this.tac.getConfig().voiceWebsocketPath,\n { websocket: true },\n (socket: WebSocket, request: FastifyRequest) => {\n const signature = request.headers['x-twilio-signature'] as string;\n const authToken = this.tac.getConfig().authToken;\n\n const proto = this.getForwardedProto(request);\n const host = this.getForwardedHost(request);\n\n if (!host) {\n this.fastify.log.warn('WebSocket connection rejected: missing host header');\n socket.close(1008, 'Invalid request');\n return;\n }\n\n const wsProto = proto === 'https' ? 'wss' : 'ws';\n const fullUrl = new URL(`${wsProto}://${host}${request.url}`);\n const params: Record<string, string> = {};\n fullUrl.searchParams.forEach((value, key) => {\n params[key] = value;\n });\n const url = fullUrl.origin + fullUrl.pathname;\n\n const isValid = twilio.validateRequest(authToken, signature, url, params);\n\n if (!isValid) {\n this.fastify.log.warn(\n { url, hasSignature: !!signature },\n 'WebSocket connection rejected: invalid Twilio signature'\n );\n socket.close(1008, 'Invalid signature');\n return;\n }\n\n if (!this.voiceChannel) {\n socket.terminate();\n return;\n }\n\n this.voiceChannel.handleWebSocketConnection(socket);\n }\n );\n });\n\n // Conversation Intelligence webhook endpoint (optional - only if path is configured)\n if (this.config.webhookPaths.cintel) {\n this.fastify.post(\n this.config.webhookPaths.cintel,\n validateSignature,\n async (request: FastifyRequest, reply: FastifyReply) => {\n if (!this.tac.isCintelEnabled()) {\n await reply.code(400).send({\n error: 'Conversation Intelligence is not enabled',\n message:\n 'Set TWILIO_TAC_CI_CONFIGURATION_ID and memory credentials to enable CI processing',\n });\n return;\n }\n\n try {\n this.fastify.log.info('Processing Conversation Intelligence webhook');\n const result = await this.tac.processCintelEvent(request.body);\n\n if (result.success) {\n if (result.skipped) {\n this.fastify.log.debug({ reason: result.skipReason }, 'CI event skipped');\n } else {\n this.fastify.log.info(\n { eventType: result.eventType, createdCount: result.createdCount },\n 'CI event processed'\n );\n }\n } else {\n this.fastify.log.error({ error: result.error }, 'CI event processing failed');\n }\n\n await reply.send(result);\n } catch (error) {\n this.fastify.log.error(\n 'CI webhook error: ' + (error instanceof Error ? error.message : String(error))\n );\n await reply.code(500).send({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n }\n }\n\n /**\n * Start the server\n */\n public async start(): Promise<void> {\n try {\n // Register required plugins, guarding against users who pre-registered\n // them on a supplied `fastifyInstance` (duplicate registration throws).\n if (!this.fastify.hasContentTypeParser('application/x-www-form-urlencoded')) {\n await this.fastify.register(formbody);\n }\n if (!this.fastify.hasDecorator('websocketServer')) {\n await this.fastify.register(websocket);\n }\n if (!this.fastify.hasDecorator('gracefulShutdown')) {\n await this.fastify.register(gracefulShutdown);\n }\n\n // Replace the default JSON parser with one that stores the raw body string,\n // needed by validateRequestWithBody for bodySHA256 signature validation.\n const defaultJsonParser = this.fastify.getDefaultJsonParser('error', 'error');\n if (this.fastify.hasContentTypeParser('application/json')) {\n this.fastify.removeContentTypeParser('application/json');\n }\n this.fastify.addContentTypeParser(\n 'application/json',\n { parseAs: 'string' },\n (request, body: string, done) => {\n (request as FastifyRequest & { rawBody?: string }).rawBody = body;\n void defaultJsonParser(request, body, done);\n }\n );\n\n // Set up routes (must be after plugin registration)\n // Signature validation is applied per-route as a `preHandler` so it only\n // runs on TAC-registered webhook routes, not on user-added routes on\n // `server.fastify`.\n await this.setupRoutes();\n\n // Configure graceful shutdown to wait for WebSocket connections\n this.fastify.gracefulShutdown(async (signal: string) => {\n this.fastify.log.info({ signal }, 'Received shutdown signal');\n\n // Wait for WebSocket connections to close naturally\n await this.waitForWebSocketsToClose();\n\n // Shutdown TAC (cleans up channel state)\n this.tac.shutdown();\n });\n\n // Start Fastify server\n await this.fastify.listen({\n host: this.config.host,\n port: this.config.port,\n });\n\n this.fastify.log.info(\n {\n host: this.config.host,\n port: this.config.port,\n conversation_webhook: this.config.webhookPaths.conversation,\n twiml_webhook: this.config.webhookPaths.twiml,\n ws_websocket: this.tac.getConfig().voiceWebsocketPath,\n conversation_relay_callback: this.tac.getConfig().voiceActionPath,\n ...(this.voiceChannel && {\n call_event_callbacks: CALL_EVENT_KINDS.map(kind =>\n this.tac.getConfig().callEventPath(kind)\n ),\n }),\n ...(this.config.webhookPaths.cintel && {\n cintel_webhook: this.config.webhookPaths.cintel,\n }),\n },\n 'TAC Server started'\n );\n } catch (error) {\n this.fastify.log.error({ err: error }, 'Failed to start TAC Server');\n throw error;\n }\n }\n\n /**\n * Wait for all WebSocket connections to close\n */\n private async waitForWebSocketsToClose(timeoutMs = 30000): Promise<void> {\n const wsServer = this.fastify.websocketServer;\n if (!wsServer || wsServer.clients.size === 0) {\n return;\n }\n\n this.fastify.log.info(\n { websocket_count: wsServer.clients.size },\n 'Waiting for WebSocket connections to close...'\n );\n\n const startTime = Date.now();\n\n return new Promise<void>(resolve => {\n const checkInterval = setInterval(() => {\n const clientCount = wsServer.clients.size;\n\n if (clientCount === 0) {\n clearInterval(checkInterval);\n this.fastify.log.info('All WebSocket connections closed');\n resolve();\n return;\n }\n\n // Check for timeout\n if (Date.now() - startTime >= timeoutMs) {\n clearInterval(checkInterval);\n this.fastify.log.warn(\n { remaining_websockets: clientCount },\n 'Timeout waiting for WebSockets to close, proceeding with shutdown'\n );\n resolve();\n return;\n }\n\n this.fastify.log.info(\n { remaining_websockets: clientCount },\n 'Waiting for WebSockets to close...'\n );\n }, 5000);\n });\n }\n\n /**\n * Stop the server gracefully\n */\n public async stop(): Promise<void> {\n try {\n await this.fastify.close();\n this.fastify.log.info('TAC Server stopped');\n } catch (error) {\n this.fastify.log.error({ err: error }, 'Error stopping TAC Server');\n throw error;\n }\n }\n}\n"]}
|