@absolutejs/voice 0.0.22-beta.119 → 0.0.22-beta.120

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
@@ -75,7 +75,7 @@ export type { VoiceLiveLatencyOptions, VoiceLiveLatencyReport, VoiceLiveLatencyR
75
75
  export type { VoiceTurnQualityHTMLHandlerOptions, VoiceTurnQualityItem, VoiceTurnQualityOptions, VoiceTurnQualityReport, VoiceTurnQualityRoutesOptions, VoiceTurnQualityStatus } from './turnQuality';
76
76
  export type { VoiceOutcomeContractDefinition, VoiceOutcomeContractHTMLHandlerOptions, VoiceOutcomeContractIssue, VoiceOutcomeContractOptions, VoiceOutcomeContractReport, VoiceOutcomeContractRoutesOptions, VoiceOutcomeContractStatus, VoiceOutcomeContractSuiteReport } from './outcomeContract';
77
77
  export type { VoiceTelephonyOutcomeAction, VoiceTelephonyOutcomeDecision, VoiceTelephonyOutcomePolicy, VoiceTelephonyOutcomeProviderEvent, VoiceTelephonyOutcomeRouteResult, VoiceTelephonyOutcomeStatusDecision, VoiceTelephonyWebhookDecision, VoiceTelephonyWebhookHandlerOptions, VoiceTelephonyWebhookIdempotencyStore, VoiceTelephonyWebhookParseInput, VoiceTelephonyWebhookProvider, VoiceTelephonyWebhookRoutesOptions, VoiceTelephonyWebhookVerificationResult, StoredVoiceTelephonyWebhookDecision } from './telephonyOutcome';
78
- export type { VoicePhoneAgentCarrier, VoicePhoneAgentPlivoCarrier, VoicePhoneAgentRoutes, VoicePhoneAgentRoutesOptions, VoicePhoneAgentTelnyxCarrier, VoicePhoneAgentTwilioCarrier } from './phoneAgent';
78
+ export type { VoicePhoneAgentCarrier, VoicePhoneAgentCarrierSummary, VoicePhoneAgentLifecycleStage, VoicePhoneAgentPlivoCarrier, VoicePhoneAgentRoutes, VoicePhoneAgentRoutesOptions, VoicePhoneAgentSetupReport, VoicePhoneAgentTelnyxCarrier, VoicePhoneAgentTwilioCarrier } from './phoneAgent';
79
79
  export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
80
80
  export type { VoiceProductionReadinessAction, VoiceProductionReadinessCheck, VoiceProductionReadinessReport, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessStatus } from './productionReadiness';
81
81
  export type { VoiceQualityLink, VoiceQualityMetric, VoiceQualityReport, VoiceQualityRoutesOptions, VoiceQualityStatus, VoiceQualityThresholds } from './qualityRoutes';
package/dist/index.js CHANGED
@@ -11486,14 +11486,14 @@ var createProofFetch = (provider, requests) => {
11486
11486
  };
11487
11487
  };
11488
11488
  var createProofDialer = (input) => {
11489
- const fetch2 = createProofFetch(input.provider, input.requests);
11489
+ const fetch = createProofFetch(input.provider, input.requests);
11490
11490
  if (input.provider === "twilio") {
11491
11491
  return createVoiceTwilioCampaignDialer({
11492
11492
  accountSid: "AC_dry_run",
11493
11493
  answerUrl: joinUrlPath(input.baseUrl, "/api/twilio/voice"),
11494
11494
  apiBaseUrl: "https://twilio.dry-run.absolutejs.local",
11495
11495
  authToken: "dry-run-token",
11496
- fetch: fetch2,
11496
+ fetch,
11497
11497
  from: input.from,
11498
11498
  statusCallbackEvents: ["answered", "completed"],
11499
11499
  statusCallbackUrl: joinUrlPath(input.baseUrl, "/api/telephony-webhook")
@@ -11504,7 +11504,7 @@ var createProofDialer = (input) => {
11504
11504
  apiBaseUrl: "https://telnyx.dry-run.absolutejs.local",
11505
11505
  apiKey: "dry-run-token",
11506
11506
  connectionId: "dry-run-connection",
11507
- fetch: fetch2,
11507
+ fetch,
11508
11508
  from: input.from,
11509
11509
  webhookUrl: joinUrlPath(input.baseUrl, "/api/telnyx/webhook")
11510
11510
  });
@@ -11515,7 +11515,7 @@ var createProofDialer = (input) => {
11515
11515
  authId: "dry-run-auth-id",
11516
11516
  authToken: "dry-run-token",
11517
11517
  callbackUrl: joinUrlPath(input.baseUrl, "/api/plivo/webhook"),
11518
- fetch: fetch2,
11518
+ fetch,
11519
11519
  from: input.from
11520
11520
  });
11521
11521
  };
@@ -15283,12 +15283,25 @@ var resolveSmokePath = (carrier) => {
15283
15283
  }
15284
15284
  return carrier.options?.smoke?.path === false ? false : carrier.options?.smoke?.path ?? defaultSmokePath(carrier.provider);
15285
15285
  };
15286
- var fetchJson = async (origin, path) => {
15287
- const response = await fetch(new URL(path, origin).toString(), {
15286
+ var PHONE_AGENT_LIFECYCLE_STAGES = [
15287
+ "ringing",
15288
+ "answered",
15289
+ "media-started",
15290
+ "transcript",
15291
+ "assistant-response",
15292
+ "transfer",
15293
+ "voicemail",
15294
+ "no-answer",
15295
+ "completed",
15296
+ "failed"
15297
+ ];
15298
+ var escapeHtml28 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
15299
+ var loadRouteJson = async (input) => {
15300
+ const response = await input.app.handle(new Request(new URL(input.path, input.origin).toString(), {
15288
15301
  headers: {
15289
15302
  accept: "application/json"
15290
15303
  }
15291
- });
15304
+ }));
15292
15305
  if (!response.ok) {
15293
15306
  return;
15294
15307
  }
@@ -15302,12 +15315,20 @@ var loadCarrierMatrixInputs = async (input) => {
15302
15315
  if (!setupPath) {
15303
15316
  continue;
15304
15317
  }
15305
- const setup = await fetchJson(origin, setupPath);
15318
+ const setup = await loadRouteJson({
15319
+ app: input.app,
15320
+ origin,
15321
+ path: setupPath
15322
+ });
15306
15323
  if (!setup) {
15307
15324
  continue;
15308
15325
  }
15309
15326
  const smokePath = resolveSmokePath(carrier);
15310
- const smoke = smokePath ? await fetchJson(origin, smokePath) : undefined;
15327
+ const smoke = smokePath ? await loadRouteJson({
15328
+ app: input.app,
15329
+ origin,
15330
+ path: smokePath
15331
+ }) : undefined;
15311
15332
  entries.push({
15312
15333
  name: carrier.name,
15313
15334
  setup,
@@ -15316,6 +15337,11 @@ var loadCarrierMatrixInputs = async (input) => {
15316
15337
  }
15317
15338
  return entries;
15318
15339
  };
15340
+ var renderVoicePhoneAgentSetupHTML = (report) => {
15341
+ const carrierRows = report.carriers.map((carrier) => `<tr><td>${escapeHtml28(carrier.name ?? carrier.provider)}</td><td>${escapeHtml28(carrier.provider)}</td><td><code>${escapeHtml28(carrier.setupPath || "disabled")}</code></td><td><code>${escapeHtml28(carrier.smokePath || "disabled")}</code></td></tr>`).join("");
15342
+ const stageList = report.lifecycleStages.map((stage) => `<li><code>${escapeHtml28(stage)}</code></li>`).join("");
15343
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml28(report.title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.2),rgba(245,158,11,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}table{background:#151d27;border:1px solid #283544;border-collapse:collapse;border-radius:18px;overflow:hidden;width:100%}td,th{border-bottom:1px solid #283544;padding:12px;text-align:left}code{color:#fde68a}ul{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));padding-left:18px}</style></head><body><main><section class="hero"><p class="eyebrow">Phone agent setup</p><h1>${escapeHtml28(report.title)}</h1><p>One self-hosted entrypoint for carrier routes, setup reports, smoke checks, and normalized call lifecycle stages.</p><p class="badge ${report.ready ? "pass" : "fail"}">Ready: ${String(report.ready)}</p>${report.matrixPath ? `<p><a href="${escapeHtml28(report.matrixPath)}?format=html">Open carrier matrix</a></p>` : ""}</section><h2>Carriers</h2><table><thead><tr><th>Name</th><th>Provider</th><th>Setup</th><th>Smoke</th></tr></thead><tbody>${carrierRows}</tbody></table><h2>Lifecycle Schema</h2><ul>${stageList}</ul></main></body></html>`;
15344
+ };
15319
15345
  var createVoicePhoneAgent = (options) => {
15320
15346
  const carrierSummaries = options.carriers.map((carrier) => ({
15321
15347
  name: carrier.name,
@@ -15340,20 +15366,55 @@ var createVoicePhoneAgent = (options) => {
15340
15366
  }
15341
15367
  }
15342
15368
  const matrixPath = options.matrix === false ? undefined : options.matrix?.path ?? "/api/voice/phone/carriers";
15369
+ const setupPath = options.setup === false ? undefined : options.setup?.path ?? "/api/voice/phone/setup";
15370
+ const setupTitle = options.setup === false ? "AbsoluteJS Voice Phone Agent" : options.setup?.title ?? "AbsoluteJS Voice Phone Agent";
15343
15371
  if (options.matrix !== false) {
15344
15372
  app.use(createVoiceTelephonyCarrierMatrixRoutes({
15345
15373
  ...options.matrix ?? {},
15346
15374
  path: matrixPath,
15347
15375
  load: ({ request }) => loadCarrierMatrixInputs({
15376
+ app,
15348
15377
  carriers: options.carriers,
15349
15378
  request
15350
15379
  })
15351
15380
  }));
15352
15381
  }
15382
+ if (setupPath) {
15383
+ app.get(setupPath, async ({ query, request }) => {
15384
+ const matrixInputs = options.matrix === false ? [] : await loadCarrierMatrixInputs({
15385
+ app,
15386
+ carriers: options.carriers,
15387
+ request
15388
+ });
15389
+ const matrix = options.matrix === false ? undefined : createVoiceTelephonyCarrierMatrix({
15390
+ contract: options.matrix?.contract,
15391
+ providers: matrixInputs
15392
+ });
15393
+ const report = {
15394
+ carriers: carrierSummaries,
15395
+ generatedAt: Date.now(),
15396
+ lifecycleStages: PHONE_AGENT_LIFECYCLE_STAGES,
15397
+ matrix,
15398
+ matrixPath,
15399
+ ready: matrix ? matrix.pass : carrierSummaries.length > 0,
15400
+ setupPath,
15401
+ title: setupTitle
15402
+ };
15403
+ if (query.format === "html") {
15404
+ return new Response(renderVoicePhoneAgentSetupHTML(report), {
15405
+ headers: {
15406
+ "content-type": "text/html; charset=utf-8"
15407
+ }
15408
+ });
15409
+ }
15410
+ return report;
15411
+ });
15412
+ }
15353
15413
  return {
15354
15414
  carriers: carrierSummaries,
15355
15415
  matrixPath,
15356
- routes: app
15416
+ routes: app,
15417
+ setupPath
15357
15418
  };
15358
15419
  };
15359
15420
  // src/fileStore.ts
@@ -18785,7 +18846,7 @@ var createVoiceOpsRuntime = (config) => {
18785
18846
  pollIntervalMs: _pollIntervalMs,
18786
18847
  backoffMs,
18787
18848
  eventTypes,
18788
- fetch: fetch2,
18849
+ fetch,
18789
18850
  headers,
18790
18851
  retries,
18791
18852
  signingSecret,
@@ -18799,7 +18860,7 @@ var createVoiceOpsRuntime = (config) => {
18799
18860
  webhook: {
18800
18861
  backoffMs,
18801
18862
  eventTypes,
18802
- fetch: fetch2,
18863
+ fetch,
18803
18864
  headers,
18804
18865
  retries,
18805
18866
  signingSecret,
@@ -2,8 +2,9 @@ import { Elysia } from 'elysia';
2
2
  import { type PlivoVoiceRoutesOptions } from './telephony/plivo';
3
3
  import { type TelnyxVoiceRoutesOptions } from './telephony/telnyx';
4
4
  import { type TwilioVoiceRoutesOptions } from './telephony/twilio';
5
- import { type VoiceTelephonyCarrierMatrixRoutesOptions } from './telephony/matrix';
5
+ import { type VoiceTelephonyCarrierMatrix, type VoiceTelephonyCarrierMatrixRoutesOptions } from './telephony/matrix';
6
6
  import type { VoiceSessionRecord } from './types';
7
+ export type VoicePhoneAgentLifecycleStage = 'ringing' | 'answered' | 'media-started' | 'transcript' | 'assistant-response' | 'transfer' | 'voicemail' | 'no-answer' | 'completed' | 'failed';
7
8
  type VoicePhoneAgentCarrierBase = {
8
9
  name?: string;
9
10
  smokePath?: false | string;
@@ -26,16 +27,32 @@ export type VoicePhoneAgentRoutesOptions<TContext = unknown, TSession extends Vo
26
27
  carriers: readonly VoicePhoneAgentCarrier<TContext, TSession, TResult>[];
27
28
  matrix?: false | Omit<VoiceTelephonyCarrierMatrixRoutesOptions, 'load'>;
28
29
  name?: string;
30
+ setup?: false | {
31
+ path?: string;
32
+ title?: string;
33
+ };
34
+ };
35
+ export type VoicePhoneAgentCarrierSummary = {
36
+ name?: string;
37
+ provider: 'plivo' | 'telnyx' | 'twilio';
38
+ setupPath?: false | string;
39
+ smokePath?: false | string;
29
40
  };
30
41
  export type VoicePhoneAgentRoutes = {
31
- carriers: {
32
- name?: string;
33
- provider: 'plivo' | 'telnyx' | 'twilio';
34
- setupPath?: false | string;
35
- smokePath?: false | string;
36
- }[];
42
+ carriers: VoicePhoneAgentCarrierSummary[];
37
43
  matrixPath?: string;
38
44
  routes: Elysia;
45
+ setupPath?: string;
46
+ };
47
+ export type VoicePhoneAgentSetupReport = {
48
+ carriers: VoicePhoneAgentCarrierSummary[];
49
+ generatedAt: number;
50
+ lifecycleStages: VoicePhoneAgentLifecycleStage[];
51
+ matrix?: VoiceTelephonyCarrierMatrix;
52
+ matrixPath?: string;
53
+ ready: boolean;
54
+ setupPath?: string;
55
+ title: string;
39
56
  };
40
57
  export declare const createVoicePhoneAgent: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options: VoicePhoneAgentRoutesOptions<TContext, TSession, TResult>) => VoicePhoneAgentRoutes;
41
58
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.119",
3
+ "version": "0.0.22-beta.120",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",