twilio-agent-connect 1.0.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/LICENSE +22 -0
- package/README.md +251 -0
- package/dist/index.d.ts +5695 -0
- package/dist/index.js +5629 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +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/channels/voice.ts","../packages/core/src/util/handoff-urls.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 // API default is 0 (no communications fetched). SDK defaults to 10 for a useful out-of-box experience.\n communicationsLimit: z.number().int().min(0).max(100).default(10),\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 * 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.default({}),\n conversationConfigurationId: z\n .string()\n .regex(/^conv_configuration_[0-9a-z]{26}$/, 'Invalid Conversation Configuration ID format')\n .optional(),\n voicePublicDomain: z\n .string()\n .max(253, 'Hostname too long (max 253 characters)')\n .regex(\n /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,\n 'Invalid hostname format. Must be a hostname without protocol, port, or path (e.g., \"abc123.ngrok.app\", \"localhost\", or \"192.168.1.100\")'\n )\n .optional(),\n cintelConfigurationId: z.string().optional(),\n cintelObservationOperatorSid: 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_TAC_CI_CONFIGURATION_ID: 'TWILIO_TAC_CI_CONFIGURATION_ID',\n TWILIO_TAC_CI_OBSERVATION_OPERATOR_SID: 'TWILIO_TAC_CI_OBSERVATION_OPERATOR_SID',\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.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';\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\n .object({\n channelId: z.string().optional(),\n // TODO(conv-orch): Drop `chatService` once the Actions API resolves the V1 Chat\n // service SID server-side. Confirmed this should not be required client-side;\n // keep the field until the server-side fix ships.\n chatService: z.string().optional(),\n })\n .passthrough();\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 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.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\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()).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.string().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 * Conversations V1 bridge settings on a ConversationConfiguration.\n *\n * TODO(conv-orch): Remove this schema once the Actions API resolves the V1 Chat\n * service SID server-side. Currently used to extract `conversationsV1Bridge.serviceId`\n * from the Configuration so the chat channel can forward it as\n * channelSettings.chatService — drop together with the other TODO(conv-orch) sites.\n */\nexport const ConversationsV1BridgeSchema = z.object({\n serviceId: z.string(),\n});\n\nexport type ConversationsV1Bridge = z.infer<typeof ConversationsV1BridgeSchema>;\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(ChannelSettingsSchema).nullable().optional(),\n statusCallbacks: z.array(StatusCallbackSchema).max(20).nullable().optional(),\n intelligenceConfigurationIds: z.array(z.string()).max(5).nullable().optional(),\n // TODO(conv-orch): Drop this field once the Actions API resolves the V1 Chat\n // service SID server-side — see ConversationsV1BridgeSchema above.\n conversationsV1Bridge: ConversationsV1BridgeSchema.nullish(),\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.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\n * lazily on the first prompt via callSid lookup.\n */\nexport interface InitiateVoiceConversationResult {\n callSid: string;\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 */\nexport const MemoryModeSchema = z.enum(['always', 'never']);\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(['HUMAN_AGENT', 'CUSTOMER', 'AI_AGENT', 'AGENT']);\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.string().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.string().datetime(),\n ended_at: z.string().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.string().datetime(),\n occurredAt: z.string().datetime().optional(),\n updatedAt: z.string().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.string().datetime(),\n updatedAt: z.string().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.string().datetime().optional(),\n endDate: z.string().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.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 * Response from creating an observation\n */\nexport const CreateObservationResponseSchema = z.object({\n content: z.string(),\n source: z.string(),\n occurredAt: z.string(),\n conversationIds: z.array(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';\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.string().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.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.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 * 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// 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 */\nexport interface InitiateVoiceConversationOptions {\n to: string;\n conversationRelayConfig: ConversationRelayConfig;\n actionUrl?: string | undefined;\n}\n\nexport const InitiateVoiceConversationOptionsSchema: z.ZodType<InitiateVoiceConversationOptions> =\n z.object({\n to: z.string().min(1, 'Recipient phone number is required'),\n conversationRelayConfig: ConversationRelayConfigSchema,\n actionUrl: z.string().url().optional(),\n });\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.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 = any, TResult = any> = (\n params: TParams\n) => Promise<TResult> | TResult;\n\n/**\n * Core tool definition\n */\nexport interface TACTool<TParams = any, TResult = any> {\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 * 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.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 observationOperatorSid: z.string().optional(),\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 { 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 public readonly cintelConfigurationId?: string;\n public readonly cintelObservationOperatorSid?: 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 if (validatedConfig.cintelConfigurationId) {\n this.cintelConfigurationId = validatedConfig.cintelConfigurationId;\n }\n if (validatedConfig.cintelObservationOperatorSid) {\n this.cintelObservationOperatorSid = validatedConfig.cintelObservationOperatorSid;\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 WebSocket connections (domain only, without protocol/port/path, e.g., 'abc123.ngrok.app')\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 cintelConfigurationId: process.env[EnvironmentVariables.TWILIO_TAC_CI_CONFIGURATION_ID],\n cintelObservationOperatorSid:\n process.env[EnvironmentVariables.TWILIO_TAC_CI_OBSERVATION_OPERATOR_SID],\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 * Whether Conversation Orchestrator is configured.\n * Returns false in voice-only mode (no conversationConfigurationId).\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","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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction piiLogMethod(this: any, args: unknown[], method: pino.LogFn) {\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\": \"1.0.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 \"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\": \"https://github.com/twilio/twilio-agent-connect-typescript.git\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.0.0\",\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 \"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\": \"^3.22.0\"\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 {\n MemoryRetrievalRequest,\n MemoryRetrievalRequestSchema,\n MemoryRetrievalResponse,\n MemoryRetrievalResponseSchema,\n EMPTY_MEMORY_RESPONSE,\n ProfileLookupResponse,\n ProfileLookupResponseSchema,\n ProfileResponse,\n ProfileResponseSchema,\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 // Validate and parse the response\n const validatedResponse = MemoryRetrievalResponseSchema.safeParse(data);\n\n if (!validatedResponse.success) {\n this.logger.warn(\n {\n profile_id: profileId,\n memory_store_id: this.storeId,\n validation_errors: validatedResponse.error.errors,\n },\n 'Invalid memory response format'\n );\n return EMPTY_MEMORY_RESPONSE;\n }\n\n this.logger.debug(\n {\n memory_store_id: this.storeId,\n profile_id: profileId,\n observation_count: validatedResponse.data.observations.length,\n summary_count: validatedResponse.data.summaries.length,\n },\n 'Memory retrieval succeeded'\n );\n\n return validatedResponse.data;\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 /**\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 * @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 - Optional timestamp when the observation occurred\n * @returns Promise containing the created observation\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 requestBody: Record<string, unknown> = {\n content,\n source,\n };\n\n if (conversationIds && conversationIds.length > 0) {\n requestBody.conversationIds = conversationIds;\n }\n\n if (occurredAt) {\n requestBody.occurredAt = occurredAt;\n }\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 observations content from JSON result\n *\n * Expects format: { \"observations\": [\"obs1\", \"obs2\", ...] }\n *\n * @param jsonContent - JSON string to parse\n * @returns Array of observation strings\n */\nfunction parseObservationsContent(jsonContent: string): string[] {\n try {\n const parsed = JSON.parse(jsonContent) as unknown;\n\n if (typeof parsed === 'object' && parsed !== null && 'observations' in parsed) {\n const observations = (parsed as { observations: unknown }).observations;\n if (Array.isArray(observations)) {\n return observations.filter(\n (obs): obs is string => typeof obs === 'string' && obs.trim() !== ''\n );\n }\n }\n\n return [];\n } catch {\n return [];\n }\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 observations or summaries\n * in the 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.errors },\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 isObservationOperator = this.config.observationOperatorSid === operatorSid;\n const isSummaryOperator = this.config.summaryOperatorSid === operatorSid;\n\n if (!isObservationOperator && !isSummaryOperator) {\n this.logger.debug(\n {\n operator_sid: operatorSid,\n observation_operator_sid: this.config.observationOperatorSid,\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 // Process based on operator type\n if (isObservationOperator) {\n return this.processObservationEvent(event, operatorResult, content, profileIds);\n } else {\n return this.processSummaryEvent(event, operatorResult, content, profileIds);\n }\n }\n\n /**\n * Process an observation operator result\n */\n private async processObservationEvent(\n event: OperatorResultEvent,\n operatorResult: OperatorResult,\n content: string,\n profileIds: string[]\n ): Promise<OperatorProcessingResult> {\n // Parse observations from JSON content\n const observations = parseObservationsContent(content);\n\n if (observations.length === 0) {\n this.logger.debug(\n { operator_sid: operatorResult.operator.id },\n 'No observations found in content'\n );\n return {\n success: true,\n eventType: 'observation',\n skipped: true,\n skipReason: 'No observations found in operator result content',\n createdCount: 0,\n };\n }\n\n let createdCount = 0;\n\n // Create observations for each profile\n for (const profileId of profileIds) {\n for (const observation of observations) {\n try {\n await this.memoryClient.createObservation(\n profileId,\n observation,\n 'conversation-intelligence',\n [event.conversationId],\n operatorResult.dateCreated\n );\n createdCount++;\n\n this.logger.debug(\n {\n profile_id: profileId,\n conversation_id: event.conversationId,\n observation_preview: observation.substring(0, 100),\n },\n 'Created observation'\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 observation'\n );\n return {\n success: false,\n eventType: 'observation',\n skipped: false,\n error: `Failed to create observation: ${error instanceof Error ? error.message : String(error)}`,\n createdCount,\n };\n }\n }\n }\n\n return {\n success: true,\n eventType: 'observation',\n skipped: false,\n createdCount,\n };\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 /**\n * V1 Conversations service SID sourced from `conversationsV1Bridge.serviceId`\n * on the configuration. Forwarded by the chat channel as\n * `channelSettings.chatService` on Actions API requests.\n *\n * TODO(conv-orch): Remove once the Actions API resolves the V1 Chat service SID\n * server-side. Confirmed this should not be required client-side; until the\n * server-side fix ships, CHAT sends fail with\n * \"chatService attribute is required for CHAT channel\"\n * unless we pass it on channelSettings.chatService. When the server-side fix\n * lands, drop this attribute plus ActionChannelSettings.chatService and the\n * chat channel's chatServiceSid plumbing.\n */\n public conversationsV1ServiceSid: 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 // TODO(conv-orch): Remove once the Actions API resolves the V1 Chat service SID\n // server-side — see the conversationsV1ServiceSid field comment above.\n tac.conversationsV1ServiceSid =\n conversationConfig.conversationsV1Bridge?.serviceId ?? undefined;\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 observationOperatorSid: tac.config.cintelObservationOperatorSid,\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 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 * @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 ): 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: session.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 ProfileId,\n MemoryMode,\n MemoryModeSchema,\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 for every inbound message and available in `onMessageReady` callback.\n */\n memoryMode?: MemoryMode;\n}\n\n/**\n * Abstract base class for all channel implementations\n *\n * Provides common functionality for conversation lifecycle management,\n * session tracking, and shared utilities across different channel types.\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\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(`Invalid memoryMode: \"${modeToValidate}\". Must be \"always\" or \"never\".`);\n }\n this.memoryMode = parseResult.data;\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 * 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 * Extract conversation ID from webhook payload (implemented by subclasses)\n */\n protected abstract extractConversationId(payload: unknown): ConversationId | null;\n\n /**\n * Extract profile ID from webhook payload (implemented by subclasses)\n */\n protected abstract extractProfileId(payload: unknown): ProfileId | null;\n\n /**\n * Retrieve memory only when memoryMode === 'always'.\n *\n * This method handles the common logic for memory retrieval across all channels,\n * including error handling and debug logging. If memoryMode is 'never',\n * automatic memory retrieval is skipped.\n */\n protected async retrieveMemoryIfEnabled(\n session: ConversationSession,\n query?: string\n ): Promise<TACMemoryResponse | undefined> {\n if (this.memoryMode !== 'always') {\n return undefined;\n }\n\n try {\n const memory = await this.tac.retrieveMemory(session, query);\n this.logger.debug(\n { conversation_id: session.conversationId },\n 'Memory retrieved successfully'\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 * 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 InitiateConversationResult,\n ProfileId,\n SendMessageActionRequest,\n isConversationId,\n isProfileId,\n MemoryMode,\n} from '../types/index';\nimport axios from 'axios';\nimport { BaseChannel, BaseChannelEvents } 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 webhook event types from Twilio Conversations Service\n * Supports the v2 format for SMS and Chat channels\n */\nexport interface MessagingWebhookPayload {\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\n/**\n * Messaging channel configuration options\n */\nexport interface MessagingChannelConfig {\n /** Maximum number of idempotency tokens to track for deduplication (default: 10,000) */\n dedupCapacity?: number;\n /** Memory retrieval mode. Default is \"never\". Set to \"always\" to retrieve memory for every message. */\n memoryMode?: MemoryMode;\n}\n\nconst DEFAULT_DEDUP_CAPACITY = 10_000;\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 private readonly processedTokens = new Set<string>();\n private readonly maxTrackedTokens: number;\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 const capacity = config?.dedupCapacity ?? DEFAULT_DEDUP_CAPACITY;\n if (capacity < 1 || !Number.isInteger(capacity)) {\n throw new Error('dedupCapacity must be a positive integer');\n }\n this.maxTrackedTokens = capacity;\n }\n\n /**\n * Check if a webhook has already been processed, and if not, record the token immediately.\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 * Uses a sliding window with FIFO eviction at capacity.\n */\n private isDuplicateWebhook(idempotencyToken: string): boolean {\n if (this.processedTokens.has(idempotencyToken)) {\n return true;\n }\n\n if (this.processedTokens.size >= this.maxTrackedTokens) {\n const oldest = this.processedTokens.values().next().value!;\n this.processedTokens.delete(oldest);\n }\n\n this.processedTokens.add(idempotencyToken);\n return false;\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 * Check if this webhook event belongs to this channel.\n * Returns false if the event is clearly for a different channel type.\n */\n private isEventForThisChannel(webhookData: MessagingWebhookPayload): 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; // Missing channel - cannot safely determine ownership\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.isConversationActive(conversationId)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Process messaging channel webhook from Twilio Conversations Service\n */\n public async processWebhook(payload: unknown, idempotencyToken?: string): Promise<void> {\n this.logger.debug({ operation: 'webhook_processing' }, 'Processing webhook');\n\n try {\n if (idempotencyToken && this.isDuplicateWebhook(idempotencyToken)) {\n this.logger.debug({ idempotency_token: idempotencyToken }, 'Skipping duplicate webhook');\n return;\n }\n\n if (!this.validateWebhookPayload(payload)) {\n throw new Error('Invalid webhook payload');\n }\n\n const webhookData = payload as MessagingWebhookPayload;\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;\n }\n\n this.logger.info(\n {\n event_type: eventType,\n raw_event_type: webhookData.eventType,\n conversation_id: conversationId,\n },\n 'Processing webhook event'\n );\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.processedTokens.delete(idempotencyToken);\n }\n this.logger.error(\n { err: error, operation: 'webhook_processing' },\n 'Webhook processing error'\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: MessagingWebhookPayload): 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: MessagingWebhookPayload): 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 this.logger.warn(\n { conversation_id: conversationId },\n 'Reconciliation failed; skipping callback for this inbound'\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: MessagingWebhookPayload): 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.info(\n { conversation_id: conversationId, status: payload.data.status },\n 'Conversation closed, cleaning up'\n );\n await this.endConversation(conversationId);\n }\n }\n\n /**\n * Extract conversation ID from webhook payload\n */\n protected extractConversationId(payload: unknown): ConversationId | null {\n const webhookData = payload as MessagingWebhookPayload;\n const conversationId = webhookData.data?.conversationId || webhookData.data?.id;\n\n if (conversationId && isConversationId(conversationId)) {\n return conversationId;\n }\n\n return null;\n }\n\n /**\n * Extract profile ID from webhook payload\n */\n protected extractProfileId(payload: unknown): ProfileId | null {\n const webhookData = payload as MessagingWebhookPayload;\n const profileId = webhookData.data?.profileId;\n\n if (profileId && isProfileId(profileId)) {\n this.logger.debug(\n { profile_id: profileId, conversation_id: webhookData.data?.conversationId },\n 'Extracted profile ID from webhook payload'\n );\n return profileId;\n }\n\n this.logger.debug(\n { conversation_id: webhookData.data?.conversationId },\n 'Profile ID missing or invalid in webhook payload'\n );\n return null;\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 MessagingWebhookPayload;\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.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 // TODO(conv-orch): Drop `chatService` here once the Actions API resolves\n // the V1 Chat service SID server-side. Confirmed this should not be\n // required client-side; keep the workaround until the server-side fix\n // ships. `channelId` stays — it's a permanent per-conversation requirement.\n const chatServiceSid = this.tac.conversationsV1ServiceSid;\n const channelSettings: ActionChannelSettings = {\n channelId: chatChannelSid,\n ...(chatServiceSid ? { chatService: chatServiceSid } : {}),\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 const chatServiceSid = this.tac.conversationsV1ServiceSid;\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 ...(chatServiceSid ? { chatService: chatServiceSid } : {}),\n },\n });\n }\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} 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 } from '../util/log-redaction';\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 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\n constructor(tac: TAC, options?: BaseChannelOptions) {\n super(tac, 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 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 webhook - Voice channel doesn't use traditional webhooks,\n * but this method is required by the base class\n */\n public processWebhook(_payload: unknown): Promise<void> {\n this.logger.warn('processWebhook called but Voice channel uses WebSocket connections');\n return Promise.resolve();\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 * 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\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.errors.map(error => ({\n path: error.path.join('.'),\n message: error.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 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\n if (fromNumber) {\n session.authorInfo = { address: fromNumber };\n }\n } else {\n // Orchestrated mode: poll for conversation created by CO\n if (!this.conversationClient) {\n throw new Error('Conversation client is required in orchestrated mode');\n }\n\n const POLL_ATTEMPTS = 5;\n const POLL_DELAY_MS = 500;\n let conversations: Awaited<\n ReturnType<typeof this.conversationClient.listConversations>\n > = [];\n\n for (let attempt = 0; attempt < POLL_ATTEMPTS; attempt++) {\n conversations = await this.conversationClient.listConversations({\n channelId: callSid,\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 await new Promise(resolve => setTimeout(resolve, POLL_DELAY_MS));\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 conversationId = conversation.id as ConversationId;\n\n const participants =\n 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\n if (customerAddress) {\n session.authorInfo = {\n address: customerAddress,\n };\n }\n }\n\n if (this.voiceCallbacks.onWebSocketConnected) {\n this.voiceCallbacks.onWebSocketConnected({ conversationId });\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 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\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 // End conversation (endConversation is async in BaseChannel)\n await this.endConversation(conversationId);\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 * Handle incoming voice call - generate TwiML to connect to ConversationRelay\n *\n * ConversationRelay will create the conversation automatically. The conversation\n * will be initialized on the first prompt using the callSid.\n *\n * @param options - Options for handling the incoming call\n * @returns TwiML XML string with ConversationRelay configuration\n */\n public handleIncomingCall(options: {\n actionUrl?: string;\n conversationRelayConfig: ConversationRelayConfig;\n }): string {\n const { actionUrl, conversationRelayConfig } = options;\n const conversationConfiguration = this.tac.isOrchestratorEnabled()\n ? (conversationRelayConfig.conversationConfiguration ??\n this.config.conversationConfigurationId)\n : undefined;\n return this.connectConversationRelay(\n {\n ...conversationRelayConfig,\n ...(conversationConfiguration !== undefined && { conversationConfiguration }),\n },\n actionUrl ? { actionUrl } : undefined\n );\n }\n\n // =========================================================================\n // Outbound Call Handling\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 lazily\n * on the first prompt when the conversation is discovered by callSid.\n *\n * `conversationRelayConfig.url` must be the publicly accessible WebSocket\n * endpoint (e.g., `wss://your-domain.ngrok.app/ws`). Unlike inbound calls\n * where TACServer sets this automatically, outbound calls require it\n * explicitly since there is no incoming HTTP request to derive the host from.\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 const conversationConfiguration = this.tac.isOrchestratorEnabled()\n ? (validated.conversationRelayConfig.conversationConfiguration ??\n this.config.conversationConfigurationId)\n : undefined;\n const twiml = this.connectConversationRelay(\n {\n ...validated.conversationRelayConfig,\n ...(conversationConfiguration !== undefined && { conversationConfiguration }),\n },\n {\n ...(validated.actionUrl ? { actionUrl: validated.actionUrl } : {}),\n }\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 });\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\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') {\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 // 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 * 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 * Extract conversation ID - Not applicable for Voice channel\n */\n protected extractConversationId(_payload: unknown): ConversationId | null {\n // Voice channel doesn't use traditional webhooks\n return null;\n }\n\n /**\n * Extract profile ID - Not applicable for Voice channel\n */\n protected extractProfileId(_payload: unknown): ProfileId | null {\n // Voice channel doesn't use traditional webhooks\n return null;\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","/**\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 { 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 * // Basic usage - includes all available data\n * const memoryPrompt = MemoryPromptBuilder.build(memoryResponse, session);\n * const systemPrompt = 'You are a helpful assistant.' + (memoryPrompt && `\\n\\n${memoryPrompt}`);\n *\n * // With trait filtering - only include specific profile trait groups\n * const memoryPrompt = MemoryPromptBuilder.build(\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 * 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 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 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 } 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 = any, TResult = any> {\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(): Record<string, any> {\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(): Record<string, any> {\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 {\n throw new Error(\n 'toOpenAIAgentsSDKTool() requires the @openai/agents package. ' +\n 'Install with: npm install @openai/agents'\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 = any, TResult = any>(\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 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 ConversationRelayConfig,\n studioVoiceHandoffUrl,\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 /** Custom webhook paths */\n webhookPaths?: {\n messaging?: string;\n twiml?: string;\n ws?: string;\n conversationRelayCallback?: string;\n /** Path for Conversation Intelligence webhook (optional - only registered if provided) */\n cintel?: string;\n };\n\n /** ConversationRelay configuration (welcomeGreeting, transcription, TTS, interaction settings, etc.) */\n conversationRelayConfig?: Partial<Omit<ConversationRelayConfig, 'url'>>;\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 messaging: '/webhook',\n twiml: '/twiml',\n ws: '/ws',\n conversationRelayCallback: '/conversation-relay-callback',\n },\n conversationRelayConfig: {\n welcomeGreeting: 'Hello! How can I assist you today?',\n },\n} satisfies Omit<\n TACServerConfig,\n 'fastify' | 'fastifyInstance' | 'voiceChannel' | 'messagingChannels'\n>;\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 — webhooks are fanned out to each one */\n private readonly messagingChannels: MessagingChannel[];\n /** Voice channel instance */\n private readonly voiceChannel: VoiceChannel | undefined;\n\n constructor(tac: TAC, config: TACServerConfig = {}) {\n this.tac = tac;\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n // Deep merge webhookPaths to preserve defaults while allowing overrides\n webhookPaths: {\n ...DEFAULT_CONFIG.webhookPaths,\n ...config.webhookPaths,\n },\n // Deep merge conversationRelayConfig to preserve defaults while allowing overrides\n conversationRelayConfig: {\n ...DEFAULT_CONFIG.conversationRelayConfig,\n ...config.conversationRelayConfig,\n },\n };\n\n // Resolve channels: prefer explicit kwargs, fall back to tac.getChannel()\n this.voiceChannel = config.voiceChannel ?? tac.getChannel<VoiceChannel>('voice');\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 if (this.messagingChannels.length === 0) {\n // eslint-disable-next-line no-console -- Fastify logger not yet initialized\n console.warn(\n 'TACServer: No messaging channels configured. Messaging webhooks will be disabled. Register a MessagingChannel (e.g., \"sms\", \"rcs\", \"chat\", or \"whatsapp\") with TAC to enable messaging.'\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 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 * Register global Twilio webhook signature validation hook\n */\n private registerWebhookValidation(): void {\n this.fastify.addHook('preHandler', (request, reply, done): void => {\n // Skip GET requests — WebSocket upgrades are validated in the route handler\n if (request.method === 'GET') {\n done();\n return;\n }\n\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\n // Check if this is a JSON body webhook (has bodySHA256 in query string)\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 // Form-encoded validation - use parsed params\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(\n { url, hasSignature: !!signature },\n 'Invalid Twilio webhook signature'\n );\n void reply.code(403).send({ error: 'Invalid webhook signature' });\n done();\n return;\n }\n\n done();\n });\n }\n\n /**\n * Setup routes\n */\n private async setupRoutes(): Promise<void> {\n // Messaging webhook — fan out to all enabled messaging channels (each self-filters)\n if (this.messagingChannels.length > 0) {\n this.fastify.post(\n this.config.webhookPaths.messaging || '/webhook',\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 for (const channel of this.messagingChannels) {\n channel.processWebhook(request.body, idempotencyToken).catch((err: unknown) => {\n this.fastify.log.error(\n { err, channel: channel.channelType },\n 'Messaging webhook processing error'\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 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 // Generate WebSocket URL\n const protocol = this.getForwardedProto(request);\n const host = this.getForwardedHost(request);\n const websocketUrl = `${protocol === 'https' ? 'wss' : 'ws'}://${host}${this.config.webhookPaths.ws || '/ws'}`;\n\n // If a Studio handoff flow is configured, point `<Connect action>`\n // directly at the Studio webhook so Studio (and Flex) takes over\n // when the ConversationRelay session ends. Otherwise, route the\n // post-CR action back to TAC's own callback.\n const tacConfig = this.tac.getConfig();\n const actionUrl = tacConfig.studioHandoffFlowSid\n ? studioVoiceHandoffUrl(tacConfig.accountSid, tacConfig.studioHandoffFlowSid)\n : `${protocol}://${host}${this.config.webhookPaths.conversationRelayCallback || '/conversation-relay-callback'}`;\n\n // Generate TwiML to connect to ConversationRelay\n // ConversationRelay will create the conversation automatically\n const twiml = voiceChannel.handleIncomingCall({\n actionUrl,\n conversationRelayConfig: {\n url: websocketUrl,\n ...this.config.conversationRelayConfig,\n },\n });\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\n this.fastify.post(\n this.config.webhookPaths.conversationRelayCallback || '/conversation-relay-callback',\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.errors },\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 // Voice WebSocket endpoint\n await this.fastify.register(fastify => {\n fastify.get(\n this.config.webhookPaths.ws || '/ws',\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 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 // Register webhook signature validation (must be after formbody for body access)\n this.registerWebhookValidation();\n\n // Set up routes (must be after plugin registration)\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 messaging_webhook: this.config.webhookPaths.messaging,\n twiml_webhook: this.config.webhookPaths.twiml,\n ws_websocket: this.config.webhookPaths.ws,\n conversation_relay_callback: this.config.webhookPaths.conversationRelayCallback,\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"]}
|