@absolutejs/voice 0.0.22-beta.406 → 0.0.22-beta.407

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
@@ -3174,7 +3174,7 @@ Readiness emits the stable `voice.readiness.ops_recovery` gate code when unresol
3174
3174
 
3175
3175
  ## Customer-Owned Observability Export
3176
3176
 
3177
- Use observability exports when a buyer wants the hosted-dashboard evidence graph, but inside their own storage, warehouse, SIEM, incident flow, or release notes. The export manifest links traces, audits, operations records, delivery queues, provider SLOs, readiness reports, screenshots, and proof-pack artifacts without making AbsoluteJS Voice the dashboard.
3177
+ Use observability exports when a buyer wants the hosted-dashboard evidence graph, but inside their own storage, warehouse, SIEM, incident flow, or release notes. The export manifest links traces, audits, operations records, session snapshots, call-debugger reports, delivery queues, provider SLOs, readiness reports, screenshots, and proof-pack artifacts without making AbsoluteJS Voice the dashboard.
3178
3178
 
3179
3179
  Every export manifest and artifact index includes a stable schema contract:
3180
3180
 
@@ -3287,7 +3287,10 @@ app.use(
3287
3287
  audit: runtimeStorage.audit,
3288
3288
  auditDeliveries: runtimeStorage.auditDeliveries,
3289
3289
  links: {
3290
- operationsRecord: (sessionId) => `/voice-operations/${sessionId}`
3290
+ callDebugger: (sessionId) => `/voice-call-debugger/${sessionId}`,
3291
+ operationsRecord: (sessionId) => `/voice-operations/${sessionId}`,
3292
+ sessionSnapshot: (sessionId) =>
3293
+ `/api/voice/session-snapshot/${sessionId}`
3291
3294
  },
3292
3295
  redact: true,
3293
3296
  store: runtimeStorage.traces,
@@ -3312,16 +3315,20 @@ const exportReport = await buildVoiceObservabilityExport({
3312
3315
  },
3313
3316
  audit: runtimeStorage.audit,
3314
3317
  auditDeliveries: runtimeStorage.auditDeliveries,
3318
+ callDebuggerReports: [latestCallDebuggerReport],
3315
3319
  links: {
3316
- operationsRecord: (sessionId) => `/voice-operations/${sessionId}`
3320
+ callDebugger: (sessionId) => `/voice-call-debugger/${sessionId}`,
3321
+ operationsRecord: (sessionId) => `/voice-operations/${sessionId}`,
3322
+ sessionSnapshot: (sessionId) => `/api/voice/session-snapshot/${sessionId}`
3317
3323
  },
3318
3324
  redact: true,
3325
+ sessionSnapshots: [latestSessionSnapshot],
3319
3326
  store: runtimeStorage.traces,
3320
3327
  traceDeliveries: runtimeStorage.traceDeliveries
3321
3328
  });
3322
3329
  ```
3323
3330
 
3324
- The route helper exposes JSON at `/api/voice/observability-export`, an artifact index at `/api/voice/observability-export/artifacts`, per-artifact downloads at `/api/voice/observability-export/artifacts/:artifactId`, delivery at `POST /api/voice/observability-export/deliveries`, delivery history at `GET /api/voice/observability-export/deliveries`, Markdown at `/voice/observability-export.md`, and HTML at `/voice/observability-export`. `createVoiceObservabilityExportReplayRoutes(...)` adds JSON replay proof at `/api/voice/observability-export/replay` and a readable replay proof page at `/voice/observability-export/replay`. Path-backed artifacts are hashed with SHA-256 by default, include byte size and freshness metadata, and can fail the export when required evidence is missing or stale. File delivery writes `manifest.json`, `artifact-index.json`, and artifact files into a customer-owned archive directory; webhook delivery posts the manifest and artifact index to a buyer-owned collector, SIEM bridge, or warehouse endpoint; S3 delivery writes the same manifest, index, and artifact files through Bun's native S3 client; SQLite and Postgres delivery persist the schema id/version, manifest, artifact index, checksum metadata, status, run id, and timestamps into buyer-owned database tables. Delivery receipt stores persist run id, destinations, status, schema, and target history so operators can prove exports have been continuously healthy. Failed trace/audit deliveries fail the export report, pending deliveries warn, and every trace/audit envelope includes the linked operations-record URL when one is configured. This is the primitive to use when customers ask how voice evidence leaves the app without going through a hosted vendor dashboard.
3331
+ The route helper exposes JSON at `/api/voice/observability-export`, an artifact index at `/api/voice/observability-export/artifacts`, per-artifact downloads at `/api/voice/observability-export/artifacts/:artifactId`, delivery at `POST /api/voice/observability-export/deliveries`, delivery history at `GET /api/voice/observability-export/deliveries`, Markdown at `/voice/observability-export.md`, and HTML at `/voice/observability-export`. `createVoiceObservabilityExportReplayRoutes(...)` adds JSON replay proof at `/api/voice/observability-export/replay` and a readable replay proof page at `/voice/observability-export/replay`. Path-backed artifacts are hashed with SHA-256 by default, include byte size and freshness metadata, and can fail the export when required evidence is missing or stale. File delivery writes `manifest.json`, `artifact-index.json`, and artifact files into a customer-owned archive directory; webhook delivery posts the manifest and artifact index to a buyer-owned collector, SIEM bridge, or warehouse endpoint; S3 delivery writes the same manifest, index, and artifact files through Bun's native S3 client; SQLite and Postgres delivery persist the schema id/version, manifest, artifact index, checksum metadata, status, run id, and timestamps into buyer-owned database tables. Delivery receipt stores persist run id, destinations, status, schema, and target history so operators can prove exports have been continuously healthy. Failed trace/audit deliveries fail the export report, pending deliveries warn, and every trace/audit envelope includes the linked operations-record URL when one is configured. Session snapshots and call-debugger reports become first-class artifact-index rows when passed through `sessionSnapshots` and `callDebuggerReports`, so support bundles, incident handoffs, SIEM records, and warehouse exports share one customer-owned evidence graph. This is the primitive to use when customers ask how voice evidence leaves the app without going through a hosted vendor dashboard.
3325
3332
 
3326
3333
  Pass the same report into production readiness when export health should block deploys:
3327
3334
 
package/dist/index.js CHANGED
@@ -32368,6 +32368,25 @@ var createOperationArtifact = (record, href) => ({
32368
32368
  sessionId: record.sessionId,
32369
32369
  status: record.status === "failed" ? "fail" : record.status === "warning" ? "warn" : "pass"
32370
32370
  });
32371
+ var toSnapshotArtifactStatus = (status) => status === "fail" ? "fail" : status === "warn" ? "warn" : "pass";
32372
+ var createSessionSnapshotArtifact = (snapshot, href) => ({
32373
+ generatedAt: snapshot.capturedAt,
32374
+ href,
32375
+ id: `session-snapshot:${snapshot.sessionId}`,
32376
+ kind: "session-snapshot",
32377
+ label: `Session snapshot ${snapshot.sessionId}`,
32378
+ sessionId: snapshot.sessionId,
32379
+ status: toSnapshotArtifactStatus(snapshot.status)
32380
+ });
32381
+ var createCallDebuggerArtifact = (report, href) => ({
32382
+ generatedAt: report.checkedAt,
32383
+ href,
32384
+ id: `call-debugger:${report.sessionId}`,
32385
+ kind: "call-debugger",
32386
+ label: `Call debugger ${report.sessionId}`,
32387
+ sessionId: report.sessionId,
32388
+ status: report.status === "failed" ? "fail" : report.status === "warning" ? "warn" : "pass"
32389
+ });
32371
32390
  var unique2 = (values) => [...new Set(values)].sort();
32372
32391
  var stripArtifactPathAnchor = (path) => path.split("#")[0] ?? path;
32373
32392
  var toEpochMs = (value) => {
@@ -33027,7 +33046,9 @@ var collectSessionIds = (input) => unique2([
33027
33046
  ...input.sessionIds ?? [],
33028
33047
  ...input.events.map((event) => event.sessionId),
33029
33048
  ...input.auditEvents.map((event) => event.sessionId).filter((sessionId) => Boolean(sessionId)),
33030
- ...input.operationsRecords.map((record) => record.sessionId)
33049
+ ...input.operationsRecords.map((record) => record.sessionId),
33050
+ ...input.sessionSnapshots.map((snapshot) => snapshot.sessionId),
33051
+ ...input.callDebuggerReports.map((report) => report.sessionId)
33031
33052
  ]);
33032
33053
  var collectIssues = (input) => {
33033
33054
  const issues = [];
@@ -33133,11 +33154,15 @@ var buildVoiceObservabilityExport = async (options = {}) => {
33133
33154
  const events = options.events ?? await options.store?.list() ?? [];
33134
33155
  const auditEvents = options.audit ? await options.audit.list() : [];
33135
33156
  const baseOperationsRecords = options.operationsRecords ?? [];
33157
+ const sessionSnapshots = options.sessionSnapshots ?? [];
33158
+ const callDebuggerReports = options.callDebuggerReports ?? [];
33136
33159
  const sessionIds = collectSessionIds({
33137
33160
  auditEvents,
33161
+ callDebuggerReports,
33138
33162
  events,
33139
33163
  operationsRecords: baseOperationsRecords,
33140
- sessionIds: options.sessionIds
33164
+ sessionIds: options.sessionIds,
33165
+ sessionSnapshots
33141
33166
  });
33142
33167
  const shouldBuildOperationsRecords = options.includeOperationsRecords === true && options.store;
33143
33168
  const builtOperationsRecords = shouldBuildOperationsRecords ? await Promise.all(sessionIds.map((sessionId) => buildVoiceOperationsRecord({
@@ -33155,7 +33180,14 @@ var buildVoiceObservabilityExport = async (options = {}) => {
33155
33180
  const traceDeliverySummary = traceDeliveries ? await summarizeVoiceTraceSinkDeliveries(traceDeliveries) : undefined;
33156
33181
  const auditDeliverySummary = auditDeliveries ? await summarizeVoiceAuditSinkDeliveries(auditDeliveries) : undefined;
33157
33182
  const operationArtifacts = operationsRecords.map((record) => createOperationArtifact(record, options.links?.operationsRecord?.(record.sessionId)));
33158
- const artifacts = addArtifactDownloadHrefs(await verifyArtifacts([...operationArtifacts, ...options.artifacts ?? []], options.artifactIntegrity), options.links);
33183
+ const sessionSnapshotArtifacts = sessionSnapshots.map((snapshot) => createSessionSnapshotArtifact(snapshot, options.links?.sessionSnapshot?.(snapshot.sessionId)));
33184
+ const callDebuggerArtifacts = callDebuggerReports.map((report) => createCallDebuggerArtifact(report, options.links?.callDebugger?.(report.sessionId)));
33185
+ const artifacts = addArtifactDownloadHrefs(await verifyArtifacts([
33186
+ ...operationArtifacts,
33187
+ ...sessionSnapshotArtifacts,
33188
+ ...callDebuggerArtifacts,
33189
+ ...options.artifacts ?? []
33190
+ ], options.artifactIntegrity), options.links);
33159
33191
  const operationHrefBySessionId = new Map(sessionIds.map((sessionId) => [
33160
33192
  sessionId,
33161
33193
  options.links?.operationsRecord?.(sessionId)
@@ -3,7 +3,9 @@ import type { S3Client, S3Options } from 'bun';
3
3
  import { Database } from 'bun:sqlite';
4
4
  import { type VoiceAuditSinkDeliveryQueueSummary, type VoiceAuditSinkDeliveryRecord, type VoiceAuditSinkDeliveryStore } from './auditSinks';
5
5
  import type { VoiceAuditEventStore, VoiceAuditEventType } from './audit';
6
+ import type { VoiceCallDebuggerReport } from './callDebugger';
6
7
  import { type VoiceOperationsRecord } from './operationsRecord';
8
+ import type { VoiceSessionSnapshot } from './sessionSnapshot';
7
9
  import { type VoiceTraceSinkDeliveryQueueSummary } from './queue';
8
10
  import { type StoredVoiceTraceEvent, type VoiceTraceEventStore, type VoiceTraceEventType, type VoiceTraceRedactionConfig, type VoiceTraceSinkDeliveryRecord, type VoiceTraceSinkDeliveryStore, type VoiceTraceSummary } from './trace';
9
11
  import type { VoicePostgresClient } from './postgresStore';
@@ -41,7 +43,7 @@ export type VoiceObservabilityExportRecordValidationOptions = {
41
43
  };
42
44
  export declare const validateVoiceObservabilityExportRecord: (input: unknown, options?: VoiceObservabilityExportRecordValidationOptions) => VoiceObservabilityExportValidationResult;
43
45
  export declare const assertVoiceObservabilityExportRecord: (input: unknown, options?: VoiceObservabilityExportRecordValidationOptions) => VoiceObservabilityExportValidationResult;
44
- export type VoiceObservabilityExportArtifactKind = 'incident' | 'markdown' | 'operations-record' | 'proof-pack' | 'readiness' | 'screenshot' | 'slo' | 'trace' | 'audit' | 'custom';
46
+ export type VoiceObservabilityExportArtifactKind = 'call-debugger' | 'incident' | 'markdown' | 'operations-record' | 'proof-pack' | 'readiness' | 'screenshot' | 'session-snapshot' | 'slo' | 'trace' | 'audit' | 'custom';
45
47
  export type VoiceObservabilityExportArtifactChecksum = {
46
48
  algorithm: 'sha256';
47
49
  value: string;
@@ -380,11 +382,15 @@ export type VoiceObservabilityExportOptions = {
380
382
  includeOperationsRecords?: boolean;
381
383
  links?: {
382
384
  artifactDownload?: (artifact: VoiceObservabilityExportArtifact) => string;
385
+ callDebugger?: (sessionId: string) => string;
383
386
  operationsRecord?: (sessionId: string) => string;
387
+ sessionSnapshot?: (sessionId: string) => string;
384
388
  };
389
+ callDebuggerReports?: VoiceCallDebuggerReport[];
385
390
  operationsRecords?: VoiceOperationsRecord[];
386
391
  redact?: VoiceTraceRedactionConfig;
387
392
  sessionIds?: string[];
393
+ sessionSnapshots?: VoiceSessionSnapshot[];
388
394
  store?: VoiceTraceEventStore;
389
395
  traceDeliveries?: VoiceTraceSinkDeliveryRecord[] | VoiceTraceSinkDeliveryStore;
390
396
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.406",
3
+ "version": "0.0.22-beta.407",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",