@absolutejs/voice 0.0.22-beta.224 → 0.0.22-beta.225

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
@@ -2748,9 +2748,15 @@ Use observability exports when a buyer wants the hosted-dashboard evidence graph
2748
2748
  ```ts
2749
2749
  import {
2750
2750
  buildVoiceObservabilityExport,
2751
+ createVoiceFileObservabilityExportDeliveryReceiptStore,
2751
2752
  createVoiceObservabilityExportRoutes
2752
2753
  } from '@absolutejs/voice';
2753
2754
 
2755
+ const observabilityReceipts =
2756
+ createVoiceFileObservabilityExportDeliveryReceiptStore({
2757
+ directory: '.voice-runtime/observability-export-receipts'
2758
+ });
2759
+
2754
2760
  app.use(
2755
2761
  createVoiceObservabilityExportRoutes({
2756
2762
  artifactIntegrity: {
@@ -2769,6 +2775,7 @@ app.use(
2769
2775
  label: 'S3 customer-owned observability archive'
2770
2776
  }
2771
2777
  ],
2778
+ deliveryReceipts: observabilityReceipts,
2772
2779
  artifacts: [
2773
2780
  {
2774
2781
  id: 'latest-proof-pack',
@@ -2804,7 +2811,7 @@ const exportReport = await buildVoiceObservabilityExport({
2804
2811
  });
2805
2812
  ```
2806
2813
 
2807
- 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`, Markdown at `/voice/observability-export.md`, and HTML at `/voice/observability-export`. 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. 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.
2814
+ 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`. 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. Delivery receipt stores persist run id, destinations, status, 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.
2808
2815
 
2809
2816
  Pass the same report into production readiness when export health should block deploys:
2810
2817
 
package/dist/index.d.ts CHANGED
@@ -53,7 +53,7 @@ export { createVoiceReadinessProfile, recommendVoiceReadinessProfile } from './r
53
53
  export { buildVoiceProviderContractMatrix, createVoiceProviderContractMatrixHTMLHandler, createVoiceProviderContractMatrixJSONHandler, createVoiceProviderContractMatrixPreset, createVoiceProviderContractMatrixRoutes, evaluateVoiceProviderStackGaps, renderVoiceProviderContractMatrixHTML, recommendVoiceProviderStack } from './providerStackRecommendations';
54
54
  export { buildVoiceOpsConsoleReport, createVoiceOpsConsoleRoutes, renderVoiceOpsConsoleHTML } from './opsConsoleRoutes';
55
55
  export { buildVoiceOperationsRecord, createVoiceOperationsRecordRoutes, renderVoiceOperationsRecordHTML, renderVoiceOperationsRecordIncidentMarkdown } from './operationsRecord';
56
- export { buildVoiceObservabilityArtifactIndex, buildVoiceObservabilityExport, createVoiceObservabilityExportRoutes, deliverVoiceObservabilityExport, renderVoiceObservabilityExportMarkdown } from './observabilityExport';
56
+ export { buildVoiceObservabilityArtifactIndex, buildVoiceObservabilityExportDeliveryHistory, buildVoiceObservabilityExport, createVoiceFileObservabilityExportDeliveryReceiptStore, createVoiceMemoryObservabilityExportDeliveryReceiptStore, createVoiceObservabilityExportRoutes, deliverVoiceObservabilityExport, renderVoiceObservabilityExportMarkdown } from './observabilityExport';
57
57
  export { buildVoiceOpsRecoveryReadinessCheck, buildVoiceOpsRecoveryReport, createVoiceOpsRecoveryRoutes, renderVoiceOpsRecoveryHTML, renderVoiceOpsRecoveryMarkdown } from './opsRecovery';
58
58
  export { buildVoiceIncidentBundle, createStoredVoiceIncidentBundleArtifact, createVoiceIncidentBundleRoutes, createVoiceMemoryIncidentBundleStore, pruneVoiceIncidentBundleArtifacts, saveVoiceIncidentBundleArtifact } from './incidentBundle';
59
59
  export { summarizeVoiceOpsStatus } from './opsStatus';
@@ -118,7 +118,7 @@ export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptio
118
118
  export type { VoiceReadinessProfileName, VoiceReadinessProfileOptions, VoiceReadinessProfileRecommendation, VoiceReadinessProfileRecommendationScore, VoiceReadinessProfileRoutesOptions } from './readinessProfiles';
119
119
  export type { VoiceProviderStackChoice, VoiceProviderStackCapabilities, VoiceProviderStackCapabilityGap, VoiceProviderStackCapabilityGapInput, VoiceProviderStackCapabilityGapReport, VoiceProviderContractCheck, VoiceProviderContractCheckStatus, VoiceProviderContractDefinition, VoiceProviderContractMatrixHandlerOptions, VoiceProviderContractMatrixHTMLHandlerOptions, VoiceProviderContractMatrixInput, VoiceProviderContractMatrixPresetOptions, VoiceProviderContractMatrixReport, VoiceProviderContractMatrixRoutesOptions, VoiceProviderContractMatrixRow, VoiceProviderStackInput, VoiceProviderStackKind, VoiceProviderStackRecommendation } from './providerStackRecommendations';
120
120
  export type { VoiceOperationsRecord, VoiceOperationsRecordAgentHandoff, VoiceOperationsRecordAuditSummary, VoiceOperationsRecordIntegrationEventSummary, VoiceOperationsRecordOptions, VoiceOperationsRecordOutcome, VoiceOperationsRecordProviderDecision, VoiceOperationsRecordReviewSummary, VoiceOperationsRecordRoutesOptions, VoiceOperationsRecordStatus, VoiceOperationsRecordTaskSummary, VoiceOperationsRecordTranscriptTurn, VoiceOperationsRecordTool } from './operationsRecord';
121
- export type { VoiceObservabilityExportArtifact, VoiceObservabilityExportArtifactChecksum, VoiceObservabilityExportArtifactFreshness, VoiceObservabilityExportArtifactIndex, VoiceObservabilityExportArtifactIndexItem, VoiceObservabilityExportArtifactKind, VoiceObservabilityExportDeliverySummary, VoiceObservabilityExportDeliveryDestination, VoiceObservabilityExportDeliveryDestinationResult, VoiceObservabilityExportDeliveryOptions, VoiceObservabilityExportDeliveryReport, VoiceObservabilityExportEnvelope, VoiceObservabilityExportIssue, VoiceObservabilityExportIssueCode, VoiceObservabilityExportOptions, VoiceObservabilityExportRedactionSummary, VoiceObservabilityExportReport, VoiceObservabilityExportRoutesOptions, VoiceObservabilityExportStatus } from './observabilityExport';
121
+ export type { VoiceObservabilityExportArtifact, VoiceObservabilityExportArtifactChecksum, VoiceObservabilityExportArtifactFreshness, VoiceObservabilityExportArtifactIndex, VoiceObservabilityExportArtifactIndexItem, VoiceObservabilityExportArtifactKind, VoiceObservabilityExportDeliverySummary, VoiceObservabilityExportDeliveryDestination, VoiceObservabilityExportDeliveryDestinationResult, VoiceObservabilityExportDeliveryHistory, VoiceObservabilityExportDeliveryOptions, VoiceObservabilityExportDeliveryReceipt, VoiceObservabilityExportDeliveryReceiptStore, VoiceObservabilityExportDeliveryReport, VoiceObservabilityExportEnvelope, VoiceObservabilityExportIssue, VoiceObservabilityExportIssueCode, VoiceObservabilityExportOptions, VoiceObservabilityExportRedactionSummary, VoiceObservabilityExportReport, VoiceObservabilityExportRoutesOptions, VoiceObservabilityExportStatus } from './observabilityExport';
122
122
  export type { VoiceOpsRecoveryFailedSession, VoiceOpsRecoveryInterventionSummary, VoiceOpsRecoveryIssue, VoiceOpsRecoveryIssueCode, VoiceOpsRecoveryLinks, VoiceOpsRecoveryProviderSummary, VoiceOpsRecoveryReport, VoiceOpsRecoveryReportOptions, VoiceOpsRecoveryRoutesOptions, VoiceOpsRecoveryStatus } from './opsRecovery';
123
123
  export type { StoredVoiceIncidentBundleArtifact, VoiceIncidentBundle, VoiceIncidentBundleArtifactOptions, VoiceIncidentBundleFormat, VoiceIncidentBundleOptions, VoiceIncidentBundleRetentionOptions, VoiceIncidentBundleRetentionReport, VoiceIncidentBundleRoutesOptions, VoiceIncidentBundleStore, VoiceIncidentBundleStoreFilter, VoiceIncidentBundleSummary } from './incidentBundle';
124
124
  export type { VoiceQualityLink, VoiceQualityMetric, VoiceQualityReport, VoiceQualityRoutesOptions, VoiceQualityStatus, VoiceQualityThresholds } from './qualityRoutes';
package/dist/index.js CHANGED
@@ -24943,7 +24943,7 @@ var createVoiceOperationsRecordRoutes = (options) => {
24943
24943
  // src/observabilityExport.ts
24944
24944
  import { Elysia as Elysia42 } from "elysia";
24945
24945
  import { createHash } from "crypto";
24946
- import { mkdir as mkdir4, readFile as readFile2, stat } from "fs/promises";
24946
+ import { mkdir as mkdir4, readFile as readFile2, stat, unlink } from "fs/promises";
24947
24947
  import { join as join3 } from "path";
24948
24948
  var isDeliveryStore = (value) => !Array.isArray(value) && typeof value.list === "function";
24949
24949
  var getString18 = (value) => typeof value === "string" ? value : undefined;
@@ -24984,6 +24984,7 @@ var checksumFile = async (path) => {
24984
24984
  return createHash("sha256").update(buffer).digest("hex");
24985
24985
  };
24986
24986
  var byteLength = (value) => new TextEncoder().encode(value).byteLength;
24987
+ var deliveryReceiptId = (runId) => `observability-export:${encodeURIComponent(runId)}`;
24987
24988
  var safeArtifactFileName = (artifact) => {
24988
24989
  const extension = artifact.contentType === "image/png" ? ".png" : artifact.contentType?.includes("markdown") ? ".md" : artifact.contentType?.includes("json") ? ".json" : "";
24989
24990
  return `${artifact.id.replace(/[^a-z0-9_.-]/gi, "-")}${extension}`;
@@ -24996,6 +24997,67 @@ var writeS3Object = async (input) => {
24996
24997
  type: input.contentType
24997
24998
  });
24998
24999
  };
25000
+ var createVoiceMemoryObservabilityExportDeliveryReceiptStore = () => {
25001
+ const receipts = new Map;
25002
+ return {
25003
+ get: (id) => receipts.get(id),
25004
+ list: () => [...receipts.values()].sort((left, right) => right.checkedAt - left.checkedAt),
25005
+ remove: (id) => {
25006
+ receipts.delete(id);
25007
+ },
25008
+ set: (id, receipt) => {
25009
+ receipts.set(id, receipt);
25010
+ }
25011
+ };
25012
+ };
25013
+ var createVoiceFileObservabilityExportDeliveryReceiptStore = (options) => {
25014
+ const receiptPath = (id) => join3(options.directory, `${encodeURIComponent(id)}.json`);
25015
+ return {
25016
+ get: async (id) => {
25017
+ const file = Bun.file(receiptPath(id));
25018
+ if (!await file.exists()) {
25019
+ return;
25020
+ }
25021
+ return JSON.parse(await file.text());
25022
+ },
25023
+ list: async () => {
25024
+ await mkdir4(options.directory, { recursive: true });
25025
+ const receipts = [];
25026
+ for (const entry of await Array.fromAsync(new Bun.Glob("*.json").scan(options.directory))) {
25027
+ const file = Bun.file(join3(options.directory, entry));
25028
+ receipts.push(JSON.parse(await file.text()));
25029
+ }
25030
+ return receipts.sort((left, right) => right.checkedAt - left.checkedAt);
25031
+ },
25032
+ remove: async (id) => {
25033
+ await unlink(receiptPath(id)).catch(() => {
25034
+ return;
25035
+ });
25036
+ },
25037
+ set: async (id, receipt) => {
25038
+ await mkdir4(options.directory, { recursive: true });
25039
+ await Bun.write(receiptPath(id), `${JSON.stringify(receipt, null, 2)}
25040
+ `);
25041
+ }
25042
+ };
25043
+ };
25044
+ var buildVoiceObservabilityExportDeliveryHistory = async (store) => {
25045
+ const receipts = await store.list();
25046
+ const failed = receipts.reduce((count, receipt) => count + receipt.summary.failed, 0);
25047
+ const delivered = receipts.reduce((count, receipt) => count + receipt.summary.delivered, 0);
25048
+ const totalDestinations = receipts.reduce((count, receipt) => count + receipt.summary.total, 0);
25049
+ return {
25050
+ checkedAt: Date.now(),
25051
+ receipts,
25052
+ status: failed > 0 || receipts.some((receipt) => receipt.status === "fail") ? "fail" : receipts.some((receipt) => receipt.status === "warn") ? "warn" : "pass",
25053
+ summary: {
25054
+ delivered,
25055
+ failed,
25056
+ receipts: receipts.length,
25057
+ totalDestinations
25058
+ }
25059
+ };
25060
+ };
24999
25061
  var inferContentType = (artifact) => {
25000
25062
  if (artifact.contentType) {
25001
25063
  return artifact.contentType;
@@ -25453,17 +25515,27 @@ var deliverVoiceObservabilityExport = async (options) => {
25453
25515
  }
25454
25516
  }));
25455
25517
  const failed = destinations.filter((destination) => destination.status === "failed").length;
25456
- return {
25518
+ const status = failed > 0 || options.report.status === "fail" ? "fail" : options.report.status === "warn" ? "warn" : "pass";
25519
+ const report = {
25457
25520
  checkedAt,
25458
25521
  destinations,
25459
25522
  exportStatus: options.report.status,
25460
- status: failed > 0 || options.report.status === "fail" ? "fail" : options.report.status === "warn" ? "warn" : "pass",
25523
+ status,
25461
25524
  summary: {
25462
25525
  delivered: destinations.length - failed,
25463
25526
  failed,
25464
25527
  total: destinations.length
25465
25528
  }
25466
25529
  };
25530
+ if (options.receipts) {
25531
+ const receipt = {
25532
+ ...report,
25533
+ id: deliveryReceiptId(runId),
25534
+ runId
25535
+ };
25536
+ await options.receipts.set(receipt.id, receipt);
25537
+ }
25538
+ return report;
25467
25539
  };
25468
25540
  var createVoiceObservabilityExportRoutes = (options = {}) => {
25469
25541
  const path = options.path ?? "/api/voice/observability-export";
@@ -25520,8 +25592,12 @@ var createVoiceObservabilityExportRoutes = (options = {}) => {
25520
25592
  });
25521
25593
  }
25522
25594
  if (deliveryPath !== false && options.deliveryDestinations) {
25595
+ if (options.deliveryReceipts) {
25596
+ app.get(deliveryPath, async () => Response.json(await buildVoiceObservabilityExportDeliveryHistory(options.deliveryReceipts), { headers }));
25597
+ }
25523
25598
  app.post(deliveryPath, async () => Response.json(await deliverVoiceObservabilityExport({
25524
25599
  destinations: options.deliveryDestinations ?? [],
25600
+ receipts: options.deliveryReceipts,
25525
25601
  report: await buildReport()
25526
25602
  }), { headers }));
25527
25603
  }
@@ -28418,6 +28494,7 @@ export {
28418
28494
  createVoiceMemoryTraceSinkDeliveryStore,
28419
28495
  createVoiceMemoryTraceEventStore,
28420
28496
  createVoiceMemoryStore,
28497
+ createVoiceMemoryObservabilityExportDeliveryReceiptStore,
28421
28498
  createVoiceMemoryLiveOpsControlStore,
28422
28499
  createVoiceMemoryIncidentBundleStore,
28423
28500
  createVoiceMemoryHandoffDeliveryStore,
@@ -28453,6 +28530,7 @@ export {
28453
28530
  createVoiceFileScenarioFixtureStore,
28454
28531
  createVoiceFileRuntimeStorage,
28455
28532
  createVoiceFileReviewStore,
28533
+ createVoiceFileObservabilityExportDeliveryReceiptStore,
28456
28534
  createVoiceFileIntegrationEventStore,
28457
28535
  createVoiceFileIncidentBundleStore,
28458
28536
  createVoiceFileExternalObjectMapStore,
@@ -28551,6 +28629,7 @@ export {
28551
28629
  buildVoiceOpsConsoleReport,
28552
28630
  buildVoiceOpsActionHistoryReport,
28553
28631
  buildVoiceOperationsRecord,
28632
+ buildVoiceObservabilityExportDeliveryHistory,
28554
28633
  buildVoiceObservabilityExport,
28555
28634
  buildVoiceObservabilityArtifactIndex,
28556
28635
  buildVoiceLiveOpsControlState,
@@ -154,9 +154,36 @@ export type VoiceObservabilityExportDeliveryReport = {
154
154
  total: number;
155
155
  };
156
156
  };
157
+ export type VoiceObservabilityExportDeliveryReceipt = {
158
+ checkedAt: number;
159
+ destinations: VoiceObservabilityExportDeliveryDestinationResult[];
160
+ exportStatus: VoiceObservabilityExportStatus;
161
+ id: string;
162
+ runId: string;
163
+ status: VoiceObservabilityExportStatus;
164
+ summary: VoiceObservabilityExportDeliveryReport['summary'];
165
+ };
166
+ export type VoiceObservabilityExportDeliveryReceiptStore = {
167
+ get: (id: string) => Promise<VoiceObservabilityExportDeliveryReceipt | undefined> | VoiceObservabilityExportDeliveryReceipt | undefined;
168
+ list: () => Promise<VoiceObservabilityExportDeliveryReceipt[]> | VoiceObservabilityExportDeliveryReceipt[];
169
+ remove: (id: string) => Promise<void> | void;
170
+ set: (id: string, receipt: VoiceObservabilityExportDeliveryReceipt) => Promise<void> | void;
171
+ };
172
+ export type VoiceObservabilityExportDeliveryHistory = {
173
+ checkedAt: number;
174
+ receipts: VoiceObservabilityExportDeliveryReceipt[];
175
+ status: VoiceObservabilityExportStatus;
176
+ summary: {
177
+ delivered: number;
178
+ failed: number;
179
+ receipts: number;
180
+ totalDestinations: number;
181
+ };
182
+ };
157
183
  export type VoiceObservabilityExportDeliveryOptions = {
158
184
  destinations: VoiceObservabilityExportDeliveryDestination[];
159
185
  report: VoiceObservabilityExportReport;
186
+ receipts?: VoiceObservabilityExportDeliveryReceiptStore;
160
187
  runId?: string;
161
188
  };
162
189
  export type VoiceObservabilityExportOptions = {
@@ -188,6 +215,7 @@ export type VoiceObservabilityExportRoutesOptions = VoiceObservabilityExportOpti
188
215
  artifactIndexPath?: false | string;
189
216
  deliveryDestinations?: VoiceObservabilityExportDeliveryDestination[];
190
217
  deliveryPath?: false | string;
218
+ deliveryReceipts?: VoiceObservabilityExportDeliveryReceiptStore;
191
219
  htmlPath?: false | string;
192
220
  markdownPath?: false | string;
193
221
  name?: string;
@@ -195,6 +223,11 @@ export type VoiceObservabilityExportRoutesOptions = VoiceObservabilityExportOpti
195
223
  render?: (report: VoiceObservabilityExportReport) => string | Promise<string>;
196
224
  title?: string;
197
225
  };
226
+ export declare const createVoiceMemoryObservabilityExportDeliveryReceiptStore: () => VoiceObservabilityExportDeliveryReceiptStore;
227
+ export declare const createVoiceFileObservabilityExportDeliveryReceiptStore: (options: {
228
+ directory: string;
229
+ }) => VoiceObservabilityExportDeliveryReceiptStore;
230
+ export declare const buildVoiceObservabilityExportDeliveryHistory: (store: VoiceObservabilityExportDeliveryReceiptStore) => Promise<VoiceObservabilityExportDeliveryHistory>;
198
231
  export declare const buildVoiceObservabilityExport: (options?: VoiceObservabilityExportOptions) => Promise<VoiceObservabilityExportReport>;
199
232
  export declare const renderVoiceObservabilityExportMarkdown: (report: VoiceObservabilityExportReport, options?: {
200
233
  title?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.224",
3
+ "version": "0.0.22-beta.225",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",