@absolutejs/voice 0.0.22-beta.487 → 0.0.22-beta.488

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
@@ -81,6 +81,8 @@ export { describeVoiceAssistantMode, resolveVoiceAssistantMode, } from "./assist
81
81
  export type { VoiceAssistantMode, VoiceAssistantModality, VoiceAssistantModeDescriptor, VoiceSemanticVADConfig, } from "./assistantMode";
82
82
  export { createPunctuationSemanticTurnDetector, createRegexSemanticTurnDetector, } from "./semanticTurn";
83
83
  export { VOICE_WEBHOOK_SIGNATURE_HEADER, VOICE_WEBHOOK_TIMESTAMP_HEADER, extractVoiceWebhookSignatureFromHeaders, signVoiceWebhookBody, verifyVoiceWebhookSignature, } from "./webhookVerification";
84
+ export { createVoiceIVRSession, describeVoiceIVRPlan, evaluateVoiceIVRPlan, } from "./ivrPlan";
85
+ export type { VoiceIVRBranch, VoiceIVRDecision, VoiceIVRInput, VoiceIVRMatch, VoiceIVRPlan, VoiceIVRSession, } from "./ivrPlan";
84
86
  export { VOICE_CALLER_MEMORY_KEY, buildVoiceCallerMemoryNamespace, createVoiceCallerMemoryNamespace, summarizeVoiceCallerTranscript, } from "./callerMemory";
85
87
  export type { CreateVoiceCallerMemoryNamespaceOptions, SummarizeVoiceCallerTranscriptOptions, VoiceCallerIdentity, VoiceCallerMemoryCompletion, VoiceCallerMemorySnapshot, VoiceCallerMemorySummarizerInput, } from "./callerMemory";
86
88
  export { aggregateVoiceTurnLatencySpans, buildOTELSpanId, buildOTELTraceId, buildVoiceOTELPayload, createVoiceOTELHTTPExporter, } from "./otelExporter";
package/dist/index.js CHANGED
@@ -35475,6 +35475,90 @@ var extractVoiceWebhookSignatureFromHeaders = (headers) => {
35475
35475
  timestamp: get(VOICE_WEBHOOK_TIMESTAMP_HEADER)
35476
35476
  };
35477
35477
  };
35478
+ // src/ivrPlan.ts
35479
+ var speechMatchesPattern = (pattern, speech) => {
35480
+ const normalized = speech.toLowerCase().trim();
35481
+ if (pattern instanceof RegExp) {
35482
+ return pattern.test(normalized);
35483
+ }
35484
+ const target = pattern.toLowerCase().trim();
35485
+ if (!target) {
35486
+ return false;
35487
+ }
35488
+ return normalized.includes(target);
35489
+ };
35490
+ var digitsMatchPattern = (pattern, input) => {
35491
+ return input === pattern;
35492
+ };
35493
+ var branchMatches = (branch, input) => {
35494
+ const matcher = branch.match;
35495
+ if (matcher.digit && input.digits) {
35496
+ if (input.digits === matcher.digit) {
35497
+ return true;
35498
+ }
35499
+ }
35500
+ if (matcher.digits && input.digits) {
35501
+ if (digitsMatchPattern(matcher.digits, input.digits)) {
35502
+ return true;
35503
+ }
35504
+ }
35505
+ if (matcher.speech && input.speech) {
35506
+ if (speechMatchesPattern(matcher.speech, input.speech)) {
35507
+ return true;
35508
+ }
35509
+ }
35510
+ return false;
35511
+ };
35512
+ var evaluateVoiceIVRPlan = (plan, input) => {
35513
+ if (!input.digits && !input.speech) {
35514
+ return { reason: "timeout" };
35515
+ }
35516
+ for (const branch of plan.branches) {
35517
+ if (branchMatches(branch, input)) {
35518
+ return { branch, reason: "matched" };
35519
+ }
35520
+ }
35521
+ if (plan.fallbackBranchId) {
35522
+ const fallback = plan.branches.find((branch) => branch.id === plan.fallbackBranchId);
35523
+ if (fallback) {
35524
+ return { branch: fallback, reason: "fallback" };
35525
+ }
35526
+ }
35527
+ return { reason: "no-match" };
35528
+ };
35529
+ var createVoiceIVRSession = (plan) => {
35530
+ const maxAttempts = plan.maxAttempts ?? 3;
35531
+ let attempts = 0;
35532
+ return {
35533
+ attempt: () => attempts,
35534
+ decide: (input) => {
35535
+ attempts += 1;
35536
+ return evaluateVoiceIVRPlan(plan, input);
35537
+ },
35538
+ exhausted: () => attempts >= maxAttempts,
35539
+ reset: () => {
35540
+ attempts = 0;
35541
+ }
35542
+ };
35543
+ };
35544
+ var describeVoiceIVRPlan = (plan) => {
35545
+ const lines = [plan.greeting];
35546
+ for (const branch of plan.branches) {
35547
+ const triggers = [];
35548
+ if (branch.match.digit) {
35549
+ triggers.push(`press ${branch.match.digit}`);
35550
+ }
35551
+ if (branch.match.digits) {
35552
+ triggers.push(`press ${branch.match.digits}`);
35553
+ }
35554
+ if (branch.match.speech) {
35555
+ triggers.push(`say "${branch.match.speech instanceof RegExp ? branch.match.speech.source : branch.match.speech}"`);
35556
+ }
35557
+ lines.push(`- ${branch.label}: ${triggers.join(" or ")}`);
35558
+ }
35559
+ return lines.join(`
35560
+ `);
35561
+ };
35478
35562
  // src/callerMemory.ts
35479
35563
  var VOICE_CALLER_MEMORY_KEY = "caller-memory-snapshot";
35480
35564
  var normalizeIdentifier = (value) => value.trim().replace(/[^a-zA-Z0-9+@._-]/g, "-").toLowerCase();
@@ -46553,6 +46637,7 @@ export {
46553
46637
  evaluateVoiceMediaPipelineEvidence,
46554
46638
  evaluateVoiceLiveOpsEvidence,
46555
46639
  evaluateVoiceLiveOpsControlEvidence,
46640
+ evaluateVoiceIVRPlan,
46556
46641
  evaluateVoiceGuardrailPolicy,
46557
46642
  evaluateVoiceDataControlEvidence,
46558
46643
  evaluateVoiceCompetitiveCoverage,
@@ -46562,6 +46647,7 @@ export {
46562
46647
  evaluateVoiceAgentSquadContractEvidence,
46563
46648
  encodeTwilioMulawBase64,
46564
46649
  encodePcmAsWav,
46650
+ describeVoiceIVRPlan,
46565
46651
  describeVoiceAssistantMode,
46566
46652
  deliverVoiceTraceEventsToSinks,
46567
46653
  deliverVoiceObservabilityExport,
@@ -46807,6 +46893,7 @@ export {
46807
46893
  createVoiceIncidentBundleRoutes,
46808
46894
  createVoiceInMemoryRealCallProfileRecoveryJobStore,
46809
46895
  createVoiceInMemoryMonitorRegistry,
46896
+ createVoiceIVRSession,
46810
46897
  createVoiceHubSpotTaskUpdateSink,
46811
46898
  createVoiceHubSpotTaskSyncSinks,
46812
46899
  createVoiceHubSpotTaskSink,
@@ -0,0 +1,40 @@
1
+ export type VoiceIVRMatch = {
2
+ digit?: string;
3
+ digits?: string;
4
+ speech?: string | RegExp;
5
+ };
6
+ export type VoiceIVRBranch = {
7
+ assistantId?: string;
8
+ description?: string;
9
+ id: string;
10
+ label: string;
11
+ match: VoiceIVRMatch;
12
+ metadata?: Record<string, unknown>;
13
+ target?: string;
14
+ };
15
+ export type VoiceIVRPlan = {
16
+ branches: readonly VoiceIVRBranch[];
17
+ fallbackBranchId?: string;
18
+ greeting: string;
19
+ maxAttempts?: number;
20
+ noMatchPrompt?: string;
21
+ timeoutMs?: number;
22
+ timeoutPrompt?: string;
23
+ };
24
+ export type VoiceIVRInput = {
25
+ digits?: string;
26
+ speech?: string;
27
+ };
28
+ export type VoiceIVRDecision = {
29
+ branch?: VoiceIVRBranch;
30
+ reason: "matched" | "no-match" | "fallback" | "timeout";
31
+ };
32
+ export declare const evaluateVoiceIVRPlan: (plan: VoiceIVRPlan, input: VoiceIVRInput) => VoiceIVRDecision;
33
+ export type VoiceIVRSession = {
34
+ attempt: () => number;
35
+ decide: (input: VoiceIVRInput) => VoiceIVRDecision;
36
+ exhausted: () => boolean;
37
+ reset: () => void;
38
+ };
39
+ export declare const createVoiceIVRSession: (plan: VoiceIVRPlan) => VoiceIVRSession;
40
+ export declare const describeVoiceIVRPlan: (plan: VoiceIVRPlan) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.487",
3
+ "version": "0.0.22-beta.488",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",