@absolutejs/voice 0.0.22-beta.405 → 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 +129 -4
- package/dist/index.js +35 -3
- package/dist/observabilityExport.d.ts +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2193,6 +2193,124 @@ For custom elements:
|
|
|
2193
2193
|
</script>
|
|
2194
2194
|
```
|
|
2195
2195
|
|
|
2196
|
+
### Call Debugger Launch Widgets
|
|
2197
|
+
|
|
2198
|
+
Mount `createVoiceCallDebuggerRoutes(...)` on the server, then expose a small framework-native launcher anywhere operators or developers need the latest support artifact. The launcher opens the full debugger with session snapshot, operations record, failure replay, provider path, transcript, user-heard output, linked artifacts, and incident markdown.
|
|
2199
|
+
|
|
2200
|
+
React:
|
|
2201
|
+
|
|
2202
|
+
```tsx
|
|
2203
|
+
import { VoiceCallDebuggerLaunch } from '@absolutejs/voice/react';
|
|
2204
|
+
|
|
2205
|
+
export function DebugLatestCall() {
|
|
2206
|
+
return (
|
|
2207
|
+
<VoiceCallDebuggerLaunch
|
|
2208
|
+
description="Open snapshot, replay, provider path, transcript, and incident markdown."
|
|
2209
|
+
intervalMs={5000}
|
|
2210
|
+
path="/api/voice-call-debugger/latest"
|
|
2211
|
+
title="Debug Latest Call"
|
|
2212
|
+
/>
|
|
2213
|
+
);
|
|
2214
|
+
}
|
|
2215
|
+
```
|
|
2216
|
+
|
|
2217
|
+
Vue:
|
|
2218
|
+
|
|
2219
|
+
```vue
|
|
2220
|
+
<script setup lang="ts">
|
|
2221
|
+
import { VoiceCallDebuggerLaunch } from '@absolutejs/voice/vue';
|
|
2222
|
+
</script>
|
|
2223
|
+
|
|
2224
|
+
<template>
|
|
2225
|
+
<VoiceCallDebuggerLaunch
|
|
2226
|
+
description="Open snapshot, replay, provider path, transcript, and incident markdown."
|
|
2227
|
+
:interval-ms="5000"
|
|
2228
|
+
path="/api/voice-call-debugger/latest"
|
|
2229
|
+
title="Debug Latest Call"
|
|
2230
|
+
/>
|
|
2231
|
+
</template>
|
|
2232
|
+
```
|
|
2233
|
+
|
|
2234
|
+
Svelte:
|
|
2235
|
+
|
|
2236
|
+
```svelte
|
|
2237
|
+
<script lang="ts">
|
|
2238
|
+
import { onDestroy, onMount } from 'svelte';
|
|
2239
|
+
import { createVoiceCallDebugger } from '@absolutejs/voice/svelte';
|
|
2240
|
+
|
|
2241
|
+
const debuggerLaunch = createVoiceCallDebugger('/api/voice-call-debugger/latest', {
|
|
2242
|
+
description: 'Open snapshot, replay, provider path, transcript, and incident markdown.',
|
|
2243
|
+
intervalMs: 5000,
|
|
2244
|
+
title: 'Debug Latest Call'
|
|
2245
|
+
});
|
|
2246
|
+
let html = debuggerLaunch.getHTML();
|
|
2247
|
+
let unsubscribe = () => {};
|
|
2248
|
+
|
|
2249
|
+
onMount(() => {
|
|
2250
|
+
unsubscribe = debuggerLaunch.subscribe(() => {
|
|
2251
|
+
html = debuggerLaunch.getHTML();
|
|
2252
|
+
});
|
|
2253
|
+
void debuggerLaunch.refresh().catch(() => {});
|
|
2254
|
+
});
|
|
2255
|
+
onDestroy(() => {
|
|
2256
|
+
unsubscribe();
|
|
2257
|
+
debuggerLaunch.close();
|
|
2258
|
+
});
|
|
2259
|
+
</script>
|
|
2260
|
+
|
|
2261
|
+
{@html html}
|
|
2262
|
+
```
|
|
2263
|
+
|
|
2264
|
+
Angular:
|
|
2265
|
+
|
|
2266
|
+
```ts
|
|
2267
|
+
import { Component, computed, inject } from '@angular/core';
|
|
2268
|
+
import { createVoiceCallDebuggerLaunchViewModel } from '@absolutejs/voice/client';
|
|
2269
|
+
import { VoiceCallDebuggerService } from '@absolutejs/voice/angular';
|
|
2270
|
+
|
|
2271
|
+
@Component({
|
|
2272
|
+
selector: 'app-debug-latest-call',
|
|
2273
|
+
template: `
|
|
2274
|
+
<a [href]="model().href">{{ model().label }}</a>
|
|
2275
|
+
<p>{{ model().description }}</p>
|
|
2276
|
+
`
|
|
2277
|
+
})
|
|
2278
|
+
export class DebugLatestCallComponent {
|
|
2279
|
+
private readonly callDebugger = inject(VoiceCallDebuggerService).connect(
|
|
2280
|
+
'/api/voice-call-debugger/latest',
|
|
2281
|
+
{ intervalMs: 5000 }
|
|
2282
|
+
);
|
|
2283
|
+
readonly model = computed(() =>
|
|
2284
|
+
createVoiceCallDebuggerLaunchViewModel(
|
|
2285
|
+
'/api/voice-call-debugger/latest',
|
|
2286
|
+
{
|
|
2287
|
+
error: this.callDebugger.error(),
|
|
2288
|
+
isLoading: this.callDebugger.isLoading(),
|
|
2289
|
+
report: this.callDebugger.report(),
|
|
2290
|
+
updatedAt: this.callDebugger.updatedAt()
|
|
2291
|
+
},
|
|
2292
|
+
{ title: 'Debug Latest Call' }
|
|
2293
|
+
)
|
|
2294
|
+
);
|
|
2295
|
+
}
|
|
2296
|
+
```
|
|
2297
|
+
|
|
2298
|
+
HTML or HTMX:
|
|
2299
|
+
|
|
2300
|
+
```html
|
|
2301
|
+
<absolute-voice-call-debugger-launch
|
|
2302
|
+
interval-ms="5000"
|
|
2303
|
+
path="/api/voice-call-debugger/latest"
|
|
2304
|
+
title="Debug Latest Call"
|
|
2305
|
+
></absolute-voice-call-debugger-launch>
|
|
2306
|
+
|
|
2307
|
+
<script type="module">
|
|
2308
|
+
import { defineVoiceCallDebuggerLaunchElement } from '@absolutejs/voice/client';
|
|
2309
|
+
|
|
2310
|
+
defineVoiceCallDebuggerLaunchElement();
|
|
2311
|
+
</script>
|
|
2312
|
+
```
|
|
2313
|
+
|
|
2196
2314
|
## Delivery Runtime Widgets
|
|
2197
2315
|
|
|
2198
2316
|
After mounting `createVoiceDeliveryRuntimeRoutes(...)`, apps can expose audit and trace worker health through the same framework-native primitives:
|
|
@@ -3056,7 +3174,7 @@ Readiness emits the stable `voice.readiness.ops_recovery` gate code when unresol
|
|
|
3056
3174
|
|
|
3057
3175
|
## Customer-Owned Observability Export
|
|
3058
3176
|
|
|
3059
|
-
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.
|
|
3060
3178
|
|
|
3061
3179
|
Every export manifest and artifact index includes a stable schema contract:
|
|
3062
3180
|
|
|
@@ -3169,7 +3287,10 @@ app.use(
|
|
|
3169
3287
|
audit: runtimeStorage.audit,
|
|
3170
3288
|
auditDeliveries: runtimeStorage.auditDeliveries,
|
|
3171
3289
|
links: {
|
|
3172
|
-
|
|
3290
|
+
callDebugger: (sessionId) => `/voice-call-debugger/${sessionId}`,
|
|
3291
|
+
operationsRecord: (sessionId) => `/voice-operations/${sessionId}`,
|
|
3292
|
+
sessionSnapshot: (sessionId) =>
|
|
3293
|
+
`/api/voice/session-snapshot/${sessionId}`
|
|
3173
3294
|
},
|
|
3174
3295
|
redact: true,
|
|
3175
3296
|
store: runtimeStorage.traces,
|
|
@@ -3194,16 +3315,20 @@ const exportReport = await buildVoiceObservabilityExport({
|
|
|
3194
3315
|
},
|
|
3195
3316
|
audit: runtimeStorage.audit,
|
|
3196
3317
|
auditDeliveries: runtimeStorage.auditDeliveries,
|
|
3318
|
+
callDebuggerReports: [latestCallDebuggerReport],
|
|
3197
3319
|
links: {
|
|
3198
|
-
|
|
3320
|
+
callDebugger: (sessionId) => `/voice-call-debugger/${sessionId}`,
|
|
3321
|
+
operationsRecord: (sessionId) => `/voice-operations/${sessionId}`,
|
|
3322
|
+
sessionSnapshot: (sessionId) => `/api/voice/session-snapshot/${sessionId}`
|
|
3199
3323
|
},
|
|
3200
3324
|
redact: true,
|
|
3325
|
+
sessionSnapshots: [latestSessionSnapshot],
|
|
3201
3326
|
store: runtimeStorage.traces,
|
|
3202
3327
|
traceDeliveries: runtimeStorage.traceDeliveries
|
|
3203
3328
|
});
|
|
3204
3329
|
```
|
|
3205
3330
|
|
|
3206
|
-
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.
|
|
3207
3332
|
|
|
3208
3333
|
Pass the same report into production readiness when export health should block deploys:
|
|
3209
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
|
|
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
|
};
|