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

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
@@ -2756,6 +2756,19 @@ app.use(
2756
2756
  artifactIntegrity: {
2757
2757
  maxAgeMs: 15 * 60 * 1000
2758
2758
  },
2759
+ deliveryDestinations: [
2760
+ {
2761
+ directory: '.voice-runtime/observability-exports',
2762
+ kind: 'file',
2763
+ label: 'Local customer-owned observability archive'
2764
+ },
2765
+ {
2766
+ bucket: process.env.VOICE_OBSERVABILITY_EXPORT_S3_BUCKET,
2767
+ keyPrefix: 'voice/observability-exports',
2768
+ kind: 's3',
2769
+ label: 'S3 customer-owned observability archive'
2770
+ }
2771
+ ],
2759
2772
  artifacts: [
2760
2773
  {
2761
2774
  id: 'latest-proof-pack',
@@ -2791,7 +2804,7 @@ const exportReport = await buildVoiceObservabilityExport({
2791
2804
  });
2792
2805
  ```
2793
2806
 
2794
- 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`, 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. 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.
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.
2795
2808
 
2796
2809
  Pass the same report into production readiness when export health should block deploys:
2797
2810
 
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, renderVoiceObservabilityExportMarkdown } from './observabilityExport';
56
+ export { buildVoiceObservabilityArtifactIndex, buildVoiceObservabilityExport, 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, VoiceObservabilityExportEnvelope, VoiceObservabilityExportIssue, VoiceObservabilityExportIssueCode, VoiceObservabilityExportOptions, VoiceObservabilityExportRedactionSummary, VoiceObservabilityExportReport, VoiceObservabilityExportRoutesOptions, VoiceObservabilityExportStatus } from './observabilityExport';
121
+ export type { VoiceObservabilityExportArtifact, VoiceObservabilityExportArtifactChecksum, VoiceObservabilityExportArtifactFreshness, VoiceObservabilityExportArtifactIndex, VoiceObservabilityExportArtifactIndexItem, VoiceObservabilityExportArtifactKind, VoiceObservabilityExportDeliverySummary, VoiceObservabilityExportDeliveryDestination, VoiceObservabilityExportDeliveryDestinationResult, VoiceObservabilityExportDeliveryOptions, 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
@@ -6972,14 +6972,14 @@ var createProofFetch = (provider, requests) => {
6972
6972
  };
6973
6973
  };
6974
6974
  var createProofDialer = (input) => {
6975
- const fetch = createProofFetch(input.provider, input.requests);
6975
+ const fetch2 = createProofFetch(input.provider, input.requests);
6976
6976
  if (input.provider === "twilio") {
6977
6977
  return createVoiceTwilioCampaignDialer({
6978
6978
  accountSid: "AC_dry_run",
6979
6979
  answerUrl: joinUrlPath(input.baseUrl, "/api/twilio/voice"),
6980
6980
  apiBaseUrl: "https://twilio.dry-run.absolutejs.local",
6981
6981
  authToken: "dry-run-token",
6982
- fetch,
6982
+ fetch: fetch2,
6983
6983
  from: input.from,
6984
6984
  statusCallbackEvents: ["answered", "completed"],
6985
6985
  statusCallbackUrl: joinUrlPath(input.baseUrl, "/api/telephony-webhook")
@@ -6990,7 +6990,7 @@ var createProofDialer = (input) => {
6990
6990
  apiBaseUrl: "https://telnyx.dry-run.absolutejs.local",
6991
6991
  apiKey: "dry-run-token",
6992
6992
  connectionId: "dry-run-connection",
6993
- fetch,
6993
+ fetch: fetch2,
6994
6994
  from: input.from,
6995
6995
  webhookUrl: joinUrlPath(input.baseUrl, "/api/telnyx/webhook")
6996
6996
  });
@@ -7001,7 +7001,7 @@ var createProofDialer = (input) => {
7001
7001
  authId: "dry-run-auth-id",
7002
7002
  authToken: "dry-run-token",
7003
7003
  callbackUrl: joinUrlPath(input.baseUrl, "/api/plivo/webhook"),
7004
- fetch,
7004
+ fetch: fetch2,
7005
7005
  from: input.from
7006
7006
  });
7007
7007
  };
@@ -24943,7 +24943,8 @@ var createVoiceOperationsRecordRoutes = (options) => {
24943
24943
  // src/observabilityExport.ts
24944
24944
  import { Elysia as Elysia42 } from "elysia";
24945
24945
  import { createHash } from "crypto";
24946
- import { readFile as readFile2, stat } from "fs/promises";
24946
+ import { mkdir as mkdir4, readFile as readFile2, stat } from "fs/promises";
24947
+ import { join as join3 } from "path";
24947
24948
  var isDeliveryStore = (value) => !Array.isArray(value) && typeof value.list === "function";
24948
24949
  var getString18 = (value) => typeof value === "string" ? value : undefined;
24949
24950
  var getProviderKind = (payload) => getString18(payload.kind) ?? getString18(payload.providerKind);
@@ -24982,6 +24983,19 @@ var checksumFile = async (path) => {
24982
24983
  const buffer = await readFile2(path);
24983
24984
  return createHash("sha256").update(buffer).digest("hex");
24984
24985
  };
24986
+ var byteLength = (value) => new TextEncoder().encode(value).byteLength;
24987
+ var safeArtifactFileName = (artifact) => {
24988
+ const extension = artifact.contentType === "image/png" ? ".png" : artifact.contentType?.includes("markdown") ? ".md" : artifact.contentType?.includes("json") ? ".json" : "";
24989
+ return `${artifact.id.replace(/[^a-z0-9_.-]/gi, "-")}${extension}`;
24990
+ };
24991
+ var normalizeExportS3KeyPrefix = (prefix) => prefix?.trim().replace(/^\/+|\/+$/g, "") ?? "voice/observability-exports";
24992
+ var joinS3Key = (...parts) => parts.map((part) => part.trim().replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
24993
+ var writeS3Object = async (input) => {
24994
+ const file = input.client.file(input.key, input.options);
24995
+ await file.write(input.value, {
24996
+ type: input.contentType
24997
+ });
24998
+ };
24985
24999
  var inferContentType = (artifact) => {
24986
25000
  if (artifact.contentType) {
24987
25001
  return artifact.contentType;
@@ -25310,10 +25324,152 @@ var buildVoiceObservabilityArtifactIndex = (report) => {
25310
25324
  }
25311
25325
  };
25312
25326
  };
25327
+ var deliverVoiceObservabilityExport = async (options) => {
25328
+ const checkedAt = Date.now();
25329
+ const runId = options.runId ?? new Date(checkedAt).toISOString().replaceAll(":", "-");
25330
+ const artifactIndex = buildVoiceObservabilityArtifactIndex(options.report);
25331
+ const manifest = `${JSON.stringify(options.report, null, 2)}
25332
+ `;
25333
+ const index = `${JSON.stringify(artifactIndex, null, 2)}
25334
+ `;
25335
+ const destinations = await Promise.all(options.destinations.map(async (destination) => {
25336
+ const destinationId = destination.id ?? `${destination.kind}-${destination.label ?? "export"}`;
25337
+ const label = destination.label ?? (destination.kind === "file" ? "File observability export" : "Webhook observability export");
25338
+ try {
25339
+ if (destination.kind === "file") {
25340
+ const target = join3(destination.directory, runId);
25341
+ await mkdir4(join3(target, "artifacts"), { recursive: true });
25342
+ await Bun.write(join3(target, "manifest.json"), manifest);
25343
+ await Bun.write(join3(target, "artifact-index.json"), index);
25344
+ if (destination.includeArtifacts !== false) {
25345
+ for (const artifact of options.report.artifacts) {
25346
+ if (!artifact.path) {
25347
+ continue;
25348
+ }
25349
+ await Bun.write(join3(target, "artifacts", safeArtifactFileName(artifact)), await readFile2(stripArtifactPathAnchor(artifact.path)));
25350
+ }
25351
+ }
25352
+ return {
25353
+ artifactCount: destination.includeArtifacts === false ? 0 : options.report.artifacts.filter((artifact) => artifact.path).length,
25354
+ deliveredAt: Date.now(),
25355
+ destinationId,
25356
+ destinationKind: destination.kind,
25357
+ label,
25358
+ manifestBytes: byteLength(manifest),
25359
+ status: "delivered",
25360
+ target
25361
+ };
25362
+ }
25363
+ if (destination.kind === "s3") {
25364
+ const keyPrefix = normalizeExportS3KeyPrefix(destination.keyPrefix);
25365
+ const rootKey = joinS3Key(keyPrefix, runId);
25366
+ const client = destination.client ?? new Bun.S3Client(destination);
25367
+ const s3Options = destination;
25368
+ await writeS3Object({
25369
+ client,
25370
+ contentType: "application/json",
25371
+ key: joinS3Key(rootKey, "manifest.json"),
25372
+ options: s3Options,
25373
+ value: manifest
25374
+ });
25375
+ await writeS3Object({
25376
+ client,
25377
+ contentType: "application/json",
25378
+ key: joinS3Key(rootKey, "artifact-index.json"),
25379
+ options: s3Options,
25380
+ value: index
25381
+ });
25382
+ if (destination.includeArtifacts !== false) {
25383
+ for (const artifact of options.report.artifacts) {
25384
+ if (!artifact.path) {
25385
+ continue;
25386
+ }
25387
+ await writeS3Object({
25388
+ client,
25389
+ contentType: artifact.contentType ?? inferContentType(artifact),
25390
+ key: joinS3Key(rootKey, "artifacts", safeArtifactFileName(artifact)),
25391
+ options: s3Options,
25392
+ value: await readFile2(stripArtifactPathAnchor(artifact.path))
25393
+ });
25394
+ }
25395
+ }
25396
+ return {
25397
+ artifactCount: destination.includeArtifacts === false ? 0 : options.report.artifacts.filter((artifact) => artifact.path).length,
25398
+ deliveredAt: Date.now(),
25399
+ destinationId,
25400
+ destinationKind: destination.kind,
25401
+ label,
25402
+ manifestBytes: byteLength(manifest),
25403
+ status: "delivered",
25404
+ target: destination.bucket ? `s3://${destination.bucket}/${rootKey}` : rootKey
25405
+ };
25406
+ }
25407
+ const controller = new AbortController;
25408
+ const timeout = setTimeout(() => controller.abort(), destination.timeoutMs ?? 1e4);
25409
+ try {
25410
+ const response = await (destination.fetch ?? fetch)(destination.url, {
25411
+ body: JSON.stringify({
25412
+ artifactIndex,
25413
+ artifacts: destination.includeArtifacts === false ? [] : options.report.artifacts,
25414
+ manifest: options.report,
25415
+ runId,
25416
+ source: "absolutejs-voice"
25417
+ }),
25418
+ headers: {
25419
+ "content-type": "application/json",
25420
+ ...destination.headers ?? {}
25421
+ },
25422
+ method: "POST",
25423
+ signal: controller.signal
25424
+ });
25425
+ if (!response.ok) {
25426
+ throw new Error(`Webhook returned HTTP ${response.status}`);
25427
+ }
25428
+ } finally {
25429
+ clearTimeout(timeout);
25430
+ }
25431
+ return {
25432
+ artifactCount: destination.includeArtifacts === false ? 0 : options.report.artifacts.length,
25433
+ deliveredAt: Date.now(),
25434
+ destinationId,
25435
+ destinationKind: destination.kind,
25436
+ label,
25437
+ manifestBytes: byteLength(manifest),
25438
+ status: "delivered",
25439
+ target: destination.url
25440
+ };
25441
+ } catch (error) {
25442
+ return {
25443
+ artifactCount: 0,
25444
+ deliveredAt: Date.now(),
25445
+ destinationId,
25446
+ destinationKind: destination.kind,
25447
+ error: error instanceof Error ? error.message : String(error),
25448
+ label,
25449
+ manifestBytes: byteLength(manifest),
25450
+ status: "failed",
25451
+ target: destination.kind === "file" ? destination.directory : destination.kind === "s3" ? destination.bucket ? `s3://${destination.bucket}/${normalizeExportS3KeyPrefix(destination.keyPrefix)}` : normalizeExportS3KeyPrefix(destination.keyPrefix) : destination.url
25452
+ };
25453
+ }
25454
+ }));
25455
+ const failed = destinations.filter((destination) => destination.status === "failed").length;
25456
+ return {
25457
+ checkedAt,
25458
+ destinations,
25459
+ exportStatus: options.report.status,
25460
+ status: failed > 0 || options.report.status === "fail" ? "fail" : options.report.status === "warn" ? "warn" : "pass",
25461
+ summary: {
25462
+ delivered: destinations.length - failed,
25463
+ failed,
25464
+ total: destinations.length
25465
+ }
25466
+ };
25467
+ };
25313
25468
  var createVoiceObservabilityExportRoutes = (options = {}) => {
25314
25469
  const path = options.path ?? "/api/voice/observability-export";
25315
25470
  const artifactIndexPath = options.artifactIndexPath ?? `${path}/artifacts`;
25316
25471
  const artifactDownloadPath = options.artifactDownloadPath ?? `${path}/artifacts`;
25472
+ const deliveryPath = options.deliveryPath ?? `${path}/deliveries`;
25317
25473
  const markdownPath = options.markdownPath ?? "/voice/observability-export.md";
25318
25474
  const htmlPath = options.htmlPath ?? "/voice/observability-export";
25319
25475
  const headers = {
@@ -25363,6 +25519,12 @@ var createVoiceObservabilityExportRoutes = (options = {}) => {
25363
25519
  }
25364
25520
  });
25365
25521
  }
25522
+ if (deliveryPath !== false && options.deliveryDestinations) {
25523
+ app.post(deliveryPath, async () => Response.json(await deliverVoiceObservabilityExport({
25524
+ destinations: options.deliveryDestinations ?? [],
25525
+ report: await buildReport()
25526
+ }), { headers }));
25527
+ }
25366
25528
  if (markdownPath !== false) {
25367
25529
  app.get(markdownPath, async () => {
25368
25530
  const report = await buildReport();
@@ -27157,7 +27319,7 @@ var createVoiceOpsRuntime = (config) => {
27157
27319
  pollIntervalMs: _pollIntervalMs,
27158
27320
  backoffMs,
27159
27321
  eventTypes,
27160
- fetch,
27322
+ fetch: fetch2,
27161
27323
  headers,
27162
27324
  retries,
27163
27325
  signingSecret,
@@ -27171,7 +27333,7 @@ var createVoiceOpsRuntime = (config) => {
27171
27333
  webhook: {
27172
27334
  backoffMs,
27173
27335
  eventTypes,
27174
- fetch,
27336
+ fetch: fetch2,
27175
27337
  headers,
27176
27338
  retries,
27177
27339
  signingSecret,
@@ -28113,6 +28275,7 @@ export {
28113
28275
  evaluateVoiceProviderStackGaps,
28114
28276
  encodeTwilioMulawBase64,
28115
28277
  deliverVoiceTraceEventsToSinks,
28278
+ deliverVoiceObservabilityExport,
28116
28279
  deliverVoiceIntegrationEventToSinks,
28117
28280
  deliverVoiceIntegrationEvent,
28118
28281
  deliverVoiceHandoffDelivery,
@@ -1,4 +1,5 @@
1
1
  import { Elysia } from 'elysia';
2
+ import type { S3Client, S3Options } from 'bun';
2
3
  import { type VoiceAuditSinkDeliveryQueueSummary, type VoiceAuditSinkDeliveryRecord, type VoiceAuditSinkDeliveryStore } from './auditSinks';
3
4
  import type { VoiceAuditEventStore, VoiceAuditEventType } from './audit';
4
5
  import { type VoiceOperationsRecord } from './operationsRecord';
@@ -107,6 +108,57 @@ export type VoiceObservabilityExportArtifactIndex = {
107
108
  warn: number;
108
109
  };
109
110
  };
111
+ export type VoiceObservabilityExportDeliveryDestination = {
112
+ directory: string;
113
+ id?: string;
114
+ includeArtifacts?: boolean;
115
+ kind: 'file';
116
+ label?: string;
117
+ } | (S3Options & {
118
+ bucket?: string;
119
+ client?: Pick<S3Client, 'file'>;
120
+ id?: string;
121
+ includeArtifacts?: boolean;
122
+ keyPrefix?: string;
123
+ kind: 's3';
124
+ label?: string;
125
+ }) | {
126
+ fetch?: typeof fetch;
127
+ headers?: Record<string, string>;
128
+ id?: string;
129
+ includeArtifacts?: boolean;
130
+ kind: 'webhook';
131
+ label?: string;
132
+ timeoutMs?: number;
133
+ url: string;
134
+ };
135
+ export type VoiceObservabilityExportDeliveryDestinationResult = {
136
+ artifactCount: number;
137
+ deliveredAt: number;
138
+ destinationId: string;
139
+ destinationKind: VoiceObservabilityExportDeliveryDestination['kind'];
140
+ error?: string;
141
+ label: string;
142
+ manifestBytes: number;
143
+ status: 'delivered' | 'failed';
144
+ target: string;
145
+ };
146
+ export type VoiceObservabilityExportDeliveryReport = {
147
+ checkedAt: number;
148
+ destinations: VoiceObservabilityExportDeliveryDestinationResult[];
149
+ exportStatus: VoiceObservabilityExportStatus;
150
+ status: VoiceObservabilityExportStatus;
151
+ summary: {
152
+ delivered: number;
153
+ failed: number;
154
+ total: number;
155
+ };
156
+ };
157
+ export type VoiceObservabilityExportDeliveryOptions = {
158
+ destinations: VoiceObservabilityExportDeliveryDestination[];
159
+ report: VoiceObservabilityExportReport;
160
+ runId?: string;
161
+ };
110
162
  export type VoiceObservabilityExportOptions = {
111
163
  artifacts?: VoiceObservabilityExportArtifact[];
112
164
  artifactIntegrity?: {
@@ -134,6 +186,8 @@ export type VoiceObservabilityExportRoutesOptions = VoiceObservabilityExportOpti
134
186
  headers?: HeadersInit;
135
187
  artifactDownloadPath?: false | string;
136
188
  artifactIndexPath?: false | string;
189
+ deliveryDestinations?: VoiceObservabilityExportDeliveryDestination[];
190
+ deliveryPath?: false | string;
137
191
  htmlPath?: false | string;
138
192
  markdownPath?: false | string;
139
193
  name?: string;
@@ -146,6 +200,7 @@ export declare const renderVoiceObservabilityExportMarkdown: (report: VoiceObser
146
200
  title?: string;
147
201
  }) => string;
148
202
  export declare const buildVoiceObservabilityArtifactIndex: (report: VoiceObservabilityExportReport) => VoiceObservabilityExportArtifactIndex;
203
+ export declare const deliverVoiceObservabilityExport: (options: VoiceObservabilityExportDeliveryOptions) => Promise<VoiceObservabilityExportDeliveryReport>;
149
204
  export declare const createVoiceObservabilityExportRoutes: (options?: VoiceObservabilityExportRoutesOptions) => Elysia<"", {
150
205
  decorator: {};
151
206
  store: {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.222",
3
+ "version": "0.0.22-beta.224",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",