@absolutejs/voice 0.0.22-beta.465 → 0.0.22-beta.466
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/incidentTimeline.d.ts +1 -0
- package/dist/index.js +48 -4
- package/dist/operationsRecord.d.ts +16 -0
- package/dist/testing/index.js +41 -2
- package/package.json +1 -1
|
@@ -163,6 +163,7 @@ export type VoiceIncidentTimelineLinks = {
|
|
|
163
163
|
supportBundle?: string | ((sessionId: string) => string);
|
|
164
164
|
};
|
|
165
165
|
export type VoiceIncidentTimelineOptions = {
|
|
166
|
+
extraEvents?: VoiceIncidentTimelineValue<readonly VoiceIncidentTimelineEvent[]>;
|
|
166
167
|
failureReplays?: VoiceIncidentTimelineValue<readonly VoiceFailureReplayReport[]>;
|
|
167
168
|
links?: VoiceIncidentTimelineLinks;
|
|
168
169
|
limit?: number;
|
package/dist/index.js
CHANGED
|
@@ -19025,6 +19025,11 @@ import { Elysia as Elysia29 } from "elysia";
|
|
|
19025
19025
|
|
|
19026
19026
|
// src/operationsRecord.ts
|
|
19027
19027
|
import { Elysia as Elysia28 } from "elysia";
|
|
19028
|
+
import {
|
|
19029
|
+
summarizeMediaProcessorGraphReport as summarizeMediaProcessorGraphReport2,
|
|
19030
|
+
summarizeMediaQualityReport as summarizeMediaQualityReport2,
|
|
19031
|
+
summarizeMediaTransportReport as summarizeMediaTransportReport2
|
|
19032
|
+
} from "@absolutejs/media";
|
|
19028
19033
|
|
|
19029
19034
|
// src/sessionReplay.ts
|
|
19030
19035
|
import { Elysia as Elysia26 } from "elysia";
|
|
@@ -19685,6 +19690,29 @@ var toTelephonyMediaEvent = (event) => {
|
|
|
19685
19690
|
streamId
|
|
19686
19691
|
};
|
|
19687
19692
|
};
|
|
19693
|
+
var summarizeMediaPipelineForOperationsRecord = (report) => {
|
|
19694
|
+
const quality = summarizeMediaQualityReport2(report.quality);
|
|
19695
|
+
const transport = report.transport ? summarizeMediaTransportReport2(report.transport) : undefined;
|
|
19696
|
+
const processorGraph = report.processorGraph ? summarizeMediaProcessorGraphReport2(report.processorGraph) : undefined;
|
|
19697
|
+
const calibrationCodes = report.calibration.issues.map((issue) => issue.code);
|
|
19698
|
+
const interruptionCodes = report.interruption.issues.map((issue) => issue.code);
|
|
19699
|
+
const issueCodes = Array.from(new Set([
|
|
19700
|
+
...calibrationCodes,
|
|
19701
|
+
...quality.issueCodes,
|
|
19702
|
+
...interruptionCodes,
|
|
19703
|
+
...processorGraph?.issueCodes ?? []
|
|
19704
|
+
]));
|
|
19705
|
+
return {
|
|
19706
|
+
frames: report.frames,
|
|
19707
|
+
issueCodes,
|
|
19708
|
+
jitterMs: report.quality.jitterMs,
|
|
19709
|
+
processorGraphStatus: processorGraph?.status,
|
|
19710
|
+
qualityStatus: quality.status,
|
|
19711
|
+
status: report.status,
|
|
19712
|
+
surface: report.surface,
|
|
19713
|
+
transportStatus: transport?.status
|
|
19714
|
+
};
|
|
19715
|
+
};
|
|
19688
19716
|
var summarizeTelephonyMedia = (events) => {
|
|
19689
19717
|
const mediaEvents = events.map(toTelephonyMediaEvent).filter((event) => event !== undefined);
|
|
19690
19718
|
const eventNames = mediaEvents.map((event) => event.event.toLowerCase());
|
|
@@ -19851,6 +19879,7 @@ var buildVoiceOperationsRecord = async (options) => {
|
|
|
19851
19879
|
tasks,
|
|
19852
19880
|
total: tasks.length
|
|
19853
19881
|
} : undefined,
|
|
19882
|
+
mediaPipeline: options.mediaPipeline ? summarizeMediaPipelineForOperationsRecord(options.mediaPipeline) : undefined,
|
|
19854
19883
|
telephonyMedia: summarizeTelephonyMedia(traceEvents),
|
|
19855
19884
|
timeline: timelineSession?.events ?? [],
|
|
19856
19885
|
tools: traceEvents.filter((event) => event.type === "agent.tool").map(toTool),
|
|
@@ -20068,15 +20097,18 @@ var buildVoiceFailureReplay = (record, options = {}) => {
|
|
|
20068
20097
|
const recovery = step.status === "fallback" ? `recovered through ${step.fallbackProvider ?? step.selectedProvider ?? "fallback"}` : step.status === "degraded" ? `degraded to ${step.fallbackProvider ?? step.selectedProvider ?? "fallback"}` : "failed before recovery";
|
|
20069
20098
|
return `${provider} ${recovery}${step.reason ? `: ${step.reason}` : ""}`;
|
|
20070
20099
|
});
|
|
20100
|
+
const pipelineIssueCodes = record.mediaPipeline?.issueCodes ?? [];
|
|
20071
20101
|
const mediaIssues = [
|
|
20072
20102
|
...mediaSteps.map((step) => step.issue).filter((issue) => typeof issue === "string"),
|
|
20073
20103
|
record.telephonyMedia.total > 0 && record.telephonyMedia.inbound === 0 ? "Carrier stream has no inbound media evidence." : undefined,
|
|
20074
|
-
record.telephonyMedia.total > 0 && record.telephonyMedia.outbound === 0 ? "Carrier stream has no outbound assistant media/control evidence." : undefined
|
|
20104
|
+
record.telephonyMedia.total > 0 && record.telephonyMedia.outbound === 0 ? "Carrier stream has no outbound assistant media/control evidence." : undefined,
|
|
20105
|
+
...pipelineIssueCodes.map((code) => `Media pipeline issue: ${code}.`)
|
|
20075
20106
|
].filter((issue) => typeof issue === "string");
|
|
20076
20107
|
const userHeard = [
|
|
20077
20108
|
...new Set(record.transcript.flatMap((turn) => turn.assistantReplies))
|
|
20078
20109
|
];
|
|
20079
|
-
const
|
|
20110
|
+
const mediaPipelineStatus = record.mediaPipeline?.status;
|
|
20111
|
+
const status = record.providerDecisionSummary.errors > 0 || record.telephonyMedia.errors > 0 || mediaPipelineStatus === "fail" ? "failed" : record.providerDecisionSummary.degraded > 0 || mediaPipelineStatus === "warn" ? "degraded" : record.providerDecisionSummary.fallbacks > 0 || mediaIssues.length > 0 ? "recovered" : "healthy";
|
|
20080
20112
|
const turns = record.transcript.map((turn) => ({
|
|
20081
20113
|
...turn,
|
|
20082
20114
|
media: mediaSteps.filter((step) => record.traceEvents.some((event) => event.turnId === turn.id && event.type === "client.telephony_media" && event.at === step.at)),
|
|
@@ -20089,6 +20121,8 @@ var buildVoiceFailureReplay = (record, options = {}) => {
|
|
|
20089
20121
|
clears: record.telephonyMedia.clears,
|
|
20090
20122
|
errors: record.telephonyMedia.errors,
|
|
20091
20123
|
issues: mediaIssues,
|
|
20124
|
+
pipelineIssueCodes,
|
|
20125
|
+
pipelineStatus: record.mediaPipeline?.status,
|
|
20092
20126
|
steps: mediaSteps,
|
|
20093
20127
|
total: record.telephonyMedia.total
|
|
20094
20128
|
},
|
|
@@ -20145,6 +20179,8 @@ var renderVoiceFailureReplayMarkdown = (report) => {
|
|
|
20145
20179
|
}).join(`
|
|
20146
20180
|
`) : "- none recorded";
|
|
20147
20181
|
const issues = report.summary.issues.length ? report.summary.issues.map((issue) => `- ${issue}`).join(`
|
|
20182
|
+
`) : "- none";
|
|
20183
|
+
const pipelineCodes = report.media.pipelineIssueCodes.length ? report.media.pipelineIssueCodes.map((code) => `- ${code}`).join(`
|
|
20148
20184
|
`) : "- none";
|
|
20149
20185
|
return [
|
|
20150
20186
|
`# Voice Failure Replay: ${report.sessionId}`,
|
|
@@ -20162,6 +20198,9 @@ var renderVoiceFailureReplayMarkdown = (report) => {
|
|
|
20162
20198
|
"## Media Path",
|
|
20163
20199
|
mediaSteps,
|
|
20164
20200
|
"",
|
|
20201
|
+
`## Media Pipeline (status: ${report.media.pipelineStatus ?? "n/a"})`,
|
|
20202
|
+
pipelineCodes,
|
|
20203
|
+
"",
|
|
20165
20204
|
"## What The User Heard",
|
|
20166
20205
|
heard
|
|
20167
20206
|
].join(`
|
|
@@ -27675,13 +27714,15 @@ var buildVoiceIncidentTimelineReport = async (options) => {
|
|
|
27675
27714
|
opsRecovery,
|
|
27676
27715
|
monitorIssues,
|
|
27677
27716
|
operationsRecords,
|
|
27678
|
-
failureReplays
|
|
27717
|
+
failureReplays,
|
|
27718
|
+
extraEvents
|
|
27679
27719
|
] = await Promise.all([
|
|
27680
27720
|
resolveValue(options.operationalStatus),
|
|
27681
27721
|
resolveValue(options.opsRecovery),
|
|
27682
27722
|
resolveValue(options.monitorIssues),
|
|
27683
27723
|
resolveValue(options.operationsRecords),
|
|
27684
|
-
resolveValue(options.failureReplays)
|
|
27724
|
+
resolveValue(options.failureReplays),
|
|
27725
|
+
resolveValue(options.extraEvents)
|
|
27685
27726
|
]);
|
|
27686
27727
|
const events = [];
|
|
27687
27728
|
pushOperationalStatusEvents(events, operationalStatus, links);
|
|
@@ -27689,6 +27730,9 @@ var buildVoiceIncidentTimelineReport = async (options) => {
|
|
|
27689
27730
|
pushMonitorEvents(events, monitorIssues, links);
|
|
27690
27731
|
pushOperationsRecordEvents(events, operationsRecords, links);
|
|
27691
27732
|
pushFailureReplayEvents(events, failureReplays, links);
|
|
27733
|
+
if (extraEvents && extraEvents.length > 0) {
|
|
27734
|
+
events.push(...extraEvents);
|
|
27735
|
+
}
|
|
27692
27736
|
const filtered = events.filter((event) => withinWindow(event, now, options.windowMs)).sort((left, right) => right.at - left.at).slice(0, options.limit ?? 50);
|
|
27693
27737
|
const summary = {
|
|
27694
27738
|
critical: filtered.filter((event) => event.severity === "critical").length,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Elysia } from "elysia";
|
|
2
|
+
import { type MediaPipelineStatus } from "@absolutejs/media";
|
|
2
3
|
import { type StoredVoiceAuditEvent, type VoiceAuditEventStore } from "./audit";
|
|
4
|
+
import type { VoiceMediaPipelineReport } from "./mediaPipelineRoutes";
|
|
3
5
|
import type { StoredVoiceIntegrationEvent, StoredVoiceOpsTask, VoiceIntegrationEventStore, VoiceOpsTaskStore } from "./ops";
|
|
4
6
|
import { type VoiceSessionReplay } from "./sessionReplay";
|
|
5
7
|
import type { StoredVoiceCallReviewArtifact, VoiceCallReviewStore } from "./testing/review";
|
|
@@ -143,6 +145,16 @@ export type VoiceOperationsRecordTelephonyMediaSummary = {
|
|
|
143
145
|
streamIds: string[];
|
|
144
146
|
total: number;
|
|
145
147
|
};
|
|
148
|
+
export type VoiceOperationsRecordMediaPipelineSummary = {
|
|
149
|
+
frames: number;
|
|
150
|
+
issueCodes: readonly string[];
|
|
151
|
+
jitterMs?: number;
|
|
152
|
+
processorGraphStatus?: MediaPipelineStatus;
|
|
153
|
+
qualityStatus: MediaPipelineStatus;
|
|
154
|
+
status: MediaPipelineStatus;
|
|
155
|
+
surface: string;
|
|
156
|
+
transportStatus?: MediaPipelineStatus;
|
|
157
|
+
};
|
|
146
158
|
export type VoiceOperationsRecordGuardrailAssertionInput = {
|
|
147
159
|
minBlocked?: number;
|
|
148
160
|
minDecisions?: number;
|
|
@@ -201,6 +213,7 @@ export type VoiceOperationsRecord = {
|
|
|
201
213
|
guardrails: VoiceOperationsRecordGuardrailSummary;
|
|
202
214
|
handoffs: VoiceOperationsRecordAgentHandoff[];
|
|
203
215
|
integrationEvents?: VoiceOperationsRecordIntegrationEventSummary;
|
|
216
|
+
mediaPipeline?: VoiceOperationsRecordMediaPipelineSummary;
|
|
204
217
|
outcome: VoiceOperationsRecordOutcome;
|
|
205
218
|
providerDecisions: VoiceOperationsRecordProviderDecision[];
|
|
206
219
|
providerDecisionSummary: VoiceOperationsRecordProviderDecisionSummary;
|
|
@@ -257,6 +270,8 @@ export type VoiceFailureReplayReport = {
|
|
|
257
270
|
clears: number;
|
|
258
271
|
errors: number;
|
|
259
272
|
issues: string[];
|
|
273
|
+
pipelineIssueCodes: readonly string[];
|
|
274
|
+
pipelineStatus?: MediaPipelineStatus;
|
|
260
275
|
steps: VoiceFailureReplayMediaStep[];
|
|
261
276
|
total: number;
|
|
262
277
|
};
|
|
@@ -291,6 +306,7 @@ export type VoiceOperationsRecordOptions = {
|
|
|
291
306
|
evaluation?: VoiceTraceEvaluationOptions;
|
|
292
307
|
events?: StoredVoiceTraceEvent[];
|
|
293
308
|
integrationEvents?: VoiceIntegrationEventStore;
|
|
309
|
+
mediaPipeline?: VoiceMediaPipelineReport;
|
|
294
310
|
redact?: VoiceTraceRedactionConfig;
|
|
295
311
|
reviews?: VoiceCallReviewStore;
|
|
296
312
|
sessionId: string;
|
package/dist/testing/index.js
CHANGED
|
@@ -8376,6 +8376,11 @@ var runVoiceSessionBenchmarkSeries = async (input) => {
|
|
|
8376
8376
|
};
|
|
8377
8377
|
// src/operationsRecord.ts
|
|
8378
8378
|
import { Elysia as Elysia4 } from "elysia";
|
|
8379
|
+
import {
|
|
8380
|
+
summarizeMediaProcessorGraphReport,
|
|
8381
|
+
summarizeMediaQualityReport,
|
|
8382
|
+
summarizeMediaTransportReport
|
|
8383
|
+
} from "@absolutejs/media";
|
|
8379
8384
|
|
|
8380
8385
|
// src/audit.ts
|
|
8381
8386
|
var includes = (filter, value) => {
|
|
@@ -10379,6 +10384,29 @@ var toTelephonyMediaEvent = (event) => {
|
|
|
10379
10384
|
streamId
|
|
10380
10385
|
};
|
|
10381
10386
|
};
|
|
10387
|
+
var summarizeMediaPipelineForOperationsRecord = (report) => {
|
|
10388
|
+
const quality = summarizeMediaQualityReport(report.quality);
|
|
10389
|
+
const transport = report.transport ? summarizeMediaTransportReport(report.transport) : undefined;
|
|
10390
|
+
const processorGraph = report.processorGraph ? summarizeMediaProcessorGraphReport(report.processorGraph) : undefined;
|
|
10391
|
+
const calibrationCodes = report.calibration.issues.map((issue) => issue.code);
|
|
10392
|
+
const interruptionCodes = report.interruption.issues.map((issue) => issue.code);
|
|
10393
|
+
const issueCodes = Array.from(new Set([
|
|
10394
|
+
...calibrationCodes,
|
|
10395
|
+
...quality.issueCodes,
|
|
10396
|
+
...interruptionCodes,
|
|
10397
|
+
...processorGraph?.issueCodes ?? []
|
|
10398
|
+
]));
|
|
10399
|
+
return {
|
|
10400
|
+
frames: report.frames,
|
|
10401
|
+
issueCodes,
|
|
10402
|
+
jitterMs: report.quality.jitterMs,
|
|
10403
|
+
processorGraphStatus: processorGraph?.status,
|
|
10404
|
+
qualityStatus: quality.status,
|
|
10405
|
+
status: report.status,
|
|
10406
|
+
surface: report.surface,
|
|
10407
|
+
transportStatus: transport?.status
|
|
10408
|
+
};
|
|
10409
|
+
};
|
|
10382
10410
|
var summarizeTelephonyMedia = (events) => {
|
|
10383
10411
|
const mediaEvents = events.map(toTelephonyMediaEvent).filter((event) => event !== undefined);
|
|
10384
10412
|
const eventNames = mediaEvents.map((event) => event.event.toLowerCase());
|
|
@@ -10545,6 +10573,7 @@ var buildVoiceOperationsRecord = async (options) => {
|
|
|
10545
10573
|
tasks,
|
|
10546
10574
|
total: tasks.length
|
|
10547
10575
|
} : undefined,
|
|
10576
|
+
mediaPipeline: options.mediaPipeline ? summarizeMediaPipelineForOperationsRecord(options.mediaPipeline) : undefined,
|
|
10548
10577
|
telephonyMedia: summarizeTelephonyMedia(traceEvents),
|
|
10549
10578
|
timeline: timelineSession?.events ?? [],
|
|
10550
10579
|
tools: traceEvents.filter((event) => event.type === "agent.tool").map(toTool),
|
|
@@ -10762,15 +10791,18 @@ var buildVoiceFailureReplay = (record, options = {}) => {
|
|
|
10762
10791
|
const recovery = step.status === "fallback" ? `recovered through ${step.fallbackProvider ?? step.selectedProvider ?? "fallback"}` : step.status === "degraded" ? `degraded to ${step.fallbackProvider ?? step.selectedProvider ?? "fallback"}` : "failed before recovery";
|
|
10763
10792
|
return `${provider} ${recovery}${step.reason ? `: ${step.reason}` : ""}`;
|
|
10764
10793
|
});
|
|
10794
|
+
const pipelineIssueCodes = record.mediaPipeline?.issueCodes ?? [];
|
|
10765
10795
|
const mediaIssues = [
|
|
10766
10796
|
...mediaSteps.map((step) => step.issue).filter((issue) => typeof issue === "string"),
|
|
10767
10797
|
record.telephonyMedia.total > 0 && record.telephonyMedia.inbound === 0 ? "Carrier stream has no inbound media evidence." : undefined,
|
|
10768
|
-
record.telephonyMedia.total > 0 && record.telephonyMedia.outbound === 0 ? "Carrier stream has no outbound assistant media/control evidence." : undefined
|
|
10798
|
+
record.telephonyMedia.total > 0 && record.telephonyMedia.outbound === 0 ? "Carrier stream has no outbound assistant media/control evidence." : undefined,
|
|
10799
|
+
...pipelineIssueCodes.map((code) => `Media pipeline issue: ${code}.`)
|
|
10769
10800
|
].filter((issue) => typeof issue === "string");
|
|
10770
10801
|
const userHeard = [
|
|
10771
10802
|
...new Set(record.transcript.flatMap((turn) => turn.assistantReplies))
|
|
10772
10803
|
];
|
|
10773
|
-
const
|
|
10804
|
+
const mediaPipelineStatus = record.mediaPipeline?.status;
|
|
10805
|
+
const status = record.providerDecisionSummary.errors > 0 || record.telephonyMedia.errors > 0 || mediaPipelineStatus === "fail" ? "failed" : record.providerDecisionSummary.degraded > 0 || mediaPipelineStatus === "warn" ? "degraded" : record.providerDecisionSummary.fallbacks > 0 || mediaIssues.length > 0 ? "recovered" : "healthy";
|
|
10774
10806
|
const turns = record.transcript.map((turn) => ({
|
|
10775
10807
|
...turn,
|
|
10776
10808
|
media: mediaSteps.filter((step) => record.traceEvents.some((event) => event.turnId === turn.id && event.type === "client.telephony_media" && event.at === step.at)),
|
|
@@ -10783,6 +10815,8 @@ var buildVoiceFailureReplay = (record, options = {}) => {
|
|
|
10783
10815
|
clears: record.telephonyMedia.clears,
|
|
10784
10816
|
errors: record.telephonyMedia.errors,
|
|
10785
10817
|
issues: mediaIssues,
|
|
10818
|
+
pipelineIssueCodes,
|
|
10819
|
+
pipelineStatus: record.mediaPipeline?.status,
|
|
10786
10820
|
steps: mediaSteps,
|
|
10787
10821
|
total: record.telephonyMedia.total
|
|
10788
10822
|
},
|
|
@@ -10839,6 +10873,8 @@ var renderVoiceFailureReplayMarkdown = (report) => {
|
|
|
10839
10873
|
}).join(`
|
|
10840
10874
|
`) : "- none recorded";
|
|
10841
10875
|
const issues = report.summary.issues.length ? report.summary.issues.map((issue) => `- ${issue}`).join(`
|
|
10876
|
+
`) : "- none";
|
|
10877
|
+
const pipelineCodes = report.media.pipelineIssueCodes.length ? report.media.pipelineIssueCodes.map((code) => `- ${code}`).join(`
|
|
10842
10878
|
`) : "- none";
|
|
10843
10879
|
return [
|
|
10844
10880
|
`# Voice Failure Replay: ${report.sessionId}`,
|
|
@@ -10856,6 +10892,9 @@ var renderVoiceFailureReplayMarkdown = (report) => {
|
|
|
10856
10892
|
"## Media Path",
|
|
10857
10893
|
mediaSteps,
|
|
10858
10894
|
"",
|
|
10895
|
+
`## Media Pipeline (status: ${report.media.pipelineStatus ?? "n/a"})`,
|
|
10896
|
+
pipelineCodes,
|
|
10897
|
+
"",
|
|
10859
10898
|
"## What The User Heard",
|
|
10860
10899
|
heard
|
|
10861
10900
|
].join(`
|