@absolutejs/voice 0.0.22-beta.461 → 0.0.22-beta.464
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/angular/index.js +265 -0
- package/dist/client/htmxBootstrap.js +330 -7
- package/dist/client/index.js +322 -0
- package/dist/generated/htmxBootstrapBundle.d.ts +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.js +1231 -497
- package/dist/mediaPipelineRoutes.d.ts +55 -1
- package/dist/mediaPipelineSurfaces.d.ts +48 -0
- package/dist/productionReadiness.d.ts +17 -0
- package/dist/proofTrends.d.ts +25 -0
- package/dist/react/index.js +322 -0
- package/dist/sessionObservability.d.ts +41 -0
- package/dist/svelte/index.js +265 -0
- package/dist/testing/index.js +265 -0
- package/dist/vue/index.js +322 -0
- package/dist/vue/useVoiceReadinessFailures.d.ts +16 -0
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Elysia } from "elysia";
|
|
2
|
-
import { type MediaFrame, type MediaInterruptionReport, type MediaPipelineCalibrationInput, type MediaPipelineCalibrationReport, type MediaPipelineStatus, type MediaProcessorGraphReport, type MediaQualityReport, type MediaResamplingPlan, type MediaTransportReport, type MediaVadReport } from "@absolutejs/media";
|
|
2
|
+
import { type MediaFrame, type MediaInterruptionReport, type MediaPipelineCalibrationIssue, type MediaPipelineCalibrationInput, type MediaPipelineCalibrationReport, type MediaPipelineStatus, type MediaProcessorGraphReport, type MediaProcessorGraphSummary, type MediaQualityReport, type MediaQualitySummary, type MediaResamplingPlan, type MediaTransportReport, type MediaTransportSummary, type MediaVadReport } from "@absolutejs/media";
|
|
3
3
|
export type VoiceMediaPipelineReportOptions = MediaPipelineCalibrationInput & {
|
|
4
4
|
frames?: readonly MediaFrame[];
|
|
5
5
|
maxInterruptionLatencyMs?: number;
|
|
@@ -115,3 +115,57 @@ export declare const createVoiceMediaPipelineRoutes: (options?: VoiceMediaPipeli
|
|
|
115
115
|
standaloneSchema: {};
|
|
116
116
|
response: {};
|
|
117
117
|
}>;
|
|
118
|
+
export type VoiceMediaPipelineCalibrationSummary = {
|
|
119
|
+
assistantAudioFrames: number;
|
|
120
|
+
backpressureFrames: number;
|
|
121
|
+
firstAudioLatencyMs?: number;
|
|
122
|
+
inputAudioFrames: number;
|
|
123
|
+
interruptionFrames: number;
|
|
124
|
+
issueCodes: readonly string[];
|
|
125
|
+
jitterMs?: number;
|
|
126
|
+
resamplingRequired: boolean;
|
|
127
|
+
status: MediaPipelineStatus;
|
|
128
|
+
surface: string;
|
|
129
|
+
traceLinkedFrames: number;
|
|
130
|
+
turnCommitFrames: number;
|
|
131
|
+
};
|
|
132
|
+
export type VoiceMediaPipelineProofArtifactLinks = {
|
|
133
|
+
processorGraph?: string;
|
|
134
|
+
quality?: string;
|
|
135
|
+
transport?: string;
|
|
136
|
+
};
|
|
137
|
+
export type VoiceMediaPipelineProofSummary = {
|
|
138
|
+
artifacts?: VoiceMediaPipelineProofArtifactLinks;
|
|
139
|
+
calibration: VoiceMediaPipelineCalibrationSummary;
|
|
140
|
+
checkedAt: number;
|
|
141
|
+
frames: number;
|
|
142
|
+
interruption: {
|
|
143
|
+
interruptionFrames: number;
|
|
144
|
+
issueCodes: readonly string[];
|
|
145
|
+
latenciesMs: readonly number[];
|
|
146
|
+
status: MediaPipelineStatus;
|
|
147
|
+
};
|
|
148
|
+
issueCodes: readonly string[];
|
|
149
|
+
issues: readonly MediaPipelineCalibrationIssue[];
|
|
150
|
+
ok: boolean;
|
|
151
|
+
processorGraph?: MediaProcessorGraphSummary;
|
|
152
|
+
quality: MediaQualitySummary;
|
|
153
|
+
resampling?: {
|
|
154
|
+
ratio: number;
|
|
155
|
+
required: boolean;
|
|
156
|
+
status: MediaPipelineStatus;
|
|
157
|
+
};
|
|
158
|
+
sessionIds: readonly string[];
|
|
159
|
+
status: MediaPipelineStatus;
|
|
160
|
+
surface: string;
|
|
161
|
+
transport?: MediaTransportSummary;
|
|
162
|
+
vad: {
|
|
163
|
+
inputAudioFrames: number;
|
|
164
|
+
segmentCount: number;
|
|
165
|
+
status: MediaPipelineStatus;
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
export type VoiceMediaPipelineProofSummaryOptions = {
|
|
169
|
+
artifacts?: VoiceMediaPipelineProofArtifactLinks;
|
|
170
|
+
};
|
|
171
|
+
export declare const summarizeVoiceMediaPipelineReport: (report: VoiceMediaPipelineReport, options?: VoiceMediaPipelineProofSummaryOptions) => VoiceMediaPipelineProofSummary;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type MediaProcessorGraphSummary, type MediaQualitySummary, type MediaTransportSummary } from "@absolutejs/media";
|
|
2
|
+
import type { VoiceIncidentTimelineEvent } from "./incidentTimeline";
|
|
3
|
+
import type { VoiceMediaPipelineReport } from "./mediaPipelineRoutes";
|
|
4
|
+
import type { VoiceProductionReadinessCheck } from "./productionReadiness";
|
|
5
|
+
export type VoiceMediaPipelineIssueSource = "calibration" | "interruption" | "processor-graph" | "quality" | "transport";
|
|
6
|
+
export type VoiceMediaPipelineIssueEntry = {
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
severity: "error" | "warning";
|
|
10
|
+
source: VoiceMediaPipelineIssueSource;
|
|
11
|
+
surface: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const extractVoiceMediaPipelineIssueEntries: (report: VoiceMediaPipelineReport) => readonly VoiceMediaPipelineIssueEntry[];
|
|
14
|
+
export type VoiceMediaPipelineReadinessOptions = {
|
|
15
|
+
baseHref?: string;
|
|
16
|
+
label?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const buildVoiceMediaPipelineReadinessChecks: (report: VoiceMediaPipelineReport, options?: VoiceMediaPipelineReadinessOptions) => readonly VoiceProductionReadinessCheck[];
|
|
19
|
+
export type VoiceMediaPipelineIncidentOptions = {
|
|
20
|
+
baseHref?: string;
|
|
21
|
+
category?: VoiceIncidentTimelineEvent["category"];
|
|
22
|
+
now?: () => number;
|
|
23
|
+
source?: string;
|
|
24
|
+
};
|
|
25
|
+
export declare const buildVoiceMediaPipelineIncidentEvents: (report: VoiceMediaPipelineReport, options?: VoiceMediaPipelineIncidentOptions) => readonly VoiceIncidentTimelineEvent[];
|
|
26
|
+
export type VoiceMediaPipelineArtifactKind = "processor-graph" | "quality" | "transport";
|
|
27
|
+
export type VoiceMediaPipelineArtifactRecord = {
|
|
28
|
+
href?: string;
|
|
29
|
+
jsonPath: string;
|
|
30
|
+
kind: VoiceMediaPipelineArtifactKind;
|
|
31
|
+
markdownPath: string;
|
|
32
|
+
summary: MediaProcessorGraphSummary | MediaQualitySummary | MediaTransportSummary;
|
|
33
|
+
};
|
|
34
|
+
export type VoiceMediaPipelineArtifactWriteOptions = {
|
|
35
|
+
dir: string;
|
|
36
|
+
hrefBase?: string;
|
|
37
|
+
report: VoiceMediaPipelineReport;
|
|
38
|
+
slugPrefix?: string;
|
|
39
|
+
};
|
|
40
|
+
export type VoiceMediaPipelineArtifactWriteResult = {
|
|
41
|
+
artifacts: VoiceMediaPipelineArtifactRecord[];
|
|
42
|
+
hrefs: {
|
|
43
|
+
processorGraph?: string;
|
|
44
|
+
quality?: string;
|
|
45
|
+
transport?: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export declare const writeVoiceMediaPipelineArtifacts: (options: VoiceMediaPipelineArtifactWriteOptions) => Promise<VoiceMediaPipelineArtifactWriteResult>;
|
|
@@ -15,6 +15,7 @@ import type { VoiceAuditEventStore, VoiceAuditEventType, VoiceAuditOutcome } fro
|
|
|
15
15
|
import { type VoiceAuditSinkDeliveryStore } from "./auditSinks";
|
|
16
16
|
import type { VoiceProviderContractMatrixReport, VoiceProviderStackCapabilityGapReport } from "./providerStackRecommendations";
|
|
17
17
|
import { type VoiceProviderSloReport, type VoiceProviderSloReportOptions } from "./providerSlo";
|
|
18
|
+
import { type VoiceSessionObservabilityEvidenceInput, type VoiceSessionObservabilityReport } from "./sessionObservability";
|
|
18
19
|
import type { VoiceProviderOrchestrationReport } from "./providerOrchestration";
|
|
19
20
|
import type { VoiceCampaignReadinessProofReport } from "./campaign";
|
|
20
21
|
import { type VoiceOpsRecoveryReport } from "./opsRecovery";
|
|
@@ -214,6 +215,7 @@ export type VoiceProductionReadinessReport = {
|
|
|
214
215
|
resilience?: string;
|
|
215
216
|
sessions?: string;
|
|
216
217
|
sloReadinessThresholds?: string;
|
|
218
|
+
sessionObservability?: string;
|
|
217
219
|
traceDeliveries?: string;
|
|
218
220
|
};
|
|
219
221
|
profile?: VoiceProductionReadinessProfileExplanation;
|
|
@@ -418,6 +420,13 @@ export type VoiceProductionReadinessReport = {
|
|
|
418
420
|
status: VoiceProductionReadinessStatus;
|
|
419
421
|
total: number;
|
|
420
422
|
};
|
|
423
|
+
sessionObservability?: {
|
|
424
|
+
failed: number;
|
|
425
|
+
passed: number;
|
|
426
|
+
status: VoiceProductionReadinessStatus;
|
|
427
|
+
total: number;
|
|
428
|
+
warnings: number;
|
|
429
|
+
};
|
|
421
430
|
quality: {
|
|
422
431
|
status: "fail" | "pass";
|
|
423
432
|
};
|
|
@@ -677,6 +686,14 @@ export type VoiceProductionReadinessRoutesOptions = {
|
|
|
677
686
|
store: VoiceTraceEventStore;
|
|
678
687
|
sttProviders?: readonly string[];
|
|
679
688
|
title?: string;
|
|
689
|
+
sessionObservability?: false | VoiceSessionObservabilityReport | ((input: {
|
|
690
|
+
query: Record<string, unknown>;
|
|
691
|
+
request: Request;
|
|
692
|
+
}) => Promise<VoiceSessionObservabilityReport> | VoiceSessionObservabilityReport);
|
|
693
|
+
sessionObservabilityEvidence?: false | VoiceSessionObservabilityEvidenceInput | ((input: {
|
|
694
|
+
query: Record<string, unknown>;
|
|
695
|
+
request: Request;
|
|
696
|
+
}) => Promise<VoiceSessionObservabilityEvidenceInput> | VoiceSessionObservabilityEvidenceInput);
|
|
680
697
|
traceDeliveries?: false | VoiceProductionReadinessTraceDeliveryOptions;
|
|
681
698
|
ttsProviders?: readonly string[];
|
|
682
699
|
traceMaxAgeMs?: number;
|
package/dist/proofTrends.d.ts
CHANGED
|
@@ -237,14 +237,28 @@ export type VoiceRealCallProfileTraceCollector<TEvent extends StoredVoiceTraceEv
|
|
|
237
237
|
listEvidence: (options?: VoiceRealCallProfileTraceCollectorEvidenceOptions) => Promise<VoiceProofTrendRealCallProfileEvidence[]>;
|
|
238
238
|
};
|
|
239
239
|
export type VoiceRealCallEvidenceRuntimeSourceOptions = {
|
|
240
|
+
browserEvidence?: VoiceRealCallEvidenceRuntimeSurfaceEvidenceSource;
|
|
240
241
|
existingEvidenceLimit?: number;
|
|
241
242
|
evidenceStore: VoiceRealCallProfileEvidenceStore;
|
|
242
243
|
history?: Omit<VoiceRealCallProfileHistoryOptions, "evidence">;
|
|
244
|
+
phoneEvidence?: VoiceRealCallEvidenceRuntimeSurfaceEvidenceSource;
|
|
245
|
+
providerRoleEvidence?: VoiceRealCallEvidenceRuntimeProviderRoleEvidenceSource;
|
|
243
246
|
reconnectEvidence?: VoiceReconnectRealCallProfileEvidenceOptions;
|
|
244
247
|
reconnectReports?: ((options: VoiceRealCallEvidenceRuntimeCollectOptions) => Promise<VoiceReconnectProofReport | VoiceReconnectContractReport | readonly (VoiceReconnectProofReport | VoiceReconnectContractReport)[] | undefined> | VoiceReconnectProofReport | VoiceReconnectContractReport | readonly (VoiceReconnectProofReport | VoiceReconnectContractReport)[] | undefined) | VoiceReconnectProofReport | VoiceReconnectContractReport | readonly (VoiceReconnectProofReport | VoiceReconnectContractReport)[];
|
|
245
248
|
traceEvidence?: VoiceRealCallProfileTraceCollectorEvidenceOptions;
|
|
246
249
|
traceStore?: VoiceTraceEventStore;
|
|
247
250
|
};
|
|
251
|
+
export type VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions = Omit<VoiceProofTrendRealCallProfileEvidence, "profileId" | "providers" | "sessionId" | "surfaces"> & {
|
|
252
|
+
profileId?: string;
|
|
253
|
+
providers?: readonly VoiceProofTrendProviderSummary[];
|
|
254
|
+
sessionId?: string;
|
|
255
|
+
surfaces?: readonly string[];
|
|
256
|
+
};
|
|
257
|
+
export type VoiceRealCallEvidenceRuntimeProviderRoleEvidenceOptions = Omit<VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions, "providers"> & {
|
|
258
|
+
providers: readonly VoiceProofTrendProviderSummary[];
|
|
259
|
+
};
|
|
260
|
+
export type VoiceRealCallEvidenceRuntimeSurfaceEvidenceSource = VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions | readonly VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions[] | ((options: VoiceRealCallEvidenceRuntimeCollectOptions) => Promise<VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions | readonly VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions[] | undefined> | VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions | readonly VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions[] | undefined);
|
|
261
|
+
export type VoiceRealCallEvidenceRuntimeProviderRoleEvidenceSource = VoiceRealCallEvidenceRuntimeProviderRoleEvidenceOptions | readonly VoiceRealCallEvidenceRuntimeProviderRoleEvidenceOptions[] | ((options: VoiceRealCallEvidenceRuntimeCollectOptions) => Promise<VoiceRealCallEvidenceRuntimeProviderRoleEvidenceOptions | readonly VoiceRealCallEvidenceRuntimeProviderRoleEvidenceOptions[] | undefined> | VoiceRealCallEvidenceRuntimeProviderRoleEvidenceOptions | readonly VoiceRealCallEvidenceRuntimeProviderRoleEvidenceOptions[] | undefined);
|
|
248
262
|
export type VoiceRealCallEvidenceRuntimeOptions = VoiceRealCallEvidenceRuntimeSourceOptions & {
|
|
249
263
|
dedupe?: boolean;
|
|
250
264
|
now?: () => Date;
|
|
@@ -764,6 +778,17 @@ export declare const loadVoiceRealCallProfileEvidenceFromTraceStore: (options: V
|
|
|
764
778
|
export declare const loadVoiceRealCallProfileEvidenceFromStore: (options: VoiceRealCallProfileEvidenceListOptions & {
|
|
765
779
|
store: VoiceRealCallProfileEvidenceStore;
|
|
766
780
|
}) => Promise<VoiceRealCallProfileEvidenceRecord[]>;
|
|
781
|
+
export declare const buildVoiceRealCallProfileEvidenceFromRuntimeSurface: (input: VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions | readonly VoiceRealCallEvidenceRuntimeSurfaceEvidenceOptions[], options: {
|
|
782
|
+
defaultProfileId: string;
|
|
783
|
+
defaultSessionPrefix: string;
|
|
784
|
+
defaultSurfaces: readonly string[];
|
|
785
|
+
now?: () => Date;
|
|
786
|
+
}) => VoiceProofTrendRealCallProfileEvidence[];
|
|
787
|
+
export declare const buildVoiceRealCallProfileEvidenceFromRuntimeProviderRoles: (input: VoiceRealCallEvidenceRuntimeProviderRoleEvidenceOptions | readonly VoiceRealCallEvidenceRuntimeProviderRoleEvidenceOptions[], options?: {
|
|
788
|
+
defaultProfileId?: string;
|
|
789
|
+
defaultSessionPrefix?: string;
|
|
790
|
+
now?: () => Date;
|
|
791
|
+
}) => VoiceProofTrendRealCallProfileEvidence[];
|
|
767
792
|
export declare const createVoiceRealCallEvidenceRuntime: (options: VoiceRealCallEvidenceRuntimeOptions) => VoiceRealCallEvidenceRuntime;
|
|
768
793
|
export declare const buildVoiceRealCallEvidenceRuntimeReadinessCheck: (report: VoiceRealCallEvidenceRuntimeReport, options?: VoiceRealCallEvidenceRuntimeReadinessCheckOptions) => VoiceProductionReadinessCheck;
|
|
769
794
|
export declare const createVoiceRealCallEvidenceRuntimeWorker: (options: VoiceRealCallEvidenceRuntimeWorkerOptions) => VoiceRealCallEvidenceRuntimeWorker;
|
package/dist/react/index.js
CHANGED
|
@@ -3769,7 +3769,38 @@ var resolveRealCallEvidenceRuntimeReconnectReports = async (reports, options) =>
|
|
|
3769
3769
|
}
|
|
3770
3770
|
return Array.isArray(resolved) ? resolved : [resolved];
|
|
3771
3771
|
};
|
|
3772
|
+
var resolveRealCallEvidenceRuntimeSurfaceEvidence = async (source, options) => {
|
|
3773
|
+
const resolved = typeof source === "function" ? await source(options) : source;
|
|
3774
|
+
if (!resolved) {
|
|
3775
|
+
return [];
|
|
3776
|
+
}
|
|
3777
|
+
return Array.isArray(resolved) ? [...resolved] : [resolved];
|
|
3778
|
+
};
|
|
3779
|
+
var createRealCallEvidenceRuntimeSessionId = (prefix, generatedAt) => `${prefix}-${Date.parse(generatedAt) || Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
3780
|
+
var buildVoiceRealCallProfileEvidenceFromRuntimeSurface = (input, options) => {
|
|
3781
|
+
const evidence = Array.isArray(input) ? input : [input];
|
|
3782
|
+
return evidence.map((item) => {
|
|
3783
|
+
const generatedAt = item.generatedAt ?? (options.now ?? (() => new Date))().toISOString();
|
|
3784
|
+
return {
|
|
3785
|
+
...item,
|
|
3786
|
+
generatedAt,
|
|
3787
|
+
profileId: item.profileId ?? options.defaultProfileId,
|
|
3788
|
+
providers: item.providers ? [...item.providers] : undefined,
|
|
3789
|
+
sessionId: item.sessionId ?? createRealCallEvidenceRuntimeSessionId(options.defaultSessionPrefix, generatedAt),
|
|
3790
|
+
surfaces: [
|
|
3791
|
+
...new Set([...item.surfaces ?? [], ...options.defaultSurfaces])
|
|
3792
|
+
].sort()
|
|
3793
|
+
};
|
|
3794
|
+
});
|
|
3795
|
+
};
|
|
3796
|
+
var buildVoiceRealCallProfileEvidenceFromRuntimeProviderRoles = (input, options = {}) => buildVoiceRealCallProfileEvidenceFromRuntimeSurface(input, {
|
|
3797
|
+
defaultProfileId: options.defaultProfileId ?? "provider-role-evidence",
|
|
3798
|
+
defaultSessionPrefix: options.defaultSessionPrefix ?? "provider-role-evidence",
|
|
3799
|
+
defaultSurfaces: ["provider-path"],
|
|
3800
|
+
now: options.now
|
|
3801
|
+
});
|
|
3772
3802
|
var mergeRealCallEvidenceRuntimeOptions = (base, override = {}) => ({
|
|
3803
|
+
browserEvidence: override.browserEvidence ?? base.browserEvidence,
|
|
3773
3804
|
dedupe: override.dedupe ?? base.dedupe,
|
|
3774
3805
|
evidenceStore: override.evidenceStore ?? base.evidenceStore,
|
|
3775
3806
|
existingEvidenceLimit: override.existingEvidenceLimit ?? base.existingEvidenceLimit,
|
|
@@ -3778,6 +3809,8 @@ var mergeRealCallEvidenceRuntimeOptions = (base, override = {}) => ({
|
|
|
3778
3809
|
...override.history ?? {}
|
|
3779
3810
|
},
|
|
3780
3811
|
now: override.now ?? base.now,
|
|
3812
|
+
phoneEvidence: override.phoneEvidence ?? base.phoneEvidence,
|
|
3813
|
+
providerRoleEvidence: override.providerRoleEvidence ?? base.providerRoleEvidence,
|
|
3781
3814
|
reconnectEvidence: {
|
|
3782
3815
|
...base.reconnectEvidence ?? {},
|
|
3783
3816
|
...override.reconnectEvidence ?? {}
|
|
@@ -3826,6 +3859,30 @@ var buildRealCallEvidenceRuntimeReport = async (options, input = {}) => {
|
|
|
3826
3859
|
};
|
|
3827
3860
|
var collectVoiceRealCallEvidenceRuntimeEvidence = async (options) => {
|
|
3828
3861
|
const evidence = [];
|
|
3862
|
+
const browserEvidence = await resolveRealCallEvidenceRuntimeSurfaceEvidence(options.browserEvidence, options);
|
|
3863
|
+
if (browserEvidence.length > 0) {
|
|
3864
|
+
evidence.push(...buildVoiceRealCallProfileEvidenceFromRuntimeSurface(browserEvidence, {
|
|
3865
|
+
defaultProfileId: "browser-call",
|
|
3866
|
+
defaultSessionPrefix: "browser-call",
|
|
3867
|
+
defaultSurfaces: ["browser"],
|
|
3868
|
+
now: options.now
|
|
3869
|
+
}));
|
|
3870
|
+
}
|
|
3871
|
+
const phoneEvidence = await resolveRealCallEvidenceRuntimeSurfaceEvidence(options.phoneEvidence, options);
|
|
3872
|
+
if (phoneEvidence.length > 0) {
|
|
3873
|
+
evidence.push(...buildVoiceRealCallProfileEvidenceFromRuntimeSurface(phoneEvidence, {
|
|
3874
|
+
defaultProfileId: "phone-agent",
|
|
3875
|
+
defaultSessionPrefix: "phone-agent",
|
|
3876
|
+
defaultSurfaces: ["phone", "telephony"],
|
|
3877
|
+
now: options.now
|
|
3878
|
+
}));
|
|
3879
|
+
}
|
|
3880
|
+
const providerRoleEvidence = await resolveRealCallEvidenceRuntimeSurfaceEvidence(options.providerRoleEvidence, options);
|
|
3881
|
+
if (providerRoleEvidence.length > 0) {
|
|
3882
|
+
evidence.push(...buildVoiceRealCallProfileEvidenceFromRuntimeProviderRoles(providerRoleEvidence, {
|
|
3883
|
+
now: options.now
|
|
3884
|
+
}));
|
|
3885
|
+
}
|
|
3829
3886
|
if (options.traceStore) {
|
|
3830
3887
|
evidence.push(...buildVoiceRealCallProfileEvidenceFromTraceEvents(await options.traceStore.list({
|
|
3831
3888
|
limit: options.traceEvidence?.limit ?? 5000
|
|
@@ -11030,6 +11087,8 @@ var serverMessageToAction = (message) => {
|
|
|
11030
11087
|
};
|
|
11031
11088
|
|
|
11032
11089
|
// node_modules/@absolutejs/media/dist/index.js
|
|
11090
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
11091
|
+
import { join } from "path";
|
|
11033
11092
|
var formatLabel = (format) => `${format.container}/${format.encoding}/${String(format.sampleRateHz)}hz/${String(format.channels)}ch`;
|
|
11034
11093
|
var formatMatches = (actual, expected) => actual.container === expected.container && actual.encoding === expected.encoding && actual.sampleRateHz === expected.sampleRateHz && actual.channels === expected.channels;
|
|
11035
11094
|
var pushIssue = (issues, severity, code, message) => {
|
|
@@ -11690,6 +11749,269 @@ var buildMediaPipelineCalibrationReport = (input = {}) => {
|
|
|
11690
11749
|
turnCommitFrames: turnCommitFrames.length
|
|
11691
11750
|
};
|
|
11692
11751
|
};
|
|
11752
|
+
var DEFAULT_METADATA_DENY = [
|
|
11753
|
+
"audioPayload",
|
|
11754
|
+
"auth",
|
|
11755
|
+
"authorization",
|
|
11756
|
+
"cookie",
|
|
11757
|
+
"email",
|
|
11758
|
+
"phone",
|
|
11759
|
+
"phoneNumber",
|
|
11760
|
+
"rawPayload",
|
|
11761
|
+
"secret",
|
|
11762
|
+
"token",
|
|
11763
|
+
"transcript",
|
|
11764
|
+
"utterance"
|
|
11765
|
+
];
|
|
11766
|
+
var DEFAULT_TRUNCATE = 8;
|
|
11767
|
+
var issueCodes = (issues) => Array.from(new Set(issues.map((issue) => issue.code)));
|
|
11768
|
+
var lastEventKind = (events) => events[events.length - 1]?.kind;
|
|
11769
|
+
var formatOptionalMs = (value) => value === undefined ? "n/a" : `${String(Math.round(value))}ms`;
|
|
11770
|
+
var formatRatio = (value) => `${(value * 100).toFixed(1)}%`;
|
|
11771
|
+
var escapeMarkdownCell = (value) => value.replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
11772
|
+
var renderIssuesTable = (issues) => {
|
|
11773
|
+
if (issues.length === 0) {
|
|
11774
|
+
return `- No issues.
|
|
11775
|
+
`;
|
|
11776
|
+
}
|
|
11777
|
+
const rows = issues.map((issue) => `| ${issue.severity} | ${escapeMarkdownCell(issue.code)} | ${escapeMarkdownCell(issue.message)} |`).join(`
|
|
11778
|
+
`);
|
|
11779
|
+
return `| Severity | Code | Message |
|
|
11780
|
+
| --- | --- | --- |
|
|
11781
|
+
${rows}
|
|
11782
|
+
`;
|
|
11783
|
+
};
|
|
11784
|
+
var summarizeMediaQualityReport = (report) => ({
|
|
11785
|
+
backpressureEvents: report.backpressureEvents,
|
|
11786
|
+
description: `${report.totalFrames} frame(s), ${report.gapCount} gap(s), speech ${formatRatio(report.speechRatio)}, status ${report.status}.`,
|
|
11787
|
+
driftMs: report.timestampDriftMs,
|
|
11788
|
+
frameCount: report.totalFrames,
|
|
11789
|
+
gapCount: report.gapCount,
|
|
11790
|
+
issueCodes: issueCodes(report.issues),
|
|
11791
|
+
issueCount: report.issues.length,
|
|
11792
|
+
jitterMs: report.jitterMs,
|
|
11793
|
+
silenceRatio: report.silenceRatio,
|
|
11794
|
+
speechRatio: report.speechRatio,
|
|
11795
|
+
status: report.status
|
|
11796
|
+
});
|
|
11797
|
+
var summarizeMediaTransportReport = (report) => ({
|
|
11798
|
+
backpressureEvents: report.backpressureEvents,
|
|
11799
|
+
description: `${report.name}: ${report.state}, in ${report.inputFrames}, out ${report.outputFrames}, backpressure ${report.backpressureEvents}.`,
|
|
11800
|
+
errors: report.events.filter((event) => event.kind === "error").length,
|
|
11801
|
+
inputFrames: report.inputFrames,
|
|
11802
|
+
lastEventKind: lastEventKind(report.events),
|
|
11803
|
+
name: report.name,
|
|
11804
|
+
outputFrames: report.outputFrames,
|
|
11805
|
+
state: report.state,
|
|
11806
|
+
status: report.status
|
|
11807
|
+
});
|
|
11808
|
+
var summarizeMediaProcessorGraphReport = (report) => {
|
|
11809
|
+
const errorIssueCodes = Array.from(new Set(report.errors.map((event) => event.kind)));
|
|
11810
|
+
return {
|
|
11811
|
+
backpressureEvents: report.backpressure.events.length,
|
|
11812
|
+
description: `${report.name}: ${report.state}, ${report.nodes.length} node(s), in ${report.inputFrames}, out ${report.emittedFrames}, dropped ${report.droppedFrames}.`,
|
|
11813
|
+
droppedFrames: report.droppedFrames,
|
|
11814
|
+
edgeCount: report.edges.length,
|
|
11815
|
+
edgeEventCount: report.edgeEvents.length,
|
|
11816
|
+
emittedFrames: report.emittedFrames,
|
|
11817
|
+
errorCount: report.errors.length,
|
|
11818
|
+
inputFrames: report.inputFrames,
|
|
11819
|
+
issueCodes: errorIssueCodes,
|
|
11820
|
+
lifecycleEventCount: report.lifecycleEvents.length,
|
|
11821
|
+
name: report.name,
|
|
11822
|
+
nodeCount: report.nodes.length,
|
|
11823
|
+
state: report.state,
|
|
11824
|
+
status: report.status,
|
|
11825
|
+
timingMaxMs: report.timing.maxNodeMs
|
|
11826
|
+
};
|
|
11827
|
+
};
|
|
11828
|
+
var renderMediaQualityMarkdown = (report, options = {}) => {
|
|
11829
|
+
const title = options.title ?? "Media Quality Report";
|
|
11830
|
+
const lines = [
|
|
11831
|
+
`# ${title}`,
|
|
11832
|
+
"",
|
|
11833
|
+
`Status: **${report.status}**`,
|
|
11834
|
+
"",
|
|
11835
|
+
"| Metric | Value |",
|
|
11836
|
+
"| --- | ---: |",
|
|
11837
|
+
`| Total frames | ${report.totalFrames} |`,
|
|
11838
|
+
`| Input audio | ${report.inputAudioFrames} |`,
|
|
11839
|
+
`| Assistant audio | ${report.assistantAudioFrames} |`,
|
|
11840
|
+
`| Gaps | ${report.gapCount} |`,
|
|
11841
|
+
`| Jitter | ${formatOptionalMs(report.jitterMs)} |`,
|
|
11842
|
+
`| Timestamp drift | ${formatOptionalMs(report.timestampDriftMs)} |`,
|
|
11843
|
+
`| Speech ratio | ${formatRatio(report.speechRatio)} |`,
|
|
11844
|
+
`| Silence ratio | ${formatRatio(report.silenceRatio)} |`,
|
|
11845
|
+
`| Backpressure events | ${report.backpressureEvents} |`,
|
|
11846
|
+
"",
|
|
11847
|
+
"## Issues",
|
|
11848
|
+
"",
|
|
11849
|
+
renderIssuesTable(report.issues).trimEnd()
|
|
11850
|
+
];
|
|
11851
|
+
return `${lines.join(`
|
|
11852
|
+
`)}
|
|
11853
|
+
`;
|
|
11854
|
+
};
|
|
11855
|
+
var renderMediaTransportMarkdown = (report, options = {}) => {
|
|
11856
|
+
const title = options.title ?? `Media Transport: ${report.name}`;
|
|
11857
|
+
const limit = options.redact?.truncateArraysAt ?? DEFAULT_TRUNCATE;
|
|
11858
|
+
const events = report.events.slice(-limit);
|
|
11859
|
+
const eventRows = events.length === 0 ? "- No transport events recorded." : ["| At | Kind | State | Buffered | Error |", "| --- | --- | --- | ---: | --- |"].concat(events.map((event) => `| ${event.at} | ${event.kind} | ${event.state} | ${event.bufferedFrames ?? ""} | ${escapeMarkdownCell(event.error ?? "")} |`)).join(`
|
|
11860
|
+
`);
|
|
11861
|
+
const lines = [
|
|
11862
|
+
`# ${title}`,
|
|
11863
|
+
"",
|
|
11864
|
+
`Status: **${report.status}** \xB7 State: **${report.state}**`,
|
|
11865
|
+
"",
|
|
11866
|
+
"| Metric | Value |",
|
|
11867
|
+
"| --- | ---: |",
|
|
11868
|
+
`| Input frames | ${report.inputFrames} |`,
|
|
11869
|
+
`| Output frames | ${report.outputFrames} |`,
|
|
11870
|
+
`| Backpressure events | ${report.backpressureEvents} |`,
|
|
11871
|
+
`| Connected | ${report.connected ? "yes" : "no"} |`,
|
|
11872
|
+
`| Closed | ${report.closed ? "yes" : "no"} |`,
|
|
11873
|
+
`| Failed | ${report.failed ? "yes" : "no"} |`,
|
|
11874
|
+
"",
|
|
11875
|
+
`## Last ${events.length} event(s)`,
|
|
11876
|
+
"",
|
|
11877
|
+
eventRows
|
|
11878
|
+
];
|
|
11879
|
+
return `${lines.join(`
|
|
11880
|
+
`)}
|
|
11881
|
+
`;
|
|
11882
|
+
};
|
|
11883
|
+
var renderMediaProcessorGraphMarkdown = (report, options = {}) => {
|
|
11884
|
+
const title = options.title ?? `Media Processor Graph: ${report.name}`;
|
|
11885
|
+
const limit = options.redact?.truncateArraysAt ?? DEFAULT_TRUNCATE;
|
|
11886
|
+
const nodeRows = report.nodes.map((node) => `| ${escapeMarkdownCell(node.name)} | ${node.kind} | ${node.status} | ${node.inputFrames} | ${node.emittedFrames} | ${node.droppedFrames} | ${node.errors.length} |`).join(`
|
|
11887
|
+
`);
|
|
11888
|
+
const edgeRows = report.edges.slice(0, limit).map((edge) => `| ${escapeMarkdownCell(edge.from)} | ${escapeMarkdownCell(edge.to)} | ${edge.status} | ${edge.emittedFrames} |`).join(`
|
|
11889
|
+
`);
|
|
11890
|
+
const issues = report.errors.map((event) => ({
|
|
11891
|
+
code: event.kind,
|
|
11892
|
+
message: event.error ?? `Processor graph ${event.kind} (state ${event.state}).`,
|
|
11893
|
+
severity: "error"
|
|
11894
|
+
}));
|
|
11895
|
+
const lines = [
|
|
11896
|
+
`# ${title}`,
|
|
11897
|
+
"",
|
|
11898
|
+
`Status: **${report.status}** \xB7 State: **${report.state}**`,
|
|
11899
|
+
"",
|
|
11900
|
+
"| Metric | Value |",
|
|
11901
|
+
"| --- | ---: |",
|
|
11902
|
+
`| Nodes | ${report.nodes.length} |`,
|
|
11903
|
+
`| Input frames | ${report.inputFrames} |`,
|
|
11904
|
+
`| Emitted frames | ${report.emittedFrames} |`,
|
|
11905
|
+
`| Dropped frames | ${report.droppedFrames} |`,
|
|
11906
|
+
`| Lifecycle events | ${report.lifecycleEvents.length} |`,
|
|
11907
|
+
`| Edge events | ${report.edgeEvents.length} |`,
|
|
11908
|
+
`| Backpressure events | ${report.backpressure.events.length} |`,
|
|
11909
|
+
`| Timing max | ${formatOptionalMs(report.timing.maxNodeMs)} |`,
|
|
11910
|
+
`| Timing average | ${formatOptionalMs(report.timing.averageNodeMs)} |`,
|
|
11911
|
+
"",
|
|
11912
|
+
"## Nodes",
|
|
11913
|
+
"",
|
|
11914
|
+
nodeRows ? `| Node | Kind | Status | In | Out | Dropped | Errors |
|
|
11915
|
+
| --- | --- | --- | ---: | ---: | ---: | ---: |
|
|
11916
|
+
${nodeRows}` : "- No nodes.",
|
|
11917
|
+
"",
|
|
11918
|
+
`## Edges (showing up to ${limit})`,
|
|
11919
|
+
"",
|
|
11920
|
+
edgeRows ? `| From | To | Status | Frames |
|
|
11921
|
+
| --- | --- | --- | ---: |
|
|
11922
|
+
${edgeRows}` : "- No edges.",
|
|
11923
|
+
"",
|
|
11924
|
+
"## Errors",
|
|
11925
|
+
"",
|
|
11926
|
+
renderIssuesTable(issues).trimEnd()
|
|
11927
|
+
];
|
|
11928
|
+
return `${lines.join(`
|
|
11929
|
+
`)}
|
|
11930
|
+
`;
|
|
11931
|
+
};
|
|
11932
|
+
var truncateArrays = (value, limit, seen) => {
|
|
11933
|
+
if (Array.isArray(value)) {
|
|
11934
|
+
const head = value.slice(0, limit).map((entry) => truncateArrays(entry, limit, seen));
|
|
11935
|
+
if (value.length > limit) {
|
|
11936
|
+
return [...head, { truncated: value.length - limit }];
|
|
11937
|
+
}
|
|
11938
|
+
return head;
|
|
11939
|
+
}
|
|
11940
|
+
if (value && typeof value === "object") {
|
|
11941
|
+
if (seen.has(value))
|
|
11942
|
+
return value;
|
|
11943
|
+
seen.add(value);
|
|
11944
|
+
const next = {};
|
|
11945
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
11946
|
+
next[key] = truncateArrays(entry, limit, seen);
|
|
11947
|
+
}
|
|
11948
|
+
return next;
|
|
11949
|
+
}
|
|
11950
|
+
return value;
|
|
11951
|
+
};
|
|
11952
|
+
var applyRedaction = (value, options, seen) => {
|
|
11953
|
+
const mode = options.mode ?? "omit";
|
|
11954
|
+
const maskValue = options.maskValue ?? "[redacted]";
|
|
11955
|
+
const allow = new Set(options.metadataAllow ?? []);
|
|
11956
|
+
const deny = new Set(options.metadataDeny ?? DEFAULT_METADATA_DENY);
|
|
11957
|
+
const walk = (input) => {
|
|
11958
|
+
if (Array.isArray(input)) {
|
|
11959
|
+
return input.map((entry) => walk(entry));
|
|
11960
|
+
}
|
|
11961
|
+
if (input && typeof input === "object") {
|
|
11962
|
+
if (seen.has(input))
|
|
11963
|
+
return input;
|
|
11964
|
+
seen.add(input);
|
|
11965
|
+
const next = {};
|
|
11966
|
+
for (const [key, entry] of Object.entries(input)) {
|
|
11967
|
+
if (allow.has(key)) {
|
|
11968
|
+
next[key] = entry;
|
|
11969
|
+
continue;
|
|
11970
|
+
}
|
|
11971
|
+
if (deny.has(key)) {
|
|
11972
|
+
if (mode === "mask")
|
|
11973
|
+
next[key] = maskValue;
|
|
11974
|
+
continue;
|
|
11975
|
+
}
|
|
11976
|
+
next[key] = walk(entry);
|
|
11977
|
+
}
|
|
11978
|
+
return next;
|
|
11979
|
+
}
|
|
11980
|
+
return input;
|
|
11981
|
+
};
|
|
11982
|
+
return walk(value);
|
|
11983
|
+
};
|
|
11984
|
+
var redactMediaReport = (report, options = {}) => {
|
|
11985
|
+
const limit = options.truncateArraysAt ?? DEFAULT_TRUNCATE;
|
|
11986
|
+
const truncated = truncateArrays(report, limit, new WeakSet);
|
|
11987
|
+
return applyRedaction(truncated, options, new WeakSet);
|
|
11988
|
+
};
|
|
11989
|
+
var buildArtifactPair = (report, summary, markdown, options) => {
|
|
11990
|
+
const jsonValue = options.redact ? redactMediaReport(report, options.redact) : report;
|
|
11991
|
+
return {
|
|
11992
|
+
json: JSON.stringify(jsonValue, null, 2),
|
|
11993
|
+
jsonValue,
|
|
11994
|
+
markdown,
|
|
11995
|
+
summary
|
|
11996
|
+
};
|
|
11997
|
+
};
|
|
11998
|
+
var buildMediaQualityArtifact = (report, options = {}) => buildArtifactPair(report, summarizeMediaQualityReport(report), renderMediaQualityMarkdown(report, options), options);
|
|
11999
|
+
var buildMediaTransportArtifact = (report, options = {}) => buildArtifactPair(report, summarizeMediaTransportReport(report), renderMediaTransportMarkdown(report, options), options);
|
|
12000
|
+
var buildMediaProcessorGraphArtifact = (report, options = {}) => buildArtifactPair(report, summarizeMediaProcessorGraphReport(report), renderMediaProcessorGraphMarkdown(report, options), options);
|
|
12001
|
+
var writeMediaArtifact = async (input) => {
|
|
12002
|
+
await mkdir(input.dir, { recursive: true });
|
|
12003
|
+
const jsonPath = join(input.dir, `${input.slug}.json`);
|
|
12004
|
+
const markdownPath = join(input.dir, `${input.slug}.md`);
|
|
12005
|
+
await Promise.all([
|
|
12006
|
+
writeFile(jsonPath, input.json, "utf8"),
|
|
12007
|
+
writeFile(markdownPath, input.markdown, "utf8")
|
|
12008
|
+
]);
|
|
12009
|
+
return {
|
|
12010
|
+
jsonPath,
|
|
12011
|
+
markdownPath,
|
|
12012
|
+
summary: input.summary
|
|
12013
|
+
};
|
|
12014
|
+
};
|
|
11693
12015
|
|
|
11694
12016
|
// src/client/browserMedia.ts
|
|
11695
12017
|
var DEFAULT_BROWSER_MEDIA_PATH = "/api/voice/browser-media";
|
|
@@ -51,6 +51,45 @@ export type VoiceSessionObservabilityReport = {
|
|
|
51
51
|
};
|
|
52
52
|
turns: VoiceSessionObservabilityTurn[];
|
|
53
53
|
};
|
|
54
|
+
export type VoiceSessionObservabilityEvidenceStatus = "pass" | "warn" | "fail";
|
|
55
|
+
export type VoiceSessionObservabilityEvidenceInput = {
|
|
56
|
+
requireHealthy?: boolean;
|
|
57
|
+
minStageCount?: number;
|
|
58
|
+
minTurns?: number;
|
|
59
|
+
minTurnWaterfalls?: number;
|
|
60
|
+
minProviderDecisions?: number;
|
|
61
|
+
minToolCalls?: number;
|
|
62
|
+
requireOperationsRecordLink?: boolean;
|
|
63
|
+
requireTraceTimelineLink?: boolean;
|
|
64
|
+
requireCallDebuggerLink?: boolean;
|
|
65
|
+
requireIncidentMarkdownLink?: boolean;
|
|
66
|
+
requireIncidentMarkdown?: boolean;
|
|
67
|
+
maxErrors?: number;
|
|
68
|
+
maxFallbacks?: number;
|
|
69
|
+
requireProviderRecoveryStatus?: VoiceOperationsRecord["providerDecisionSummary"]["recoveryStatus"] | readonly VoiceOperationsRecord["providerDecisionSummary"]["recoveryStatus"][];
|
|
70
|
+
};
|
|
71
|
+
export type VoiceSessionObservabilityEvidenceReport = {
|
|
72
|
+
checkedAt: number;
|
|
73
|
+
issues: string[];
|
|
74
|
+
ok: boolean;
|
|
75
|
+
status: VoiceSessionObservabilityEvidenceStatus;
|
|
76
|
+
summary: {
|
|
77
|
+
incidentMarkdownLength: number;
|
|
78
|
+
providerDecisions: number;
|
|
79
|
+
providerRecoveryStatus: VoiceOperationsRecord["providerDecisionSummary"]["recoveryStatus"];
|
|
80
|
+
reportStatus: VoiceSessionObservabilityStatus;
|
|
81
|
+
stages: number;
|
|
82
|
+
turns: number;
|
|
83
|
+
turnsWithWaterfalls: number;
|
|
84
|
+
toolCalls: number;
|
|
85
|
+
links: {
|
|
86
|
+
callDebugger: boolean;
|
|
87
|
+
incidentMarkdown: boolean;
|
|
88
|
+
operationsRecord: boolean;
|
|
89
|
+
traceTimeline: boolean;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
};
|
|
54
93
|
export type VoiceSessionObservabilityReportOptions = Omit<VoiceOperationsRecordOptions, "sessionId"> & {
|
|
55
94
|
callDebuggerHref?: false | string | ((sessionId: string) => string);
|
|
56
95
|
customLinks?: readonly VoiceSessionObservabilityLink[];
|
|
@@ -74,6 +113,8 @@ export declare const renderVoiceSessionObservabilityMarkdown: (report: VoiceSess
|
|
|
74
113
|
export declare const renderVoiceSessionObservabilityHTML: (report: VoiceSessionObservabilityReport, options?: {
|
|
75
114
|
title?: string;
|
|
76
115
|
}) => string;
|
|
116
|
+
export declare const evaluateVoiceSessionObservabilityEvidence: (report: VoiceSessionObservabilityReport, input?: VoiceSessionObservabilityEvidenceInput) => VoiceSessionObservabilityEvidenceReport;
|
|
117
|
+
export declare const assertVoiceSessionObservabilityEvidence: (report: VoiceSessionObservabilityReport, input?: VoiceSessionObservabilityEvidenceInput) => VoiceSessionObservabilityEvidenceReport;
|
|
77
118
|
export declare const createVoiceSessionObservabilityRoutes: (options: VoiceSessionObservabilityRoutesOptions) => Elysia<"", {
|
|
78
119
|
decorator: {};
|
|
79
120
|
store: {};
|