@absolutejs/voice 0.0.22-beta.436 → 0.0.22-beta.437
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/incidentBundle.d.ts +3 -0
- package/dist/index.js +75 -2
- package/dist/observabilityExport.d.ts +6 -2
- package/package.json +1 -1
package/dist/incidentBundle.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
2
|
import { type VoiceOperationsRecord, type VoiceOperationsRecordOptions } from './operationsRecord';
|
|
3
|
+
import type { VoiceIncidentRecoveryOutcomeReport } from './incidentTimeline';
|
|
3
4
|
import { type VoiceTraceRedactionConfig } from './trace';
|
|
4
5
|
export type VoiceIncidentBundleFormat = 'json' | 'markdown';
|
|
5
6
|
export type VoiceIncidentBundle = {
|
|
@@ -8,6 +9,7 @@ export type VoiceIncidentBundle = {
|
|
|
8
9
|
formatVersion: 1;
|
|
9
10
|
markdown: string;
|
|
10
11
|
record: VoiceOperationsRecord;
|
|
12
|
+
recoveryOutcomes?: VoiceIncidentRecoveryOutcomeReport;
|
|
11
13
|
redacted: boolean;
|
|
12
14
|
sessionId: string;
|
|
13
15
|
summary: VoiceIncidentBundleSummary;
|
|
@@ -46,6 +48,7 @@ export type VoiceIncidentBundleSummary = {
|
|
|
46
48
|
};
|
|
47
49
|
export type VoiceIncidentBundleOptions = VoiceOperationsRecordOptions & {
|
|
48
50
|
redact?: VoiceTraceRedactionConfig;
|
|
51
|
+
recoveryOutcomes?: VoiceIncidentRecoveryOutcomeReport;
|
|
49
52
|
title?: string;
|
|
50
53
|
};
|
|
51
54
|
export type VoiceIncidentBundleRoutesOptions = Omit<VoiceIncidentBundleOptions, 'sessionId'> & {
|
package/dist/index.js
CHANGED
|
@@ -26759,6 +26759,41 @@ var createCallDebuggerArtifact = (report, href) => ({
|
|
|
26759
26759
|
sessionId: report.sessionId,
|
|
26760
26760
|
status: "pass"
|
|
26761
26761
|
});
|
|
26762
|
+
var createIncidentBundleArtifact = (bundle) => ({
|
|
26763
|
+
generatedAt: bundle.exportedAt,
|
|
26764
|
+
id: `incident-bundle:${bundle.sessionId}`,
|
|
26765
|
+
kind: "incident",
|
|
26766
|
+
label: `Incident bundle ${bundle.sessionId}`,
|
|
26767
|
+
metadata: {
|
|
26768
|
+
errors: bundle.summary.errors,
|
|
26769
|
+
recoveryOutcomes: bundle.recoveryOutcomes ? {
|
|
26770
|
+
failed: bundle.recoveryOutcomes.failed,
|
|
26771
|
+
improved: bundle.recoveryOutcomes.improved,
|
|
26772
|
+
regressed: bundle.recoveryOutcomes.regressed,
|
|
26773
|
+
total: bundle.recoveryOutcomes.total,
|
|
26774
|
+
unchanged: bundle.recoveryOutcomes.unchanged
|
|
26775
|
+
} : undefined,
|
|
26776
|
+
status: bundle.summary.status
|
|
26777
|
+
},
|
|
26778
|
+
required: true,
|
|
26779
|
+
sessionId: bundle.sessionId,
|
|
26780
|
+
status: bundle.summary.status === "failed" ? "fail" : bundle.summary.status === "warning" ? "warn" : "pass"
|
|
26781
|
+
});
|
|
26782
|
+
var createIncidentRecoveryOutcomeArtifact = (report) => ({
|
|
26783
|
+
generatedAt: report.checkedAt,
|
|
26784
|
+
id: `incident-recovery-outcomes:${report.checkedAt}`,
|
|
26785
|
+
kind: "incident-recovery-outcomes",
|
|
26786
|
+
label: "Incident recovery outcomes",
|
|
26787
|
+
metadata: {
|
|
26788
|
+
failed: report.failed,
|
|
26789
|
+
improved: report.improved,
|
|
26790
|
+
regressed: report.regressed,
|
|
26791
|
+
total: report.total,
|
|
26792
|
+
unchanged: report.unchanged
|
|
26793
|
+
},
|
|
26794
|
+
required: true,
|
|
26795
|
+
status: report.failed > 0 || report.regressed > 0 ? "fail" : report.unchanged > 0 ? "warn" : "pass"
|
|
26796
|
+
});
|
|
26762
26797
|
var unique2 = (values) => [...new Set(values)].sort();
|
|
26763
26798
|
var stripArtifactPathAnchor = (path) => path.split("#")[0] ?? path;
|
|
26764
26799
|
var toEpochMs = (value) => {
|
|
@@ -27419,6 +27454,7 @@ var collectSessionIds = (input) => unique2([
|
|
|
27419
27454
|
...input.events.map((event) => event.sessionId),
|
|
27420
27455
|
...input.auditEvents.map((event) => event.sessionId).filter((sessionId) => Boolean(sessionId)),
|
|
27421
27456
|
...input.operationsRecords.map((record) => record.sessionId),
|
|
27457
|
+
...input.incidentBundles.map((bundle) => bundle.sessionId),
|
|
27422
27458
|
...input.sessionSnapshots.map((snapshot) => snapshot.sessionId),
|
|
27423
27459
|
...input.callDebuggerReports.map((report) => report.sessionId)
|
|
27424
27460
|
]);
|
|
@@ -27443,6 +27479,15 @@ var collectIssues = (input) => {
|
|
|
27443
27479
|
});
|
|
27444
27480
|
}
|
|
27445
27481
|
for (const artifact of input.artifacts) {
|
|
27482
|
+
if (artifact.required && (artifact.status === "fail" || artifact.status === "warn")) {
|
|
27483
|
+
issues.push({
|
|
27484
|
+
code: "voice.observability.artifact_failed",
|
|
27485
|
+
detail: `${artifact.label} reported ${artifact.status}.`,
|
|
27486
|
+
label: "Artifact status",
|
|
27487
|
+
severity: artifact.status,
|
|
27488
|
+
value: artifact.id
|
|
27489
|
+
});
|
|
27490
|
+
}
|
|
27446
27491
|
if (artifact.path && artifact.status !== "pass" && artifact.required && artifact.bytes === undefined && artifact.freshness?.ageMs === undefined) {
|
|
27447
27492
|
issues.push({
|
|
27448
27493
|
code: "voice.observability.artifact_missing",
|
|
@@ -27541,14 +27586,22 @@ var buildVoiceObservabilityExport = async (options = {}) => {
|
|
|
27541
27586
|
const events = await time("events", async () => options.events ?? await options.store?.list() ?? []);
|
|
27542
27587
|
const auditEvents = await time("auditEvents", async () => options.audit ? await options.audit.list() : []);
|
|
27543
27588
|
const baseOperationsRecords = options.operationsRecords ?? [];
|
|
27544
|
-
const [
|
|
27589
|
+
const [
|
|
27590
|
+
sessionSnapshots,
|
|
27591
|
+
callDebuggerReports,
|
|
27592
|
+
incidentBundles,
|
|
27593
|
+
incidentRecoveryOutcomeReports
|
|
27594
|
+
] = await time("supportArtifacts", () => Promise.all([
|
|
27545
27595
|
resolveObservabilityExportList(options.sessionSnapshots),
|
|
27546
|
-
resolveObservabilityExportList(options.callDebuggerReports)
|
|
27596
|
+
resolveObservabilityExportList(options.callDebuggerReports),
|
|
27597
|
+
resolveObservabilityExportList(options.incidentBundles),
|
|
27598
|
+
resolveObservabilityExportList(options.incidentRecoveryOutcomeReports)
|
|
27547
27599
|
]));
|
|
27548
27600
|
const sessionIds = await time("sessionIds", () => collectSessionIds({
|
|
27549
27601
|
auditEvents,
|
|
27550
27602
|
callDebuggerReports,
|
|
27551
27603
|
events,
|
|
27604
|
+
incidentBundles,
|
|
27552
27605
|
operationsRecords: baseOperationsRecords,
|
|
27553
27606
|
sessionIds: options.sessionIds,
|
|
27554
27607
|
sessionSnapshots
|
|
@@ -27575,10 +27628,14 @@ var buildVoiceObservabilityExport = async (options = {}) => {
|
|
|
27575
27628
|
const operationArtifacts = await time("operationArtifacts", () => operationsRecords.map((record) => createOperationArtifact(record, options.links?.operationsRecord?.(record.sessionId))));
|
|
27576
27629
|
const sessionSnapshotArtifacts = await time("sessionSnapshotArtifacts", () => sessionSnapshots.map((snapshot) => createSessionSnapshotArtifact(snapshot, options.links?.sessionSnapshot?.(snapshot.sessionId))));
|
|
27577
27630
|
const callDebuggerArtifacts = await time("callDebuggerArtifacts", () => callDebuggerReports.map((report) => createCallDebuggerArtifact(report, options.links?.callDebugger?.(report.sessionId))));
|
|
27631
|
+
const incidentBundleArtifacts = await time("incidentBundleArtifacts", () => incidentBundles.map(createIncidentBundleArtifact));
|
|
27632
|
+
const incidentRecoveryOutcomeArtifacts = await time("incidentRecoveryOutcomeArtifacts", () => incidentRecoveryOutcomeReports.map(createIncidentRecoveryOutcomeArtifact));
|
|
27578
27633
|
const artifacts = await time("artifacts", async () => addArtifactDownloadHrefs(await verifyArtifacts([
|
|
27579
27634
|
...operationArtifacts,
|
|
27580
27635
|
...sessionSnapshotArtifacts,
|
|
27581
27636
|
...callDebuggerArtifacts,
|
|
27637
|
+
...incidentBundleArtifacts,
|
|
27638
|
+
...incidentRecoveryOutcomeArtifacts,
|
|
27582
27639
|
...options.artifacts ?? []
|
|
27583
27640
|
], options.artifactIntegrity), options.links));
|
|
27584
27641
|
const operationHrefBySessionId = new Map(sessionIds.map((sessionId) => [
|
|
@@ -37903,6 +37960,7 @@ var buildSummary = (record) => ({
|
|
|
37903
37960
|
turns: record.summary.turnCount
|
|
37904
37961
|
});
|
|
37905
37962
|
var renderIncidentMarkdown = (input) => {
|
|
37963
|
+
const recoveryOutcomes = input.recoveryOutcomes;
|
|
37906
37964
|
const lines = [
|
|
37907
37965
|
`# ${input.title ?? `Voice Incident ${input.summary.sessionId}`}`,
|
|
37908
37966
|
"",
|
|
@@ -37934,6 +37992,18 @@ var renderIncidentMarkdown = (input) => {
|
|
|
37934
37992
|
"",
|
|
37935
37993
|
...input.record.tools.length ? input.record.tools.map((tool) => `- ${tool.toolName ?? "tool"} ${tool.status ?? ""} ${tool.elapsedMs === undefined ? "" : `${tool.elapsedMs}ms`} ${tool.error ?? ""}`.trim()) : ["- none"],
|
|
37936
37994
|
"",
|
|
37995
|
+
"## Recovery Outcomes",
|
|
37996
|
+
"",
|
|
37997
|
+
...recoveryOutcomes ? [
|
|
37998
|
+
`- Improved: ${recoveryOutcomes.improved}`,
|
|
37999
|
+
`- Unchanged: ${recoveryOutcomes.unchanged}`,
|
|
38000
|
+
`- Regressed: ${recoveryOutcomes.regressed}`,
|
|
38001
|
+
`- Failed: ${recoveryOutcomes.failed}`,
|
|
38002
|
+
`- Total actions: ${recoveryOutcomes.total}`,
|
|
38003
|
+
"",
|
|
38004
|
+
...recoveryOutcomes.entries.length ? recoveryOutcomes.entries.map((entry) => `- ${entry.outcome}: ${entry.actionId} ${entry.beforeStatus ?? "unknown"} -> ${entry.afterStatus ?? "unknown"}${entry.detail ? ` - ${entry.detail}` : ""}`) : ["- no recovery actions recorded"]
|
|
38005
|
+
] : ["- no recovery outcome report attached"],
|
|
38006
|
+
"",
|
|
37937
38007
|
renderVoiceOperationsRecordGuardrailMarkdown(input.record),
|
|
37938
38008
|
"",
|
|
37939
38009
|
"## Trace Evidence",
|
|
@@ -37983,6 +38053,7 @@ var buildVoiceIncidentBundle = async (options) => {
|
|
|
37983
38053
|
traceEvents: redactedTraceEvents
|
|
37984
38054
|
});
|
|
37985
38055
|
const summary = buildSummary(redactedRecord);
|
|
38056
|
+
const recoveryOutcomes = options.recoveryOutcomes ? redactRecordValue(options.recoveryOutcomes, redactedTraceEvents, options.redact) : undefined;
|
|
37986
38057
|
const traceMarkdown = renderVoiceTraceMarkdown(record.traceEvents, {
|
|
37987
38058
|
evaluation: options.evaluation,
|
|
37988
38059
|
redact: options.redact,
|
|
@@ -37995,6 +38066,7 @@ var buildVoiceIncidentBundle = async (options) => {
|
|
|
37995
38066
|
const markdown = renderIncidentMarkdown({
|
|
37996
38067
|
auditMarkdown,
|
|
37997
38068
|
record: redactedRecord,
|
|
38069
|
+
recoveryOutcomes,
|
|
37998
38070
|
summary,
|
|
37999
38071
|
title: options.title,
|
|
38000
38072
|
traceMarkdown
|
|
@@ -38005,6 +38077,7 @@ var buildVoiceIncidentBundle = async (options) => {
|
|
|
38005
38077
|
formatVersion: 1,
|
|
38006
38078
|
markdown,
|
|
38007
38079
|
record: redactedRecord,
|
|
38080
|
+
recoveryOutcomes,
|
|
38008
38081
|
redacted: Boolean(options.redact),
|
|
38009
38082
|
sessionId: options.sessionId,
|
|
38010
38083
|
summary,
|
|
@@ -4,6 +4,8 @@ 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
6
|
import type { VoiceCallDebuggerReport } from './callDebugger';
|
|
7
|
+
import type { VoiceIncidentBundle } from './incidentBundle';
|
|
8
|
+
import type { VoiceIncidentRecoveryOutcomeReport } from './incidentTimeline';
|
|
7
9
|
import { type VoiceOperationsRecord } from './operationsRecord';
|
|
8
10
|
import type { VoiceSessionSnapshot } from './sessionSnapshot';
|
|
9
11
|
import { type VoiceTraceSinkDeliveryQueueSummary } from './queue';
|
|
@@ -43,7 +45,7 @@ export type VoiceObservabilityExportRecordValidationOptions = {
|
|
|
43
45
|
};
|
|
44
46
|
export declare const validateVoiceObservabilityExportRecord: (input: unknown, options?: VoiceObservabilityExportRecordValidationOptions) => VoiceObservabilityExportValidationResult;
|
|
45
47
|
export declare const assertVoiceObservabilityExportRecord: (input: unknown, options?: VoiceObservabilityExportRecordValidationOptions) => VoiceObservabilityExportValidationResult;
|
|
46
|
-
export type VoiceObservabilityExportArtifactKind = 'call-debugger' | 'incident' | 'markdown' | 'operations-record' | 'proof-pack' | 'readiness' | 'screenshot' | 'session-snapshot' | 'slo' | 'trace' | 'audit' | 'custom';
|
|
48
|
+
export type VoiceObservabilityExportArtifactKind = 'call-debugger' | 'incident' | 'incident-recovery-outcomes' | 'markdown' | 'operations-record' | 'proof-pack' | 'readiness' | 'screenshot' | 'session-snapshot' | 'slo' | 'trace' | 'audit' | 'custom';
|
|
47
49
|
export type VoiceObservabilityExportArtifactChecksum = {
|
|
48
50
|
algorithm: 'sha256';
|
|
49
51
|
value: string;
|
|
@@ -86,7 +88,7 @@ export type VoiceObservabilityExportEnvelope = {
|
|
|
86
88
|
severity: VoiceObservabilityExportStatus;
|
|
87
89
|
traceId?: string;
|
|
88
90
|
};
|
|
89
|
-
export type VoiceObservabilityExportIssueCode = 'voice.observability.no_evidence' | 'voice.observability.operation_failed' | 'voice.observability.artifact_missing' | 'voice.observability.artifact_stale' | 'voice.observability.audit_delivery_failed' | 'voice.observability.audit_delivery_pending' | 'voice.observability.trace_delivery_failed' | 'voice.observability.trace_delivery_pending';
|
|
91
|
+
export type VoiceObservabilityExportIssueCode = 'voice.observability.no_evidence' | 'voice.observability.operation_failed' | 'voice.observability.artifact_failed' | 'voice.observability.artifact_missing' | 'voice.observability.artifact_stale' | 'voice.observability.audit_delivery_failed' | 'voice.observability.audit_delivery_pending' | 'voice.observability.trace_delivery_failed' | 'voice.observability.trace_delivery_pending';
|
|
90
92
|
export type VoiceObservabilityExportIssue = {
|
|
91
93
|
code: VoiceObservabilityExportIssueCode;
|
|
92
94
|
detail?: string;
|
|
@@ -389,6 +391,8 @@ export type VoiceObservabilityExportOptions = {
|
|
|
389
391
|
sessionSnapshot?: (sessionId: string) => string;
|
|
390
392
|
};
|
|
391
393
|
callDebuggerReports?: VoiceCallDebuggerReport[] | (() => VoiceCallDebuggerReport[] | Promise<VoiceCallDebuggerReport[]>);
|
|
394
|
+
incidentBundles?: VoiceIncidentBundle[] | (() => VoiceIncidentBundle[] | Promise<VoiceIncidentBundle[]>);
|
|
395
|
+
incidentRecoveryOutcomeReports?: VoiceIncidentRecoveryOutcomeReport[] | (() => VoiceIncidentRecoveryOutcomeReport[] | Promise<VoiceIncidentRecoveryOutcomeReport[]>);
|
|
392
396
|
operationsRecords?: VoiceOperationsRecord[];
|
|
393
397
|
onTiming?: (timing: VoiceObservabilityExportTiming) => void;
|
|
394
398
|
redact?: VoiceTraceRedactionConfig;
|