@absolutejs/voice 0.0.22-beta.421 → 0.0.22-beta.423

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
@@ -34,6 +34,7 @@ export type VoiceAuditEventFilter = {
34
34
  beforeOrAt?: number;
35
35
  limit?: number;
36
36
  outcome?: VoiceAuditOutcome | VoiceAuditOutcome[];
37
+ readWindow?: 'recent';
37
38
  resourceId?: string;
38
39
  resourceType?: string;
39
40
  sessionId?: string;
package/dist/index.d.ts CHANGED
@@ -157,7 +157,7 @@ export type { VoiceMonitorDefinition, VoiceMonitorEvaluation, VoiceMonitorEvalua
157
157
  export type { VoiceReadinessProfileName, VoiceReadinessProfileOptions, VoiceReadinessProfileRecommendation, VoiceReadinessProfileRecommendationScore, VoiceReadinessProfileRoutesOptions } from './readinessProfiles';
158
158
  export type { VoiceProviderStackChoice, VoiceProviderStackCapabilities, VoiceProviderStackCapabilityGap, VoiceProviderStackCapabilityGapInput, VoiceProviderStackCapabilityGapReport, VoiceProviderContractCheck, VoiceProviderContractCheckStatus, VoiceProviderContractDefinition, VoiceProviderContractMatrixAssertionInput, VoiceProviderContractMatrixAssertionReport, VoiceProviderContractMatrixHandlerOptions, VoiceProviderContractMatrixHTMLHandlerOptions, VoiceProviderContractMatrixInput, VoiceProviderContractMatrixPresetOptions, VoiceProviderContractMatrixReport, VoiceProviderContractMatrixRoutesOptions, VoiceProviderContractMatrixRow, VoiceProviderStackAssertionInput, VoiceProviderStackAssertionReport, VoiceProviderStackInput, VoiceProviderStackKind, VoiceProviderStackRecommendation } from './providerStackRecommendations';
159
159
  export type { VoiceFailureReplayMediaStep, VoiceFailureReplayOptions, VoiceFailureReplayProviderStep, VoiceFailureReplayReport, VoiceFailureReplayStatus, VoiceFailureReplayTurn, VoiceOperationsRecord, VoiceOperationsRecordAgentHandoff, VoiceOperationsRecordAuditSummary, VoiceOperationsRecordGuardrailAssertionInput, VoiceOperationsRecordGuardrailAssertionReport, VoiceOperationsRecordGuardrailDecision, VoiceOperationsRecordGuardrailFinding, VoiceOperationsRecordGuardrailSummary, VoiceOperationsRecordIntegrationEventSummary, VoiceOperationsRecordOptions, VoiceOperationsRecordOutcome, VoiceOperationsRecordProviderDecision, VoiceOperationsRecordProviderDecisionRecoveryStatus, VoiceOperationsRecordProviderDecisionSummary, VoiceOperationsRecordProviderRecoveryAssertionInput, VoiceOperationsRecordProviderRecoveryAssertionReport, VoiceOperationsRecordReviewSummary, VoiceOperationsRecordRoutesOptions, VoiceOperationsRecordStatus, VoiceOperationsRecordTaskSummary, VoiceOperationsRecordTelephonyMediaEvent, VoiceOperationsRecordTelephonyMediaSummary, VoiceOperationsRecordTranscriptTurn, VoiceOperationsRecordTool } from './operationsRecord';
160
- export type { VoiceObservabilityExportArtifact, VoiceObservabilityExportArtifactChecksum, VoiceObservabilityExportArtifactFreshness, VoiceObservabilityExportArtifactIndex, VoiceObservabilityExportArtifactIndexItem, VoiceObservabilityExportArtifactKind, VoiceObservabilityExportDeliveryAssertionInput, VoiceObservabilityExportDeliveryAssertionReport, VoiceObservabilityExportDeliverySummary, VoiceObservabilityExportDeliveryDestination, VoiceObservabilityExportDeliveryDestinationResult, VoiceObservabilityExportDeliveryHistory, VoiceObservabilityExportDeliveryOptions, VoiceObservabilityExportDeliveryReceipt, VoiceObservabilityExportDeliveryReceiptStore, VoiceObservabilityExportDeliveryReport, VoiceObservabilityExportEnvelope, VoiceObservabilityExportIssue, VoiceObservabilityExportIssueCode, VoiceObservabilityExportOptions, VoiceObservabilityExportIngestedRecordKind, VoiceObservabilityExportRedactionSummary, VoiceObservabilityExportRecordValidationOptions, VoiceObservabilityExportReplayIssue, VoiceObservabilityExportReplayIssueCode, VoiceObservabilityExportReplayAssertionInput, VoiceObservabilityExportReplayAssertionReport, VoiceObservabilityExportReplayRecords, VoiceObservabilityExportReplayReport, VoiceObservabilityExportReplayRoutesOptions, VoiceObservabilityExportReplaySource, VoiceObservabilityExportReport, VoiceObservabilityExportRoutesOptions, VoiceObservabilityExportSchema, VoiceObservabilityExportStatus, VoiceObservabilityExportValidationIssue, VoiceObservabilityExportValidationResult } from './observabilityExport';
160
+ export type { VoiceObservabilityExportArtifact, VoiceObservabilityExportArtifactChecksum, VoiceObservabilityExportArtifactFreshness, VoiceObservabilityExportArtifactIndex, VoiceObservabilityExportArtifactIndexItem, VoiceObservabilityExportArtifactKind, VoiceObservabilityExportDeliveryAssertionInput, VoiceObservabilityExportDeliveryAssertionReport, VoiceObservabilityExportDeliverySummary, VoiceObservabilityExportDeliveryDestination, VoiceObservabilityExportDeliveryDestinationResult, VoiceObservabilityExportDeliveryHistory, VoiceObservabilityExportDeliveryOptions, VoiceObservabilityExportDeliveryReceipt, VoiceObservabilityExportDeliveryReceiptStore, VoiceObservabilityExportDeliveryReport, VoiceObservabilityExportEnvelope, VoiceObservabilityExportIssue, VoiceObservabilityExportIssueCode, VoiceObservabilityExportOptions, VoiceObservabilityExportIngestedRecordKind, VoiceObservabilityExportRedactionSummary, VoiceObservabilityExportRecordValidationOptions, VoiceObservabilityExportReplayIssue, VoiceObservabilityExportReplayIssueCode, VoiceObservabilityExportReplayAssertionInput, VoiceObservabilityExportReplayAssertionReport, VoiceObservabilityExportReplayRecords, VoiceObservabilityExportReplayReport, VoiceObservabilityExportReplayRoutesOptions, VoiceObservabilityExportReplaySource, VoiceObservabilityExportReport, VoiceObservabilityExportRoutesOptions, VoiceObservabilityExportSchema, VoiceObservabilityExportStatus, VoiceObservabilityExportTiming, VoiceObservabilityExportValidationIssue, VoiceObservabilityExportValidationResult } from './observabilityExport';
161
161
  export type { VoiceOpsRecoveryFailedSession, VoiceOpsRecoveryInterventionSummary, VoiceOpsRecoveryIssue, VoiceOpsRecoveryIssueCode, VoiceOpsRecoveryLinks, VoiceOpsRecoveryProviderSummary, VoiceOpsRecoveryReport, VoiceOpsRecoveryReportOptions, VoiceOpsRecoveryRoutesOptions, VoiceOpsRecoveryStatus } from './opsRecovery';
162
162
  export type { StoredVoiceIncidentBundleArtifact, VoiceIncidentBundle, VoiceIncidentBundleArtifactOptions, VoiceIncidentBundleFormat, VoiceIncidentBundleOptions, VoiceIncidentBundleRetentionOptions, VoiceIncidentBundleRetentionReport, VoiceIncidentBundleRoutesOptions, VoiceIncidentBundleStore, VoiceIncidentBundleStoreFilter, VoiceIncidentBundleSummary } from './incidentBundle';
163
163
  export type { VoiceQualityLink, VoiceQualityMetric, VoiceQualityReport, VoiceQualityRoutesOptions, VoiceQualityStatus, VoiceQualityThresholds } from './qualityRoutes';
package/dist/index.js CHANGED
@@ -28724,7 +28724,15 @@ var createVoicePhoneAgent = (options) => {
28724
28724
  };
28725
28725
  };
28726
28726
  // src/fileStore.ts
28727
- import { mkdir as mkdir3, readFile, readdir, rename, rm, writeFile } from "fs/promises";
28727
+ import {
28728
+ mkdir as mkdir3,
28729
+ readFile,
28730
+ readdir,
28731
+ rename,
28732
+ rm,
28733
+ stat,
28734
+ writeFile
28735
+ } from "fs/promises";
28728
28736
  import { join as join2 } from "path";
28729
28737
  var listJsonFiles = async (directory) => {
28730
28738
  try {
@@ -28739,6 +28747,31 @@ var listJsonFiles = async (directory) => {
28739
28747
  throw error;
28740
28748
  }
28741
28749
  };
28750
+ var listRecentJsonFiles = async (directory, limit) => {
28751
+ if (limit === 0) {
28752
+ return [];
28753
+ }
28754
+ const files = await listJsonFiles(directory);
28755
+ const candidates = await Promise.all(files.map(async (path) => {
28756
+ try {
28757
+ return {
28758
+ path,
28759
+ updatedAt: (await stat(path)).mtimeMs
28760
+ };
28761
+ } catch (error) {
28762
+ if (error.code === "ENOENT") {
28763
+ return;
28764
+ }
28765
+ throw error;
28766
+ }
28767
+ }));
28768
+ return candidates.filter((candidate) => Boolean(candidate)).sort((left, right) => right.updatedAt - left.updatedAt).slice(0, limit).map((candidate) => candidate.path);
28769
+ };
28770
+ var shouldUseRecentReadWindow = (filter) => filter.readWindow === "recent" && typeof filter.limit === "number" && filter.limit >= 0;
28771
+ var omitReadWindow = (filter) => {
28772
+ const { readWindow: _readWindow, ...next } = filter;
28773
+ return next;
28774
+ };
28742
28775
  var encodeStoreId = (id) => `${encodeURIComponent(id)}.json`;
28743
28776
  var resolveFilePath = (directory, id) => join2(directory, encodeStoreId(id));
28744
28777
  var createMemoryStoreId = (input) => `${input.assistantId}:${input.namespace}:${input.key}`;
@@ -28947,9 +28980,9 @@ var createVoiceFileTraceEventStore = (options) => {
28947
28980
  }
28948
28981
  };
28949
28982
  const list = async (filter = {}) => {
28950
- const files = await listJsonFiles(options.directory);
28983
+ const files = shouldUseRecentReadWindow(filter) ? await listRecentJsonFiles(options.directory, filter.limit) : await listJsonFiles(options.directory);
28951
28984
  const events = await Promise.all(files.map((file) => readJsonFile(file)));
28952
- return filterVoiceTraceEvents(events, filter);
28985
+ return filterVoiceTraceEvents(events, omitReadWindow(filter));
28953
28986
  };
28954
28987
  const remove = async (id) => {
28955
28988
  await rm(resolveFilePath(options.directory, id), {
@@ -29006,9 +29039,10 @@ var createVoiceFileAuditEventStore = (options) => {
29006
29039
  return stored;
29007
29040
  };
29008
29041
  const list = async (filter) => {
29009
- const files = await listJsonFiles(options.directory);
29042
+ const resolvedFilter = filter ?? {};
29043
+ const files = shouldUseRecentReadWindow(resolvedFilter) ? await listRecentJsonFiles(options.directory, resolvedFilter.limit) : await listJsonFiles(options.directory);
29010
29044
  const events = await Promise.all(files.map((file) => readJsonFile(file)));
29011
- return filterVoiceAuditEvents(events, filter);
29045
+ return filterVoiceAuditEvents(events, omitReadWindow(resolvedFilter));
29012
29046
  };
29013
29047
  return { append, get, list };
29014
29048
  };
@@ -32162,7 +32196,7 @@ var createVoiceOpsRecoveryRoutes = (options = {}) => {
32162
32196
  import { Elysia as Elysia55 } from "elysia";
32163
32197
  import { Database as Database4 } from "bun:sqlite";
32164
32198
  import { createHash } from "crypto";
32165
- import { mkdir as mkdir4, readFile as readFile2, stat, unlink } from "fs/promises";
32199
+ import { mkdir as mkdir4, readFile as readFile2, stat as stat2, unlink } from "fs/promises";
32166
32200
  import { join as join3 } from "path";
32167
32201
  var voiceObservabilityExportSchemaVersion = "1.0.0";
32168
32202
  var voiceObservabilityExportSchemaId = "com.absolutejs.voice.observability-export";
@@ -33097,7 +33131,7 @@ var verifyArtifact = async (artifact, options) => {
33097
33131
  }
33098
33132
  const filePath = stripArtifactPathAnchor(artifact.path);
33099
33133
  try {
33100
- const file = await stat(filePath);
33134
+ const file = await stat2(filePath);
33101
33135
  const generatedAt = artifact.generatedAt ?? file.mtimeMs;
33102
33136
  const generatedAtMs = toEpochMs(generatedAt);
33103
33137
  const ageMs = generatedAtMs === undefined ? undefined : now - generatedAtMs;
@@ -33248,60 +33282,78 @@ var buildAuditEnvelope = (event, operationsRecordHref) => ({
33248
33282
  });
33249
33283
  var resolveObservabilityExportList = async (value) => typeof value === "function" ? await value() : value ?? [];
33250
33284
  var buildVoiceObservabilityExport = async (options = {}) => {
33251
- const events = options.events ?? await options.store?.list() ?? [];
33252
- const auditEvents = options.audit ? await options.audit.list() : [];
33285
+ const time = async (label, run) => {
33286
+ const startedAt = Date.now();
33287
+ try {
33288
+ return await run();
33289
+ } finally {
33290
+ const endedAt = Date.now();
33291
+ options.onTiming?.({
33292
+ durationMs: Math.max(0, endedAt - startedAt),
33293
+ endedAt,
33294
+ label,
33295
+ startedAt
33296
+ });
33297
+ }
33298
+ };
33299
+ const events = await time("events", async () => options.events ?? await options.store?.list() ?? []);
33300
+ const auditEvents = await time("auditEvents", async () => options.audit ? await options.audit.list() : []);
33253
33301
  const baseOperationsRecords = options.operationsRecords ?? [];
33254
- const [sessionSnapshots, callDebuggerReports] = await Promise.all([
33302
+ const [sessionSnapshots, callDebuggerReports] = await time("supportArtifacts", () => Promise.all([
33255
33303
  resolveObservabilityExportList(options.sessionSnapshots),
33256
33304
  resolveObservabilityExportList(options.callDebuggerReports)
33257
- ]);
33258
- const sessionIds = collectSessionIds({
33305
+ ]));
33306
+ const sessionIds = await time("sessionIds", () => collectSessionIds({
33259
33307
  auditEvents,
33260
33308
  callDebuggerReports,
33261
33309
  events,
33262
33310
  operationsRecords: baseOperationsRecords,
33263
33311
  sessionIds: options.sessionIds,
33264
33312
  sessionSnapshots
33265
- });
33313
+ }));
33266
33314
  const shouldBuildOperationsRecords = options.includeOperationsRecords === true && options.store;
33267
- const builtOperationsRecords = shouldBuildOperationsRecords ? await Promise.all(sessionIds.map((sessionId) => buildVoiceOperationsRecord({
33315
+ const builtOperationsRecords = await time("operationsRecords", () => shouldBuildOperationsRecords ? Promise.all(sessionIds.map((sessionId) => buildVoiceOperationsRecord({
33268
33316
  audit: options.audit,
33269
33317
  redact: options.redact,
33270
33318
  sessionId,
33271
33319
  store: options.store
33272
- }))) : [];
33320
+ }))) : []);
33273
33321
  const operationsRecords = [
33274
33322
  ...baseOperationsRecords,
33275
33323
  ...builtOperationsRecords.filter((record) => !baseOperationsRecords.some((existing) => existing.sessionId === record.sessionId))
33276
33324
  ];
33277
- const traceDeliveries = options.traceDeliveries ? isDeliveryStore(options.traceDeliveries) ? await options.traceDeliveries.list() : options.traceDeliveries : undefined;
33278
- const auditDeliveries = options.auditDeliveries ? isDeliveryStore(options.auditDeliveries) ? await options.auditDeliveries.list() : options.auditDeliveries : undefined;
33279
- const traceDeliverySummary = traceDeliveries ? await summarizeVoiceTraceSinkDeliveries(traceDeliveries) : undefined;
33280
- const auditDeliverySummary = auditDeliveries ? await summarizeVoiceAuditSinkDeliveries(auditDeliveries) : undefined;
33281
- const operationArtifacts = operationsRecords.map((record) => createOperationArtifact(record, options.links?.operationsRecord?.(record.sessionId)));
33282
- const sessionSnapshotArtifacts = sessionSnapshots.map((snapshot) => createSessionSnapshotArtifact(snapshot, options.links?.sessionSnapshot?.(snapshot.sessionId)));
33283
- const callDebuggerArtifacts = callDebuggerReports.map((report) => createCallDebuggerArtifact(report, options.links?.callDebugger?.(report.sessionId)));
33284
- const artifacts = addArtifactDownloadHrefs(await verifyArtifacts([
33325
+ const [traceDeliveries, auditDeliveries] = await time("deliveries", () => Promise.all([
33326
+ options.traceDeliveries ? isDeliveryStore(options.traceDeliveries) ? options.traceDeliveries.list() : options.traceDeliveries : undefined,
33327
+ options.auditDeliveries ? isDeliveryStore(options.auditDeliveries) ? options.auditDeliveries.list() : options.auditDeliveries : undefined
33328
+ ]));
33329
+ const [traceDeliverySummary, auditDeliverySummary] = await time("deliverySummaries", () => Promise.all([
33330
+ traceDeliveries ? summarizeVoiceTraceSinkDeliveries(traceDeliveries) : undefined,
33331
+ auditDeliveries ? summarizeVoiceAuditSinkDeliveries(auditDeliveries) : undefined
33332
+ ]));
33333
+ const operationArtifacts = await time("operationArtifacts", () => operationsRecords.map((record) => createOperationArtifact(record, options.links?.operationsRecord?.(record.sessionId))));
33334
+ const sessionSnapshotArtifacts = await time("sessionSnapshotArtifacts", () => sessionSnapshots.map((snapshot) => createSessionSnapshotArtifact(snapshot, options.links?.sessionSnapshot?.(snapshot.sessionId))));
33335
+ const callDebuggerArtifacts = await time("callDebuggerArtifacts", () => callDebuggerReports.map((report) => createCallDebuggerArtifact(report, options.links?.callDebugger?.(report.sessionId))));
33336
+ const artifacts = await time("artifacts", async () => addArtifactDownloadHrefs(await verifyArtifacts([
33285
33337
  ...operationArtifacts,
33286
33338
  ...sessionSnapshotArtifacts,
33287
33339
  ...callDebuggerArtifacts,
33288
33340
  ...options.artifacts ?? []
33289
- ], options.artifactIntegrity), options.links);
33341
+ ], options.artifactIntegrity), options.links));
33290
33342
  const operationHrefBySessionId = new Map(sessionIds.map((sessionId) => [
33291
33343
  sessionId,
33292
33344
  options.links?.operationsRecord?.(sessionId)
33293
33345
  ]));
33294
- const envelopes = [
33346
+ const envelopes = await time("envelopes", () => [
33295
33347
  ...events.map((event) => buildTraceEnvelope(event, operationHrefBySessionId.get(event.sessionId))),
33296
33348
  ...auditEvents.map((event) => buildAuditEnvelope(event, event.sessionId ? operationHrefBySessionId.get(event.sessionId) : undefined))
33297
- ].sort((left, right) => left.at - right.at);
33298
- const issues = collectIssues({
33349
+ ].sort((left, right) => left.at - right.at));
33350
+ const issues = await time("issues", () => collectIssues({
33299
33351
  artifacts,
33300
33352
  auditDeliveries: auditDeliverySummary,
33301
33353
  operationsRecords,
33302
33354
  totalEvidence: events.length + auditEvents.length + operationsRecords.length + artifacts.length,
33303
33355
  traceDeliveries: traceDeliverySummary
33304
- });
33356
+ }));
33305
33357
  const status = issues.some((issue) => issue.severity === "fail") ? "fail" : issues.some((issue) => issue.severity === "warn") ? "warn" : "pass";
33306
33358
  return {
33307
33359
  artifacts,
@@ -390,12 +390,19 @@ export type VoiceObservabilityExportOptions = {
390
390
  };
391
391
  callDebuggerReports?: VoiceCallDebuggerReport[] | (() => VoiceCallDebuggerReport[] | Promise<VoiceCallDebuggerReport[]>);
392
392
  operationsRecords?: VoiceOperationsRecord[];
393
+ onTiming?: (timing: VoiceObservabilityExportTiming) => void;
393
394
  redact?: VoiceTraceRedactionConfig;
394
395
  sessionIds?: string[];
395
396
  sessionSnapshots?: VoiceSessionSnapshot[] | (() => VoiceSessionSnapshot[] | Promise<VoiceSessionSnapshot[]>);
396
397
  store?: VoiceTraceEventStore;
397
398
  traceDeliveries?: VoiceTraceSinkDeliveryRecord[] | VoiceTraceSinkDeliveryStore;
398
399
  };
400
+ export type VoiceObservabilityExportTiming = {
401
+ durationMs: number;
402
+ endedAt: number;
403
+ label: string;
404
+ startedAt: number;
405
+ };
399
406
  export type VoiceObservabilityExportRoutesOptions = VoiceObservabilityExportOptions & {
400
407
  headers?: HeadersInit;
401
408
  artifactDownloadPath?: false | string;
package/dist/trace.d.ts CHANGED
@@ -16,6 +16,7 @@ export type StoredVoiceTraceEvent<TPayload extends Record<string, unknown> = Rec
16
16
  };
17
17
  export type VoiceTraceEventFilter = {
18
18
  limit?: number;
19
+ readWindow?: 'recent';
19
20
  scenarioId?: string;
20
21
  sessionId?: string;
21
22
  traceId?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.421",
3
+ "version": "0.0.22-beta.423",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",