@absolutejs/voice 0.0.22-beta.410 → 0.0.22-beta.412

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/audit.d.ts CHANGED
@@ -45,6 +45,7 @@ export type VoiceAuditEventStore<TEvent extends StoredVoiceAuditEvent = StoredVo
45
45
  get: (id: string) => Promise<TEvent | undefined> | TEvent | undefined;
46
46
  list: (filter?: VoiceAuditEventFilter) => Promise<TEvent[]> | TEvent[];
47
47
  };
48
+ export type VoiceScopedAuditEventStoreOptions = VoiceAuditEventFilter;
48
49
  export type VoiceAuditLogger = {
49
50
  handoff: (input: Omit<VoiceHandoffAuditEventInput, 'store'>) => Promise<StoredVoiceAuditEvent> | StoredVoiceAuditEvent;
50
51
  operatorAction: (input: Omit<VoiceOperatorAuditEventInput, 'store'>) => Promise<StoredVoiceAuditEvent> | StoredVoiceAuditEvent;
@@ -118,6 +119,7 @@ export type VoiceOperatorAuditEventInput = {
118
119
  };
119
120
  export declare const createVoiceAuditEvent: <TPayload extends Record<string, unknown> = Record<string, unknown>>(event: VoiceAuditEvent<TPayload>) => StoredVoiceAuditEvent<TPayload>;
120
121
  export declare const filterVoiceAuditEvents: <TEvent extends StoredVoiceAuditEvent = StoredVoiceAuditEvent>(events: TEvent[], filter?: VoiceAuditEventFilter) => TEvent[];
122
+ export declare const createVoiceScopedAuditEventStore: <TEvent extends StoredVoiceAuditEvent = StoredVoiceAuditEvent>(store: VoiceAuditEventStore<TEvent>, scope: VoiceScopedAuditEventStoreOptions) => VoiceAuditEventStore<TEvent>;
121
123
  export declare const createVoiceMemoryAuditEventStore: <TEvent extends StoredVoiceAuditEvent = StoredVoiceAuditEvent>() => VoiceAuditEventStore<TEvent>;
122
124
  export declare const recordVoiceAuditEvent: (store: VoiceAuditEventStore, event: VoiceAuditEvent) => StoredVoiceAuditEvent<Record<string, unknown>> | Promise<StoredVoiceAuditEvent<Record<string, unknown>>>;
123
125
  export declare const recordVoiceProviderAuditEvent: (input: VoiceProviderAuditEventInput) => StoredVoiceAuditEvent<Record<string, unknown>> | Promise<StoredVoiceAuditEvent<Record<string, unknown>>>;
@@ -5364,6 +5364,38 @@ var filterVoiceTraceEvents = (events, filter = {}) => {
5364
5364
  const sorted = events.filter((event) => matchesTraceFilter(event, filter)).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
5365
5365
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
5366
5366
  };
5367
+ var createVoiceScopedTraceEventStore = (store, scope) => {
5368
+ const upstreamFilter = (filter = {}) => {
5369
+ const next = { ...filter };
5370
+ delete next.limit;
5371
+ if (scope.scenarioId !== undefined) {
5372
+ delete next.scenarioId;
5373
+ }
5374
+ if (scope.sessionId !== undefined) {
5375
+ delete next.sessionId;
5376
+ }
5377
+ if (scope.traceId !== undefined) {
5378
+ delete next.traceId;
5379
+ }
5380
+ if (scope.turnId !== undefined) {
5381
+ delete next.turnId;
5382
+ }
5383
+ if (scope.type !== undefined) {
5384
+ delete next.type;
5385
+ }
5386
+ return next;
5387
+ };
5388
+ const scopedFilter = (filter = {}) => ({
5389
+ ...filter,
5390
+ ...scope
5391
+ });
5392
+ return {
5393
+ append: (event) => store.append(event),
5394
+ get: (id) => store.get(id),
5395
+ list: async (filter) => filterVoiceTraceEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter)),
5396
+ remove: (id) => store.remove(id)
5397
+ };
5398
+ };
5367
5399
  var isPruneTimeMatch = (event, options) => {
5368
5400
  if (typeof options.before === "number" && event.at >= options.before) {
5369
5401
  return false;
@@ -8695,6 +8727,43 @@ var filterVoiceAuditEvents = (events, filter = {}) => {
8695
8727
  }).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
8696
8728
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
8697
8729
  };
8730
+ var createVoiceScopedAuditEventStore = (store, scope) => {
8731
+ const upstreamFilter = (filter = {}) => {
8732
+ const next = { ...filter };
8733
+ delete next.limit;
8734
+ if (scope.actorId !== undefined) {
8735
+ delete next.actorId;
8736
+ }
8737
+ if (scope.outcome !== undefined) {
8738
+ delete next.outcome;
8739
+ }
8740
+ if (scope.resourceId !== undefined) {
8741
+ delete next.resourceId;
8742
+ }
8743
+ if (scope.resourceType !== undefined) {
8744
+ delete next.resourceType;
8745
+ }
8746
+ if (scope.sessionId !== undefined) {
8747
+ delete next.sessionId;
8748
+ }
8749
+ if (scope.traceId !== undefined) {
8750
+ delete next.traceId;
8751
+ }
8752
+ if (scope.type !== undefined) {
8753
+ delete next.type;
8754
+ }
8755
+ return next;
8756
+ };
8757
+ const scopedFilter = (filter = {}) => ({
8758
+ ...filter,
8759
+ ...scope
8760
+ });
8761
+ return {
8762
+ append: (event) => store.append(event),
8763
+ get: (id) => store.get(id),
8764
+ list: async (filter) => filterVoiceAuditEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter))
8765
+ };
8766
+ };
8698
8767
  var createVoiceMemoryAuditEventStore = () => {
8699
8768
  const events = new Map;
8700
8769
  return {
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { applyVoiceCampaignTelephonyOutcome, assertVoiceCampaignReadinessEvidenc
3
3
  export { assertVoiceCampaignDialerProofEvidence, createVoicePlivoCampaignDialer, createVoiceTelnyxCampaignDialer, createVoiceTwilioCampaignDialer, evaluateVoiceCampaignDialerProofEvidence, getVoiceCampaignDialerProofStatus, runVoiceCampaignDialerProof } from './campaignDialers';
4
4
  export { createVoiceAssistant, createVoiceExperiment, summarizeVoiceAssistantRuns } from './assistant';
5
5
  export { createVoiceAssistantHealthHTMLHandler, createVoiceAssistantHealthJSONHandler, createVoiceAssistantHealthRoutes, renderVoiceAssistantHealthHTML, summarizeVoiceAssistantHealth } from './assistantHealth';
6
- export { createVoiceAuditEvent, createVoiceAuditLogger, createVoiceMemoryAuditEventStore, filterVoiceAuditEvents, recordVoiceAuditEvent, recordVoiceHandoffAuditEvent, recordVoiceOperatorAuditEvent, recordVoiceProviderAuditEvent, recordVoiceRetentionAuditEvent, recordVoiceToolAuditEvent } from './audit';
6
+ export { createVoiceAuditEvent, createVoiceAuditLogger, createVoiceMemoryAuditEventStore, createVoiceScopedAuditEventStore, filterVoiceAuditEvents, recordVoiceAuditEvent, recordVoiceHandoffAuditEvent, recordVoiceOperatorAuditEvent, recordVoiceProviderAuditEvent, recordVoiceRetentionAuditEvent, recordVoiceToolAuditEvent } from './audit';
7
7
  export { buildVoiceAuditTrailReport, createVoiceAuditTrailRoutes, renderVoiceAuditTrailHTML, resolveVoiceAuditTrailFilter, summarizeVoiceAuditTrail } from './auditRoutes';
8
8
  export { buildVoiceAuditExport, exportVoiceAuditTrail, redactVoiceAuditEvent, redactVoiceAuditEvents, renderVoiceAuditHTML, renderVoiceAuditMarkdown } from './auditExport';
9
9
  export { createVoiceAuditHTTPSink, createVoiceAuditS3Sink, createVoiceAuditSinkDeliveryId, createVoiceAuditSinkDeliveryRecord, createVoiceAuditSinkDeliveryWorker, createVoiceAuditSinkDeliveryWorkerLoop, createVoiceAuditSinkStore, createVoiceMemoryAuditSinkDeliveryStore, deliverVoiceAuditEventsToSinks, summarizeVoiceAuditSinkDeliveries } from './auditSinks';
@@ -96,7 +96,7 @@ export { createVoiceOpsStatusRoutes, renderVoiceOpsStatusHTML } from './opsStatu
96
96
  export { createVoiceQualityRoutes, evaluateVoiceQuality, renderVoiceQualityHTML } from './qualityRoutes';
97
97
  export { createVoiceResilienceRoutes, createVoiceRoutingDecisionSummary, listVoiceRoutingEvents, renderVoiceResilienceHTML, summarizeVoiceRoutingDecision, summarizeVoiceRoutingSessions } from './resilienceRoutes';
98
98
  export { createVoiceSTTProviderRouter, createVoiceTTSProviderRouter } from './providerAdapters';
99
- 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';
99
+ export { buildVoiceTraceReplay, createVoiceMemoryTraceSinkDeliveryStore, createVoiceProfileTraceTagger, createVoiceTraceHTTPSink, createVoiceTraceS3Sink, createVoiceMemoryTraceEventStore, createVoiceScopedTraceEventStore, createVoiceTraceSinkDeliveryId, createVoiceTraceSinkDeliveryRecord, createVoiceTraceSinkStore, createVoiceTraceEvent, createVoiceTraceEventId, deliverVoiceTraceEventsToSinks, evaluateVoiceTrace, exportVoiceTrace, filterVoiceTraceEvents, pruneVoiceTraceEvents, redactVoiceTraceEvent, redactVoiceTraceEvents, redactVoiceTraceText, renderVoiceTraceHTML, renderVoiceTraceMarkdown, resolveVoiceTraceRedactionOptions, selectVoiceTraceEventsForPrune, summarizeVoiceTrace } from './trace';
100
100
  export { buildVoiceTraceDeliveryReport, createVoiceTraceDeliveryHTMLHandler, createVoiceTraceDeliveryJSONHandler, createVoiceTraceDeliveryRoutes, renderVoiceTraceDeliveryHTML, resolveVoiceTraceDeliveryFilter } from './traceDeliveryRoutes';
101
101
  export { createVoiceTraceTimelineRoutes, renderVoiceTraceTimelineHTML, renderVoiceTraceTimelineSessionHTML, summarizeVoiceTraceTimeline } from './traceTimeline';
102
102
  export { createVoiceSQLiteAuditEventStore, createVoiceSQLiteAuditSinkDeliveryStore, createVoiceSQLiteCampaignStore, createVoiceSQLiteExternalObjectMapStore, createVoiceSQLiteIntegrationEventStore, createVoiceSQLiteReviewStore, createVoiceSQLiteRuntimeStorage, createVoiceSQLiteSessionStore, createVoiceSQLiteTaskStore, createVoiceSQLiteTelephonyWebhookIdempotencyStore, createVoiceSQLiteTraceSinkDeliveryStore, createVoiceSQLiteTraceEventStore } from './sqliteStore';
@@ -206,6 +206,6 @@ export type { PlivoInboundMessage, PlivoMediaStreamBridge, PlivoMediaStreamBridg
206
206
  export type { VoiceTelephonyCarrierMatrix, VoiceTelephonyCarrierMatrixEntry, VoiceTelephonyCarrierMatrixInput, VoiceTelephonyCarrierMatrixOptions, VoiceTelephonyCarrierMatrixRoutesOptions, VoiceTelephonyCarrierMatrixStatus } from './telephony/matrix';
207
207
  export { shapeTelephonyAssistantText } from './telephony/response';
208
208
  export type { TelephonyResponseShapeMode, TelephonyResponseShapeOptions } from './telephony/response';
209
- export { buildVoiceProofPack, buildVoiceProofPackFromObservabilityExport, createVoiceProofPackArtifacts, createVoiceProofPackRoutes, renderVoiceProofPackMarkdown, writeVoiceProofPack } from './proofPack';
209
+ export { buildVoiceProofPack, buildVoiceProofPackFromObservabilityExport, createVoiceProofPackArtifacts, createVoiceProofPackOperationsRecordSection, createVoiceProofPackProductionReadinessSection, createVoiceProofPackProviderSloSection, createVoiceProofPackRoutes, createVoiceProofPackSupportBundleSection, renderVoiceProofPackMarkdown, writeVoiceProofPack } from './proofPack';
210
210
  export type { VoiceProofPack, VoiceProofPackEvidence, VoiceProofPackInput, VoiceProofPackRoutesOptions, VoiceProofPackSection, VoiceProofPackStatus, VoiceProofPackWriteResult } from './proofPack';
211
211
  export * from './types';
package/dist/index.js CHANGED
@@ -5266,6 +5266,43 @@ var filterVoiceAuditEvents = (events, filter = {}) => {
5266
5266
  }).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
5267
5267
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
5268
5268
  };
5269
+ var createVoiceScopedAuditEventStore = (store, scope) => {
5270
+ const upstreamFilter = (filter = {}) => {
5271
+ const next = { ...filter };
5272
+ delete next.limit;
5273
+ if (scope.actorId !== undefined) {
5274
+ delete next.actorId;
5275
+ }
5276
+ if (scope.outcome !== undefined) {
5277
+ delete next.outcome;
5278
+ }
5279
+ if (scope.resourceId !== undefined) {
5280
+ delete next.resourceId;
5281
+ }
5282
+ if (scope.resourceType !== undefined) {
5283
+ delete next.resourceType;
5284
+ }
5285
+ if (scope.sessionId !== undefined) {
5286
+ delete next.sessionId;
5287
+ }
5288
+ if (scope.traceId !== undefined) {
5289
+ delete next.traceId;
5290
+ }
5291
+ if (scope.type !== undefined) {
5292
+ delete next.type;
5293
+ }
5294
+ return next;
5295
+ };
5296
+ const scopedFilter = (filter = {}) => ({
5297
+ ...filter,
5298
+ ...scope
5299
+ });
5300
+ return {
5301
+ append: (event) => store.append(event),
5302
+ get: (id) => store.get(id),
5303
+ list: async (filter) => filterVoiceAuditEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter))
5304
+ };
5305
+ };
5269
5306
  var createVoiceMemoryAuditEventStore = () => {
5270
5307
  const events = new Map;
5271
5308
  return {
@@ -9860,6 +9897,38 @@ var filterVoiceTraceEvents = (events, filter = {}) => {
9860
9897
  const sorted = events.filter((event) => matchesTraceFilter(event, filter)).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
9861
9898
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
9862
9899
  };
9900
+ var createVoiceScopedTraceEventStore = (store, scope) => {
9901
+ const upstreamFilter = (filter = {}) => {
9902
+ const next = { ...filter };
9903
+ delete next.limit;
9904
+ if (scope.scenarioId !== undefined) {
9905
+ delete next.scenarioId;
9906
+ }
9907
+ if (scope.sessionId !== undefined) {
9908
+ delete next.sessionId;
9909
+ }
9910
+ if (scope.traceId !== undefined) {
9911
+ delete next.traceId;
9912
+ }
9913
+ if (scope.turnId !== undefined) {
9914
+ delete next.turnId;
9915
+ }
9916
+ if (scope.type !== undefined) {
9917
+ delete next.type;
9918
+ }
9919
+ return next;
9920
+ };
9921
+ const scopedFilter = (filter = {}) => ({
9922
+ ...filter,
9923
+ ...scope
9924
+ });
9925
+ return {
9926
+ append: (event) => store.append(event),
9927
+ get: (id) => store.get(id),
9928
+ list: async (filter) => filterVoiceTraceEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter)),
9929
+ remove: (id) => store.remove(id)
9930
+ };
9931
+ };
9863
9932
  var isPruneTimeMatch = (event, options) => {
9864
9933
  if (typeof options.before === "number" && event.at >= options.before) {
9865
9934
  return false;
@@ -39882,6 +39951,176 @@ var summarizeProofPackSections = (sections) => {
39882
39951
  }
39883
39952
  return { fail, pass, sections: sections.length, warn };
39884
39953
  };
39954
+ var toProofPackStatus = (status) => {
39955
+ if (status === "fail" || status === "failed") {
39956
+ return "fail";
39957
+ }
39958
+ if (status === "warn" || status === "warning" || status === "degraded" || status === "stale") {
39959
+ return "warn";
39960
+ }
39961
+ return "pass";
39962
+ };
39963
+ var numberEvidence = (label, value, options = {}) => {
39964
+ const safeValue = value ?? 0;
39965
+ const status = options.failWhenPositive ? safeValue > 0 ? "fail" : "pass" : options.passWhenPositive ? safeValue > 0 ? "pass" : "warn" : "pass";
39966
+ return {
39967
+ label,
39968
+ status,
39969
+ value: safeValue
39970
+ };
39971
+ };
39972
+ var createVoiceProofPackProviderSloSection = (report, options = {}) => ({
39973
+ evidence: [
39974
+ {
39975
+ href: options.href,
39976
+ label: "Provider SLO status",
39977
+ status: toProofPackStatus(report.status),
39978
+ value: report.status
39979
+ },
39980
+ numberEvidence("Provider routing events", report.events, {
39981
+ passWhenPositive: true
39982
+ }),
39983
+ numberEvidence("Latency samples", report.eventsWithLatency, {
39984
+ passWhenPositive: true
39985
+ }),
39986
+ numberEvidence("Provider SLO issues", report.issues.length, {
39987
+ failWhenPositive: true
39988
+ })
39989
+ ],
39990
+ status: toProofPackStatus(report.status),
39991
+ summary: "Provider latency, timeout, fallback, and unresolved error evidence.",
39992
+ title: options.title ?? "Provider SLO"
39993
+ });
39994
+ var createVoiceProofPackProductionReadinessSection = (report, options = {}) => {
39995
+ const checkFailures = report.checks.filter((check) => check.status === "fail").length;
39996
+ const checkWarnings = report.checks.filter((check) => check.status === "warn").length;
39997
+ return {
39998
+ evidence: [
39999
+ {
40000
+ label: "Production readiness status",
40001
+ status: toProofPackStatus(report.status),
40002
+ value: report.status
40003
+ },
40004
+ numberEvidence("Readiness checks", report.checks.length, {
40005
+ passWhenPositive: true
40006
+ }),
40007
+ numberEvidence("Failed readiness checks", checkFailures, {
40008
+ failWhenPositive: true
40009
+ }),
40010
+ {
40011
+ label: "Warning readiness checks",
40012
+ status: checkWarnings > 0 ? "warn" : "pass",
40013
+ value: checkWarnings
40014
+ },
40015
+ ...report.summary.providerSlo ? [
40016
+ {
40017
+ href: report.links.providerSlo,
40018
+ label: "Provider SLO samples",
40019
+ status: toProofPackStatus(report.summary.providerSlo.status),
40020
+ value: report.summary.providerSlo.eventsWithLatency
40021
+ }
40022
+ ] : [],
40023
+ ...report.summary.traceDeliveries ? [
40024
+ {
40025
+ href: report.links.traceDeliveries,
40026
+ label: "Trace delivery status",
40027
+ status: toProofPackStatus(report.summary.traceDeliveries.status),
40028
+ value: report.summary.traceDeliveries.pending
40029
+ }
40030
+ ] : []
40031
+ ],
40032
+ status: toProofPackStatus(report.status),
40033
+ summary: "Production readiness gates and linked proof surfaces.",
40034
+ title: options.title ?? "Production readiness"
40035
+ };
40036
+ };
40037
+ var createVoiceProofPackOperationsRecordSection = (records, options = {}) => {
40038
+ const failed = records.filter((record) => record.status === "failed").length;
40039
+ const warnings = records.filter((record) => record.status === "warning").length;
40040
+ const errors = records.reduce((total, record) => total + record.summary.errorCount, 0);
40041
+ const fallbacks = records.reduce((total, record) => total + record.providerDecisionSummary.fallbacks, 0);
40042
+ return {
40043
+ evidence: [
40044
+ numberEvidence("Operations records", records.length, {
40045
+ passWhenPositive: true
40046
+ }),
40047
+ numberEvidence("Failed operations records", failed, {
40048
+ failWhenPositive: true
40049
+ }),
40050
+ {
40051
+ label: "Warning operations records",
40052
+ status: warnings > 0 ? "warn" : "pass",
40053
+ value: warnings
40054
+ },
40055
+ numberEvidence("Trace errors", errors, { failWhenPositive: true }),
40056
+ {
40057
+ label: "Provider fallbacks",
40058
+ status: fallbacks > 0 ? "warn" : "pass",
40059
+ value: fallbacks
40060
+ },
40061
+ ...records.slice(0, 5).map((record) => ({
40062
+ href: options.href?.(record.sessionId),
40063
+ label: `Session ${record.sessionId}`,
40064
+ status: toProofPackStatus(record.status),
40065
+ value: record.status
40066
+ }))
40067
+ ],
40068
+ status: failed > 0 || errors > 0 ? "fail" : warnings > 0 || fallbacks > 0 ? "warn" : "pass",
40069
+ summary: "Per-call operations records, trace errors, and provider recovery.",
40070
+ title: options.title ?? "Operations records"
40071
+ };
40072
+ };
40073
+ var createVoiceProofPackSupportBundleSection = (input) => {
40074
+ const snapshots = input.sessionSnapshots ?? [];
40075
+ const debuggerReports = input.callDebuggerReports ?? [];
40076
+ const failedSnapshots = snapshots.filter((snapshot) => snapshot.status === "fail").length;
40077
+ const failedDebuggerReports = debuggerReports.filter((report) => report.status === "failed").length;
40078
+ const warnings = snapshots.filter((snapshot) => snapshot.status === "warn").length + debuggerReports.filter((report) => report.status === "warning").length;
40079
+ return {
40080
+ evidence: [
40081
+ numberEvidence("Session snapshots", snapshots.length, {
40082
+ passWhenPositive: true
40083
+ }),
40084
+ numberEvidence("Call debugger reports", debuggerReports.length, {
40085
+ passWhenPositive: true
40086
+ }),
40087
+ numberEvidence("Failed snapshots", failedSnapshots, {
40088
+ failWhenPositive: true
40089
+ }),
40090
+ numberEvidence("Failed debugger reports", failedDebuggerReports, {
40091
+ failWhenPositive: true
40092
+ }),
40093
+ {
40094
+ label: "Warning support artifacts",
40095
+ status: warnings > 0 ? "warn" : "pass",
40096
+ value: warnings
40097
+ }
40098
+ ],
40099
+ status: failedSnapshots > 0 || failedDebuggerReports > 0 ? "fail" : warnings > 0 ? "warn" : "pass",
40100
+ summary: "Support artifacts that make the latest call debuggable.",
40101
+ title: input.title ?? "Support bundle"
40102
+ };
40103
+ };
40104
+ var buildDerivedProofPackSections = (input) => [
40105
+ ...input.productionReadiness ? [createVoiceProofPackProductionReadinessSection(input.productionReadiness)] : [],
40106
+ ...input.providerSlo ? [
40107
+ createVoiceProofPackProviderSloSection(input.providerSlo, {
40108
+ href: input.productionReadiness?.links.providerSlo
40109
+ })
40110
+ ] : [],
40111
+ ...input.operationsRecords && input.operationsRecords.length > 0 ? [
40112
+ createVoiceProofPackOperationsRecordSection(input.operationsRecords, {
40113
+ href: (sessionId) => input.productionReadiness?.links.operationsRecords ? `${input.productionReadiness.links.operationsRecords}/${encodeURIComponent(sessionId)}` : undefined
40114
+ })
40115
+ ] : [],
40116
+ ...input.sessionSnapshots?.length || input.callDebuggerReports?.length ? [
40117
+ createVoiceProofPackSupportBundleSection({
40118
+ callDebuggerReports: input.callDebuggerReports,
40119
+ sessionSnapshots: input.sessionSnapshots
40120
+ })
40121
+ ] : [],
40122
+ ...input.observabilityExport ? buildVoiceProofPackFromObservabilityExport(input.observabilityExport).sections : []
40123
+ ];
39885
40124
  var resolveProofPack = async (source) => {
39886
40125
  const input = typeof source === "function" ? await source() : source;
39887
40126
  return buildVoiceProofPack(input);
@@ -39890,7 +40129,7 @@ var buildVoiceProofPack = (input) => {
39890
40129
  if ("status" in input && "ok" in input && "summary" in input && Array.isArray(input.sections)) {
39891
40130
  return input;
39892
40131
  }
39893
- const sections = input.sections ?? [];
40132
+ const sections = [...buildDerivedProofPackSections(input), ...input.sections ?? []];
39894
40133
  const summary = summarizeProofPackSections(sections);
39895
40134
  const status = summary.fail > 0 ? "fail" : summary.warn > 0 ? "warn" : "pass";
39896
40135
  return {
@@ -40407,6 +40646,8 @@ export {
40407
40646
  createVoiceSessionRecord,
40408
40647
  createVoiceSessionListRoutes,
40409
40648
  createVoiceSession,
40649
+ createVoiceScopedTraceEventStore,
40650
+ createVoiceScopedAuditEventStore,
40410
40651
  createVoiceSTTRoutingCorrectionHandler,
40411
40652
  createVoiceSTTProviderRouter,
40412
40653
  createVoiceSQLiteTraceSinkDeliveryStore,
@@ -40462,7 +40703,11 @@ export {
40462
40703
  createVoiceProviderCapabilityHTMLHandler,
40463
40704
  createVoiceProofTrendRoutes,
40464
40705
  createVoiceProofTrendRecommendationRoutes,
40706
+ createVoiceProofPackSupportBundleSection,
40465
40707
  createVoiceProofPackRoutes,
40708
+ createVoiceProofPackProviderSloSection,
40709
+ createVoiceProofPackProductionReadinessSection,
40710
+ createVoiceProofPackOperationsRecordSection,
40466
40711
  createVoiceProofPackArtifacts,
40467
40712
  createVoiceProofAssertion,
40468
40713
  createVoiceProfileTraceTagger,
@@ -1,5 +1,10 @@
1
1
  import { Elysia } from 'elysia';
2
2
  import type { VoiceObservabilityExportArtifact, VoiceObservabilityExportReport } from './observabilityExport';
3
+ import type { VoiceCallDebuggerReport } from './callDebugger';
4
+ import type { VoiceOperationsRecord } from './operationsRecord';
5
+ import type { VoiceProductionReadinessReport } from './productionReadiness';
6
+ import type { VoiceProviderSloReport } from './providerSlo';
7
+ import type { VoiceSessionSnapshot } from './sessionSnapshot';
3
8
  export type VoiceProofPackStatus = 'fail' | 'pass' | 'warn';
4
9
  export type VoiceProofPackEvidence = {
5
10
  detail?: string;
@@ -31,10 +36,16 @@ export type VoiceProofPack = {
31
36
  };
32
37
  export type VoiceProofPackInput = {
33
38
  artifacts?: VoiceObservabilityExportArtifact[];
39
+ callDebuggerReports?: VoiceCallDebuggerReport[];
34
40
  generatedAt?: number | string;
41
+ observabilityExport?: VoiceObservabilityExportReport;
42
+ operationsRecords?: VoiceOperationsRecord[];
35
43
  outputDir?: string;
44
+ productionReadiness?: VoiceProductionReadinessReport;
45
+ providerSlo?: VoiceProviderSloReport;
36
46
  runId?: string;
37
47
  sections?: VoiceProofPackSection[];
48
+ sessionSnapshots?: VoiceSessionSnapshot[];
38
49
  };
39
50
  export type VoiceProofPackWriteResult = {
40
51
  artifacts: VoiceObservabilityExportArtifact[];
@@ -49,6 +60,22 @@ export type VoiceProofPackRoutesOptions = {
49
60
  name?: string;
50
61
  source: VoiceProofPack | VoiceProofPackInput | (() => VoiceProofPack | VoiceProofPackInput | Promise<VoiceProofPack | VoiceProofPackInput>);
51
62
  };
63
+ export declare const createVoiceProofPackProviderSloSection: (report: VoiceProviderSloReport, options?: {
64
+ href?: string;
65
+ title?: string;
66
+ }) => VoiceProofPackSection;
67
+ export declare const createVoiceProofPackProductionReadinessSection: (report: VoiceProductionReadinessReport, options?: {
68
+ title?: string;
69
+ }) => VoiceProofPackSection;
70
+ export declare const createVoiceProofPackOperationsRecordSection: (records: readonly VoiceOperationsRecord[], options?: {
71
+ href?: (sessionId: string) => string | undefined;
72
+ title?: string;
73
+ }) => VoiceProofPackSection;
74
+ export declare const createVoiceProofPackSupportBundleSection: (input: {
75
+ callDebuggerReports?: readonly VoiceCallDebuggerReport[];
76
+ sessionSnapshots?: readonly VoiceSessionSnapshot[];
77
+ title?: string;
78
+ }) => VoiceProofPackSection;
52
79
  export declare const buildVoiceProofPack: (input: VoiceProofPackInput | VoiceProofPack) => VoiceProofPack;
53
80
  export declare const buildVoiceProofPackFromObservabilityExport: (report: VoiceObservabilityExportReport, input?: Omit<VoiceProofPackInput, "artifacts" | "sections">) => VoiceProofPack;
54
81
  export declare const renderVoiceProofPackMarkdown: (proofPack: VoiceProofPack) => string;
@@ -2556,6 +2556,38 @@ var filterVoiceTraceEvents = (events, filter = {}) => {
2556
2556
  const sorted = events.filter((event) => matchesTraceFilter(event, filter)).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
2557
2557
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
2558
2558
  };
2559
+ var createVoiceScopedTraceEventStore = (store, scope) => {
2560
+ const upstreamFilter = (filter = {}) => {
2561
+ const next = { ...filter };
2562
+ delete next.limit;
2563
+ if (scope.scenarioId !== undefined) {
2564
+ delete next.scenarioId;
2565
+ }
2566
+ if (scope.sessionId !== undefined) {
2567
+ delete next.sessionId;
2568
+ }
2569
+ if (scope.traceId !== undefined) {
2570
+ delete next.traceId;
2571
+ }
2572
+ if (scope.turnId !== undefined) {
2573
+ delete next.turnId;
2574
+ }
2575
+ if (scope.type !== undefined) {
2576
+ delete next.type;
2577
+ }
2578
+ return next;
2579
+ };
2580
+ const scopedFilter = (filter = {}) => ({
2581
+ ...filter,
2582
+ ...scope
2583
+ });
2584
+ return {
2585
+ append: (event) => store.append(event),
2586
+ get: (id) => store.get(id),
2587
+ list: async (filter) => filterVoiceTraceEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter)),
2588
+ remove: (id) => store.remove(id)
2589
+ };
2590
+ };
2559
2591
  var isPruneTimeMatch = (event, options) => {
2560
2592
  if (typeof options.before === "number" && event.at >= options.before) {
2561
2593
  return false;
@@ -904,6 +904,43 @@ var filterVoiceAuditEvents = (events, filter = {}) => {
904
904
  }).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
905
905
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
906
906
  };
907
+ var createVoiceScopedAuditEventStore = (store, scope) => {
908
+ const upstreamFilter = (filter = {}) => {
909
+ const next = { ...filter };
910
+ delete next.limit;
911
+ if (scope.actorId !== undefined) {
912
+ delete next.actorId;
913
+ }
914
+ if (scope.outcome !== undefined) {
915
+ delete next.outcome;
916
+ }
917
+ if (scope.resourceId !== undefined) {
918
+ delete next.resourceId;
919
+ }
920
+ if (scope.resourceType !== undefined) {
921
+ delete next.resourceType;
922
+ }
923
+ if (scope.sessionId !== undefined) {
924
+ delete next.sessionId;
925
+ }
926
+ if (scope.traceId !== undefined) {
927
+ delete next.traceId;
928
+ }
929
+ if (scope.type !== undefined) {
930
+ delete next.type;
931
+ }
932
+ return next;
933
+ };
934
+ const scopedFilter = (filter = {}) => ({
935
+ ...filter,
936
+ ...scope
937
+ });
938
+ return {
939
+ append: (event) => store.append(event),
940
+ get: (id) => store.get(id),
941
+ list: async (filter) => filterVoiceAuditEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter))
942
+ };
943
+ };
907
944
  var createVoiceMemoryAuditEventStore = () => {
908
945
  const events = new Map;
909
946
  return {
@@ -1080,6 +1117,38 @@ var filterVoiceTraceEvents = (events, filter = {}) => {
1080
1117
  const sorted = events.filter((event) => matchesTraceFilter(event, filter)).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
1081
1118
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
1082
1119
  };
1120
+ var createVoiceScopedTraceEventStore = (store, scope) => {
1121
+ const upstreamFilter = (filter = {}) => {
1122
+ const next = { ...filter };
1123
+ delete next.limit;
1124
+ if (scope.scenarioId !== undefined) {
1125
+ delete next.scenarioId;
1126
+ }
1127
+ if (scope.sessionId !== undefined) {
1128
+ delete next.sessionId;
1129
+ }
1130
+ if (scope.traceId !== undefined) {
1131
+ delete next.traceId;
1132
+ }
1133
+ if (scope.turnId !== undefined) {
1134
+ delete next.turnId;
1135
+ }
1136
+ if (scope.type !== undefined) {
1137
+ delete next.type;
1138
+ }
1139
+ return next;
1140
+ };
1141
+ const scopedFilter = (filter = {}) => ({
1142
+ ...filter,
1143
+ ...scope
1144
+ });
1145
+ return {
1146
+ append: (event) => store.append(event),
1147
+ get: (id) => store.get(id),
1148
+ list: async (filter) => filterVoiceTraceEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter)),
1149
+ remove: (id) => store.remove(id)
1150
+ };
1151
+ };
1083
1152
  var isPruneTimeMatch = (event, options) => {
1084
1153
  if (typeof options.before === "number" && event.at >= options.before) {
1085
1154
  return false;
@@ -9069,6 +9069,43 @@ var filterVoiceAuditEvents = (events, filter = {}) => {
9069
9069
  }).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
9070
9070
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
9071
9071
  };
9072
+ var createVoiceScopedAuditEventStore = (store, scope) => {
9073
+ const upstreamFilter = (filter = {}) => {
9074
+ const next = { ...filter };
9075
+ delete next.limit;
9076
+ if (scope.actorId !== undefined) {
9077
+ delete next.actorId;
9078
+ }
9079
+ if (scope.outcome !== undefined) {
9080
+ delete next.outcome;
9081
+ }
9082
+ if (scope.resourceId !== undefined) {
9083
+ delete next.resourceId;
9084
+ }
9085
+ if (scope.resourceType !== undefined) {
9086
+ delete next.resourceType;
9087
+ }
9088
+ if (scope.sessionId !== undefined) {
9089
+ delete next.sessionId;
9090
+ }
9091
+ if (scope.traceId !== undefined) {
9092
+ delete next.traceId;
9093
+ }
9094
+ if (scope.type !== undefined) {
9095
+ delete next.type;
9096
+ }
9097
+ return next;
9098
+ };
9099
+ const scopedFilter = (filter = {}) => ({
9100
+ ...filter,
9101
+ ...scope
9102
+ });
9103
+ return {
9104
+ append: (event) => store.append(event),
9105
+ get: (id) => store.get(id),
9106
+ list: async (filter) => filterVoiceAuditEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter))
9107
+ };
9108
+ };
9072
9109
  var createVoiceMemoryAuditEventStore = () => {
9073
9110
  const events = new Map;
9074
9111
  return {
@@ -9245,6 +9282,38 @@ var filterVoiceTraceEvents = (events, filter = {}) => {
9245
9282
  const sorted = events.filter((event) => matchesTraceFilter(event, filter)).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
9246
9283
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
9247
9284
  };
9285
+ var createVoiceScopedTraceEventStore = (store, scope) => {
9286
+ const upstreamFilter = (filter = {}) => {
9287
+ const next = { ...filter };
9288
+ delete next.limit;
9289
+ if (scope.scenarioId !== undefined) {
9290
+ delete next.scenarioId;
9291
+ }
9292
+ if (scope.sessionId !== undefined) {
9293
+ delete next.sessionId;
9294
+ }
9295
+ if (scope.traceId !== undefined) {
9296
+ delete next.traceId;
9297
+ }
9298
+ if (scope.turnId !== undefined) {
9299
+ delete next.turnId;
9300
+ }
9301
+ if (scope.type !== undefined) {
9302
+ delete next.type;
9303
+ }
9304
+ return next;
9305
+ };
9306
+ const scopedFilter = (filter = {}) => ({
9307
+ ...filter,
9308
+ ...scope
9309
+ });
9310
+ return {
9311
+ append: (event) => store.append(event),
9312
+ get: (id) => store.get(id),
9313
+ list: async (filter) => filterVoiceTraceEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter)),
9314
+ remove: (id) => store.remove(id)
9315
+ };
9316
+ };
9248
9317
  var isPruneTimeMatch = (event, options) => {
9249
9318
  if (typeof options.before === "number" && event.at >= options.before) {
9250
9319
  return false;
package/dist/trace.d.ts CHANGED
@@ -28,6 +28,7 @@ export type VoiceTraceEventStore<TEvent extends StoredVoiceTraceEvent = StoredVo
28
28
  list: (filter?: VoiceTraceEventFilter) => Promise<TEvent[]>;
29
29
  remove: (id: string) => Promise<void>;
30
30
  };
31
+ export type VoiceScopedTraceEventStoreOptions = VoiceTraceEventFilter;
31
32
  export type VoiceTracePruneFilter = Omit<VoiceTraceEventFilter, 'limit'>;
32
33
  export type VoiceTracePruneOptions = {
33
34
  before?: number;
@@ -212,6 +213,7 @@ export declare const createVoiceTraceSinkDeliveryRecord: (input: {
212
213
  id?: string;
213
214
  } & Partial<Omit<VoiceTraceSinkDeliveryRecord, "createdAt" | "events" | "id">>) => VoiceTraceSinkDeliveryRecord;
214
215
  export declare const filterVoiceTraceEvents: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(events: TEvent[], filter?: VoiceTraceEventFilter) => TEvent[];
216
+ export declare const createVoiceScopedTraceEventStore: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(store: VoiceTraceEventStore<TEvent>, scope: VoiceScopedTraceEventStoreOptions) => VoiceTraceEventStore<TEvent>;
215
217
  export declare const selectVoiceTraceEventsForPrune: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(events: TEvent[], options?: Omit<VoiceTracePruneOptions, "store">) => TEvent[];
216
218
  export declare const pruneVoiceTraceEvents: (options: VoiceTracePruneOptions) => Promise<VoiceTracePruneResult>;
217
219
  export declare const createVoiceTraceHTTPSink: <TBody extends Record<string, unknown> = Record<string, unknown>>(options: VoiceTraceHTTPSinkOptions<TBody>) => VoiceTraceSink;
package/dist/vue/index.js CHANGED
@@ -2477,6 +2477,38 @@ var filterVoiceTraceEvents = (events, filter = {}) => {
2477
2477
  const sorted = events.filter((event) => matchesTraceFilter(event, filter)).sort((left, right) => left.at - right.at || left.id.localeCompare(right.id));
2478
2478
  return typeof filter.limit === "number" && filter.limit >= 0 ? sorted.slice(0, filter.limit) : sorted;
2479
2479
  };
2480
+ var createVoiceScopedTraceEventStore = (store, scope) => {
2481
+ const upstreamFilter = (filter = {}) => {
2482
+ const next = { ...filter };
2483
+ delete next.limit;
2484
+ if (scope.scenarioId !== undefined) {
2485
+ delete next.scenarioId;
2486
+ }
2487
+ if (scope.sessionId !== undefined) {
2488
+ delete next.sessionId;
2489
+ }
2490
+ if (scope.traceId !== undefined) {
2491
+ delete next.traceId;
2492
+ }
2493
+ if (scope.turnId !== undefined) {
2494
+ delete next.turnId;
2495
+ }
2496
+ if (scope.type !== undefined) {
2497
+ delete next.type;
2498
+ }
2499
+ return next;
2500
+ };
2501
+ const scopedFilter = (filter = {}) => ({
2502
+ ...filter,
2503
+ ...scope
2504
+ });
2505
+ return {
2506
+ append: (event) => store.append(event),
2507
+ get: (id) => store.get(id),
2508
+ list: async (filter) => filterVoiceTraceEvents(await store.list(upstreamFilter(filter)), scopedFilter(filter)),
2509
+ remove: (id) => store.remove(id)
2510
+ };
2511
+ };
2480
2512
  var isPruneTimeMatch = (event, options) => {
2481
2513
  if (typeof options.before === "number" && event.at >= options.before) {
2482
2514
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.410",
3
+ "version": "0.0.22-beta.412",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",