twilio-agent-connect 2.0.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import pino from 'pino';
4
4
  import { AxiosInstance } from 'axios';
5
5
  import { WebSocket } from 'ws';
6
6
  import VoiceResponse from 'twilio/lib/twiml/VoiceResponse.js';
7
+ import { CallListInstanceCreateOptions } from 'twilio/lib/rest/api/v2010/account/call.js';
7
8
  import { FastifyInstance, FastifyServerOptions } from 'fastify';
8
9
 
9
10
  /**
@@ -30,6 +31,15 @@ declare const TwilioMemoryConfigSchema: z.ZodObject<{
30
31
  phoneTraitField: z.ZodDefault<z.ZodString>;
31
32
  }, z.core.$strip>;
32
33
  type TwilioMemoryConfig = z.infer<typeof TwilioMemoryConfigSchema>;
34
+ /** The three Twilio call callbacks TAC serves, one route per kind. */
35
+ declare const CallEventKindSchema: z.ZodEnum<{
36
+ status: "status";
37
+ amd: "amd";
38
+ recording: "recording";
39
+ }>;
40
+ type CallEventKind = z.infer<typeof CallEventKindSchema>;
41
+ /** Iterable form of {@link CallEventKind}, for registering every route. */
42
+ declare const CALL_EVENT_KINDS: readonly CallEventKind[];
33
43
  /**
34
44
  * TAC configuration schema
35
45
  */
@@ -54,8 +64,8 @@ declare const TACConfigSchema: z.ZodObject<{
54
64
  voicePublicDomain: z.ZodOptional<z.ZodPreprocess<z.ZodOptional<z.ZodString>>>;
55
65
  voiceWebsocketPath: z.ZodType<string, unknown, z.core.$ZodTypeInternals<string, unknown>>;
56
66
  voiceActionPath: z.ZodType<string, unknown, z.core.$ZodTypeInternals<string, unknown>>;
67
+ voiceCallEventPath: z.ZodType<string, unknown, z.core.$ZodTypeInternals<string, unknown>>;
57
68
  cintelConfigurationId: z.ZodOptional<z.ZodString>;
58
- cintelObservationOperatorSid: z.ZodOptional<z.ZodString>;
59
69
  cintelSummaryOperatorSid: z.ZodOptional<z.ZodString>;
60
70
  region: z.ZodOptional<z.ZodString>;
61
71
  studioHandoffFlowSid: z.ZodOptional<z.ZodString>;
@@ -83,8 +93,8 @@ declare const EnvironmentVariables: {
83
93
  readonly TWILIO_VOICE_PUBLIC_DOMAIN: "TWILIO_VOICE_PUBLIC_DOMAIN";
84
94
  readonly TWILIO_VOICE_WEBSOCKET_PATH: "TWILIO_VOICE_WEBSOCKET_PATH";
85
95
  readonly TWILIO_VOICE_ACTION_PATH: "TWILIO_VOICE_ACTION_PATH";
96
+ readonly TWILIO_VOICE_CALL_EVENT_PATH: "TWILIO_VOICE_CALL_EVENT_PATH";
86
97
  readonly TWILIO_TAC_CI_CONFIGURATION_ID: "TWILIO_TAC_CI_CONFIGURATION_ID";
87
- readonly TWILIO_TAC_CI_OBSERVATION_OPERATOR_SID: "TWILIO_TAC_CI_OBSERVATION_OPERATOR_SID";
88
98
  readonly TWILIO_TAC_CI_SUMMARY_OPERATOR_SID: "TWILIO_TAC_CI_SUMMARY_OPERATOR_SID";
89
99
  readonly TWILIO_REGION: "TWILIO_REGION";
90
100
  readonly TWILIO_STUDIO_HANDOFF_FLOW_SID: "TWILIO_STUDIO_HANDOFF_FLOW_SID";
@@ -94,8 +104,9 @@ declare const EnvironmentVariables: {
94
104
  * Memory retrieval mode for channels.
95
105
  *
96
106
  * - "always": Fetch memory with the message as query on every inbound message.
97
- * - "once": Fetch memory once at conversation start with an empty query and
98
- * cache it. The cache is invalidated when the conversation becomes INACTIVE.
107
+ * - "once": Fetch memory once at conversation start with no query (and no
108
+ * conversation id, skipping query expansion) and cache it. The cache is
109
+ * invalidated when the conversation becomes INACTIVE.
99
110
  * - "never": Never automatically fetch memory (default).
100
111
  */
101
112
  declare const MemoryModeSchema: z.ZodEnum<{
@@ -134,6 +145,7 @@ declare const MemoryParticipantTypeSchema: z.ZodEnum<{
134
145
  CUSTOMER: "CUSTOMER";
135
146
  AI_AGENT: "AI_AGENT";
136
147
  AGENT: "AGENT";
148
+ UNKNOWN: "UNKNOWN";
137
149
  }>;
138
150
  type MemoryParticipantType = z.infer<typeof MemoryParticipantTypeSchema>;
139
151
  /**
@@ -173,6 +185,7 @@ declare const MemoryParticipantSchema: z.ZodObject<{
173
185
  CUSTOMER: "CUSTOMER";
174
186
  AI_AGENT: "AI_AGENT";
175
187
  AGENT: "AGENT";
188
+ UNKNOWN: "UNKNOWN";
176
189
  }>>;
177
190
  profileId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
178
191
  deliveryStatus: z.ZodOptional<z.ZodEnum<{
@@ -222,6 +235,7 @@ declare const MemoryCommunicationSchema: z.ZodObject<{
222
235
  CUSTOMER: "CUSTOMER";
223
236
  AI_AGENT: "AI_AGENT";
224
237
  AGENT: "AGENT";
238
+ UNKNOWN: "UNKNOWN";
225
239
  }>>;
226
240
  profileId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
227
241
  deliveryStatus: z.ZodOptional<z.ZodEnum<{
@@ -254,6 +268,7 @@ declare const MemoryCommunicationSchema: z.ZodObject<{
254
268
  CUSTOMER: "CUSTOMER";
255
269
  AI_AGENT: "AI_AGENT";
256
270
  AGENT: "AGENT";
271
+ UNKNOWN: "UNKNOWN";
257
272
  }>>;
258
273
  profileId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
259
274
  deliveryStatus: z.ZodOptional<z.ZodEnum<{
@@ -390,6 +405,7 @@ declare const MemoryRetrievalResponseSchema: z.ZodObject<{
390
405
  CUSTOMER: "CUSTOMER";
391
406
  AI_AGENT: "AI_AGENT";
392
407
  AGENT: "AGENT";
408
+ UNKNOWN: "UNKNOWN";
393
409
  }>>;
394
410
  profileId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
395
411
  deliveryStatus: z.ZodOptional<z.ZodEnum<{
@@ -422,6 +438,7 @@ declare const MemoryRetrievalResponseSchema: z.ZodObject<{
422
438
  CUSTOMER: "CUSTOMER";
423
439
  AI_AGENT: "AI_AGENT";
424
440
  AGENT: "AGENT";
441
+ UNKNOWN: "UNKNOWN";
425
442
  }>>;
426
443
  profileId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
427
444
  deliveryStatus: z.ZodOptional<z.ZodEnum<{
@@ -463,13 +480,39 @@ type ProfileResponse = z.infer<typeof ProfileResponseSchema>;
463
480
  */
464
481
  declare const EMPTY_MEMORY_RESPONSE: MemoryRetrievalResponse;
465
482
  /**
466
- * Response from creating an observation
483
+ * A single observation in a create request.
484
+ *
485
+ * `occurredAt` is required by the Memory API and formatted as ISO 8601.
467
486
  */
468
- declare const CreateObservationResponseSchema: z.ZodObject<{
487
+ declare const ObservationCreateRequestSchema: z.ZodObject<{
469
488
  content: z.ZodString;
470
489
  source: z.ZodString;
471
490
  occurredAt: z.ZodString;
472
- conversationIds: z.ZodArray<z.ZodString>;
491
+ conversationIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
492
+ }, z.core.$strip>;
493
+ type ObservationCreateRequest = z.infer<typeof ObservationCreateRequestSchema>;
494
+ /**
495
+ * Request body for the Memory API Observations endpoint.
496
+ *
497
+ * The endpoint is a batch create that wraps observations in an array.
498
+ */
499
+ declare const CreateObservationsRequestSchema: z.ZodObject<{
500
+ observations: z.ZodArray<z.ZodObject<{
501
+ content: z.ZodString;
502
+ source: z.ZodString;
503
+ occurredAt: z.ZodString;
504
+ conversationIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
505
+ }, z.core.$strip>>;
506
+ }, z.core.$strip>;
507
+ type CreateObservationsRequest = z.infer<typeof CreateObservationsRequestSchema>;
508
+ /**
509
+ * Response from creating an observation.
510
+ *
511
+ * The Memory API Observations endpoint is a batch create that returns a
512
+ * confirmation message rather than the persisted observation.
513
+ */
514
+ declare const CreateObservationResponseSchema: z.ZodObject<{
515
+ message: z.ZodString;
473
516
  }, z.core.$strip>;
474
517
  type CreateObservationResponse = z.infer<typeof CreateObservationResponseSchema>;
475
518
  /**
@@ -1152,6 +1195,7 @@ interface Profile {
1152
1195
  */
1153
1196
  declare const ConversationSessionSchema: z.ZodObject<{
1154
1197
  conversationId: z.ZodString;
1198
+ callSid: z.ZodOptional<z.ZodString>;
1155
1199
  profileId: z.ZodOptional<z.ZodString>;
1156
1200
  serviceId: z.ZodOptional<z.ZodString>;
1157
1201
  channel: z.ZodEnum<{
@@ -1440,8 +1484,8 @@ interface InitiateConversationResult {
1440
1484
  /**
1441
1485
  * Result of initiating an outbound voice conversation.
1442
1486
  * Note: conversationId is not included because the conversation is created by
1443
- * Conversation Orchestrator during passive hydration — the SDK discovers it
1444
- * lazily on the first prompt via callSid lookup.
1487
+ * Conversation Orchestrator during passive hydration — the SDK discovers it by
1488
+ * callSid, in the background from WebSocket setup.
1445
1489
  */
1446
1490
  interface InitiateVoiceConversationResult {
1447
1491
  callSid: string;
@@ -1827,6 +1871,213 @@ declare const ConversationRelayCallbackPayloadSchema: z.ZodObject<{
1827
1871
  SessionDuration: z.ZodOptional<z.ZodString>;
1828
1872
  }, z.core.$strip>;
1829
1873
  type ConversationRelayCallbackPayload = z.infer<typeof ConversationRelayCallbackPayloadSchema>;
1874
+ /**
1875
+ * A Twilio `statusCallback` webhook — call progress and disposition.
1876
+ *
1877
+ * By default Twilio sends only the terminal event, which covers every
1878
+ * disposition (`completed` / `busy` / `no-answer` / `failed` / `canceled`); set
1879
+ * `CallOptions.statusCallbackEvent` for the intermediate ones. Register a
1880
+ * handler via `VoiceChannel.onCallStatus`.
1881
+ *
1882
+ * `isUnreached` is computed at parse time so application code doesn't have to
1883
+ * match disposition strings itself.
1884
+ */
1885
+ declare const CallStatusEventSchema: z.ZodPipe<z.ZodObject<{
1886
+ callStatus: z.ZodOptional<z.ZodString>;
1887
+ callDuration: z.ZodOptional<z.ZodString>;
1888
+ sipResponseCode: z.ZodOptional<z.ZodString>;
1889
+ callSid: z.ZodString;
1890
+ accountSid: z.ZodOptional<z.ZodString>;
1891
+ extra: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
1892
+ }, z.core.$strip>, z.ZodTransform<{
1893
+ /** Call ended without reaching the callee — i.e. worth a retry. */
1894
+ isUnreached: boolean;
1895
+ callSid: string;
1896
+ extra: Record<string, string>;
1897
+ callStatus?: string | undefined;
1898
+ callDuration?: string | undefined;
1899
+ sipResponseCode?: string | undefined;
1900
+ accountSid?: string | undefined;
1901
+ }, {
1902
+ callSid: string;
1903
+ extra: Record<string, string>;
1904
+ callStatus?: string | undefined;
1905
+ callDuration?: string | undefined;
1906
+ sipResponseCode?: string | undefined;
1907
+ accountSid?: string | undefined;
1908
+ }>>;
1909
+ type CallStatusEvent = z.infer<typeof CallStatusEventSchema>;
1910
+ /** Build a {@link CallStatusEvent} from a raw Twilio webhook form. */
1911
+ declare function callStatusEventFromForm(form: Record<string, string>): CallStatusEvent;
1912
+ /**
1913
+ * A Twilio `asyncAmdStatusCallback` webhook — answering machine detection.
1914
+ *
1915
+ * Fires at most once per call, and only when the call set both
1916
+ * `CallOptions.machineDetection` and `asyncAmd`.
1917
+ *
1918
+ * `answeredBy` is mode-dependent — `machine_start` under `'Enable'`,
1919
+ * `machine_end_beep` / `machine_end_silence` / `machine_end_other` under
1920
+ * `'DetectMessageEnd'`, plus `human` / `fax` / `unknown` in both. Use
1921
+ * `isMachine` rather than matching those yourself. Register a handler via
1922
+ * `VoiceChannel.onAmd`.
1923
+ */
1924
+ declare const AmdEventSchema: z.ZodPipe<z.ZodObject<{
1925
+ answeredBy: z.ZodOptional<z.ZodString>;
1926
+ machineDetectionDuration: z.ZodOptional<z.ZodString>;
1927
+ callSid: z.ZodString;
1928
+ accountSid: z.ZodOptional<z.ZodString>;
1929
+ extra: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
1930
+ }, z.core.$strip>, z.ZodTransform<{
1931
+ /**
1932
+ * A machine answered — any `machine_*` value, either mode. `unknown`
1933
+ * (detection timed out) is false, so a call is never hung up on a guess.
1934
+ */
1935
+ isMachine: boolean;
1936
+ callSid: string;
1937
+ extra: Record<string, string>;
1938
+ answeredBy?: string | undefined;
1939
+ machineDetectionDuration?: string | undefined;
1940
+ accountSid?: string | undefined;
1941
+ }, {
1942
+ callSid: string;
1943
+ extra: Record<string, string>;
1944
+ answeredBy?: string | undefined;
1945
+ machineDetectionDuration?: string | undefined;
1946
+ accountSid?: string | undefined;
1947
+ }>>;
1948
+ type AmdEvent = z.infer<typeof AmdEventSchema>;
1949
+ /** Build an {@link AmdEvent} from a raw Twilio webhook form. */
1950
+ declare function amdEventFromForm(form: Record<string, string>): AmdEvent;
1951
+ /**
1952
+ * A Twilio `recordingStatusCallback` webhook — a recording became available.
1953
+ *
1954
+ * Fires when the recording is ready (`recordingUrl` accessible), only when
1955
+ * recording is enabled. Register a handler via `VoiceChannel.onRecording`.
1956
+ */
1957
+ declare const RecordingEventSchema: z.ZodObject<{
1958
+ recordingSid: z.ZodOptional<z.ZodString>;
1959
+ recordingUrl: z.ZodOptional<z.ZodString>;
1960
+ recordingStatus: z.ZodOptional<z.ZodString>;
1961
+ recordingDuration: z.ZodOptional<z.ZodString>;
1962
+ callSid: z.ZodString;
1963
+ accountSid: z.ZodOptional<z.ZodString>;
1964
+ extra: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
1965
+ }, z.core.$strip>;
1966
+ type RecordingEvent = z.infer<typeof RecordingEventSchema>;
1967
+ /** Build a {@link RecordingEvent} from a raw Twilio webhook form. */
1968
+ declare function recordingEventFromForm(form: Record<string, string>): RecordingEvent;
1969
+ /**
1970
+ * Every parameter `client.calls.create()` accepts, as of the pinned Twilio SDK.
1971
+ *
1972
+ * Unlike Python's `inspect.signature`, TypeScript has no runtime view of a
1973
+ * function's accepted keys, so the set is listed here and pinned to the SDK by
1974
+ * {@link _CallsCreateDriftGuards} at typecheck time. It's needed at runtime
1975
+ * because the Node SDK builds its request body from an explicit whitelist —
1976
+ * an unrecognized key is **silently dropped**, not an error, so without this a
1977
+ * typo would look like it worked.
1978
+ */
1979
+ declare const CALLS_CREATE_PARAMS: readonly ["applicationSid", "asyncAmd", "asyncAmdStatusCallback", "asyncAmdStatusCallbackMethod", "byoc", "callerId", "callReason", "callToken", "clientNotificationUrl", "fallbackMethod", "fallbackUrl", "from", "machineDetection", "machineDetectionSilenceTimeout", "machineDetectionSpeechEndThreshold", "machineDetectionSpeechThreshold", "machineDetectionTimeout", "method", "record", "recordingChannels", "recordingStatusCallback", "recordingStatusCallbackEvent", "recordingStatusCallbackMethod", "recordingTrack", "sendDigits", "sipAuthPassword", "sipAuthUsername", "statusCallback", "statusCallbackEvent", "statusCallbackMethod", "timeLimit", "timeout", "to", "trim", "twiml", "url"];
1980
+ /**
1981
+ * `calls.create` parameters TAC owns — it builds the call and its TwiML, so a
1982
+ * caller setting these would either be overwritten or break the call.
1983
+ */
1984
+ declare const RESERVED_CALL_PARAMS: readonly ["to", "from", "twiml", "url", "applicationSid"];
1985
+ type ReservedCallParam = (typeof RESERVED_CALL_PARAMS)[number];
1986
+ /**
1987
+ * The `calls.create` parameters TAC types explicitly — the ones outbound
1988
+ * ConversationRelay reaches for. Everything else the SDK accepts is still
1989
+ * forwarded, typed by the SDK itself via {@link CallOptions}.
1990
+ */
1991
+ interface TypedCallOptions {
1992
+ /**
1993
+ * Enables AMD. `'Enable'` reports as soon as it can tell human from machine
1994
+ * (to hang up on voicemail); `'DetectMessageEnd'` waits out the greeting (to
1995
+ * leave a message). Required, together with `asyncAmd`, for `onAmd` to fire.
1996
+ */
1997
+ machineDetection?: 'Enable' | 'DetectMessageEnd' | undefined;
1998
+ /**
1999
+ * Detect in the background. Required for `onAmd`: with it off, `AnsweredBy`
2000
+ * comes back on the TwiML request, which inline TwiML can't receive.
2001
+ *
2002
+ * Twilio's API types this as a string; a boolean is serialized for you.
2003
+ */
2004
+ asyncAmd?: boolean | string | undefined;
2005
+ asyncAmdStatusCallback?: string | undefined;
2006
+ asyncAmdStatusCallbackMethod?: string | undefined;
2007
+ machineDetectionTimeout?: number | undefined;
2008
+ machineDetectionSpeechThreshold?: number | undefined;
2009
+ machineDetectionSpeechEndThreshold?: number | undefined;
2010
+ machineDetectionSilenceTimeout?: number | undefined;
2011
+ /** Required for `onRecording`. */
2012
+ record?: boolean | undefined;
2013
+ recordingStatusCallback?: string | undefined;
2014
+ recordingStatusCallbackEvent?: string[] | undefined;
2015
+ recordingChannels?: string | undefined;
2016
+ recordingTrack?: string | undefined;
2017
+ statusCallback?: string | undefined;
2018
+ /**
2019
+ * Lifecycle events to report. Omitted, Twilio sends only `'completed'` —
2020
+ * which covers busy/canceled/failed/no-answer. Set it for ringing/answered.
2021
+ */
2022
+ statusCallbackEvent?: string[] | undefined;
2023
+ statusCallbackMethod?: string | undefined;
2024
+ /** Seconds to ring before giving up. Twilio defaults to 60. */
2025
+ timeout?: number | undefined;
2026
+ }
2027
+ /**
2028
+ * Parameters for Twilio's `client.calls.create()`.
2029
+ *
2030
+ * {@link TypedCallOptions} covers the ones outbound ConversationRelay reaches
2031
+ * for; any other parameter `calls.create()` accepts is forwarded too, typed by
2032
+ * the Twilio SDK. TAC-owned parameters (`to`, `from`, `twiml`, `url`,
2033
+ * `applicationSid`) are excluded — TAC builds the call and its TwiML.
2034
+ *
2035
+ * Unknown keys are rejected at validation, so a typo fails at
2036
+ * `initiateOutboundConversation` rather than being silently dropped by the SDK.
2037
+ *
2038
+ * @example
2039
+ * ```typescript
2040
+ * const callOptions: CallOptions = {
2041
+ * machineDetection: 'Enable',
2042
+ * asyncAmd: true,
2043
+ * record: true,
2044
+ * };
2045
+ * ```
2046
+ */
2047
+ type CallOptions = TypedCallOptions & Omit<CallListInstanceCreateOptions, ReservedCallParam | keyof TypedCallOptions>;
2048
+ /**
2049
+ * @internal Fails typecheck unless instantiated with `true`. A conditional type
2050
+ * that merely resolves to `never` is not an error on its own, so the assertion
2051
+ * has to be a constraint violation to be load-bearing.
2052
+ */
2053
+ type _AssertTrue<T extends true> = T;
2054
+ /**
2055
+ * @internal Compile-time SDK drift guards — do not use directly.
2056
+ * If the Twilio SDK adds, removes, or renames a `calls.create` parameter these
2057
+ * checks fail during `npm run typecheck`, signaling that
2058
+ * {@link CALLS_CREATE_PARAMS} needs updating. Without the `complete` direction a
2059
+ * newly added SDK parameter would be rejected at runtime as unknown.
2060
+ */
2061
+ type _CallsCreateDriftGuards = {
2062
+ known: _AssertTrue<(typeof CALLS_CREATE_PARAMS)[number] extends keyof CallListInstanceCreateOptions ? true : false>;
2063
+ complete: _AssertTrue<keyof CallListInstanceCreateOptions extends (typeof CALLS_CREATE_PARAMS)[number] ? true : false>;
2064
+ typedAreRealParams: _AssertTrue<keyof TypedCallOptions extends keyof CallListInstanceCreateOptions ? true : false>;
2065
+ reservedAreRealParams: _AssertTrue<ReservedCallParam extends keyof CallListInstanceCreateOptions ? true : false>;
2066
+ };
2067
+ /**
2068
+ * Validates {@link CallOptions}. The parsed value is re-widened to `CallOptions`
2069
+ * because the loose object's inferred index signature would otherwise erase the
2070
+ * SDK-derived parameter types.
2071
+ */
2072
+ declare const CallOptionsSchema: z.ZodType<CallOptions, unknown>;
2073
+ /**
2074
+ * Serialize {@link CallOptions} into the argument object for
2075
+ * `client.calls.create()`, dropping unset keys.
2076
+ *
2077
+ * `asyncAmd` is coerced to a string because Twilio's SDK types it as one,
2078
+ * unlike `record`.
2079
+ */
2080
+ declare function callOptionsToCreateParams(options: CallOptions): Record<string, unknown>;
1830
2081
  /**
1831
2082
  * Options for initiating an outbound voice conversation.
1832
2083
  *
@@ -1858,6 +2109,12 @@ interface InitiateVoiceConversationOptions {
1858
2109
  * `VoiceChannelConfig.defaultTwimlOptions` and TAC defaults.
1859
2110
  */
1860
2111
  twimlOptions?: TwiMLOptions | undefined;
2112
+ /**
2113
+ * Parameters for Twilio's `calls.create()` — AMD, recording, status
2114
+ * callbacks, timeout (see {@link CallOptions}). Callback URLs auto-wire when
2115
+ * the matching handler is registered; an explicit URL wins.
2116
+ */
2117
+ callOptions?: CallOptions | undefined;
1861
2118
  }
1862
2119
  declare const InitiateVoiceConversationOptionsSchema: z.ZodType<InitiateVoiceConversationOptions>;
1863
2120
 
@@ -1910,7 +2167,7 @@ type JSONSchema = z.infer<typeof JSONSchemaSchema>;
1910
2167
  /**
1911
2168
  * Tool function signature
1912
2169
  */
1913
- type ToolFunction<TParams = any, TResult = any> = (params: TParams) => Promise<TResult> | TResult;
2170
+ type ToolFunction<TParams = unknown, TResult = unknown> = (params: TParams) => Promise<TResult> | TResult;
1914
2171
  /**
1915
2172
  * OpenAI tool format
1916
2173
  */
@@ -1936,6 +2193,28 @@ declare const OpenAIToolSchema: z.ZodObject<{
1936
2193
  }, z.core.$strip>;
1937
2194
  }, z.core.$strip>;
1938
2195
  type OpenAITool = z.infer<typeof OpenAIToolSchema>;
2196
+ /**
2197
+ * Anthropic tool format
2198
+ */
2199
+ declare const AnthropicToolSchema: z.ZodObject<{
2200
+ name: z.ZodString;
2201
+ description: z.ZodString;
2202
+ input_schema: z.ZodObject<{
2203
+ type: z.ZodEnum<{
2204
+ string: "string";
2205
+ number: "number";
2206
+ boolean: "boolean";
2207
+ object: "object";
2208
+ array: "array";
2209
+ }>;
2210
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
2211
+ required: z.ZodOptional<z.ZodArray<z.ZodString>>;
2212
+ items: z.ZodOptional<z.ZodAny>;
2213
+ enum: z.ZodOptional<z.ZodArray<z.ZodAny>>;
2214
+ description: z.ZodOptional<z.ZodString>;
2215
+ }, z.core.$strip>;
2216
+ }, z.core.$strip>;
2217
+ type AnthropicTool = z.infer<typeof AnthropicToolSchema>;
1939
2218
  /**
1940
2219
  * Tool execution context
1941
2220
  */
@@ -2078,7 +2357,6 @@ type OperatorProcessingResult = z.infer<typeof OperatorProcessingResultSchema>;
2078
2357
  */
2079
2358
  declare const ConversationIntelligenceConfigSchema: z.ZodObject<{
2080
2359
  configurationId: z.ZodString;
2081
- observationOperatorSid: z.ZodOptional<z.ZodString>;
2082
2360
  summaryOperatorSid: z.ZodOptional<z.ZodString>;
2083
2361
  }, z.core.$strip>;
2084
2362
  type ConversationIntelligenceConfig = z.infer<typeof ConversationIntelligenceConfigSchema>;
@@ -2176,8 +2454,9 @@ declare class TACConfig {
2176
2454
  readonly voiceWebsocketPath: string;
2177
2455
  /** Path the ConversationRelay action callback is served at (default '/conversation-relay-callback'). */
2178
2456
  readonly voiceActionPath: string;
2457
+ /** Base path the call-event callbacks are served under (default '/twilio/call-events'). */
2458
+ readonly voiceCallEventPath: string;
2179
2459
  readonly cintelConfigurationId?: string;
2180
- readonly cintelObservationOperatorSid?: string;
2181
2460
  readonly cintelSummaryOperatorSid?: string;
2182
2461
  /** Optional Twilio region subdomain for API routing (e.g. transforms base URLs to `https://{product}.{region}.twilio.com`) */
2183
2462
  readonly region?: string;
@@ -2203,9 +2482,10 @@ declare class TACConfig {
2203
2482
  * Optional environment variables:
2204
2483
  * - TWILIO_WHATSAPP_NUMBER: WhatsApp number for WhatsApp channel (e.g., 'whatsapp:+1234567890')
2205
2484
  * - TWILIO_CONVERSATION_CONFIGURATION_ID: Conversation Orchestrator configuration ID (enables orchestrated mode)
2206
- * - TWILIO_VOICE_PUBLIC_DOMAIN: Public domain for voice routes (required for voice; domain only, without protocol/port/path, e.g., 'abc123.ngrok.app')
2485
+ * - TWILIO_VOICE_PUBLIC_DOMAIN: Public domain for voice routes (required for voice; a port and/or base path are allowed, e.g., 'abc123.ngrok.app', 'example.ngrok.app:8080', or 'example.com/server1')
2207
2486
  * - TWILIO_VOICE_WEBSOCKET_PATH: Path for the voice WebSocket (default: /ws)
2208
2487
  * - TWILIO_VOICE_ACTION_PATH: Path for the ConversationRelay action callback (default: /conversation-relay-callback)
2488
+ * - TWILIO_VOICE_CALL_EVENT_PATH: Base path for the call-event callbacks — status, async AMD, recording (default: /twilio/call-events)
2209
2489
  * - TWILIO_REGION: Twilio region subdomain for API routing (e.g. transforms base URLs to `https://{product}.{region}.twilio.com`)
2210
2490
  * - TWILIO_STUDIO_HANDOFF_FLOW_SID: Studio Flow SID used by createStudioHandoffTool for human handoff
2211
2491
  * - TWILIO_RCS_SENDER_ID: RCS Sender ID for the RCS channel
@@ -2231,6 +2511,17 @@ declare class TACConfig {
2231
2511
  * ```
2232
2512
  */
2233
2513
  static fromEnv(): TACConfig;
2514
+ /**
2515
+ * Path a call-event callback is served at.
2516
+ *
2517
+ * Single source of truth: the voice channel builds callback URLs from this
2518
+ * and TACServer registers routes at it, so the two can't drift.
2519
+ */
2520
+ callEventPath(kind: CallEventKind): string;
2521
+ /**
2522
+ * Public URL for a call-event callback, or `undefined` without a public domain.
2523
+ */
2524
+ callEventUrl(kind: CallEventKind): string | undefined;
2234
2525
  /**
2235
2526
  * Whether Conversation Orchestrator is configured.
2236
2527
  * Returns false in voice-only mode (no conversationConfigurationId).
@@ -2304,6 +2595,16 @@ declare class MemoryClient extends BaseClient {
2304
2595
  * @returns Promise containing memory retrieval response
2305
2596
  */
2306
2597
  retrieveMemories(profileId: string, request?: Partial<MemoryRetrievalRequest>): Promise<MemoryRetrievalResponse>;
2598
+ /** Cap on per-item validation warnings logged per response, to avoid flooding logs. */
2599
+ private static readonly MAX_INVALID_ITEM_LOGS;
2600
+ /**
2601
+ * Validate an array of memory items one at a time, dropping (and logging)
2602
+ * any that fail validation while keeping the rest.
2603
+ *
2604
+ * Per-item warnings are capped at {@link MemoryClient.MAX_INVALID_ITEM_LOGS}
2605
+ * and followed by a single summary warning with the total `invalid_count`.
2606
+ */
2607
+ private parseItems;
2307
2608
  /**
2308
2609
  * Find profiles that contain a specific identifier value
2309
2610
  *
@@ -2339,14 +2640,18 @@ declare class MemoryClient extends BaseClient {
2339
2640
  */
2340
2641
  getProfile(profileId: string, traitGroups?: string[]): Promise<ProfileResponse>;
2341
2642
  /**
2342
- * Create an observation for a profile
2643
+ * Create an observation for a profile.
2644
+ *
2645
+ * The Memory API Observations endpoint is a batch create: the observation is
2646
+ * wrapped in an `observations` array and `occurredAt` is required, so it
2647
+ * defaults to the current time (ISO 8601) when omitted or blank.
2343
2648
  *
2344
2649
  * @param profileId - The profile ID to create the observation for
2345
2650
  * @param content - The observation content
2346
2651
  * @param source - Source of the observation (default: 'conversation-intelligence')
2347
2652
  * @param conversationIds - Optional array of conversation IDs associated with this observation
2348
- * @param occurredAt - Optional timestamp when the observation occurred
2349
- * @returns Promise containing the created observation
2653
+ * @param occurredAt - Timestamp when the observation occurred (ISO 8601); defaults to now when omitted or blank
2654
+ * @returns Promise containing the API confirmation message
2350
2655
  */
2351
2656
  createObservation(profileId: string, content: string, source?: string, conversationIds?: string[], occurredAt?: string): Promise<CreateObservationResponse>;
2352
2657
  /**
@@ -2542,7 +2847,7 @@ interface BaseChannelOptions {
2542
2847
  *
2543
2848
  * - "never": Memory is not automatically retrieved. Use the memory TAC tool or manually call `tac.retrieveMemory()` in callbacks for conditional retrieval.
2544
2849
  * - "always": Memory is automatically retrieved (using the message as query) for every inbound message and available in `onMessageReady` callback.
2545
- * - "once": Memory is retrieved once at conversation start with an empty query and cached on the session. Subsequent messages reuse the cache until the conversation becomes INACTIVE.
2850
+ * - "once": Memory is retrieved once at conversation start with no query (and no conversation id) and cached on the session. Subsequent messages reuse the cache until the conversation becomes INACTIVE.
2546
2851
  */
2547
2852
  memoryMode?: MemoryMode;
2548
2853
  /**
@@ -2680,9 +2985,9 @@ declare abstract class BaseChannel {
2680
2985
  *
2681
2986
  * Modes:
2682
2987
  * - "always": Fetch with the provided query on every message.
2683
- * - "once": Fetch once with an empty query and cache the result on the
2684
- * session. Subsequent calls reuse the cache until it is invalidated on the
2685
- * INACTIVE transition.
2988
+ * - "once": Fetch once with neither a query nor a conversation id (skipping
2989
+ * query expansion) and cache the result on the session. Subsequent calls
2990
+ * reuse the cache until it is invalidated on the INACTIVE transition.
2686
2991
  * - "never": Skip retrieval.
2687
2992
  *
2688
2993
  * Memory retrieval failures are logged and swallowed so message processing
@@ -2833,6 +3138,10 @@ declare class TAC {
2833
3138
  *
2834
3139
  * @param session - Conversation session context
2835
3140
  * @param query - Optional semantic search query
3141
+ * @param conversationId - Passed through to `/Recall` as-is. Sending one
3142
+ * without a `query` makes Memory infer one from that conversation's history
3143
+ * — an expensive server-side step — so leave it unset when there is no
3144
+ * per-turn topic (e.g. `"once"` mode's cache-priming fetch).
2836
3145
  * @returns Promise containing TACMemoryResponse wrapper providing unified access to memory data.
2837
3146
  *
2838
3147
  * Attempts to retrieve from Memory API first:
@@ -2843,7 +3152,7 @@ declare class TAC {
2843
3152
  * - observations and summaries are empty arrays
2844
3153
  * - communications have basic fields only (no author name/type)
2845
3154
  */
2846
- retrieveMemory(session: ConversationSession, query?: string): Promise<TACMemoryResponse>;
3155
+ retrieveMemory(session: ConversationSession, query?: string, conversationId?: string): Promise<TACMemoryResponse>;
2847
3156
  /**
2848
3157
  * Fetch profile information with traits
2849
3158
  *
@@ -3202,6 +3511,14 @@ interface VoiceChannelConfig extends BaseChannelOptions {
3202
3511
  * higher-priority layer sets them.
3203
3512
  */
3204
3513
  defaultTwimlOptions?: TwiMLOptions;
3514
+ /**
3515
+ * Static {@link CallOptions} applied to every outbound call — the
3516
+ * `calls.create` parameters, including the call-event callback URLs. This is
3517
+ * the layer to use for a custom server or non-default routes: URLs set here
3518
+ * override the ones TAC would derive from `voicePublicDomain` +
3519
+ * `voiceCallEventPath`.
3520
+ */
3521
+ defaultCallOptions?: CallOptions;
3205
3522
  }
3206
3523
  /**
3207
3524
  * Callback that produces per-call overrides for the TwiML inside
@@ -3209,6 +3526,12 @@ interface VoiceChannelConfig extends BaseChannelOptions {
3209
3526
  * {@link TwiMLRequest} and returns {@link TwiMLOptions}.
3210
3527
  */
3211
3528
  type InboundCallTwimlHandler = (req: TwiMLRequest) => Promise<TwiMLOptions>;
3529
+ /** Handler for Twilio `statusCallback` webhooks. */
3530
+ type CallStatusHandler = (event: CallStatusEvent) => Promise<void> | void;
3531
+ /** Handler for Twilio `asyncAmdStatusCallback` webhooks. */
3532
+ type AmdHandler = (event: AmdEvent) => Promise<void> | void;
3533
+ /** Handler for Twilio `recordingStatusCallback` webhooks. */
3534
+ type RecordingHandler = (event: RecordingEvent) => Promise<void> | void;
3212
3535
  /**
3213
3536
  * Voice channel event callbacks extending base callbacks
3214
3537
  */
@@ -3231,6 +3554,10 @@ interface VoiceChannelEvents extends BaseChannelEvents {
3231
3554
  utteranceUntilInterrupt: string | undefined;
3232
3555
  durationUntilInterruptMs: number | undefined;
3233
3556
  }) => void;
3557
+ /**
3558
+ * Fired once the session and WebSocket registration exist — in orchestrated
3559
+ * mode possibly before the first prompt, since the lookup starts at setup.
3560
+ */
3234
3561
  onWebSocketConnected?: (data: {
3235
3562
  conversationId: ConversationId;
3236
3563
  }) => void;
@@ -3259,6 +3586,9 @@ declare class VoiceChannel extends BaseChannel {
3259
3586
  private twilioClient;
3260
3587
  private readonly voiceConfig;
3261
3588
  private onInboundCallTwimlHandler;
3589
+ private onCallStatusHandler;
3590
+ private onAmdHandler;
3591
+ private onRecordingHandler;
3262
3592
  constructor(tac: TAC, options?: VoiceChannelConfig);
3263
3593
  /**
3264
3594
  * Register a callback that produces per-call overrides for the TwiML inside
@@ -3283,6 +3613,68 @@ declare class VoiceChannel extends BaseChannel {
3283
3613
  * `InitiateVoiceConversationOptions.twimlOptions` directly.
3284
3614
  */
3285
3615
  onInboundCallTwiml(callback: InboundCallTwimlHandler): void;
3616
+ /**
3617
+ * Register a handler for Twilio `statusCallback` webhooks.
3618
+ *
3619
+ * This is the Calls-API status callback (call disposition), not the
3620
+ * ConversationRelay session callback — see
3621
+ * {@link handleConversationRelayCallback}.
3622
+ *
3623
+ * Registering does two things: it stores the handler, and it makes later
3624
+ * outbound calls pass `statusCallback` to `calls.create`. With no handler
3625
+ * registered TAC omits that parameter, so Twilio has nowhere to post and the
3626
+ * event never arrives.
3627
+ *
3628
+ * Twilio reports only the terminal event by default, which covers every
3629
+ * disposition; set `CallOptions.statusCallbackEvent` for ringing/answered.
3630
+ *
3631
+ * @example
3632
+ * ```typescript
3633
+ * voiceChannel.onCallStatus(async event => {
3634
+ * if (event.isUnreached) {
3635
+ * // queue a retry
3636
+ * }
3637
+ * });
3638
+ * ```
3639
+ */
3640
+ onCallStatus(callback: CallStatusHandler): void;
3641
+ /**
3642
+ * Register a handler for Twilio `asyncAmdStatusCallback` webhooks.
3643
+ *
3644
+ * Registering makes later outbound calls pass `asyncAmdStatusCallback` to
3645
+ * `calls.create`; without a handler TAC omits it and Twilio has nowhere to
3646
+ * post the result. It does not enable detection — that's per-call, via
3647
+ * `CallOptions.machineDetection` and `asyncAmd`, both of which are required
3648
+ * for this to fire (at most once per call).
3649
+ *
3650
+ * @example
3651
+ * ```typescript
3652
+ * voiceChannel.onAmd(async event => {
3653
+ * if (event.isMachine) {
3654
+ * await voiceChannel.endCall(event.callSid); // voicemail → hang up
3655
+ * }
3656
+ * });
3657
+ * ```
3658
+ */
3659
+ onAmd(callback: AmdHandler): void;
3660
+ /**
3661
+ * Register a handler for Twilio `recordingStatusCallback` webhooks.
3662
+ *
3663
+ * Registering makes later outbound calls pass `recordingStatusCallback` to
3664
+ * `calls.create`; without a handler TAC omits it and Twilio has nowhere to
3665
+ * post. It does not start recording — that's `CallOptions.record`, which is
3666
+ * required for this to fire.
3667
+ *
3668
+ * @example
3669
+ * ```typescript
3670
+ * voiceChannel.onRecording(async event => {
3671
+ * if (event.recordingStatus === 'completed') {
3672
+ * // store event.recordingUrl
3673
+ * }
3674
+ * });
3675
+ * ```
3676
+ */
3677
+ onRecording(callback: RecordingHandler): void;
3286
3678
  /**
3287
3679
  * Resolve the public WebSocket URL from `TACConfig.voicePublicDomain` +
3288
3680
  * `TACConfig.voiceWebsocketPath`. Throws if `voicePublicDomain` isn't set.
@@ -3323,6 +3715,13 @@ declare class VoiceChannel extends BaseChannel {
3323
3715
  * Get active WebSocket connection for a conversation
3324
3716
  */
3325
3717
  getWebsocket(conversationId: ConversationId): WebSocket | null;
3718
+ /**
3719
+ * Poll Conversation Orchestrator for the conversation ConversationRelay
3720
+ * created for `callSid`, then register the local session and WebSocket.
3721
+ * Runs in the background from `setup`, so those can exist before the
3722
+ * caller speaks.
3723
+ */
3724
+ private initializeOrchestratedConversation;
3326
3725
  /**
3327
3726
  * Handle WebSocket connection from ConversationRelay
3328
3727
  */
@@ -3443,13 +3842,42 @@ declare class VoiceChannel extends BaseChannel {
3443
3842
  * `actionUrl` left absent (key not present) falls through to the next layer.
3444
3843
  */
3445
3844
  private resolveActionUrl;
3845
+ /**
3846
+ * Overlay `perCall` onto `VoiceChannelConfig.defaultCallOptions`.
3847
+ *
3848
+ * Per-field via key presence, the same convention {@link overlayFields} uses
3849
+ * for TwiML options — so a per-call `{ machineDetection: undefined }`
3850
+ * explicitly clears the channel default rather than falling through to it.
3851
+ *
3852
+ * The result is always validated, for two reasons: a combination only
3853
+ * reachable by layering — per-call clearing `machineDetection` while the
3854
+ * default set `asyncAmd` — must still fail instead of reaching Twilio, and
3855
+ * `VoiceChannelConfig` is a plain interface, so `defaultCallOptions` has had
3856
+ * no runtime validation of its own.
3857
+ */
3858
+ private mergeCallOptions;
3859
+ /**
3860
+ * Build the extra arguments for `client.calls.create`.
3861
+ *
3862
+ * Layers, highest precedence first: this call's `callOptions`,
3863
+ * `VoiceChannelConfig.defaultCallOptions`, then callback URLs derived from
3864
+ * `voicePublicDomain` + `voiceCallEventPath`.
3865
+ *
3866
+ * A URL is derived only when its handler is registered. That's a deliberate
3867
+ * deviation from `websocketUrl` / `actionUrl`, which derive unconditionally:
3868
+ * those are load-bearing, so a wrong one fails loudly on the first call,
3869
+ * whereas an unwanted call-event URL fails as silent 11200 alerts for a
3870
+ * feature nobody asked for. Set the URLs in `defaultCallOptions` when TAC
3871
+ * isn't serving the routes.
3872
+ */
3873
+ private buildCallParams;
3446
3874
  /**
3447
3875
  * Initiate an outbound voice conversation
3448
3876
  *
3449
3877
  * Places an outbound call with inline TwiML that connects to ConversationRelay.
3450
3878
  * The conversationConfiguration attribute tells CO to create and manage the
3451
- * conversation during passive hydration. The session is initialized lazily
3452
- * on the first prompt when the conversation is discovered by callSid.
3879
+ * conversation during passive hydration. The session is initialized when the
3880
+ * background callSid lookup started at WebSocket setup finds it.
3453
3881
  *
3454
3882
  * TwiML fields are merged per-field, highest precedence first:
3455
3883
  * 1. `options.twimlOptions` — per-call overrides
@@ -3458,6 +3886,12 @@ declare class VoiceChannel extends BaseChannel {
3458
3886
  * `TACConfig`, and `actionUrl` from Studio handoff (if configured), else
3459
3887
  * derived from `TACConfig.voicePublicDomain` + `voiceActionPath`.
3460
3888
  *
3889
+ * Calls-API parameters merge the same way:
3890
+ * 1. `options.callOptions` — per-call overrides
3891
+ * 2. `VoiceChannelConfig.defaultCallOptions` — channel-wide defaults
3892
+ * 3. Callback URLs derived from `TACConfig.voicePublicDomain` +
3893
+ * `voiceCallEventPath`, for handlers that are registered
3894
+ *
3461
3895
  * The WebSocket URL is derived from `TACConfig.voicePublicDomain` +
3462
3896
  * `TACConfig.voiceWebsocketPath`, unless overridden per-call via
3463
3897
  * `options.websocketUrl`.
@@ -3475,6 +3909,120 @@ declare class VoiceChannel extends BaseChannel {
3475
3909
  content: string;
3476
3910
  contentType: string;
3477
3911
  }>;
3912
+ /**
3913
+ * Whether a call-webhook payload belongs to the configured account.
3914
+ *
3915
+ * Twilio signature validation already gates the route; this is defense in
3916
+ * depth. A payload with no `AccountSid` is allowed through.
3917
+ *
3918
+ * Subaccounts: events carry the SID the call was placed on, so configure TAC
3919
+ * with that account or its events get dropped here.
3920
+ */
3921
+ private callEventAccountOk;
3922
+ /**
3923
+ * Parse a call-event webhook form and dispatch it to its handler.
3924
+ *
3925
+ * Returns 400 when the payload can't be parsed (no `CallSid`) or the handler
3926
+ * throws — better than handing Twilio a 200 for an event that wasn't
3927
+ * processed. Everything else, including no handler registered and an
3928
+ * account mismatch, is a 200 no-op.
3929
+ */
3930
+ private dispatchCallEvent;
3931
+ /**
3932
+ * Handle a Twilio `statusCallback` webhook.
3933
+ *
3934
+ * The developer routes the request here (`TACServer` does this automatically
3935
+ * for its `/status` call-event route). Parsed into a {@link CallStatusEvent}
3936
+ * and dispatched to the {@link onCallStatus} handler. No-op if no handler is
3937
+ * registered.
3938
+ *
3939
+ * @param form - Raw form data from the webhook request.
3940
+ */
3941
+ handleCallStatusEvent(form: Record<string, string>): Promise<{
3942
+ status: number;
3943
+ content: string;
3944
+ contentType: string;
3945
+ }>;
3946
+ /**
3947
+ * Handle a Twilio `asyncAmdStatusCallback` webhook.
3948
+ *
3949
+ * The developer routes the request here (`TACServer` does this automatically
3950
+ * for its `/amd` call-event route). Parsed into an {@link AmdEvent} and
3951
+ * dispatched to the {@link onAmd} handler. No-op if no handler is registered.
3952
+ *
3953
+ * @param form - Raw form data from the webhook request.
3954
+ */
3955
+ handleAmdEvent(form: Record<string, string>): Promise<{
3956
+ status: number;
3957
+ content: string;
3958
+ contentType: string;
3959
+ }>;
3960
+ /**
3961
+ * Handle a Twilio `recordingStatusCallback` webhook.
3962
+ *
3963
+ * The developer routes the request here (`TACServer` does this automatically
3964
+ * for its `/recording` call-event route). Parsed into a
3965
+ * {@link RecordingEvent} and dispatched to the {@link onRecording} handler.
3966
+ * No-op if no handler is registered.
3967
+ *
3968
+ * @param form - Raw form data from the webhook request.
3969
+ */
3970
+ handleRecordingEvent(form: Record<string, string>): Promise<{
3971
+ status: number;
3972
+ content: string;
3973
+ contentType: string;
3974
+ }>;
3975
+ /**
3976
+ * Hang up a call and clean up its ConversationRelay session.
3977
+ *
3978
+ * Works on `callSid` alone, whether or not a session exists yet. No-ops the
3979
+ * session cleanup if none is tracked.
3980
+ *
3981
+ * Does not throw — hanging up an already-ended call is routine (the callee
3982
+ * hangs up while AMD is still resolving), and handlers shouldn't have to
3983
+ * guard against it.
3984
+ *
3985
+ * @param callSid - Twilio Call SID (from a call event, the outbound result, or
3986
+ * `ConversationSession.callSid`).
3987
+ * @returns True if Twilio accepted the hangup, false if it failed (logged).
3988
+ * Session cleanup runs either way.
3989
+ */
3990
+ endCall(callSid: string): Promise<boolean>;
3991
+ /**
3992
+ * Look up the active voice session for a Twilio Call SID.
3993
+ *
3994
+ * Out-of-band code holding a CallSid — a dashboard route, an operator action,
3995
+ * a call-event handler — can't reach the session-facing methods, which are
3996
+ * keyed by conversation id: the Orchestrator conversation id in orchestrator
3997
+ * mode, the CallSid only in ConversationRelay-only mode.
3998
+ *
3999
+ * Relay-only mode creates the session on the first prompt; orchestrated
4000
+ * mode creates it when the lookup started at setup finishes, so it may
4001
+ * exist before the caller speaks — including before `onAmd` fires. Treat it
4002
+ * as racy and hang up with {@link endCall}, which needs no session.
4003
+ *
4004
+ * At the other end, orchestrator mode keeps the session until Conversation
4005
+ * Orchestrator's CLOSED webhook, so it outlives the call and `onCallStatus` /
4006
+ * `onRecording` do resolve. Relay-only mode tears down on the
4007
+ * ConversationRelay callback instead, which races them.
4008
+ *
4009
+ * @example
4010
+ * ```typescript
4011
+ * async function nudge(callSid: string): Promise<void> {
4012
+ * const session = voiceChannel.getConversationSessionByCallSid(callSid);
4013
+ * if (session) {
4014
+ * await voiceChannel.sendResponse(session.conversationId, 'Still there?');
4015
+ * }
4016
+ * }
4017
+ * ```
4018
+ *
4019
+ * @param callSid - Twilio Call SID, e.g. from
4020
+ * `InitiateVoiceConversationResult.callSid` or a call event.
4021
+ * @returns The session, or `undefined` — not created yet, the call ended, or
4022
+ * it landed on another instance (see the horizontal-scaling note in
4023
+ * CLAUDE.md).
4024
+ */
4025
+ getConversationSessionByCallSid(callSid: string): ConversationSession | undefined;
3478
4026
  /**
3479
4027
  * Start tracking a streaming task for a conversation
3480
4028
  *
@@ -3557,6 +4105,18 @@ declare function scrubObject(obj: unknown, seen?: WeakSet<object>): unknown;
3557
4105
  declare function maskPhone(phone: string): string;
3558
4106
  declare function maskEmail(email: string): string;
3559
4107
  declare function maskAddress(address: string): string;
4108
+ /**
4109
+ * Mask `<Parameter value="...">` contents in TwiML, keeping the names.
4110
+ *
4111
+ * `<Parameter>` children carry whatever the developer put in
4112
+ * `customParameters` — profile IDs, caller names. Names stay because knowing
4113
+ * which parameters were sent is the point of logging the TwiML.
4114
+ *
4115
+ * Handles either quote style. TAC's own TwiML comes from the Twilio SDK, which
4116
+ * always double-quotes, but this takes a plain string and shouldn't depend on
4117
+ * that to stay safe.
4118
+ */
4119
+ declare function redactTwimlParameters(twiml: string | undefined | null): string;
3560
4120
 
3561
4121
  /**
3562
4122
  * URL builders for Twilio Studio handoff.
@@ -3583,8 +4143,8 @@ declare function studioVoiceHandoffUrl(accountSid: string, flowSid: string): str
3583
4143
  /**
3584
4144
  * Processor for Conversation Intelligence operator result webhooks
3585
4145
  *
3586
- * Processes operator results from CI and creates observations or summaries
3587
- * in the Memory service based on the operator configuration.
4146
+ * Processes operator results from CI and creates conversation summaries in the
4147
+ * Memory service based on the operator configuration.
3588
4148
  */
3589
4149
  declare class OperatorResultProcessor {
3590
4150
  private readonly memoryClient;
@@ -3602,10 +4162,6 @@ declare class OperatorResultProcessor {
3602
4162
  * Process an individual operator result
3603
4163
  */
3604
4164
  private processOperatorResult;
3605
- /**
3606
- * Process an observation operator result
3607
- */
3608
- private processObservationEvent;
3609
4165
  /**
3610
4166
  * Process a summary operator result
3611
4167
  */
@@ -3741,7 +4297,7 @@ declare class MemoryPromptBuilder {
3741
4297
  *
3742
4298
  * Matches Python's TACTool dataclass with conversion methods.
3743
4299
  */
3744
- declare class TACTool<TParams = any, TResult = any> {
4300
+ declare class TACTool<TParams = unknown, TResult = unknown> {
3745
4301
  readonly name: string;
3746
4302
  readonly description: string;
3747
4303
  readonly parameters: JSONSchema;
@@ -3750,11 +4306,11 @@ declare class TACTool<TParams = any, TResult = any> {
3750
4306
  /**
3751
4307
  * Convert to OpenAI function calling format
3752
4308
  */
3753
- toOpenAIFormat(): Record<string, any>;
4309
+ toOpenAIFormat(): OpenAITool;
3754
4310
  /**
3755
4311
  * Convert to Anthropic tool calling format
3756
4312
  */
3757
- toAnthropicFormat(): Record<string, any>;
4313
+ toAnthropicFormat(): AnthropicTool;
3758
4314
  /**
3759
4315
  * Convert to JSON string (OpenAI format by default)
3760
4316
  */
@@ -3781,7 +4337,7 @@ declare class TACTool<TParams = any, TResult = any> {
3781
4337
  * Simplified approach matching Python's create_tool function.
3782
4338
  * No builder pattern - just a simple function call.
3783
4339
  */
3784
- declare function defineTool<TParams = any, TResult = any>(name: string, description: string, parameters: JSONSchema, implementation: ToolFunction<TParams, TResult>): TACTool<TParams, TResult>;
4340
+ declare function defineTool<TParams = unknown, TResult = unknown>(name: string, description: string, parameters: JSONSchema, implementation: ToolFunction<TParams, TResult>): TACTool<TParams, TResult>;
3785
4341
 
3786
4342
  /**
3787
4343
  * Parameters for memory retrieval tool
@@ -3843,9 +4399,6 @@ declare function createSendMessageTool(channel: BaseChannel, conversationId: Con
3843
4399
  * Create factory function for messaging tools
3844
4400
  */
3845
4401
  declare function createMessagingTools(): {
3846
- /**
3847
- * Create send message tool for specific channel and conversation
3848
- */
3849
4402
  forConversation: (channel: BaseChannel, conversationId: ConversationId) => TACTool<SendMessageParams, SendMessageResult>;
3850
4403
  };
3851
4404
 
@@ -4051,6 +4604,19 @@ declare class TACServer {
4051
4604
  /** All channels that need webhook processing (voice + messaging) */
4052
4605
  private readonly webhookChannels;
4053
4606
  constructor(tac: TAC, config?: TACServerConfig);
4607
+ /**
4608
+ * Validate `voiceCallEventPath`, the one path that isn't literal.
4609
+ *
4610
+ * Every other TAC path registers as configured, so a bad value is visible.
4611
+ * This one expands into three sub-paths, hiding a mistake the base path looks
4612
+ * innocent for: a sub-path colliding with another route while the base looks
4613
+ * unrelated (base `/hooks` vs `webhookPaths.twiml = '/hooks/status'`). Both
4614
+ * would register as POST routes and requests would reach the wrong handler.
4615
+ *
4616
+ * The leading-slash requirement is enforced by `TACConfigSchema` at parse
4617
+ * time, so it doesn't need re-checking here.
4618
+ */
4619
+ private validateCallEventPaths;
4054
4620
  private getForwardedProto;
4055
4621
  private getForwardedHost;
4056
4622
  /**
@@ -4084,4 +4650,4 @@ declare class TACServer {
4084
4650
  stop(): Promise<void>;
4085
4651
  }
4086
4652
 
4087
- export { type ActionChannelSettings, ActionChannelSettingsSchema, type ActionParticipantRef, ActionParticipantRefSchema, type ActionResponse, ActionResponseSchema, type ActionTextContent, ActionTextContentSchema, type AdapterOptions, type AuthorInfo, AuthorInfoSchema, BaseChannel, type BaseChannelEvents, type BaseChannelOptions, BaseClient, type BuiltInToolName, BuiltInTools, type CaptureRule, CaptureRuleSchema, type ChannelSettings, ChannelSettingsSchema, type ChannelType, ChannelTypeSchema, ChatChannel, type ChatChannelConfig, type CintelParticipant, CintelParticipantSchema, type Communication, type CommunicationContent, CommunicationContentSchema, type CommunicationParticipant, CommunicationParticipantSchema, CommunicationSchema, type ConversationAddress, ConversationAddressSchema, ConversationClient, type ConversationConfiguration, ConversationConfigurationSchema, type ConversationEndedCallback, type ConversationGroupingType, ConversationGroupingTypeSchema, type ConversationId, type ConversationIntelligenceConfig, ConversationIntelligenceConfigSchema, type ConversationParticipant, ConversationParticipantSchema, type ConversationRelayAttributes, ConversationRelayAttributesSchema, type ConversationRelayCallbackPayload, ConversationRelayCallbackPayloadSchema, type ConversationRelayConfig, ConversationRelayConfigSchema, type ConversationResponse, ConversationResponseSchema, type ConversationSession, ConversationSessionSchema, type ConversationSummaryItem, ConversationSummaryItemSchema, type ConversationWebhookPayload, type CreateConversationSummariesResponse, CreateConversationSummariesResponseSchema, type CreateObservationResponse, CreateObservationResponseSchema, type CustomParameters, CustomParametersSchema, EMPTY_MEMORY_RESPONSE, EnvironmentVariables, type ExecutionDetails, ExecutionDetailsSchema, type HandoffPayload, HandoffPayloadSchema, type HandoffResult, type InboundCallTwimlHandler, type InitiateChatConversationOptions, type InitiateConversationResult, type InitiateMessagingConversationOptions, InitiateMessagingConversationOptionsSchema, type InitiateVoiceConversationOptions, InitiateVoiceConversationOptionsSchema, type InitiateVoiceConversationResult, type IntelligenceConfiguration, IntelligenceConfigurationSchema, type InterruptCallback, type InterruptMessage, InterruptMessageSchema, type InterruptMode, InterruptModeSchema, type JSONSchema, JSONSchemaSchema, type KnowledgeBase, KnowledgeBaseSchema, type KnowledgeBaseStatus, KnowledgeBaseStatusSchema, type KnowledgeChunkResult, KnowledgeChunkResultSchema, KnowledgeClient, type KnowledgeSearchResponse, KnowledgeSearchResponseSchema, type LanguageAttributes, LanguageAttributesSchema, type LanguageConfig, LanguageConfigSchema, type ListCommunicationsResponse, ListCommunicationsResponseSchema, type ListConversationsResponse, ListConversationsResponseSchema, type ListParticipantsResponse, ListParticipantsResponseSchema, type Logger, type MemoryChannelType, MemoryChannelTypeSchema, MemoryClient, type MemoryCommunication, type MemoryCommunicationContent, MemoryCommunicationContentSchema, MemoryCommunicationSchema, type MemoryDeliveryStatus, MemoryDeliveryStatusSchema, type MemoryMode, MemoryModeSchema, type MemoryParticipant, MemoryParticipantSchema, type MemoryParticipantType, MemoryParticipantTypeSchema, MemoryPromptBuilder, type MemoryRetrievalRequest, MemoryRetrievalRequestSchema, type MemoryRetrievalResponse, MemoryRetrievalResponseSchema, type MessageDirection, MessageDirectionSchema, type MessageReadyCallback, MessagingChannel, type MessagingChannelConfig, type MessagingChannelEvents, type ObservationInfo, ObservationInfoSchema, type OpenAITool, OpenAIToolSchema, type Operator, type OperatorProcessingResult, OperatorProcessingResultSchema, type OperatorResult, type OperatorResultEvent, OperatorResultEventSchema, OperatorResultProcessor, OperatorResultSchema, OperatorSchema, type ParticipantAddress, ParticipantAddressSchema, type ParticipantAddressType, ParticipantAddressTypeSchema, type ParticipantId, type PendingHandoffData, PendingHandoffDataSchema, type Profile, type ProfileId, type ProfileLookupResponse, ProfileLookupResponseSchema, type ProfileResponse, ProfileResponseSchema, type PromptMessage, PromptMessageSchema, RCSChannel, SMSChannel, type SendMessageActionPayload, SendMessageActionPayloadSchema, type SendMessageActionRequest, SendMessageActionRequestSchema, type SessionInfo, SessionInfoSchema, type SessionMessage, SessionMessageSchema, type SetupMessage, SetupMessageSchema, type StatusCallback, StatusCallbackSchema, type StatusTimeouts, StatusTimeoutsSchema, type StreamTask, type SummaryInfo, SummaryInfoSchema, TAC, type TACChannelType, TACChannelTypeSchema, type TACCommunication, type TACCommunicationAuthor, TACCommunicationAuthorSchema, type TACCommunicationContent, TACCommunicationContentSchema, TACCommunicationSchema, TACConfig, type TACConfigData, TACConfigSchema, type TACDeliveryStatus, TACDeliveryStatusSchema, TACMemoryResponse, type TACOptions, type TACParticipantType, TACParticipantTypeSchema, TACServer, type TACServerConfig, TACTool, type TextTokenMessage, TextTokenMessageSchema, type ToolContext, type ToolExecutionResult, ToolExecutionResultSchema, type ToolFunction, type Transcription, TranscriptionSchema, type TranscriptionWord, TranscriptionWordSchema, type TwiMLOptions, TwiMLOptionsSchema, type TwiMLRequest, TwiMLRequestSchema, type TwilioMemoryConfig, TwilioMemoryConfigSchema, VoiceChannel, type VoiceChannelConfig, type VoiceChannelEvents, type WebSocketMessage, WebSocketMessageSchema, WhatsAppChannel, type _SDKDriftGuards, buildHandoffPayload, createKnowledgeSearchTool, createKnowledgeSearchToolAsync, createKnowledgeTools, createLogger, createMemoryRetrievalTool, createMemoryTools, createMessagingTools, createSendMessageTool, createStudioHandoffTool, defineTool, isConversationId, isParticipantId, isProfileId, maskAddress, maskEmail, maskPhone, postStudioHandoff, scrubObject, scrubPii, studioExecutionsUrl, studioVoiceHandoffUrl, twiMLRequestFromForm };
4653
+ export { type ActionChannelSettings, ActionChannelSettingsSchema, type ActionParticipantRef, ActionParticipantRefSchema, type ActionResponse, ActionResponseSchema, type ActionTextContent, ActionTextContentSchema, type AdapterOptions, type AmdEvent, AmdEventSchema, type AmdHandler, type AnthropicTool, AnthropicToolSchema, type AuthorInfo, AuthorInfoSchema, BaseChannel, type BaseChannelEvents, type BaseChannelOptions, BaseClient, type BuiltInToolName, BuiltInTools, CALL_EVENT_KINDS, type CallEventKind, CallEventKindSchema, type CallOptions, CallOptionsSchema, type CallStatusEvent, CallStatusEventSchema, type CallStatusHandler, type CaptureRule, CaptureRuleSchema, type ChannelSettings, ChannelSettingsSchema, type ChannelType, ChannelTypeSchema, ChatChannel, type ChatChannelConfig, type CintelParticipant, CintelParticipantSchema, type Communication, type CommunicationContent, CommunicationContentSchema, type CommunicationParticipant, CommunicationParticipantSchema, CommunicationSchema, type ConversationAddress, ConversationAddressSchema, ConversationClient, type ConversationConfiguration, ConversationConfigurationSchema, type ConversationEndedCallback, type ConversationGroupingType, ConversationGroupingTypeSchema, type ConversationId, type ConversationIntelligenceConfig, ConversationIntelligenceConfigSchema, type ConversationParticipant, ConversationParticipantSchema, type ConversationRelayAttributes, ConversationRelayAttributesSchema, type ConversationRelayCallbackPayload, ConversationRelayCallbackPayloadSchema, type ConversationRelayConfig, ConversationRelayConfigSchema, type ConversationResponse, ConversationResponseSchema, type ConversationSession, ConversationSessionSchema, type ConversationSummaryItem, ConversationSummaryItemSchema, type ConversationWebhookPayload, type CreateConversationSummariesResponse, CreateConversationSummariesResponseSchema, type CreateObservationResponse, CreateObservationResponseSchema, type CreateObservationsRequest, CreateObservationsRequestSchema, type CustomParameters, CustomParametersSchema, EMPTY_MEMORY_RESPONSE, EnvironmentVariables, type ExecutionDetails, ExecutionDetailsSchema, type HandoffPayload, HandoffPayloadSchema, type HandoffResult, type InboundCallTwimlHandler, type InitiateChatConversationOptions, type InitiateConversationResult, type InitiateMessagingConversationOptions, InitiateMessagingConversationOptionsSchema, type InitiateVoiceConversationOptions, InitiateVoiceConversationOptionsSchema, type InitiateVoiceConversationResult, type IntelligenceConfiguration, IntelligenceConfigurationSchema, type InterruptCallback, type InterruptMessage, InterruptMessageSchema, type InterruptMode, InterruptModeSchema, type JSONSchema, JSONSchemaSchema, type KnowledgeBase, KnowledgeBaseSchema, type KnowledgeBaseStatus, KnowledgeBaseStatusSchema, type KnowledgeChunkResult, KnowledgeChunkResultSchema, KnowledgeClient, type KnowledgeSearchResponse, KnowledgeSearchResponseSchema, type LanguageAttributes, LanguageAttributesSchema, type LanguageConfig, LanguageConfigSchema, type ListCommunicationsResponse, ListCommunicationsResponseSchema, type ListConversationsResponse, ListConversationsResponseSchema, type ListParticipantsResponse, ListParticipantsResponseSchema, type Logger, type MemoryChannelType, MemoryChannelTypeSchema, MemoryClient, type MemoryCommunication, type MemoryCommunicationContent, MemoryCommunicationContentSchema, MemoryCommunicationSchema, type MemoryDeliveryStatus, MemoryDeliveryStatusSchema, type MemoryMode, MemoryModeSchema, type MemoryParticipant, MemoryParticipantSchema, type MemoryParticipantType, MemoryParticipantTypeSchema, MemoryPromptBuilder, type MemoryRetrievalRequest, MemoryRetrievalRequestSchema, type MemoryRetrievalResponse, MemoryRetrievalResponseSchema, type MessageDirection, MessageDirectionSchema, type MessageReadyCallback, MessagingChannel, type MessagingChannelConfig, type MessagingChannelEvents, type ObservationCreateRequest, ObservationCreateRequestSchema, type ObservationInfo, ObservationInfoSchema, type OpenAITool, OpenAIToolSchema, type Operator, type OperatorProcessingResult, OperatorProcessingResultSchema, type OperatorResult, type OperatorResultEvent, OperatorResultEventSchema, OperatorResultProcessor, OperatorResultSchema, OperatorSchema, type ParticipantAddress, ParticipantAddressSchema, type ParticipantAddressType, ParticipantAddressTypeSchema, type ParticipantId, type PendingHandoffData, PendingHandoffDataSchema, type Profile, type ProfileId, type ProfileLookupResponse, ProfileLookupResponseSchema, type ProfileResponse, ProfileResponseSchema, type PromptMessage, PromptMessageSchema, RCSChannel, type RecordingEvent, RecordingEventSchema, type RecordingHandler, SMSChannel, type SendMessageActionPayload, SendMessageActionPayloadSchema, type SendMessageActionRequest, SendMessageActionRequestSchema, type SessionInfo, SessionInfoSchema, type SessionMessage, SessionMessageSchema, type SetupMessage, SetupMessageSchema, type StatusCallback, StatusCallbackSchema, type StatusTimeouts, StatusTimeoutsSchema, type StreamTask, type SummaryInfo, SummaryInfoSchema, TAC, type TACChannelType, TACChannelTypeSchema, type TACCommunication, type TACCommunicationAuthor, TACCommunicationAuthorSchema, type TACCommunicationContent, TACCommunicationContentSchema, TACCommunicationSchema, TACConfig, type TACConfigData, TACConfigSchema, type TACDeliveryStatus, TACDeliveryStatusSchema, TACMemoryResponse, type TACOptions, type TACParticipantType, TACParticipantTypeSchema, TACServer, type TACServerConfig, TACTool, type TextTokenMessage, TextTokenMessageSchema, type ToolContext, type ToolExecutionResult, ToolExecutionResultSchema, type ToolFunction, type Transcription, TranscriptionSchema, type TranscriptionWord, TranscriptionWordSchema, type TwiMLOptions, TwiMLOptionsSchema, type TwiMLRequest, TwiMLRequestSchema, type TwilioMemoryConfig, TwilioMemoryConfigSchema, type TypedCallOptions, VoiceChannel, type VoiceChannelConfig, type VoiceChannelEvents, type WebSocketMessage, WebSocketMessageSchema, WhatsAppChannel, type _CallsCreateDriftGuards, type _SDKDriftGuards, amdEventFromForm, buildHandoffPayload, callOptionsToCreateParams, callStatusEventFromForm, createKnowledgeSearchTool, createKnowledgeSearchToolAsync, createKnowledgeTools, createLogger, createMemoryRetrievalTool, createMemoryTools, createMessagingTools, createSendMessageTool, createStudioHandoffTool, defineTool, isConversationId, isParticipantId, isProfileId, maskAddress, maskEmail, maskPhone, postStudioHandoff, recordingEventFromForm, redactTwimlParameters, scrubObject, scrubPii, studioExecutionsUrl, studioVoiceHandoffUrl, twiMLRequestFromForm };