@niadra/sdk 0.1.0 → 0.7.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.
Files changed (133) hide show
  1. package/CHANGELOG.md +161 -20
  2. package/README.md +484 -38
  3. package/dist/ai-sdk.cjs +1037 -0
  4. package/dist/ai-sdk.cjs.map +1 -0
  5. package/dist/ai-sdk.d.cts +118 -0
  6. package/dist/ai-sdk.d.ts +118 -0
  7. package/dist/ai-sdk.js +1030 -0
  8. package/dist/ai-sdk.js.map +1 -0
  9. package/dist/anthropic.cjs +528 -0
  10. package/dist/anthropic.cjs.map +1 -0
  11. package/dist/anthropic.d.cts +35 -0
  12. package/dist/anthropic.d.ts +35 -0
  13. package/dist/anthropic.js +523 -0
  14. package/dist/anthropic.js.map +1 -0
  15. package/dist/bedrock.cjs +392 -0
  16. package/dist/bedrock.cjs.map +1 -0
  17. package/dist/bedrock.d.cts +25 -0
  18. package/dist/bedrock.d.ts +25 -0
  19. package/dist/bedrock.js +388 -0
  20. package/dist/bedrock.js.map +1 -0
  21. package/dist/cli.js +11045 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/client-DsIxZxZk.d.cts +6905 -0
  24. package/dist/client-DsIxZxZk.d.ts +6905 -0
  25. package/dist/cloudflare-agents.cjs +626 -0
  26. package/dist/cloudflare-agents.cjs.map +1 -0
  27. package/dist/cloudflare-agents.d.cts +113 -0
  28. package/dist/cloudflare-agents.d.ts +113 -0
  29. package/dist/cloudflare-agents.js +622 -0
  30. package/dist/cloudflare-agents.js.map +1 -0
  31. package/dist/elevenlabs.cjs +738 -0
  32. package/dist/elevenlabs.cjs.map +1 -0
  33. package/dist/elevenlabs.d.cts +86 -0
  34. package/dist/elevenlabs.d.ts +86 -0
  35. package/dist/elevenlabs.js +733 -0
  36. package/dist/elevenlabs.js.map +1 -0
  37. package/dist/genkit.cjs +323 -0
  38. package/dist/genkit.cjs.map +1 -0
  39. package/dist/genkit.d.cts +67 -0
  40. package/dist/genkit.d.ts +67 -0
  41. package/dist/genkit.js +318 -0
  42. package/dist/genkit.js.map +1 -0
  43. package/dist/google-adk.cjs +705 -0
  44. package/dist/google-adk.cjs.map +1 -0
  45. package/dist/google-adk.d.cts +91 -0
  46. package/dist/google-adk.d.ts +91 -0
  47. package/dist/google-adk.js +701 -0
  48. package/dist/google-adk.js.map +1 -0
  49. package/dist/google-genai.cjs +422 -0
  50. package/dist/google-genai.cjs.map +1 -0
  51. package/dist/google-genai.d.cts +26 -0
  52. package/dist/google-genai.d.ts +26 -0
  53. package/dist/google-genai.js +418 -0
  54. package/dist/google-genai.js.map +1 -0
  55. package/dist/index.cjs +11449 -1796
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.cts +1006 -1247
  58. package/dist/index.d.ts +1006 -1247
  59. package/dist/index.js +11393 -1797
  60. package/dist/index.js.map +1 -1
  61. package/dist/intercept-0_lJE6k1.d.cts +20 -0
  62. package/dist/intercept-D7qFCaRb.d.ts +20 -0
  63. package/dist/langchain.cjs +1077 -0
  64. package/dist/langchain.cjs.map +1 -0
  65. package/dist/langchain.d.cts +102 -0
  66. package/dist/langchain.d.ts +102 -0
  67. package/dist/langchain.js +1068 -0
  68. package/dist/langchain.js.map +1 -0
  69. package/dist/livekit.cjs +404 -0
  70. package/dist/livekit.cjs.map +1 -0
  71. package/dist/livekit.d.cts +113 -0
  72. package/dist/livekit.d.ts +113 -0
  73. package/dist/livekit.js +398 -0
  74. package/dist/livekit.js.map +1 -0
  75. package/dist/llamaindex.cjs +349 -0
  76. package/dist/llamaindex.cjs.map +1 -0
  77. package/dist/llamaindex.d.cts +92 -0
  78. package/dist/llamaindex.d.ts +92 -0
  79. package/dist/llamaindex.js +344 -0
  80. package/dist/llamaindex.js.map +1 -0
  81. package/dist/mastra.cjs +1082 -0
  82. package/dist/mastra.cjs.map +1 -0
  83. package/dist/mastra.d.cts +86 -0
  84. package/dist/mastra.d.ts +86 -0
  85. package/dist/mastra.js +1075 -0
  86. package/dist/mastra.js.map +1 -0
  87. package/dist/openai-agents.cjs +465 -0
  88. package/dist/openai-agents.cjs.map +1 -0
  89. package/dist/openai-agents.d.cts +75 -0
  90. package/dist/openai-agents.d.ts +75 -0
  91. package/dist/openai-agents.js +459 -0
  92. package/dist/openai-agents.js.map +1 -0
  93. package/dist/retell.cjs +846 -0
  94. package/dist/retell.cjs.map +1 -0
  95. package/dist/retell.d.cts +161 -0
  96. package/dist/retell.d.ts +161 -0
  97. package/dist/retell.js +841 -0
  98. package/dist/retell.js.map +1 -0
  99. package/dist/shared-Bb5B59Bu.d.ts +39 -0
  100. package/dist/shared-DTPWVlWm.d.cts +39 -0
  101. package/dist/strands.cjs +352 -0
  102. package/dist/strands.cjs.map +1 -0
  103. package/dist/strands.d.cts +72 -0
  104. package/dist/strands.d.ts +72 -0
  105. package/dist/strands.js +347 -0
  106. package/dist/strands.js.map +1 -0
  107. package/dist/twilio.cjs +174 -0
  108. package/dist/twilio.cjs.map +1 -0
  109. package/dist/twilio.d.cts +64 -0
  110. package/dist/twilio.d.ts +64 -0
  111. package/dist/twilio.js +167 -0
  112. package/dist/twilio.js.map +1 -0
  113. package/dist/vapi.cjs +661 -0
  114. package/dist/vapi.cjs.map +1 -0
  115. package/dist/vapi.d.cts +78 -0
  116. package/dist/vapi.d.ts +78 -0
  117. package/dist/vapi.js +656 -0
  118. package/dist/vapi.js.map +1 -0
  119. package/dist/voltagent.cjs +509 -0
  120. package/dist/voltagent.cjs.map +1 -0
  121. package/dist/voltagent.d.cts +70 -0
  122. package/dist/voltagent.d.ts +70 -0
  123. package/dist/voltagent.js +503 -0
  124. package/dist/voltagent.js.map +1 -0
  125. package/dist/webhook-1ozGyksG.d.ts +37 -0
  126. package/dist/webhook-CG4om_DK.d.cts +37 -0
  127. package/dist/whatsapp.cjs +214 -0
  128. package/dist/whatsapp.cjs.map +1 -0
  129. package/dist/whatsapp.d.cts +81 -0
  130. package/dist/whatsapp.d.ts +81 -0
  131. package/dist/whatsapp.js +207 -0
  132. package/dist/whatsapp.js.map +1 -0
  133. package/package.json +355 -7
package/dist/vapi.js ADDED
@@ -0,0 +1,656 @@
1
+ // src/tools.ts
2
+ var TOOL_NAMES = {
3
+ search: "search_customer_history",
4
+ timeline: "get_customer_timeline",
5
+ open: "open_history_item"
6
+ };
7
+ var AGENT_MEMORY_TOOL_NAMES = {
8
+ search: "search_agent_memory",
9
+ remember: "remember"
10
+ };
11
+ var TOOL_DEFINITIONS = [
12
+ {
13
+ "type": "function",
14
+ "function": {
15
+ "name": "search_customer_history",
16
+ "description": "Search everything that already happened with this customer: past conversations, promises, agent actions, orders and invoices. Use it when the customer refers to something earlier or asks whether a problem happened before. Do not call it when the answer is already in the context block, including its 'Do hist\xF3rico' line, which already counts recurrences. Returns short items with date, channel and outcome, plus a recurrence count. Open one with open_history_item.",
17
+ "parameters": {
18
+ "type": "object",
19
+ "properties": {
20
+ "query": {
21
+ "type": "string",
22
+ "description": "What to look for, in the customer's words."
23
+ },
24
+ "filters": {
25
+ "type": "object",
26
+ "properties": {
27
+ "since": {
28
+ "type": "string",
29
+ "format": "date-time"
30
+ },
31
+ "until": {
32
+ "type": "string",
33
+ "format": "date-time"
34
+ },
35
+ "when": {
36
+ "type": "string",
37
+ "description": "The period in the customer's own words, as they said it: 'last week', 'semana passada', 'en marzo'."
38
+ },
39
+ "channels": {
40
+ "type": "array",
41
+ "items": {
42
+ "type": "string"
43
+ }
44
+ },
45
+ "categories": {
46
+ "type": "array",
47
+ "items": {
48
+ "type": "string"
49
+ }
50
+ },
51
+ "item_kinds": {
52
+ "type": "array",
53
+ "items": {
54
+ "enum": [
55
+ "episode",
56
+ "fact",
57
+ "open_item",
58
+ "action",
59
+ "object",
60
+ "trait"
61
+ ]
62
+ }
63
+ },
64
+ "outcome": {
65
+ "type": "string"
66
+ }
67
+ },
68
+ "additionalProperties": false
69
+ },
70
+ "max_tokens": {
71
+ "type": "integer",
72
+ "minimum": 50,
73
+ "maximum": 4e3
74
+ }
75
+ },
76
+ "required": [
77
+ "query"
78
+ ],
79
+ "additionalProperties": false
80
+ }
81
+ }
82
+ },
83
+ {
84
+ "type": "function",
85
+ "function": {
86
+ "name": "get_customer_timeline",
87
+ "description": "List this customer's conversations and agent actions in order, newest first, one line each. Use it to leaf through the history when you do not know what to search for. Pass next_cursor to continue. Prefer search_customer_history for a specific question.",
88
+ "parameters": {
89
+ "type": "object",
90
+ "properties": {
91
+ "cursor": {
92
+ "type": "string"
93
+ },
94
+ "limit": {
95
+ "type": "integer",
96
+ "minimum": 1,
97
+ "maximum": 100
98
+ },
99
+ "filters": {
100
+ "type": "object",
101
+ "properties": {
102
+ "since": {
103
+ "type": "string",
104
+ "format": "date-time"
105
+ },
106
+ "until": {
107
+ "type": "string",
108
+ "format": "date-time"
109
+ },
110
+ "when": {
111
+ "type": "string",
112
+ "description": "The period in the customer's own words, as they said it: 'last week', 'semana passada', 'en marzo'."
113
+ },
114
+ "channels": {
115
+ "type": "array",
116
+ "items": {
117
+ "type": "string"
118
+ }
119
+ },
120
+ "categories": {
121
+ "type": "array",
122
+ "items": {
123
+ "type": "string"
124
+ }
125
+ },
126
+ "item_kinds": {
127
+ "type": "array",
128
+ "items": {
129
+ "enum": [
130
+ "episode",
131
+ "fact",
132
+ "open_item",
133
+ "action",
134
+ "object",
135
+ "trait"
136
+ ]
137
+ }
138
+ },
139
+ "outcome": {
140
+ "type": "string"
141
+ }
142
+ },
143
+ "additionalProperties": false
144
+ }
145
+ },
146
+ "additionalProperties": false
147
+ }
148
+ }
149
+ },
150
+ {
151
+ "type": "function",
152
+ "function": {
153
+ "name": "open_history_item",
154
+ "description": "Open one conversation or business object returned by search_customer_history or get_customer_timeline: what was asked, what was promised and by whom, the outcome and what memory came from it. Use it only after a search or timeline pointed to the item.",
155
+ "parameters": {
156
+ "type": "object",
157
+ "properties": {
158
+ "id": {
159
+ "type": "string",
160
+ "description": "The item id, e.g. `episode:...`."
161
+ }
162
+ },
163
+ "required": [
164
+ "id"
165
+ ],
166
+ "additionalProperties": false
167
+ }
168
+ }
169
+ }
170
+ ];
171
+ var AGENT_MEMORY_TOOL_DEFINITIONS = [
172
+ {
173
+ "type": "function",
174
+ "function": {
175
+ "name": "search_agent_memory",
176
+ "description": "Search your own working notes: procedures, how the company's tools and processes behave, and known pitfalls. Use it before a task or a tool call you are unsure how to do. It holds nothing about customers; for the customer's history use search_customer_history.",
177
+ "parameters": {
178
+ "type": "object",
179
+ "properties": {
180
+ "query": {
181
+ "type": "string",
182
+ "description": "What you need to know how to do."
183
+ },
184
+ "tags": {
185
+ "type": "array",
186
+ "maxItems": 8,
187
+ "items": {
188
+ "type": "string",
189
+ "pattern": "^[a-z0-9][a-z0-9_.:-]{0,63}$"
190
+ },
191
+ "description": "Object types, operations or systems, e.g. `invoice`, `credit`, `erp`."
192
+ }
193
+ },
194
+ "required": [
195
+ "query"
196
+ ],
197
+ "additionalProperties": false
198
+ }
199
+ }
200
+ },
201
+ {
202
+ "type": "function",
203
+ "function": {
204
+ "name": "remember",
205
+ "description": "Save a working note for yourself and future runs: a procedure that worked, how a tool or process behaves, or a pitfall to avoid. Never write anything about a customer here: no names, phones, e-mails, documents, ids or words from the conversation. A note with personal data is refused. Write it so it helps with any customer.",
206
+ "parameters": {
207
+ "type": "object",
208
+ "properties": {
209
+ "kind": {
210
+ "enum": [
211
+ "procedure",
212
+ "tool_note",
213
+ "process_note",
214
+ "pitfall"
215
+ ]
216
+ },
217
+ "title": {
218
+ "type": "string",
219
+ "maxLength": 120
220
+ },
221
+ "body": {
222
+ "type": "string",
223
+ "maxLength": 2e3
224
+ },
225
+ "tags": {
226
+ "type": "array",
227
+ "maxItems": 8,
228
+ "items": {
229
+ "type": "string",
230
+ "pattern": "^[a-z0-9][a-z0-9_.:-]{0,63}$"
231
+ },
232
+ "description": "Object types, operations or systems, e.g. `invoice`, `credit`, `erp`."
233
+ }
234
+ },
235
+ "required": [
236
+ "kind",
237
+ "title",
238
+ "body"
239
+ ],
240
+ "additionalProperties": false
241
+ }
242
+ }
243
+ }
244
+ ];
245
+
246
+ // src/context.ts
247
+ function emptyResult(error) {
248
+ return { text: "", suffix: "", variables: {}, pack: null, source: "none", response: null, error, constraints: null, state: null, coordination: null };
249
+ }
250
+
251
+ // src/integrations/shared.ts
252
+ var ATTESTED = { A: "V2", B: "V1", C: "V1" };
253
+ function attestationProof(attestation) {
254
+ if (!attestation) return null;
255
+ const value = attestation.trim().toUpperCase();
256
+ if (value.includes("FAILED") || value.startsWith("NO-")) return null;
257
+ const letter = value.length === 1 ? value : /PASSED-([ABC])$/.exec(value)?.[1];
258
+ const level = letter ? ATTESTED[letter] : void 0;
259
+ return level ? { method: "network_attestation", level } : null;
260
+ }
261
+ function isConversation(session) {
262
+ return "customer" in session && typeof session.customer === "function";
263
+ }
264
+ function phoneHandle(value) {
265
+ const raw = value?.trim().replace(/^tel:/i, "").replace(/[\s().-]/g, "");
266
+ if (!raw) return null;
267
+ const e164 = raw.startsWith("+") ? raw : `+${raw}`;
268
+ return /^\+[1-9]\d{6,14}$/.test(e164) ? { type: "phone_e164", value: e164 } : null;
269
+ }
270
+ function errorName(error) {
271
+ return error instanceof Error ? error.name : typeof error;
272
+ }
273
+ var Bridge = class {
274
+ constructor(session, proof, memory = false) {
275
+ this.session = session;
276
+ this.proof = proof;
277
+ this.memory = memory;
278
+ }
279
+ session;
280
+ proof;
281
+ memory;
282
+ proving = null;
283
+ /** `begin()` started the first read of a call: the first `context()` waits for it with `ready()`. */
284
+ begun = false;
285
+ opened = false;
286
+ /**
287
+ * The context and, when enabled, the agent's notes, read side by side within the same budget.
288
+ * Never rejects.
289
+ */
290
+ async read(options = {}) {
291
+ const memoryParams = this.memory === false ? null : this.memory === true ? {} : withoutWrite(this.memory);
292
+ const [context, memory] = await Promise.all([
293
+ this.context(options),
294
+ memoryParams ? this.agentMemory(memoryParams, options) : Promise.resolve("")
295
+ ]);
296
+ return { context, memory, prefix: [memory, context.text].filter(Boolean).join("\n\n"), suffix: context.suffix };
297
+ }
298
+ get logger() {
299
+ return this.session.logger;
300
+ }
301
+ /**
302
+ * Starts the first read of a call now, in the background, after the proof when one was given (the
303
+ * pack depends on the level it proves): at call start, so the read runs while the call is set up.
304
+ * The first `context()` then waits for it within `timeouts.contextVoiceStart`. Never throws.
305
+ */
306
+ begin() {
307
+ const session = this.session;
308
+ if (!isConversation(session)) return;
309
+ const start = () => {
310
+ this.safe("start the first read", () => {
311
+ this.begun = session.begin();
312
+ });
313
+ };
314
+ if (this.proof === void 0 || this.proof === null) start();
315
+ else void this.verifyOnce().then(start);
316
+ }
317
+ /** Verifies once (when a proof was given), then reads the context. Never rejects. */
318
+ async context(options = {}) {
319
+ await this.verifyOnce();
320
+ try {
321
+ const session = this.session;
322
+ if (this.begun && !this.opened && isConversation(session)) {
323
+ this.opened = true;
324
+ await session.ready(options.timeout === void 0 ? {} : { timeout: options.timeout });
325
+ }
326
+ return await this.session.context(options);
327
+ } catch (error) {
328
+ this.logger.warn(`could not read context (${errorName(error)})`);
329
+ return emptyResult(null);
330
+ }
331
+ }
332
+ /** Records that `context` went into the prompt, unless it was empty for a reason other than the holdout. */
333
+ injected(context) {
334
+ if (!context.text && !context.suffix && context.response?.path !== "holdout") return;
335
+ this.safe("mark the injection", () => {
336
+ this.session.markInjected(context);
337
+ });
338
+ }
339
+ customer(text, options = {}) {
340
+ const session = this.session;
341
+ if (!text.trim() || !isConversation(session)) return;
342
+ this.safe("record the customer's turn", () => session.customer(text, options));
343
+ }
344
+ /** Sends the customer's turn so far, while they speak. In the background; never throws. */
345
+ prefetch(text) {
346
+ const session = this.session;
347
+ if (!text.trim() || !isConversation(session)) return;
348
+ this.safe("prefetch the turn", () => session.prefetch(text));
349
+ }
350
+ agent(text, options = {}) {
351
+ if (!text.trim()) return;
352
+ this.safe("record the agent's turn", () => this.session.agent(text, options));
353
+ }
354
+ /** Records a transfer. Tasks have no transfer; the call is ignored for them. */
355
+ async handoff(target, reason) {
356
+ const session = this.session;
357
+ if (!isConversation(session)) return;
358
+ try {
359
+ await session.handoff(reason ? { target, reason } : { target });
360
+ } catch (error) {
361
+ this.logger.warn(`could not record the handoff (${errorName(error)})`);
362
+ }
363
+ }
364
+ async end() {
365
+ try {
366
+ await this.session.end();
367
+ } catch (error) {
368
+ this.logger.warn(`could not end the session (${errorName(error)})`);
369
+ }
370
+ }
371
+ /** The navigation kit as plain specs (with the agent's memory tools when enabled), or none for a task about an object only. */
372
+ tools() {
373
+ let bound;
374
+ try {
375
+ const memory = this.memory;
376
+ bound = this.session.tools(memory === false ? {} : { agentMemory: true, writeAgentMemory: memory !== true && memory.write === true });
377
+ } catch (error) {
378
+ this.logger.warn(`could not build the tools (${errorName(error)})`);
379
+ return [];
380
+ }
381
+ return bound ? toolSpecs(bound) : [];
382
+ }
383
+ async agentMemory(params, options) {
384
+ try {
385
+ const result = await this.session.agentMemory(params, options.timeout === void 0 ? {} : { timeout: options.timeout });
386
+ return result.text;
387
+ } catch (error) {
388
+ this.logger.warn(`could not read the agent's memory (${errorName(error)})`);
389
+ return "";
390
+ }
391
+ }
392
+ async verifyOnce() {
393
+ if (this.proof === void 0 || this.proof === null) return;
394
+ this.proving ??= this.runVerify();
395
+ await this.proving;
396
+ }
397
+ async runVerify() {
398
+ try {
399
+ const source = this.proof;
400
+ const proof = typeof source === "function" ? await source() : source;
401
+ if (!proof) return;
402
+ await this.session.verify(proof);
403
+ } catch (error) {
404
+ this.logger.warn(`could not record the verification (${errorName(error)})`);
405
+ }
406
+ }
407
+ safe(what, run) {
408
+ try {
409
+ run();
410
+ } catch (error) {
411
+ this.logger.warn(`could not ${what} (${errorName(error)})`);
412
+ }
413
+ }
414
+ };
415
+ function withoutWrite(option) {
416
+ const { write: _, ...params } = option;
417
+ return params;
418
+ }
419
+ function toolSpecs(bound) {
420
+ return bound.definitions.map(({ function: definition }) => ({
421
+ name: definition.name,
422
+ description: definition.description,
423
+ parameters: definition.parameters,
424
+ execute: (args) => bound.call(definition.name, args)
425
+ }));
426
+ }
427
+ function isRecord(value) {
428
+ return typeof value === "object" && value !== null;
429
+ }
430
+
431
+ // src/integrations/webhook.ts
432
+ function memoryCallStore(max = 1e4) {
433
+ const calls = /* @__PURE__ */ new Map();
434
+ return {
435
+ get: (id) => calls.get(id),
436
+ set: (id, record) => {
437
+ calls.delete(id);
438
+ calls.set(id, record);
439
+ if (calls.size > max) {
440
+ const oldest = calls.keys().next().value;
441
+ if (oldest !== void 0) calls.delete(oldest);
442
+ }
443
+ }
444
+ };
445
+ }
446
+ function header(headers, name) {
447
+ if (typeof headers.get === "function") return headers.get(name) ?? void 0;
448
+ const wanted = name.toLowerCase();
449
+ for (const [key, value] of Object.entries(headers)) {
450
+ if (key.toLowerCase() !== wanted) continue;
451
+ return Array.isArray(value) ? value[0] : value;
452
+ }
453
+ return void 0;
454
+ }
455
+ var encoder = new TextEncoder();
456
+ function safeEqual(a, b) {
457
+ const left = encoder.encode(a);
458
+ const right = encoder.encode(b);
459
+ if (left.length !== right.length) return false;
460
+ let diff = 0;
461
+ for (let i = 0; i < left.length; i++) diff |= (left[i] ?? 0) ^ (right[i] ?? 0);
462
+ return diff === 0;
463
+ }
464
+
465
+ // src/integrations/vapi.ts
466
+ var OURS = /* @__PURE__ */ new Set([...Object.values(TOOL_NAMES), ...Object.values(AGENT_MEMORY_TOOL_NAMES)]);
467
+ var AGENT_ROLES = /* @__PURE__ */ new Set(["bot", "assistant"]);
468
+ function vapiTools(server, options = {}) {
469
+ const memory = options.agentMemory;
470
+ const definitions = [
471
+ ...TOOL_DEFINITIONS,
472
+ ...memory ? AGENT_MEMORY_TOOL_DEFINITIONS.slice(0, memory !== true && memory.write ? 2 : 1) : []
473
+ ];
474
+ return definitions.map(({ function: definition }) => ({
475
+ type: "function",
476
+ function: { name: definition.name, description: definition.description, parameters: definition.parameters },
477
+ server: server.secret ? { url: server.url, secret: server.secret } : { url: server.url }
478
+ }));
479
+ }
480
+ function vapi(options) {
481
+ const store = options.store ?? memoryCallStore();
482
+ const logger = options.niadra.logger;
483
+ const transferred = /* @__PURE__ */ new Set();
484
+ const authorized = (headers) => {
485
+ if (!options.secret) return false;
486
+ const given = header(headers, "x-vapi-secret") ?? header(headers, "authorization")?.replace(/^Bearer\s+/i, "");
487
+ return given !== void 0 && safeEqual(given, options.secret);
488
+ };
489
+ const subjectOf = (call) => {
490
+ try {
491
+ return (options.subject ? options.subject(call) : phoneHandle(call.customerNumber)) ?? null;
492
+ } catch {
493
+ return null;
494
+ }
495
+ };
496
+ const recall = async (call) => {
497
+ try {
498
+ const stored = await store.get(call.id);
499
+ if (stored) return stored;
500
+ } catch (error) {
501
+ logger.warn(`could not read the call store (${errorName(error)})`);
502
+ }
503
+ const subject = subjectOf(call);
504
+ return subject ? { subject, verification: "V0" } : null;
505
+ };
506
+ const open = (call, record) => options.niadra.conversation({ subject: record.subject, channel: "voice", conversation_id: call.id, verification: record.verification });
507
+ async function assistantRequest(call) {
508
+ const context = { context: "", agentMemory: "", turn: "" };
509
+ const subject = subjectOf(call);
510
+ if (subject) {
511
+ const conversation = options.niadra.conversation({ subject, channel: "voice", conversation_id: call.id });
512
+ const bridge = new Bridge(conversation, options.verify ? () => options.verify?.(call) : void 0, options.agentMemory);
513
+ bridge.begin();
514
+ const read = await bridge.read(options.contextTimeout ? { timeout: options.contextTimeout } : {});
515
+ bridge.injected(read.context);
516
+ context.context = read.context.text;
517
+ context.agentMemory = read.memory;
518
+ context.turn = read.suffix;
519
+ try {
520
+ await store.set(call.id, { subject, verification: conversation.verification, stamp: conversation.contextStamp });
521
+ } catch (error) {
522
+ logger.warn(`could not write the call store (${errorName(error)})`);
523
+ }
524
+ }
525
+ let chosen;
526
+ try {
527
+ chosen = typeof options.assistant === "function" ? await options.assistant(call, context) : options.assistant;
528
+ } catch (error) {
529
+ logger.warn(`could not build the assistant (${errorName(error)})`);
530
+ return { status: 200, body: { error: "The assistant is not available right now." } };
531
+ }
532
+ return { status: 200, body: assistantResponse(chosen, context, Boolean(options.agentMemory)) };
533
+ }
534
+ async function toolCalls(call) {
535
+ const list = Array.isArray(call.message.toolCallList) ? call.message.toolCallList : [];
536
+ const record = await recall(call);
537
+ const specs = record ? new Bridge(open(call, record), void 0, options.agentMemory).tools() : [];
538
+ const results = [];
539
+ for (const item of list) {
540
+ if (!isRecord(item) || !isRecord(item.function)) continue;
541
+ const id = typeof item.id === "string" ? item.id : "";
542
+ const name = typeof item.function.name === "string" ? item.function.name : "";
543
+ const args = item.function.arguments;
544
+ let result;
545
+ if (OURS.has(name)) {
546
+ const spec = specs.find((candidate) => candidate.name === name);
547
+ result = spec ? await spec.execute(args ?? {}) : JSON.stringify({ error: "unavailable", detail: "customer history is unavailable right now" });
548
+ } else if (options.otherTool) {
549
+ try {
550
+ result = await options.otherTool(name, args, call);
551
+ } catch (error) {
552
+ logger.warn(`a tool outside Niadra failed (${errorName(error)})`);
553
+ results.push({ name, toolCallId: id, error: "tool failed" });
554
+ continue;
555
+ }
556
+ } else {
557
+ results.push({ name, toolCallId: id, error: `unknown tool: ${name}` });
558
+ continue;
559
+ }
560
+ results.push({ name, toolCallId: id, result });
561
+ }
562
+ return { status: 200, body: { results } };
563
+ }
564
+ async function transfer(call, answer) {
565
+ if (!transferred.has(call.id)) {
566
+ transferred.add(call.id);
567
+ if (transferred.size > 1e4) transferred.clear();
568
+ const record = await recall(call);
569
+ if (record) await new Bridge(open(call, record)).handoff("human", "transfer");
570
+ }
571
+ if (!answer) return { status: 200, body: {} };
572
+ try {
573
+ return { status: 200, body: options.transfer ? await options.transfer(call) : {} };
574
+ } catch (error) {
575
+ logger.warn(`could not choose the transfer destination (${errorName(error)})`);
576
+ return { status: 200, body: { error: "The transfer is not available right now." } };
577
+ }
578
+ }
579
+ async function endOfCall(call) {
580
+ const record = await recall(call);
581
+ if (!record) return { status: 200, body: { recorded: 0 } };
582
+ const bridge = new Bridge(open(call, record));
583
+ const artifact = isRecord(call.message.artifact) ? call.message.artifact : {};
584
+ const messages = Array.isArray(artifact.messages) ? artifact.messages : [];
585
+ let recorded = 0;
586
+ for (const [index, message] of messages.entries()) {
587
+ if (!isRecord(message) || typeof message.message !== "string" || !message.message.trim()) continue;
588
+ const role = typeof message.role === "string" ? message.role : "";
589
+ const at = typeof message.time === "number" ? new Date(message.time) : void 0;
590
+ const base = { idempotency_key: `vapi:${call.id}:${index}`, ...at ? { occurred_at: at } : {} };
591
+ if (role === "user") {
592
+ bridge.customer(message.message, base);
593
+ recorded++;
594
+ } else if (AGENT_ROLES.has(role)) {
595
+ bridge.agent(message.message, record.stamp ? { ...base, context_stamp: record.stamp } : base);
596
+ recorded++;
597
+ }
598
+ }
599
+ await bridge.end();
600
+ await options.niadra.flush();
601
+ return { status: 200, body: { recorded } };
602
+ }
603
+ return async (body, headers) => {
604
+ if (!authorized(headers)) return { status: 401, body: { error: "unauthorized" } };
605
+ const call = callOf(body);
606
+ if (!call) return { status: 400, body: { error: "invalid_body" } };
607
+ switch (call.message.type) {
608
+ case "assistant-request":
609
+ return assistantRequest(call);
610
+ case "tool-calls":
611
+ return toolCalls(call);
612
+ case "transfer-destination-request":
613
+ return transfer(call, true);
614
+ case "transfer-update":
615
+ return transfer(call, false);
616
+ case "end-of-call-report":
617
+ return endOfCall(call);
618
+ default:
619
+ return { status: 200, body: {} };
620
+ }
621
+ };
622
+ }
623
+ function callOf(body) {
624
+ const message = isRecord(body) && isRecord(body.message) ? body.message : null;
625
+ if (!message || typeof message.type !== "string") return null;
626
+ const call = isRecord(message.call) ? message.call : {};
627
+ const id = typeof call.id === "string" ? call.id : void 0;
628
+ if (!id) return null;
629
+ const customer = isRecord(call.customer) ? call.customer : isRecord(message.customer) ? message.customer : {};
630
+ return { id, customerNumber: typeof customer.number === "string" ? customer.number : void 0, message };
631
+ }
632
+ function assistantResponse(chosen, context, memory) {
633
+ const variableValues = { niadra_context: context.context, niadra_turn: context.turn };
634
+ if (memory) variableValues.niadra_agent_memory = context.agentMemory;
635
+ if (typeof chosen === "string") return { assistantId: chosen, assistantOverrides: { variableValues } };
636
+ if (!chosen) return { assistantOverrides: { variableValues } };
637
+ if (!("model" in chosen) && ("assistantId" in chosen || "squadId" in chosen || "assistant" in chosen)) {
638
+ const overrides = isRecord(chosen.assistantOverrides) ? chosen.assistantOverrides : {};
639
+ const values = isRecord(overrides.variableValues) ? overrides.variableValues : {};
640
+ return { ...chosen, assistantOverrides: { ...overrides, variableValues: { ...values, ...variableValues } } };
641
+ }
642
+ const model = isRecord(chosen.model) ? chosen.model : null;
643
+ const messages = model && Array.isArray(model.messages) ? [...model.messages] : [];
644
+ const prefix = [context.agentMemory, context.context].filter(Boolean).join("\n\n");
645
+ if (model && prefix) {
646
+ let position = 0;
647
+ while (position < messages.length && isRecord(messages[position]) && messages[position].role === "system") position++;
648
+ messages.splice(position, 0, { role: "system", content: prefix });
649
+ }
650
+ const assistant = model ? { ...chosen, model: { ...model, messages } } : chosen;
651
+ return { assistant, assistantOverrides: { variableValues } };
652
+ }
653
+
654
+ export { attestationProof, memoryCallStore, vapi, vapiTools };
655
+ //# sourceMappingURL=vapi.js.map
656
+ //# sourceMappingURL=vapi.js.map