@absolutejs/voice 0.0.22-beta.368 → 0.0.22-beta.369

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/README.md CHANGED
@@ -1486,6 +1486,22 @@ app.use(
1486
1486
 
1487
1487
  The point is not to benchmark a fake demo once. The point is to let every real call add profile evidence so `/api/voice/real-call-profile-history`, provider recommendations, profile-switch readiness, and operations records can explain which provider/runtime path is winning for each call shape.
1488
1488
 
1489
+ Use `createVoiceProfileTraceTagger(...)` when the app already has a trace store and needs every appended trace to carry a benchmark profile label. It wraps any `VoiceTraceEventStore`, preserves the underlying store behavior, and adds `profileId`/`benchmarkProfileId` metadata and payload fields that real-call profile history can ingest later.
1490
+
1491
+ ```ts
1492
+ import { createVoiceProfileTraceTagger } from '@absolutejs/voice';
1493
+
1494
+ const trace = createVoiceProfileTraceTagger({
1495
+ defaultProfile: {
1496
+ id: 'meeting-recorder',
1497
+ label: 'Meeting recorder'
1498
+ },
1499
+ resolveProfile: (event) =>
1500
+ event.sessionId.startsWith('support-') ? 'support-agent' : undefined,
1501
+ store: runtime.traces
1502
+ });
1503
+ ```
1504
+
1489
1505
  Built-in profiles:
1490
1506
 
1491
1507
  - `meeting-recorder`: live latency, session health, provider fallback, routing contracts, reconnect proof, and barge-in interruption proof.
@@ -6081,6 +6081,46 @@ var createVoiceTraceSinkStore = (options) => {
6081
6081
  remove: (id) => options.store.remove(id)
6082
6082
  };
6083
6083
  };
6084
+ var normalizeVoiceProfileTraceTaggerProfile = (profile) => typeof profile === "string" ? { id: profile } : profile?.id ? profile : undefined;
6085
+ var createVoiceProfileTraceTagger = (options) => {
6086
+ const profiles = new Map((options.profiles ?? []).map((profile) => [profile.id, profile]));
6087
+ const defaultProfile = normalizeVoiceProfileTraceTaggerProfile(options.defaultProfile);
6088
+ const resolveProfile = async (event) => {
6089
+ const resolved = normalizeVoiceProfileTraceTaggerProfile(await options.resolveProfile?.(event));
6090
+ const profile = resolved ?? defaultProfile;
6091
+ return profile ? profiles.get(profile.id) ?? profile : undefined;
6092
+ };
6093
+ return {
6094
+ append: async (event) => {
6095
+ const profile = await resolveProfile(event);
6096
+ if (!profile) {
6097
+ return options.store.append(event);
6098
+ }
6099
+ const metadata = {
6100
+ ...event.metadata ?? {},
6101
+ benchmarkProfileId: profile.id,
6102
+ profileDescription: event.metadata?.profileDescription ?? profile.description,
6103
+ profileId: profile.id,
6104
+ profileLabel: event.metadata?.profileLabel ?? profile.label
6105
+ };
6106
+ const payload = event.payload && typeof event.payload === "object" ? {
6107
+ ...event.payload,
6108
+ benchmarkProfileId: event.payload.benchmarkProfileId ?? profile.id,
6109
+ profileDescription: event.payload.profileDescription ?? profile.description,
6110
+ profileId: event.payload.profileId ?? profile.id,
6111
+ profileLabel: event.payload.profileLabel ?? profile.label
6112
+ } : event.payload;
6113
+ return options.store.append({
6114
+ ...event,
6115
+ metadata,
6116
+ payload
6117
+ });
6118
+ },
6119
+ get: (id) => options.store.get(id),
6120
+ list: (filter) => options.store.list(filter),
6121
+ remove: (id) => options.store.remove(id)
6122
+ };
6123
+ };
6084
6124
  var createVoiceMemoryTraceSinkDeliveryStore = () => {
6085
6125
  const deliveries = new Map;
6086
6126
  return {
package/dist/index.d.ts CHANGED
@@ -86,7 +86,7 @@ export { createVoiceOpsStatusRoutes, renderVoiceOpsStatusHTML } from './opsStatu
86
86
  export { createVoiceQualityRoutes, evaluateVoiceQuality, renderVoiceQualityHTML } from './qualityRoutes';
87
87
  export { createVoiceResilienceRoutes, createVoiceRoutingDecisionSummary, listVoiceRoutingEvents, renderVoiceResilienceHTML, summarizeVoiceRoutingDecision, summarizeVoiceRoutingSessions } from './resilienceRoutes';
88
88
  export { createVoiceSTTProviderRouter, createVoiceTTSProviderRouter } from './providerAdapters';
89
- export { buildVoiceTraceReplay, createVoiceMemoryTraceSinkDeliveryStore, createVoiceTraceHTTPSink, createVoiceTraceS3Sink, createVoiceMemoryTraceEventStore, createVoiceTraceSinkDeliveryId, createVoiceTraceSinkDeliveryRecord, createVoiceTraceSinkStore, createVoiceTraceEvent, createVoiceTraceEventId, deliverVoiceTraceEventsToSinks, evaluateVoiceTrace, exportVoiceTrace, filterVoiceTraceEvents, pruneVoiceTraceEvents, redactVoiceTraceEvent, redactVoiceTraceEvents, redactVoiceTraceText, renderVoiceTraceHTML, renderVoiceTraceMarkdown, resolveVoiceTraceRedactionOptions, selectVoiceTraceEventsForPrune, summarizeVoiceTrace } from './trace';
89
+ export { buildVoiceTraceReplay, createVoiceMemoryTraceSinkDeliveryStore, createVoiceProfileTraceTagger, createVoiceTraceHTTPSink, createVoiceTraceS3Sink, createVoiceMemoryTraceEventStore, createVoiceTraceSinkDeliveryId, createVoiceTraceSinkDeliveryRecord, createVoiceTraceSinkStore, createVoiceTraceEvent, createVoiceTraceEventId, deliverVoiceTraceEventsToSinks, evaluateVoiceTrace, exportVoiceTrace, filterVoiceTraceEvents, pruneVoiceTraceEvents, redactVoiceTraceEvent, redactVoiceTraceEvents, redactVoiceTraceText, renderVoiceTraceHTML, renderVoiceTraceMarkdown, resolveVoiceTraceRedactionOptions, selectVoiceTraceEventsForPrune, summarizeVoiceTrace } from './trace';
90
90
  export { buildVoiceTraceDeliveryReport, createVoiceTraceDeliveryHTMLHandler, createVoiceTraceDeliveryJSONHandler, createVoiceTraceDeliveryRoutes, renderVoiceTraceDeliveryHTML, resolveVoiceTraceDeliveryFilter } from './traceDeliveryRoutes';
91
91
  export { createVoiceTraceTimelineRoutes, renderVoiceTraceTimelineHTML, renderVoiceTraceTimelineSessionHTML, summarizeVoiceTraceTimeline } from './traceTimeline';
92
92
  export { createVoiceSQLiteAuditEventStore, createVoiceSQLiteAuditSinkDeliveryStore, createVoiceSQLiteCampaignStore, createVoiceSQLiteExternalObjectMapStore, createVoiceSQLiteIntegrationEventStore, createVoiceSQLiteReviewStore, createVoiceSQLiteRuntimeStorage, createVoiceSQLiteSessionStore, createVoiceSQLiteTaskStore, createVoiceSQLiteTelephonyWebhookIdempotencyStore, createVoiceSQLiteTraceSinkDeliveryStore, createVoiceSQLiteTraceEventStore } from './sqliteStore';
@@ -174,7 +174,7 @@ export type { VoiceAuditExport } from './auditExport';
174
174
  export type { VoiceAuditHTTPSinkOptions, VoiceAuditS3SinkOptions, VoiceS3AuditSinkClient, VoiceS3AuditSinkFile, VoiceAuditSink, VoiceAuditSinkDeliveryQueueStatus, VoiceAuditSinkDeliveryQueueSummary, VoiceAuditSinkDeliveryRecord, VoiceAuditSinkDeliveryResult, VoiceAuditSinkDeliveryStatus, VoiceAuditSinkDeliveryStore, VoiceAuditSinkDeliveryWorkerLoop, VoiceAuditSinkDeliveryWorkerLoopOptions, VoiceAuditSinkDeliveryWorkerOptions, VoiceAuditSinkDeliveryWorkerResult, VoiceAuditSinkFanoutResult, VoiceAuditSinkStoreOptions } from './auditSinks';
175
175
  export type { VoiceAuditDeliveryDrainReport, VoiceAuditDeliveryDrainWorker, VoiceAuditDeliveryFilter, VoiceAuditDeliveryReport, VoiceAuditDeliveryRoutesOptions } from './auditDeliveryRoutes';
176
176
  export type { VoiceFileRuntimeStorage, VoiceFileStoreOptions } from './fileStore';
177
- export type { StoredVoiceTraceEvent, VoiceTraceEvaluation, VoiceTraceEvaluationOptions, VoiceTraceEvent, VoiceTraceEventFilter, VoiceTraceEventStore, VoiceTraceEventType, VoiceTraceIssue, VoiceTraceIssueSeverity, VoiceTraceHTTPSinkOptions, VoiceTraceS3SinkOptions, VoiceTracePruneFilter, VoiceTracePruneOptions, VoiceTracePruneResult, VoiceTraceRedactionConfig, VoiceTraceRedactionOptions, VoiceTraceRedactionReplacement, VoiceResolvedTraceRedactionOptions, VoiceTraceSink, VoiceTraceSinkDeliveryQueueStatus, VoiceTraceSinkDeliveryRecord, VoiceTraceSinkDeliveryResult, VoiceTraceSinkDeliveryStatus, VoiceTraceSinkDeliveryStore, VoiceTraceSinkFanoutResult, VoiceTraceSinkStoreOptions, VoiceTraceSummary, VoiceS3TraceSinkClient, VoiceS3TraceSinkFile } from './trace';
177
+ export type { VoiceProfileTraceTaggerOptions, VoiceProfileTraceTaggerProfile, StoredVoiceTraceEvent, VoiceTraceEvaluation, VoiceTraceEvaluationOptions, VoiceTraceEvent, VoiceTraceEventFilter, VoiceTraceEventStore, VoiceTraceEventType, VoiceTraceIssue, VoiceTraceIssueSeverity, VoiceTraceHTTPSinkOptions, VoiceTraceS3SinkOptions, VoiceTracePruneFilter, VoiceTracePruneOptions, VoiceTracePruneResult, VoiceTraceRedactionConfig, VoiceTraceRedactionOptions, VoiceTraceRedactionReplacement, VoiceResolvedTraceRedactionOptions, VoiceTraceSink, VoiceTraceSinkDeliveryQueueStatus, VoiceTraceSinkDeliveryRecord, VoiceTraceSinkDeliveryResult, VoiceTraceSinkDeliveryStatus, VoiceTraceSinkDeliveryStore, VoiceTraceSinkFanoutResult, VoiceTraceSinkStoreOptions, VoiceTraceSummary, VoiceS3TraceSinkClient, VoiceS3TraceSinkFile } from './trace';
178
178
  export type { VoiceTraceDeliveryDrainReport, VoiceTraceDeliveryDrainWorker, VoiceTraceDeliveryFilter, VoiceTraceDeliveryReport, VoiceTraceDeliveryRoutesOptions } from './traceDeliveryRoutes';
179
179
  export type { VoiceTraceTimelineEvent, VoiceTraceTimelineProviderSummary, VoiceTraceTimelineReport, VoiceTraceTimelineRoutesOptions, VoiceTraceTimelineSession } from './traceTimeline';
180
180
  export type { VoicePostgresClient, VoicePostgresRuntimeStorage, VoicePostgresStoreOptions } from './postgresStore';
package/dist/index.js CHANGED
@@ -10096,6 +10096,46 @@ var createVoiceTraceSinkStore = (options) => {
10096
10096
  remove: (id) => options.store.remove(id)
10097
10097
  };
10098
10098
  };
10099
+ var normalizeVoiceProfileTraceTaggerProfile = (profile) => typeof profile === "string" ? { id: profile } : profile?.id ? profile : undefined;
10100
+ var createVoiceProfileTraceTagger = (options) => {
10101
+ const profiles = new Map((options.profiles ?? []).map((profile) => [profile.id, profile]));
10102
+ const defaultProfile = normalizeVoiceProfileTraceTaggerProfile(options.defaultProfile);
10103
+ const resolveProfile = async (event) => {
10104
+ const resolved = normalizeVoiceProfileTraceTaggerProfile(await options.resolveProfile?.(event));
10105
+ const profile = resolved ?? defaultProfile;
10106
+ return profile ? profiles.get(profile.id) ?? profile : undefined;
10107
+ };
10108
+ return {
10109
+ append: async (event) => {
10110
+ const profile = await resolveProfile(event);
10111
+ if (!profile) {
10112
+ return options.store.append(event);
10113
+ }
10114
+ const metadata = {
10115
+ ...event.metadata ?? {},
10116
+ benchmarkProfileId: profile.id,
10117
+ profileDescription: event.metadata?.profileDescription ?? profile.description,
10118
+ profileId: profile.id,
10119
+ profileLabel: event.metadata?.profileLabel ?? profile.label
10120
+ };
10121
+ const payload = event.payload && typeof event.payload === "object" ? {
10122
+ ...event.payload,
10123
+ benchmarkProfileId: event.payload.benchmarkProfileId ?? profile.id,
10124
+ profileDescription: event.payload.profileDescription ?? profile.description,
10125
+ profileId: event.payload.profileId ?? profile.id,
10126
+ profileLabel: event.payload.profileLabel ?? profile.label
10127
+ } : event.payload;
10128
+ return options.store.append({
10129
+ ...event,
10130
+ metadata,
10131
+ payload
10132
+ });
10133
+ },
10134
+ get: (id) => options.store.get(id),
10135
+ list: (filter) => options.store.list(filter),
10136
+ remove: (id) => options.store.remove(id)
10137
+ };
10138
+ };
10099
10139
  var createVoiceMemoryTraceSinkDeliveryStore = () => {
10100
10140
  const deliveries = new Map;
10101
10141
  return {
@@ -38597,6 +38637,7 @@ export {
38597
38637
  createVoiceProviderCapabilityHTMLHandler,
38598
38638
  createVoiceProofTrendRoutes,
38599
38639
  createVoiceProofTrendRecommendationRoutes,
38640
+ createVoiceProfileTraceTagger,
38600
38641
  createVoiceProfileSwitchReadinessRoutes,
38601
38642
  createVoiceProfileSwitchPolicyProofRoutes,
38602
38643
  createVoiceProfileSwitchLiveDecisionRoutes,
@@ -1359,6 +1359,46 @@ var createVoiceTraceSinkStore = (options) => {
1359
1359
  remove: (id) => options.store.remove(id)
1360
1360
  };
1361
1361
  };
1362
+ var normalizeVoiceProfileTraceTaggerProfile = (profile) => typeof profile === "string" ? { id: profile } : profile?.id ? profile : undefined;
1363
+ var createVoiceProfileTraceTagger = (options) => {
1364
+ const profiles = new Map((options.profiles ?? []).map((profile) => [profile.id, profile]));
1365
+ const defaultProfile = normalizeVoiceProfileTraceTaggerProfile(options.defaultProfile);
1366
+ const resolveProfile = async (event) => {
1367
+ const resolved = normalizeVoiceProfileTraceTaggerProfile(await options.resolveProfile?.(event));
1368
+ const profile = resolved ?? defaultProfile;
1369
+ return profile ? profiles.get(profile.id) ?? profile : undefined;
1370
+ };
1371
+ return {
1372
+ append: async (event) => {
1373
+ const profile = await resolveProfile(event);
1374
+ if (!profile) {
1375
+ return options.store.append(event);
1376
+ }
1377
+ const metadata = {
1378
+ ...event.metadata ?? {},
1379
+ benchmarkProfileId: profile.id,
1380
+ profileDescription: event.metadata?.profileDescription ?? profile.description,
1381
+ profileId: profile.id,
1382
+ profileLabel: event.metadata?.profileLabel ?? profile.label
1383
+ };
1384
+ const payload = event.payload && typeof event.payload === "object" ? {
1385
+ ...event.payload,
1386
+ benchmarkProfileId: event.payload.benchmarkProfileId ?? profile.id,
1387
+ profileDescription: event.payload.profileDescription ?? profile.description,
1388
+ profileId: event.payload.profileId ?? profile.id,
1389
+ profileLabel: event.payload.profileLabel ?? profile.label
1390
+ } : event.payload;
1391
+ return options.store.append({
1392
+ ...event,
1393
+ metadata,
1394
+ payload
1395
+ });
1396
+ },
1397
+ get: (id) => options.store.get(id),
1398
+ list: (filter) => options.store.list(filter),
1399
+ remove: (id) => options.store.remove(id)
1400
+ };
1401
+ };
1362
1402
  var createVoiceMemoryTraceSinkDeliveryStore = () => {
1363
1403
  const deliveries = new Map;
1364
1404
  return {
@@ -9524,6 +9524,46 @@ var createVoiceTraceSinkStore = (options) => {
9524
9524
  remove: (id) => options.store.remove(id)
9525
9525
  };
9526
9526
  };
9527
+ var normalizeVoiceProfileTraceTaggerProfile = (profile) => typeof profile === "string" ? { id: profile } : profile?.id ? profile : undefined;
9528
+ var createVoiceProfileTraceTagger = (options) => {
9529
+ const profiles = new Map((options.profiles ?? []).map((profile) => [profile.id, profile]));
9530
+ const defaultProfile = normalizeVoiceProfileTraceTaggerProfile(options.defaultProfile);
9531
+ const resolveProfile = async (event) => {
9532
+ const resolved = normalizeVoiceProfileTraceTaggerProfile(await options.resolveProfile?.(event));
9533
+ const profile = resolved ?? defaultProfile;
9534
+ return profile ? profiles.get(profile.id) ?? profile : undefined;
9535
+ };
9536
+ return {
9537
+ append: async (event) => {
9538
+ const profile = await resolveProfile(event);
9539
+ if (!profile) {
9540
+ return options.store.append(event);
9541
+ }
9542
+ const metadata = {
9543
+ ...event.metadata ?? {},
9544
+ benchmarkProfileId: profile.id,
9545
+ profileDescription: event.metadata?.profileDescription ?? profile.description,
9546
+ profileId: profile.id,
9547
+ profileLabel: event.metadata?.profileLabel ?? profile.label
9548
+ };
9549
+ const payload = event.payload && typeof event.payload === "object" ? {
9550
+ ...event.payload,
9551
+ benchmarkProfileId: event.payload.benchmarkProfileId ?? profile.id,
9552
+ profileDescription: event.payload.profileDescription ?? profile.description,
9553
+ profileId: event.payload.profileId ?? profile.id,
9554
+ profileLabel: event.payload.profileLabel ?? profile.label
9555
+ } : event.payload;
9556
+ return options.store.append({
9557
+ ...event,
9558
+ metadata,
9559
+ payload
9560
+ });
9561
+ },
9562
+ get: (id) => options.store.get(id),
9563
+ list: (filter) => options.store.list(filter),
9564
+ remove: (id) => options.store.remove(id)
9565
+ };
9566
+ };
9527
9567
  var createVoiceMemoryTraceSinkDeliveryStore = () => {
9528
9568
  const deliveries = new Map;
9529
9569
  return {
package/dist/trace.d.ts CHANGED
@@ -127,6 +127,17 @@ export type VoiceTraceSinkStoreOptions<TEvent extends StoredVoiceTraceEvent = St
127
127
  sinks: VoiceTraceSink[];
128
128
  store: VoiceTraceEventStore<TEvent>;
129
129
  };
130
+ export type VoiceProfileTraceTaggerProfile = {
131
+ description?: string;
132
+ id: string;
133
+ label?: string;
134
+ };
135
+ export type VoiceProfileTraceTaggerOptions<TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent> = {
136
+ defaultProfile?: VoiceProfileTraceTaggerProfile | string;
137
+ profiles?: readonly VoiceProfileTraceTaggerProfile[];
138
+ resolveProfile?: (event: VoiceTraceEvent | TEvent) => Promise<VoiceProfileTraceTaggerProfile | string | undefined> | VoiceProfileTraceTaggerProfile | string | undefined;
139
+ store: VoiceTraceEventStore<TEvent>;
140
+ };
130
141
  export type VoiceTraceSummary = {
131
142
  assistantReplyCount: number;
132
143
  callDurationMs?: number;
@@ -211,6 +222,7 @@ export declare const deliverVoiceTraceEventsToSinks: (input: {
211
222
  sinks: VoiceTraceSink[];
212
223
  }) => Promise<VoiceTraceSinkFanoutResult>;
213
224
  export declare const createVoiceTraceSinkStore: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(options: VoiceTraceSinkStoreOptions<TEvent>) => VoiceTraceEventStore<TEvent>;
225
+ export declare const createVoiceProfileTraceTagger: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(options: VoiceProfileTraceTaggerOptions<TEvent>) => VoiceTraceEventStore<TEvent>;
214
226
  export declare const createVoiceMemoryTraceSinkDeliveryStore: <TDelivery extends VoiceTraceSinkDeliveryRecord = VoiceTraceSinkDeliveryRecord>() => VoiceTraceSinkDeliveryStore<TDelivery>;
215
227
  export declare const createVoiceMemoryTraceEventStore: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>() => VoiceTraceEventStore<TEvent>;
216
228
  export declare const exportVoiceTrace: (input: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.368",
3
+ "version": "0.0.22-beta.369",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",