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

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.
@@ -0,0 +1,37 @@
1
+ import type { Transcript, VoiceSessionRecord, VoiceTurnRecord } from "./types";
2
+ import type { VoiceAssistantMemoryNamespaceInput } from "./assistantMemory";
3
+ export type VoiceCallerIdentity = {
4
+ email?: string;
5
+ externalId?: string;
6
+ phone?: string;
7
+ };
8
+ export type VoiceCallerMemorySnapshot = {
9
+ facts: Record<string, string>;
10
+ identity: VoiceCallerIdentity;
11
+ lastSessionAt: number;
12
+ openActions: string[];
13
+ summary: string;
14
+ };
15
+ export declare const VOICE_CALLER_MEMORY_KEY = "caller-memory-snapshot";
16
+ export declare const buildVoiceCallerMemoryNamespace: (identity: VoiceCallerIdentity | undefined, prefix?: string) => string;
17
+ export type CreateVoiceCallerMemoryNamespaceOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord> = {
18
+ identifyCaller: (input: VoiceAssistantMemoryNamespaceInput<TContext, TSession>) => Promise<VoiceCallerIdentity | undefined> | VoiceCallerIdentity | undefined;
19
+ prefix?: string;
20
+ };
21
+ export declare const createVoiceCallerMemoryNamespace: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord>(options: CreateVoiceCallerMemoryNamespaceOptions<TContext, TSession>) => (input: VoiceAssistantMemoryNamespaceInput<TContext, TSession>) => Promise<string>;
22
+ export type VoiceCallerMemoryCompletion = (input: {
23
+ prompt: string;
24
+ systemPrompt?: string;
25
+ }) => Promise<string>;
26
+ export type SummarizeVoiceCallerTranscriptOptions = {
27
+ completion: VoiceCallerMemoryCompletion;
28
+ previousSnapshot?: VoiceCallerMemorySnapshot;
29
+ systemPrompt?: string;
30
+ };
31
+ export type VoiceCallerMemorySummarizerInput = {
32
+ identity: VoiceCallerIdentity;
33
+ options: SummarizeVoiceCallerTranscriptOptions;
34
+ transcripts?: Transcript[];
35
+ turns: VoiceTurnRecord[];
36
+ };
37
+ export declare const summarizeVoiceCallerTranscript: (input: VoiceCallerMemorySummarizerInput) => Promise<VoiceCallerMemorySnapshot>;
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 { VOICE_CALLER_MEMORY_KEY, buildVoiceCallerMemoryNamespace, createVoiceCallerMemoryNamespace, summarizeVoiceCallerTranscript, } from "./callerMemory";
85
+ export type { CreateVoiceCallerMemoryNamespaceOptions, SummarizeVoiceCallerTranscriptOptions, VoiceCallerIdentity, VoiceCallerMemoryCompletion, VoiceCallerMemorySnapshot, VoiceCallerMemorySummarizerInput, } from "./callerMemory";
84
86
  export { aggregateVoiceTurnLatencySpans, buildOTELSpanId, buildOTELTraceId, buildVoiceOTELPayload, createVoiceOTELHTTPExporter, } from "./otelExporter";
85
87
  export type { VoiceOTELAttribute, VoiceOTELExporter, VoiceOTELExporterOptions, VoiceOTELPayload, VoiceOTELResourceSpans, VoiceOTELSpan, VoiceTurnLatencySpanSet, VoiceTurnLatencySpanStage, } from "./otelExporter";
86
88
  export type { VoiceWebhookVerificationInput, VoiceWebhookVerificationReason, VoiceWebhookVerificationResult, } from "./webhookVerification";
package/dist/index.js CHANGED
@@ -35475,6 +35475,97 @@ var extractVoiceWebhookSignatureFromHeaders = (headers) => {
35475
35475
  timestamp: get(VOICE_WEBHOOK_TIMESTAMP_HEADER)
35476
35476
  };
35477
35477
  };
35478
+ // src/callerMemory.ts
35479
+ var VOICE_CALLER_MEMORY_KEY = "caller-memory-snapshot";
35480
+ var normalizeIdentifier = (value) => value.trim().replace(/[^a-zA-Z0-9+@._-]/g, "-").toLowerCase();
35481
+ var buildVoiceCallerMemoryNamespace = (identity, prefix = "caller") => {
35482
+ const identifier = identity?.externalId ?? identity?.phone ?? identity?.email ?? "anonymous";
35483
+ return `${prefix}:${normalizeIdentifier(identifier)}`;
35484
+ };
35485
+ var createVoiceCallerMemoryNamespace = (options) => async (input) => {
35486
+ const identity = await Promise.resolve(options.identifyCaller(input));
35487
+ return buildVoiceCallerMemoryNamespace(identity, options.prefix);
35488
+ };
35489
+ var DEFAULT_SYSTEM_PROMPT2 = "You write structured caller memory snapshots for a voice agent. " + "Given the latest call transcript (and an optional previous snapshot), " + "merge them into JSON with shape " + '{"summary":"\u2026","facts":{"key":"value"},"openActions":["\u2026"]}. ' + "Keep summary under 240 chars. Facts must be short value strings (name, plan, last_issue). " + "openActions are concrete follow-ups still pending. JSON only.";
35490
+ var buildTranscriptBlock = (turns) => turns.map((turn, index) => {
35491
+ const userText = turn.text.trim();
35492
+ const assistantText = typeof turn.assistantText === "string" ? turn.assistantText.trim() : "";
35493
+ const lines = [`Turn ${index + 1}:`];
35494
+ if (userText) {
35495
+ lines.push(` user: ${userText}`);
35496
+ }
35497
+ if (assistantText) {
35498
+ lines.push(` agent: ${assistantText}`);
35499
+ }
35500
+ return lines.join(`
35501
+ `);
35502
+ }).join(`
35503
+ `);
35504
+ var extractJson2 = (raw) => {
35505
+ const trimmed = raw.trim();
35506
+ if (!trimmed) {
35507
+ throw new Error("Caller-memory summarizer returned empty response");
35508
+ }
35509
+ const fenced = /```(?:json)?\s*([\s\S]*?)```/i.exec(trimmed);
35510
+ const candidate = fenced ? fenced[1].trim() : trimmed;
35511
+ try {
35512
+ return JSON.parse(candidate);
35513
+ } catch {
35514
+ const start = candidate.indexOf("{");
35515
+ const end = candidate.lastIndexOf("}");
35516
+ if (start >= 0 && end > start) {
35517
+ return JSON.parse(candidate.slice(start, end + 1));
35518
+ }
35519
+ throw new Error("Caller-memory response was not valid JSON");
35520
+ }
35521
+ };
35522
+ var coerceFacts = (input) => {
35523
+ if (!input || typeof input !== "object") {
35524
+ return {};
35525
+ }
35526
+ const out = {};
35527
+ for (const [key, value] of Object.entries(input)) {
35528
+ if (typeof value === "string") {
35529
+ out[key] = value;
35530
+ } else if (value !== null && value !== undefined) {
35531
+ out[key] = String(value);
35532
+ }
35533
+ }
35534
+ return out;
35535
+ };
35536
+ var coerceActions = (input) => {
35537
+ if (!Array.isArray(input)) {
35538
+ return [];
35539
+ }
35540
+ return input.map((value) => typeof value === "string" ? value.trim() : "").filter((value) => value.length > 0);
35541
+ };
35542
+ var summarizeVoiceCallerTranscript = async (input) => {
35543
+ const transcriptBlock = buildTranscriptBlock(input.turns);
35544
+ const previousBlock = input.options.previousSnapshot ? `Previous snapshot:
35545
+ ${JSON.stringify(input.options.previousSnapshot, null, 2)}
35546
+
35547
+ ` : "";
35548
+ const prompt = `${previousBlock}Latest call transcript:
35549
+ ${transcriptBlock}
35550
+
35551
+ Return JSON only.`;
35552
+ const raw = await input.options.completion({
35553
+ prompt,
35554
+ systemPrompt: input.options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT2
35555
+ });
35556
+ const parsed = extractJson2(raw);
35557
+ if (!parsed || typeof parsed !== "object") {
35558
+ throw new Error("Caller-memory summarizer returned non-object JSON");
35559
+ }
35560
+ const record = parsed;
35561
+ return {
35562
+ facts: coerceFacts(record.facts),
35563
+ identity: input.identity,
35564
+ lastSessionAt: Date.now(),
35565
+ openActions: coerceActions(record.openActions ?? record.open_actions),
35566
+ summary: typeof record.summary === "string" ? record.summary : ""
35567
+ };
35568
+ };
35478
35569
  // src/otelExporter.ts
35479
35570
  var SCOPE_NAME = "@absolutejs/voice";
35480
35571
  var SPAN_KIND_INTERNAL = 1;
@@ -46222,6 +46313,7 @@ export {
46222
46313
  summarizeVoiceHandoffHealth,
46223
46314
  summarizeVoiceHandoffDeliveries,
46224
46315
  summarizeVoiceCampaigns,
46316
+ summarizeVoiceCallerTranscript,
46225
46317
  summarizeVoiceBrowserMedia,
46226
46318
  summarizeVoiceBargeIn,
46227
46319
  summarizeVoiceAuditTrail,
@@ -46770,6 +46862,7 @@ export {
46770
46862
  createVoiceCampaignTelephonyOutcomeHandler,
46771
46863
  createVoiceCampaignRoutes,
46772
46864
  createVoiceCampaign,
46865
+ createVoiceCallerMemoryNamespace,
46773
46866
  createVoiceCallReviewRecorder,
46774
46867
  createVoiceCallReviewFromSession,
46775
46868
  createVoiceCallReviewFromLiveTelephonyReport,
@@ -46922,6 +47015,7 @@ export {
46922
47015
  buildVoiceDataControlReport,
46923
47016
  buildVoiceCompetitiveCoverageReport,
46924
47017
  buildVoiceCampaignObservabilityReport,
47018
+ buildVoiceCallerMemoryNamespace,
46925
47019
  buildVoiceCallDebuggerReport,
46926
47020
  buildVoiceBrowserCallProfileReport,
46927
47021
  buildVoiceAuditTrailReport,
@@ -46984,6 +47078,7 @@ export {
46984
47078
  VOICE_WEBHOOK_TIMESTAMP_HEADER,
46985
47079
  VOICE_WEBHOOK_SIGNATURE_HEADER,
46986
47080
  VOICE_LIVE_OPS_ACTIONS,
47081
+ VOICE_CALLER_MEMORY_KEY,
46987
47082
  TURN_PROFILE_DEFAULTS,
46988
47083
  DEFAULT_VOICE_REDACTION_PATTERNS,
46989
47084
  DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.486",
3
+ "version": "0.0.22-beta.487",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",