@absolutejs/voice 0.0.22-beta.532 → 0.0.22-beta.533
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/client/conversationAnalytics.d.ts +2 -1
- package/dist/client/htmxDashboardRenderers.d.ts +1 -2
- package/dist/client/platformCoverageWidget.d.ts +2 -1
- package/dist/client/proofTrendsWidget.d.ts +2 -1
- package/dist/client/voiceWidgetView.d.ts +0 -2
- package/dist/core/agent.d.ts +2 -1
- package/dist/core/agentTools.d.ts +1 -2
- package/dist/core/assistant.d.ts +2 -1
- package/dist/core/assistantExperiment.d.ts +5 -4
- package/dist/core/campaign.d.ts +2 -1
- package/dist/core/correction.d.ts +2 -1
- package/dist/core/deliveryRuntime.d.ts +3 -2
- package/dist/core/htmxDashboardRoutes.d.ts +2 -1
- package/dist/core/logger.d.ts +0 -1
- package/dist/core/midCallSummary.d.ts +3 -3
- package/dist/core/operationsRecord.d.ts +2 -1
- package/dist/core/phoneAgent.d.ts +1 -1
- package/dist/core/productionReadiness.d.ts +5 -4
- package/dist/core/providerStackRecommendations.d.ts +2 -1
- package/dist/core/reconnectContract.d.ts +2 -1
- package/dist/core/s3Store.d.ts +3 -9
- package/dist/core/simulationSuite.d.ts +2 -1
- package/dist/core/telephonyOutcome.d.ts +0 -4
- package/dist/core/turnProfiles.d.ts +1 -4
- package/dist/embed/voice-widget.js +1 -1
- package/dist/react/index.d.ts +21 -0
- package/dist/svelte/createVoiceCallDebugger.d.ts +0 -2
- package/dist/svelte/createVoiceSessionSnapshot.d.ts +0 -2
- package/package.json +1 -1
- package/dist/angular/voice-delivery-runtime.component.d.ts +0 -17
- package/dist/angular/voice-ops-status.component.d.ts +0 -15
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StoredVoiceTraceEvent } from "../core/trace";
|
|
2
|
-
|
|
2
|
+
type VoiceTrafficBucket = {
|
|
3
3
|
bucketKey: string;
|
|
4
4
|
callsCompleted: number;
|
|
5
5
|
callsFailed: number;
|
|
@@ -27,3 +27,4 @@ export type SummarizeVoiceCallTrafficOptions = {
|
|
|
27
27
|
toMs?: number;
|
|
28
28
|
};
|
|
29
29
|
export declare const summarizeVoiceCallTraffic: (options: SummarizeVoiceCallTrafficOptions) => VoiceTrafficSummary;
|
|
30
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { StoredVoiceTraceEvent } from "../core/trace";
|
|
2
2
|
import type { VoiceCallReviewArtifact } from "../testing/review";
|
|
3
|
-
import { type
|
|
3
|
+
import { type VoiceCostDashboardOptions, type VoiceCostDashboardReport } from "./costDashboard";
|
|
4
4
|
import { type LiveCallViewState, type LiveCallViewer } from "./liveCallViewer";
|
|
5
5
|
import { type ReplayTimelineReport } from "./replayTimeline";
|
|
6
6
|
import { type VoiceHTMXPollingAttributes } from "./htmxAttributes";
|
|
@@ -13,7 +13,6 @@ export type VoiceCostDashboardHTMXInput = {
|
|
|
13
13
|
title?: string;
|
|
14
14
|
};
|
|
15
15
|
export type VoiceCostDashboardRenderer = (input: VoiceCostDashboardHTMXInput) => string;
|
|
16
|
-
export type VoiceCostDashboardCellRenderer = (bucket: VoiceCostDashboardBucket, currency: string, isTotal: boolean) => string;
|
|
17
16
|
export type VoiceReplayTimelineHTMXInput = {
|
|
18
17
|
attributes?: VoiceDashboardHTMXAttributes;
|
|
19
18
|
emptyMessage?: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { VoicePlatformCoverageSurface } from "../core/platformCoverage";
|
|
2
2
|
import { type VoicePlatformCoverageClientOptions, type VoicePlatformCoverageSnapshot } from "./platformCoverage";
|
|
3
|
-
|
|
3
|
+
type VoicePlatformCoverageSurfaceView = VoicePlatformCoverageSurface & {
|
|
4
4
|
detail: string;
|
|
5
5
|
label: string;
|
|
6
6
|
};
|
|
@@ -35,3 +35,4 @@ export declare const mountVoicePlatformCoverage: (element: Element, path?: strin
|
|
|
35
35
|
refresh: () => Promise<import("..").VoicePlatformCoverageSummary | undefined>;
|
|
36
36
|
};
|
|
37
37
|
export declare const defineVoicePlatformCoverageElement: (tagName?: string) => void;
|
|
38
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type VoiceProofTrendReport } from "../core/proofTrends";
|
|
2
2
|
import { type VoiceProofTrendsClientOptions, type VoiceProofTrendsSnapshot } from "./proofTrends";
|
|
3
|
-
|
|
3
|
+
type VoiceProofTrendsMetricView = {
|
|
4
4
|
label: string;
|
|
5
5
|
value: string;
|
|
6
6
|
};
|
|
@@ -35,3 +35,4 @@ export declare const mountVoiceProofTrends: (element: Element, path?: string, op
|
|
|
35
35
|
refresh: () => Promise<VoiceProofTrendReport | undefined>;
|
|
36
36
|
};
|
|
37
37
|
export declare const defineVoiceProofTrendsElement: (tagName?: string) => void;
|
|
38
|
+
export {};
|
|
@@ -44,7 +44,5 @@ export type VoiceWidgetViewModel = {
|
|
|
44
44
|
theme: Required<VoiceWidgetTheme>;
|
|
45
45
|
title: string;
|
|
46
46
|
};
|
|
47
|
-
export declare const DEFAULT_VOICE_WIDGET_THEME: Required<VoiceWidgetTheme>;
|
|
48
|
-
export declare const DEFAULT_VOICE_WIDGET_LABELS: Required<VoiceWidgetLabels>;
|
|
49
47
|
export declare const createVoiceWidgetViewModel: (input: VoiceWidgetViewModelInput) => VoiceWidgetViewModel;
|
|
50
48
|
export declare const renderVoiceWidgetHTML: (model: VoiceWidgetViewModel) => string;
|
package/dist/core/agent.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { VoiceTraceEventStore } from "./trace";
|
|
|
3
3
|
import type { VoiceToolRuntime } from "./toolRuntime";
|
|
4
4
|
import { type VoiceAuditEventStore, type VoiceAuditLogger } from "./audit";
|
|
5
5
|
export type VoiceAgentMessageRole = "assistant" | "system" | "tool" | "user";
|
|
6
|
-
|
|
6
|
+
type VoiceAgentImageMediaType = "image/gif" | "image/jpeg" | "image/png" | "image/webp";
|
|
7
7
|
export type VoiceAgentMessageAttachment = {
|
|
8
8
|
data: string;
|
|
9
9
|
kind: "image";
|
|
@@ -185,3 +185,4 @@ export type VoiceAgentSquadOptions<TContext = unknown, TSession extends VoiceSes
|
|
|
185
185
|
export declare const createVoiceAgentTool: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TArgs = Record<string, unknown>, TToolResult = unknown, TRouteResult = unknown>(tool: VoiceAgentTool<TContext, TSession, TArgs, TToolResult, TRouteResult>) => VoiceAgentTool<TContext, TSession, TArgs, TToolResult, TRouteResult>;
|
|
186
186
|
export declare const createVoiceAgent: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options: VoiceAgentOptions<TContext, TSession, TResult>) => VoiceAgent<TContext, TSession, TResult>;
|
|
187
187
|
export declare const createVoiceAgentSquad: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options: VoiceAgentSquadOptions<TContext, TSession, TResult>) => VoiceAgent<TContext, TSession, TResult>;
|
|
188
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type VoiceAgentTool } from "./agent";
|
|
2
|
-
import type {
|
|
2
|
+
import type { VoiceSessionHandle, VoiceSessionRecord } from "./types";
|
|
3
3
|
export type VoiceEndCallToolArgs = {
|
|
4
4
|
reason?: string;
|
|
5
5
|
};
|
|
@@ -130,4 +130,3 @@ export type VoiceApiRequestToolOptions<TContext = unknown, TSession extends Voic
|
|
|
130
130
|
url: string;
|
|
131
131
|
};
|
|
132
132
|
export declare const createVoiceApiRequestTool: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TArgs extends VoiceApiRequestToolArgs = VoiceApiRequestToolArgs, TResponse = unknown>(options: VoiceApiRequestToolOptions<TContext, TSession, TArgs, TResponse>) => VoiceAgentTool<TContext, TSession, TArgs, VoiceApiRequestToolResult<TResponse>>;
|
|
133
|
-
export type VoiceRouteResultLike = VoiceRouteResult<unknown>;
|
package/dist/core/assistant.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export type VoiceAssistantMemoryLifecycle<TContext = unknown, TSession extends V
|
|
|
41
41
|
}) => Promise<void> | void;
|
|
42
42
|
beforeTurn?: (input: VoiceAssistantMemoryLifecycleInput<TContext, TSession, TResult>) => Promise<void> | void;
|
|
43
43
|
};
|
|
44
|
-
|
|
44
|
+
type VoiceAssistantExperimentResolverInput<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord> = {
|
|
45
45
|
assistantId: string;
|
|
46
46
|
context: TContext;
|
|
47
47
|
session: TSession;
|
|
@@ -140,3 +140,4 @@ export declare const summarizeVoiceAssistantRuns: (input: StoredVoiceTraceEvent[
|
|
|
140
140
|
events?: StoredVoiceTraceEvent[];
|
|
141
141
|
store?: VoiceTraceEventStore;
|
|
142
142
|
}) => Promise<VoiceAssistantRunsSummary>;
|
|
143
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DefinedVoiceAssistant } from "./defineVoiceAssistant";
|
|
2
2
|
import type { VoiceSessionRecord } from "./types";
|
|
3
|
-
|
|
3
|
+
type VoiceAssistantVariant<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
4
4
|
/** Stable variant id used for trace tagging + rollups. */
|
|
5
5
|
id: string;
|
|
6
6
|
/** Relative weight when allocator is 'random' or 'sticky' bucketing. Default 1. */
|
|
@@ -8,12 +8,12 @@ export type VoiceAssistantVariant<TContext = unknown, TSession extends VoiceSess
|
|
|
8
8
|
/** The assistant definition produced by defineVoiceAssistant. */
|
|
9
9
|
assistant: DefinedVoiceAssistant<TContext, TSession, TResult>;
|
|
10
10
|
};
|
|
11
|
-
|
|
11
|
+
type VoiceAssistantAllocatorInput<TContext = unknown> = {
|
|
12
12
|
context: TContext;
|
|
13
13
|
sessionId: string;
|
|
14
14
|
stickyKey?: string;
|
|
15
15
|
};
|
|
16
|
-
|
|
16
|
+
type VoiceAssistantAllocator<TContext = unknown> = (input: VoiceAssistantAllocatorInput<TContext>) => string;
|
|
17
17
|
export type VoiceAssistantExperimentOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
18
18
|
/** Variant chooser. Default 'sticky' (hash of stickyKey → variant) when stickyKey is present, otherwise 'random'. */
|
|
19
19
|
allocator?: "random" | "sticky" | VoiceAssistantAllocator<TContext>;
|
|
@@ -29,7 +29,7 @@ export type VoiceAssistantExperimentOptions<TContext = unknown, TSession extends
|
|
|
29
29
|
}) => void;
|
|
30
30
|
variants: ReadonlyArray<VoiceAssistantVariant<TContext, TSession, TResult>>;
|
|
31
31
|
};
|
|
32
|
-
|
|
32
|
+
type VoiceAssistantExperimentDecision<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
33
33
|
experimentId: string;
|
|
34
34
|
variant: VoiceAssistantVariant<TContext, TSession, TResult>;
|
|
35
35
|
};
|
|
@@ -39,3 +39,4 @@ export type VoiceAssistantExperiment<TContext = unknown, TSession extends VoiceS
|
|
|
39
39
|
variants: ReadonlyArray<VoiceAssistantVariant<TContext, TSession, TResult>>;
|
|
40
40
|
};
|
|
41
41
|
export declare const createVoiceAssistantExperiment: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options: VoiceAssistantExperimentOptions<TContext, TSession, TResult>) => VoiceAssistantExperiment<TContext, TSession, TResult>;
|
|
42
|
+
export {};
|
package/dist/core/campaign.d.ts
CHANGED
|
@@ -281,7 +281,7 @@ export type VoiceCampaignWorkerOptions = {
|
|
|
281
281
|
store?: VoiceCampaignStore;
|
|
282
282
|
workerId: string;
|
|
283
283
|
};
|
|
284
|
-
|
|
284
|
+
type VoiceCampaignWorkerResult = {
|
|
285
285
|
attempted: number;
|
|
286
286
|
campaigns: number;
|
|
287
287
|
errors: Array<{
|
|
@@ -792,3 +792,4 @@ export declare const createVoiceCampaignRoutes: (options: VoiceCampaignRoutesOpt
|
|
|
792
792
|
standaloneSchema: {};
|
|
793
793
|
response: {};
|
|
794
794
|
}>;
|
|
795
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { VoiceCorrectionRiskTier, VoiceDomainTerm, VoiceLexiconEntry, VoicePhraseHint, VoiceTurnCorrectionHandler } from "./types";
|
|
2
|
-
|
|
2
|
+
type VoicePhraseHintCorrectionMatch = {
|
|
3
3
|
alias: string;
|
|
4
4
|
hint: VoicePhraseHint;
|
|
5
5
|
};
|
|
@@ -31,3 +31,4 @@ export declare const createPhraseHintCorrectionHandler: (options?: VoicePhraseHi
|
|
|
31
31
|
export declare const applyLexiconCorrections: (text: string, lexicon: VoiceLexiconEntry[]) => VoicePhraseHintCorrectionResult;
|
|
32
32
|
export declare const createLexiconCorrectionHandler: (options?: VoiceLexiconCorrectionOptions) => VoiceTurnCorrectionHandler;
|
|
33
33
|
export declare const createRiskyTurnCorrectionHandler: (options?: VoiceRiskyTurnCorrectionHandlerOptions) => VoiceTurnCorrectionHandler;
|
|
34
|
+
export {};
|
|
@@ -21,7 +21,7 @@ export type VoiceDeliveryRuntimeTickResult = {
|
|
|
21
21
|
audit?: VoiceAuditSinkDeliveryWorkerResult;
|
|
22
22
|
trace?: VoiceTraceSinkDeliveryWorkerResult;
|
|
23
23
|
};
|
|
24
|
-
|
|
24
|
+
type VoiceDeliveryRuntimeRequeueDeadLettersResult = {
|
|
25
25
|
audit: number;
|
|
26
26
|
trace: number;
|
|
27
27
|
total: number;
|
|
@@ -65,7 +65,7 @@ export type VoiceDeliveryRuntimePresetLeaseConfig = VoiceRedisTaskLeaseCoordinat
|
|
|
65
65
|
audit: VoiceRedisTaskLeaseCoordinator;
|
|
66
66
|
trace: VoiceRedisTaskLeaseCoordinator;
|
|
67
67
|
};
|
|
68
|
-
|
|
68
|
+
type VoiceDeliveryRuntimePresetBaseOptions = {
|
|
69
69
|
auditDeliveries: VoiceAuditSinkDeliveryStore;
|
|
70
70
|
auditSinkId?: string;
|
|
71
71
|
auditWorkerId?: string;
|
|
@@ -156,3 +156,4 @@ export declare const createVoiceDeliveryRuntimeRoutes: (options: VoiceDeliveryRu
|
|
|
156
156
|
standaloneSchema: {};
|
|
157
157
|
response: {};
|
|
158
158
|
}>;
|
|
159
|
+
export {};
|
|
@@ -4,7 +4,7 @@ import type { StoredVoiceCallReviewArtifact, VoiceCallReviewStore } from "../tes
|
|
|
4
4
|
import type { LiveCallViewer } from "../client/liveCallViewer";
|
|
5
5
|
import { type VoiceDashboardHTMXRendererConfig } from "../client/htmxDashboardRenderers";
|
|
6
6
|
import type { VoiceCostDashboardOptions } from "../client/costDashboard";
|
|
7
|
-
|
|
7
|
+
type VoiceHTMXDashboardRoutesShared = {
|
|
8
8
|
name?: string;
|
|
9
9
|
render?: VoiceDashboardHTMXRendererConfig;
|
|
10
10
|
};
|
|
@@ -247,3 +247,4 @@ export declare const createVoiceHTMXDashboardRoutesFromStores: (options: CreateV
|
|
|
247
247
|
standaloneSchema: {};
|
|
248
248
|
response: {};
|
|
249
249
|
}>;
|
|
250
|
+
export {};
|
package/dist/core/logger.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { VoiceLogger } from "./types";
|
|
2
|
-
export declare const createNoopLogger: () => Required<VoiceLogger>;
|
|
3
2
|
export declare const resolveLogger: (logger?: VoiceLogger) => {
|
|
4
3
|
debug: (message: string, meta?: Record<string, unknown>) => void;
|
|
5
4
|
info: (message: string, meta?: Record<string, unknown>) => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VoiceSessionRecord, VoiceTurnRecord } from "./types";
|
|
2
2
|
import type { VoiceLLMJudgeCompletion } from "./llmJudge";
|
|
3
|
-
|
|
3
|
+
type MidCallSummary = {
|
|
4
4
|
generatedAt: number;
|
|
5
5
|
summary: string;
|
|
6
6
|
topicalShift?: boolean;
|
|
@@ -24,4 +24,4 @@ export type MidCallSummarizer = {
|
|
|
24
24
|
latest: () => MidCallSummary | undefined;
|
|
25
25
|
};
|
|
26
26
|
export declare const createMidCallSummarizer: (options: CreateMidCallSummarizerOptions) => MidCallSummarizer;
|
|
27
|
-
export
|
|
27
|
+
export {};
|
|
@@ -145,7 +145,7 @@ export type VoiceOperationsRecordTelephonyMediaSummary = {
|
|
|
145
145
|
streamIds: string[];
|
|
146
146
|
total: number;
|
|
147
147
|
};
|
|
148
|
-
|
|
148
|
+
type VoiceOperationsRecordMediaPipelineSummary = {
|
|
149
149
|
frames: number;
|
|
150
150
|
issueCodes: readonly string[];
|
|
151
151
|
jitterMs?: number;
|
|
@@ -368,3 +368,4 @@ export declare const createVoiceOperationsRecordRoutes: (options: VoiceOperation
|
|
|
368
368
|
standaloneSchema: {};
|
|
369
369
|
response: {};
|
|
370
370
|
}>;
|
|
371
|
+
export {};
|
|
@@ -43,7 +43,7 @@ export type VoicePhoneAgentCarrierSummary = {
|
|
|
43
43
|
setupPath?: false | string;
|
|
44
44
|
smokePath?: false | string;
|
|
45
45
|
};
|
|
46
|
-
|
|
46
|
+
type VoicePhoneAgentSetupInstruction = {
|
|
47
47
|
answerLabel: string;
|
|
48
48
|
answerUrl?: string;
|
|
49
49
|
carrierName: string;
|
|
@@ -25,7 +25,7 @@ import type { VoiceMediaPipelineReport } from "./mediaPipelineRoutes";
|
|
|
25
25
|
import type { VoiceTelephonyMediaReport } from "./telephonyMediaRoutes";
|
|
26
26
|
import type { MediaWebRTCStatsReport } from "@absolutejs/media";
|
|
27
27
|
import { type VoiceProfileSwitchReadinessOptions, type VoiceProfileSwitchReadinessReport } from "./profileSwitchRecommendation";
|
|
28
|
-
|
|
28
|
+
type VoiceProductionReadinessObservabilityExportDeliveryHistoryOptions = {
|
|
29
29
|
failOnMissing?: boolean;
|
|
30
30
|
failOnStale?: boolean;
|
|
31
31
|
history?: VoiceObservabilityExportDeliveryHistory;
|
|
@@ -33,7 +33,7 @@ export type VoiceProductionReadinessObservabilityExportDeliveryHistoryOptions =
|
|
|
33
33
|
store?: VoiceObservabilityExportDeliveryReceiptStore;
|
|
34
34
|
};
|
|
35
35
|
export type VoiceProductionReadinessStatus = "fail" | "pass" | "warn";
|
|
36
|
-
|
|
36
|
+
type VoiceProductionReconnectEvidence = VoiceReconnectContractReport | VoiceReconnectProofReport;
|
|
37
37
|
export type VoiceProductionReadinessAction = {
|
|
38
38
|
description?: string;
|
|
39
39
|
href: string;
|
|
@@ -504,7 +504,7 @@ export type VoiceProductionReadinessOpsActionHistorySummary = {
|
|
|
504
504
|
total: number;
|
|
505
505
|
warnWhenEmpty: boolean;
|
|
506
506
|
};
|
|
507
|
-
|
|
507
|
+
type VoiceProductionReadinessDeliveryRuntimeSummary = {
|
|
508
508
|
audit?: VoiceProductionReadinessDeliveryRuntimeQueueSummary;
|
|
509
509
|
deadLettered: number;
|
|
510
510
|
delivered: number;
|
|
@@ -516,7 +516,7 @@ export type VoiceProductionReadinessDeliveryRuntimeSummary = {
|
|
|
516
516
|
total: number;
|
|
517
517
|
trace?: VoiceProductionReadinessDeliveryRuntimeQueueSummary;
|
|
518
518
|
};
|
|
519
|
-
|
|
519
|
+
type VoiceProductionReadinessDeliveryRuntimeQueueSummary = {
|
|
520
520
|
deadLettered: number;
|
|
521
521
|
delivered: number;
|
|
522
522
|
failed: number;
|
|
@@ -754,3 +754,4 @@ export declare const createVoiceProductionReadinessRoutes: (options: VoiceProduc
|
|
|
754
754
|
standaloneSchema: {};
|
|
755
755
|
response: {};
|
|
756
756
|
}>;
|
|
757
|
+
export {};
|
|
@@ -53,7 +53,7 @@ export type VoiceProviderStackCapabilityGapInput<TProvider extends string = stri
|
|
|
53
53
|
required?: Partial<Record<VoiceProviderStackKind, readonly string[]>>;
|
|
54
54
|
};
|
|
55
55
|
export type VoiceProviderContractCheckStatus = "fail" | "pass" | "warn";
|
|
56
|
-
|
|
56
|
+
type VoiceProviderContractRemediation = {
|
|
57
57
|
code: string;
|
|
58
58
|
detail: string;
|
|
59
59
|
href?: string;
|
|
@@ -185,3 +185,4 @@ export declare const createVoiceProviderContractMatrixRoutes: <TProvider extends
|
|
|
185
185
|
export declare const evaluateVoiceProviderStackGaps: <TProvider extends string = string>(input: VoiceProviderStackCapabilityGapInput<TProvider>) => VoiceProviderStackCapabilityGapReport<TProvider>;
|
|
186
186
|
export declare const evaluateVoiceProviderStackEvidence: <TProvider extends string = string>(report: VoiceProviderStackCapabilityGapReport<TProvider>, input?: VoiceProviderStackAssertionInput<TProvider>) => VoiceProviderStackAssertionReport<TProvider>;
|
|
187
187
|
export declare const assertVoiceProviderStackEvidence: <TProvider extends string = string>(report: VoiceProviderStackCapabilityGapReport<TProvider>, input?: VoiceProviderStackAssertionInput<TProvider>) => VoiceProviderStackAssertionReport<TProvider>;
|
|
188
|
+
export {};
|
|
@@ -6,7 +6,7 @@ export type VoiceReconnectContractSnapshot = {
|
|
|
6
6
|
reconnect: VoiceReconnectClientState;
|
|
7
7
|
turnIds?: readonly string[];
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
type VoiceReconnectContractIssue = {
|
|
10
10
|
code: string;
|
|
11
11
|
message: string;
|
|
12
12
|
severity: "error" | "warning";
|
|
@@ -174,3 +174,4 @@ export declare const createVoiceReconnectContractRoutes: (options: VoiceReconnec
|
|
|
174
174
|
standaloneSchema: {};
|
|
175
175
|
response: {};
|
|
176
176
|
}>;
|
|
177
|
+
export {};
|
package/dist/core/s3Store.d.ts
CHANGED
|
@@ -13,17 +13,11 @@ export type VoiceS3ReviewStoreOptions = S3Options & {
|
|
|
13
13
|
keyPrefix?: string;
|
|
14
14
|
};
|
|
15
15
|
export declare const createVoiceS3ReviewStore: <TArtifact extends StoredVoiceCallReviewArtifact = StoredVoiceCallReviewArtifact>(options: VoiceS3ReviewStoreOptions) => VoiceCallReviewStore<TArtifact>;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
exists: () => Promise<boolean>;
|
|
19
|
-
text: () => Promise<string>;
|
|
20
|
-
bytes: () => Promise<Uint8Array>;
|
|
21
|
-
write: (data: string | Uint8Array) => Promise<number>;
|
|
22
|
-
};
|
|
23
|
-
export type VoiceS3RecordingStoreClient = Pick<S3Client, "file" | "list">;
|
|
24
|
-
export type VoiceS3RecordingStoreOptions = S3Options & {
|
|
16
|
+
type VoiceS3RecordingStoreClient = Pick<S3Client, "file" | "list">;
|
|
17
|
+
type VoiceS3RecordingStoreOptions = S3Options & {
|
|
25
18
|
client?: VoiceS3RecordingStoreClient;
|
|
26
19
|
keyPrefix?: string;
|
|
27
20
|
publicUrlBase?: string;
|
|
28
21
|
};
|
|
29
22
|
export declare const createVoiceS3RecordingStore: (options: VoiceS3RecordingStoreOptions) => VoiceRecordingStore;
|
|
23
|
+
export {};
|
|
@@ -26,7 +26,7 @@ export type VoiceSimulationSuiteReport = {
|
|
|
26
26
|
tools?: VoiceToolContractSuiteReport;
|
|
27
27
|
total: number;
|
|
28
28
|
};
|
|
29
|
-
|
|
29
|
+
type VoiceSimulationSuiteAction = {
|
|
30
30
|
description: string;
|
|
31
31
|
href?: string;
|
|
32
32
|
label: string;
|
|
@@ -141,3 +141,4 @@ export declare const createVoiceSimulationSuiteRoutes: <TSession extends VoiceSe
|
|
|
141
141
|
response: {};
|
|
142
142
|
}>;
|
|
143
143
|
export type VoiceSimulationSuiteEvalRoutesOptions = VoiceEvalRoutesOptions;
|
|
144
|
+
export {};
|
|
@@ -204,10 +204,6 @@ export type VoiceTelephonyWebhookRoutesOptions<TContext = unknown, TSession exte
|
|
|
204
204
|
name?: string;
|
|
205
205
|
path?: string;
|
|
206
206
|
};
|
|
207
|
-
export declare class VoiceTelephonyWebhookVerificationError extends Error {
|
|
208
|
-
result: VoiceTelephonyWebhookVerificationResult;
|
|
209
|
-
constructor(result: VoiceTelephonyWebhookVerificationResult);
|
|
210
|
-
}
|
|
211
207
|
export declare const createMemoryVoiceTelephonyWebhookIdempotencyStore: <TResult = unknown>() => VoiceTelephonyWebhookIdempotencyStore<TResult>;
|
|
212
208
|
export declare const evaluateVoiceTelephonyWebhookNormalizationEvidence: (input?: VoiceTelephonyWebhookNormalizationEvidenceInput) => VoiceTelephonyWebhookNormalizationEvidenceReport;
|
|
213
209
|
export declare const assertVoiceTelephonyWebhookNormalizationEvidence: (input?: VoiceTelephonyWebhookNormalizationEvidenceInput) => VoiceTelephonyWebhookNormalizationEvidenceReport;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import type { VoiceResolvedTurnDetectionConfig, VoiceTurnDetectionConfig,
|
|
1
|
+
import type { VoiceResolvedTurnDetectionConfig, VoiceTurnDetectionConfig, VoiceTurnProfile } from "./types";
|
|
2
2
|
export declare const TURN_PROFILE_DEFAULTS: Record<VoiceTurnProfile, Omit<VoiceResolvedTurnDetectionConfig, "profile">>;
|
|
3
|
-
export declare const QUALITY_PROFILE_DEFAULTS: Record<VoiceTurnQualityProfile, Partial<VoiceResolvedTurnDetectionConfig>>;
|
|
4
|
-
export declare const DEFAULT_TURN_PROFILE: VoiceTurnProfile;
|
|
5
|
-
export declare const DEFAULT_QUALITY_PROFILE: VoiceTurnQualityProfile;
|
|
6
3
|
export declare const resolveTurnDetectionConfig: (config?: VoiceTurnDetectionConfig) => VoiceResolvedTurnDetectionConfig;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{var{defineProperty:H,getOwnPropertyNames:oc,getOwnPropertyDescriptor:lc}=Object,Ac=Object.prototype.hasOwnProperty;function Cc(c){return this[c]}var ic=(c)=>{var n=(Y??=new WeakMap).get(c),o;if(n)return n;if(n=H({},"__esModule",{value:!0}),c&&typeof c==="object"||typeof c==="function"){for(var g of oc(c))if(!Ac.call(n,g))H(n,g,{get:Cc.bind(c,g),enumerable:!(o=lc(c,g))||o.enumerable})}return Y.set(c,n),n},Y;var Tc=(c)=>c;function yc(c,n){this[c]=Tc.bind(null,n)}var Vc=(c,n)=>{for(var o in n)H(c,o,{get:n[o],enumerable:!0,configurable:!0,set:yc.bind(n,o)})};var Bc={};Vc(Bc,{mount:()=>p,default:()=>Kc,VOICE_EMBED_VERSION:()=>cc});var Ic=(c)=>{if(typeof c!=="string")return c;return document.querySelector(c)},Rc=(c,n,o,g)=>{let l=n??c.getAttribute("hx-get")??"";if(!l)return"";let i=new URL(l,window.location.origin);if(g)i.searchParams.set(o,g);else i.searchParams.delete(o);return`${i.pathname}${i.search}${i.hash}`},Q=(c,n)=>{if(typeof window>"u"||typeof document>"u")return()=>{};let o=Ic(n.element);if(!o)return()=>{};let g=n.eventName??"voice-refresh",l=n.sessionQueryParam??"sessionId",i=()=>{let V=window,I=Rc(o,n.route,l,c.sessionId);if(I)o.setAttribute("hx-get",I);V.htmx?.process?.(o),V.htmx?.trigger?.(o,g)},C=c.subscribe(i);return i(),()=>{C()}};var hc=(c)=>Math.max(-1,Math.min(1,c)),dc=(c)=>{let n=new Int16Array(c.length);for(let o=0;o<c.length;o+=1){let g=hc(c[o]??0);n[o]=g<0?g*32768:g*32767}return new Uint8Array(n.buffer)},Sc=(c)=>{let n=c instanceof Uint8Array?c:new Uint8Array(c);if(n.byteLength<2)return 0;let o=new Int16Array(n.buffer,n.byteOffset,Math.floor(n.byteLength/2));if(o.length===0)return 0;let g=0;for(let l of o){let i=l/32768;g+=i*i}return Math.min(1,Math.max(0,Math.sqrt(g/o.length)*5.5))},_c=(c,n,o)=>{if(n===o)return c;let g=n/o,l=Math.round(c.length/g),i=new Float32Array(l),C=0,V=0;while(C<i.length){let I=Math.round((C+1)*g),d=0,y=0;for(let h=V;h<I&&h<c.length;h+=1)d+=c[h]??0,y+=1;i[C]=y>0?d/y:0,C+=1,V=I}return i},J=(c)=>{let n=null,o=null,g=null,l=null;return{start:async()=>{if(typeof navigator>"u"||!navigator.mediaDevices?.getUserMedia)throw Error("Browser microphone capture requires navigator.mediaDevices.getUserMedia.");let V=(typeof window<"u"?window.AudioContext??window.webkitAudioContext:void 0)??AudioContext;if(!V)throw Error("Browser microphone capture requires AudioContext support.");l=await navigator.mediaDevices.getUserMedia({audio:{channelCount:c.channelCount??1}}),n=new V,o=n.createMediaStreamSource(l),g=n.createScriptProcessor(4096,1,1),g.onaudioprocess=(I)=>{let d=I.inputBuffer.getChannelData(0),y=_c(d,n?.sampleRate??48000,c.sampleRateHz??16000),h=dc(y);c.onLevel?.(Sc(h)),c.onAudio(h)},o.connect(g),g.connect(n.destination)},stop:()=>{g?.disconnect(),o?.disconnect(),l?.getTracks().forEach((V)=>V.stop()),n?.close(),c.onLevel?.(0),n=null,l=null,g=null,o=null}}};var G=(c)=>{if(typeof c==="string"&&c.trim())return c;if(c instanceof Error&&c.message.trim())return c.message;if(c&&typeof c==="object"){let n=c;for(let o of["message","reason","description"]){let g=n[o];if(typeof g==="string"&&g.trim())return g}if("error"in n)return G(n.error);if("cause"in n)return G(n.cause);try{return JSON.stringify(c)}catch{}}return"Unexpected error"},q=(c)=>{switch(c.type){case"audio":return{chunk:Uint8Array.from(atob(c.chunkBase64),(n)=>n.charCodeAt(0)),format:c.format,receivedAt:c.receivedAt,turnId:c.turnId,type:"audio"};case"assistant":return{text:c.text,type:"assistant"};case"complete":return{sessionId:c.sessionId,type:"complete"};case"connection":return{reconnect:c.reconnect,type:"connection"};case"call_lifecycle":return{event:c.event,sessionId:c.sessionId,type:"call_lifecycle"};case"error":return{message:G(c.message),type:"error"};case"final":return{transcript:c.transcript,type:"final"};case"partial":return{transcript:c.transcript,type:"partial"};case"replay":return{assistantTexts:c.assistantTexts,call:c.call,partial:c.partial,scenarioId:c.scenarioId,sessionId:c.sessionId,sessionMetadata:c.sessionMetadata,status:c.status,turns:c.turns,type:"replay"};case"session":return{sessionId:c.sessionId,sessionMetadata:c.sessionMetadata,scenarioId:c.scenarioId,status:c.status,type:"session"};case"turn":return{turn:c.turn,type:"turn"};default:return null}};var tc=Math.PI*2;var D=(c,n,o,g)=>{c.push({code:o,message:g,severity:n})};var wc=(c)=>c.length===0?void 0:c.reduce((n,o)=>n+o,0)/c.length,$=(c)=>c.length===0?void 0:Math.max(...c);var _=(c,n)=>{let o=c[n];return typeof o==="number"&&Number.isFinite(o)?o:void 0},N=(c,n)=>{let o=c[n];return typeof o==="boolean"?o:void 0},w=(c,n)=>{let o=c[n];return typeof o==="string"?o:void 0},X=(c)=>String(c.id??w(c,"ssrc")??_(c,"ssrc")??w(c,"trackIdentifier")??w(c,"mid")??"unknown"),Z=(c)=>c===void 0?void 0:c*1000;var Lc=(c)=>{let n={};for(let[o,g]of Object.entries(c))if(g===null||typeof g==="boolean"||typeof g==="number"||typeof g==="string")n[o]=g;return n};var z=(c={})=>{let n=c.stats??[],o=[],g=n.filter((A)=>A.type==="inbound-rtp"&&w(A,"kind")!=="video"),l=n.filter((A)=>A.type==="outbound-rtp"&&w(A,"kind")!=="video"),i=n.filter((A)=>A.type==="candidate-pair"),C=n.filter((A)=>(A.type==="track"||A.type==="media-source")&&w(A,"kind")==="audio"),V=i.filter((A)=>N(A,"selected")===!0||N(A,"nominated")===!0||w(A,"state")==="succeeded").length,I=C.filter((A)=>w(A,"readyState")!=="ended"&&w(A,"trackState")!=="ended"&&N(A,"ended")!==!0).length,d=C.filter((A)=>w(A,"readyState")==="ended"||w(A,"trackState")==="ended"||N(A,"ended")===!0).length,y=g.reduce((A,S)=>A+(_(S,"packetsReceived")??0),0),h=l.reduce((A,S)=>A+(_(S,"packetsSent")??0),0),T=[...g,...l].reduce((A,S)=>A+Math.max(0,_(S,"packetsLost")??0),0),L=y+T,R=L===0?0:T/L,E=g.reduce((A,S)=>A+(_(S,"bytesReceived")??0),0),b=l.reduce((A,S)=>A+(_(S,"bytesSent")??0),0),M=$(i.map((A)=>Z(_(A,"currentRoundTripTime")??_(A,"roundTripTime"))).filter((A)=>A!==void 0)),O=$([...g,...l].map((A)=>Z(_(A,"jitter"))).filter((A)=>A!==void 0)),W=$(g.map((A)=>{let S=_(A,"jitterBufferDelay"),U=_(A,"jitterBufferEmittedCount");return S!==void 0&&U!==void 0&&U>0?S/U*1000:void 0}).filter((A)=>A!==void 0)),P=C.map((A)=>_(A,"audioLevel")).filter((A)=>A!==void 0);if(c.requireConnectedCandidatePair&&i.length>0&&V===0)D(o,"error","media.webrtc_candidate_pair_missing","No active WebRTC candidate pair was observed.");if(c.requireLiveAudioTrack&&I===0)D(o,"error","media.webrtc_audio_track_missing","No live WebRTC audio track was observed.");if(c.maxPacketLossRatio!==void 0&&R>c.maxPacketLossRatio)D(o,"warning","media.webrtc_packet_loss",`Observed WebRTC packet loss ratio ${String(R)} above ${String(c.maxPacketLossRatio)}.`);if(c.maxRoundTripTimeMs!==void 0&&M!==void 0&&M>c.maxRoundTripTimeMs)D(o,"warning","media.webrtc_round_trip_time",`Observed WebRTC RTT ${String(M)}ms above ${String(c.maxRoundTripTimeMs)}ms.`);if(c.maxJitterMs!==void 0&&O!==void 0&&O>c.maxJitterMs)D(o,"warning","media.webrtc_jitter",`Observed WebRTC jitter ${String(O)}ms above ${String(c.maxJitterMs)}ms.`);return{activeCandidatePairs:V,audioLevelAverage:wc(P),bytesReceived:E,bytesSent:b,checkedAt:Date.now(),endedAudioTracks:d,inboundPackets:y,issues:o,jitterBufferDelayMs:W,jitterMs:O,liveAudioTracks:I,outboundPackets:h,packetLossRatio:R,packetsLost:T,roundTripTimeMs:M,status:o.some((A)=>A.severity==="error")?"fail":o.length>0?"warn":"pass",totalStats:n.length}},B=async(c)=>{return[...(await c.peerConnection.getStats(c.selector??null)).values()].map(Lc)};var K=(c={})=>{let n=c.stats??[],o=c.previousStats??[],g=[],l=new Map(o.map((T)=>[X(T),T])),C=n.filter((T)=>(T.type==="inbound-rtp"||T.type==="outbound-rtp")&&w(T,"kind")!=="video"&&w(T,"mediaType")!=="video").map((T)=>{let L=T.type==="outbound-rtp"?"outbound":"inbound",R=L==="outbound"?"packetsSent":"packetsReceived",E=L==="outbound"?"bytesSent":"bytesReceived",b=l.get(X(T)),M=_(T,R),O=b?_(b,R):void 0,W=_(T,E),P=b?_(b,E):void 0,A=T.timestamp!==void 0&&b?.timestamp!==void 0?T.timestamp-b.timestamp:void 0;return{bytesDelta:W!==void 0&&P!==void 0?W-P:void 0,currentPackets:M,direction:L,id:X(T),packetDelta:M!==void 0&&O!==void 0?M-O:void 0,previousPackets:O,timeDeltaMs:A}}),V=C.filter((T)=>T.direction==="inbound"),I=C.filter((T)=>T.direction==="outbound"),d=$(C.map((T)=>T.timeDeltaMs).filter((T)=>T!==void 0)),y=V.filter((T)=>c.maxInboundPacketStallMs!==void 0&&T.timeDeltaMs!==void 0&&T.timeDeltaMs>=c.maxInboundPacketStallMs&&T.packetDelta!==void 0&&T.packetDelta<=0).length,h=I.filter((T)=>c.maxOutboundPacketStallMs!==void 0&&T.timeDeltaMs!==void 0&&T.timeDeltaMs>=c.maxOutboundPacketStallMs&&T.packetDelta!==void 0&&T.packetDelta<=0).length;if(c.requireInboundAudio&&V.length===0)D(g,"error","media.webrtc_inbound_audio_missing","No inbound WebRTC audio RTP stream was observed.");if(c.requireOutboundAudio&&I.length===0)D(g,"error","media.webrtc_outbound_audio_missing","No outbound WebRTC audio RTP stream was observed.");if(c.maxGapMs!==void 0&&d!==void 0&&d>c.maxGapMs)D(g,"warning","media.webrtc_stream_gap",`Observed WebRTC stream sample gap ${String(d)}ms above ${String(c.maxGapMs)}ms.`);if(y>0)D(g,"error","media.webrtc_inbound_stalled",`${String(y)} inbound WebRTC audio stream(s) stopped receiving packets.`);if(h>0)D(g,"error","media.webrtc_outbound_stalled",`${String(h)} outbound WebRTC audio stream(s) stopped sending packets.`);return{checkedAt:Date.now(),inboundAudioStreams:V.length,issues:g,maxObservedGapMs:d,outboundAudioStreams:I.length,stalledInboundStreams:y,stalledOutboundStreams:h,status:g.some((T)=>T.severity==="error")?"fail":g.length>0?"warn":"pass",streams:C,totalStats:n.length}};var Uc="/api/voice/browser-media",bc=5000,Mc=async(c)=>c.peerConnection??await c.getPeerConnection?.()??null,Oc=async(c,n)=>{let o=n.fetch??globalThis.fetch;if(!o)return;await o(n.path??Uc,{body:JSON.stringify(c),headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"})},j=(c)=>{let n=null,o=[],g=async()=>{let C=await Mc(c);if(!C)return;let V=await B({peerConnection:C}),I=z({...c,stats:V}),d=c.continuity===!1?void 0:K({...c.continuity,previousStats:o,stats:V}),y={at:Date.now(),continuity:d,report:I,scenarioId:c.getScenarioId?.()??null,sessionId:c.getSessionId?.()??null};return o=V,c.onReport?.(y),await Oc(y,c),y},l=()=>{g().catch((C)=>{c.onError?.(C)})},i=()=>{if(n)clearInterval(n),n=null};return{close:i,reportOnce:g,start:()=>{if(n)return;l(),n=setInterval(l,c.intervalMs??bc)},stop:i}};var x=()=>{},Dc=()=>x,sc={callControl:x,close:x,endTurn:x,getReadyState:()=>3,getScenarioId:()=>"",getSessionId:()=>"",send:x,sendAudio:x,simulateDisconnect:x,start:()=>{},subscribe:Dc},xc=()=>crypto.randomUUID(),Ec=(c,n,o)=>{let{hostname:g,port:l,protocol:i}=window.location,C=i==="https:"?"wss:":"ws:",V=l?`:${l}`:"",I=new URL(`${C}//${g}${V}${c}`);if(I.searchParams.set("sessionId",n),o)I.searchParams.set("scenarioId",o);return I.toString()},Wc=(c)=>{if(!c||typeof c!=="object"||!("type"in c))return!1;switch(c.type){case"audio":case"assistant":case"call_lifecycle":case"complete":case"connection":case"error":case"final":case"partial":case"pong":case"replay":case"session":case"turn":return!0;default:return!1}},Pc=(c)=>{if(typeof c.data!=="string")return null;try{let n=JSON.parse(c.data);return Wc(n)?n:null}catch{return null}},e=(c,n={})=>{if(typeof window>"u")return sc;let o=new Set,g=n.reconnect!==!1,l=n.maxReconnectAttempts??10,i=n.pingInterval??30000,C={isConnected:!1,pendingMessages:[],scenarioId:n.scenarioId??null,pingInterval:null,reconnectAttempts:0,reconnectTimeout:null,sessionId:n.sessionId??xc(),ws:null},V=(A)=>{o.forEach((S)=>S(A))},I=()=>{if(C.pingInterval)clearInterval(C.pingInterval),C.pingInterval=null;if(C.reconnectTimeout)clearTimeout(C.reconnectTimeout),C.reconnectTimeout=null},d=()=>{if(C.ws?.readyState!==1)return;while(C.pendingMessages.length>0){let A=C.pendingMessages.shift();if(A!==void 0)C.ws.send(A)}},y=()=>{let A=Date.now()+500;C.reconnectAttempts+=1,V({reconnect:{attempts:C.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:l,nextAttemptAt:A,status:"reconnecting"},type:"connection"}),C.reconnectTimeout=setTimeout(()=>{if(C.reconnectAttempts>l){V({reconnect:{attempts:C.reconnectAttempts,maxAttempts:l,status:"exhausted"},type:"connection"});return}h()},500)},h=()=>{let A=new WebSocket(Ec(c,C.sessionId,C.scenarioId));A.binaryType="arraybuffer",A.onopen=()=>{let S=C.reconnectAttempts>0;if(C.isConnected=!0,d(),S)V({reconnect:{attempts:C.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:l,status:"resumed"},type:"connection"}),C.reconnectAttempts=0;o.forEach((U)=>U({scenarioId:C.scenarioId??void 0,sessionId:C.sessionId,status:"active",type:"session"})),C.pingInterval=setInterval(()=>{if(A.readyState===1)A.send(JSON.stringify({type:"ping"}))},i)},A.onmessage=(S)=>{let U=Pc(S);if(!U)return;if(U.type==="session")C.sessionId=U.sessionId,C.scenarioId=U.scenarioId??C.scenarioId;o.forEach((gc)=>gc(U))},A.onclose=(S)=>{if(C.isConnected=!1,I(),g&&S.code!==1000&&C.reconnectAttempts<l)y();else if(g&&S.code!==1000)V({reconnect:{attempts:C.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:l,status:"exhausted"},type:"connection"})},C.ws=A},T=(A)=>{if(C.ws?.readyState===1){C.ws.send(A);return}C.pendingMessages.push(A)},L=(A)=>{T(JSON.stringify(A))},R=(A={})=>{if(A.sessionId)C.sessionId=A.sessionId;if(A.scenarioId)C.scenarioId=A.scenarioId;L({type:"start",sessionId:C.sessionId,scenarioId:C.scenarioId??void 0})},E=(A)=>{T(A)},b=()=>{L({type:"end_turn"})},M=(A)=>{L({...A,type:"call_control"})},O=()=>{if(I(),C.ws)C.ws.close(1000),C.ws=null;C.isConnected=!1,o.clear()},W=()=>{if(C.ws?.readyState===1)C.ws.close(4000,"absolutejs-voice-reconnect-proof")},P=(A)=>{return o.add(A),()=>{o.delete(A)}};return h(),{callControl:M,close:O,endTurn:b,getReadyState:()=>C.ws?.readyState??3,getScenarioId:()=>C.scenarioId??"",getSessionId:()=>C.sessionId,send:L,sendAudio:E,simulateDisconnect:W,start:R,subscribe:P}};var Nc=()=>({attempts:0,maxAttempts:0,status:"idle"}),$c=()=>({assistantAudio:[],assistantTexts:[],call:null,error:null,isConnected:!1,sessionMetadata:null,scenarioId:null,partial:"",reconnect:Nc(),sessionId:null,status:"idle",turns:[]}),f=()=>{let c=$c(),n=new Set,o=()=>{n.forEach((l)=>l())};return{dispatch:(l)=>{switch(l.type){case"audio":c={...c,assistantAudio:[...c.assistantAudio,{chunk:l.chunk,format:l.format,receivedAt:l.receivedAt,turnId:l.turnId}]};break;case"assistant":c={...c,assistantTexts:[...c.assistantTexts,l.text]};break;case"complete":c={...c,sessionId:l.sessionId,status:"completed"};break;case"call_lifecycle":c={...c,call:{...c.call,disposition:l.event.type==="end"?l.event.disposition:c.call?.disposition,endedAt:l.event.type==="end"?l.event.at:c.call?.endedAt,events:[...c.call?.events??[],l.event],lastEventAt:l.event.at,startedAt:c.call?.startedAt??l.event.at},sessionId:l.sessionId};break;case"connected":c={...c,isConnected:!0,reconnect:c.reconnect.status==="reconnecting"?{...c.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:c.reconnect};break;case"connection":c={...c,reconnect:l.reconnect};break;case"disconnected":c={...c,isConnected:!1};break;case"error":c={...c,error:l.message};break;case"final":c={...c,partial:l.transcript.text,turns:c.turns.map((i)=>i)};break;case"partial":c={...c,partial:l.transcript.text};break;case"replay":c={...c,assistantTexts:[...l.assistantTexts],call:l.call??null,error:null,isConnected:l.status==="active",partial:l.partial,reconnect:c.reconnect.status==="reconnecting"?{...c.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:c.reconnect,scenarioId:l.scenarioId??c.scenarioId,sessionId:l.sessionId,sessionMetadata:l.sessionMetadata??c.sessionMetadata,status:l.status,turns:[...l.turns]};break;case"session":c={...c,error:null,scenarioId:l.scenarioId??c.scenarioId,isConnected:l.status==="active",sessionId:l.sessionId,sessionMetadata:l.sessionMetadata??c.sessionMetadata,status:l.status};break;case"turn":c={...c,partial:"",turns:[...c.turns,l.turn]};break}o()},getServerSnapshot:()=>c,getSnapshot:()=>c,subscribe:(l)=>{return n.add(l),()=>{n.delete(l)}}}};var k=(c,n={})=>{let o=e(c,n),g=f(),l=n.browserMedia&&typeof window<"u"?j({...n.browserMedia,getScenarioId:()=>n.browserMedia?n.browserMedia.getScenarioId?.()??o.getScenarioId():o.getScenarioId(),getSessionId:()=>n.browserMedia?n.browserMedia.getSessionId?.()??o.getSessionId():o.getSessionId()}):null,i=new Set,C=(y)=>Promise.resolve().then(()=>{if(!y?.sessionId&&!y?.scenarioId)return;o.start(y),l?.start()}),V=()=>{i.forEach((y)=>y())},I=()=>{if(!n.reconnectReportPath||typeof fetch>"u")return;let y=g.getSnapshot(),h=JSON.stringify({at:Date.now(),reconnect:y.reconnect,scenarioId:y.scenarioId,sessionId:o.getSessionId(),turnIds:y.turns.map((T)=>T.id)});fetch(n.reconnectReportPath,{body:h,headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"}).catch(()=>{})},d=o.subscribe((y)=>{let h=q(y);if(h){if(g.dispatch(h),y.type==="connection")I();V()}});return{callControl(y){o.callControl(y)},close(){d(),l?.close(),o.close(),g.dispatch({type:"disconnected"}),V()},endTurn(){o.endTurn()},get error(){return g.getSnapshot().error},getServerSnapshot(){return g.getServerSnapshot()},getSnapshot(){return g.getSnapshot()},get isConnected(){return g.getSnapshot().isConnected},get scenarioId(){return g.getSnapshot().scenarioId},get sessionMetadata(){return g.getSnapshot().sessionMetadata},start:C,get partial(){return g.getSnapshot().partial},get reconnect(){return g.getSnapshot().reconnect},get sessionId(){return o.getSessionId()},get status(){return g.getSnapshot().status},get turns(){return g.getSnapshot().turns},get assistantTexts(){return g.getSnapshot().assistantTexts},get assistantAudio(){return g.getSnapshot().assistantAudio},get call(){return g.getSnapshot().call},sendAudio(y){o.sendAudio(y)},simulateDisconnect(){o.simulateDisconnect()},subscribe(y){return i.add(y),()=>{i.delete(y)}}}};var t=(c)=>{if(!c||c.enabled===!1)return;return{enabled:!0,maxGain:c.maxGain??3,noiseGateAttenuation:c.noiseGateAttenuation??0.15,noiseGateThreshold:c.noiseGateThreshold??0.006,targetLevel:c.targetLevel??0.08}};var Hc={balanced:{qualityProfile:"general",silenceMs:1400,speechThreshold:0.012,transcriptStabilityMs:1000},fast:{qualityProfile:"general",silenceMs:700,speechThreshold:0.015,transcriptStabilityMs:450},"long-form":{qualityProfile:"general",silenceMs:2200,speechThreshold:0.01,transcriptStabilityMs:1500}},Gc={general:{},"accent-heavy":{silenceMs:1200,speechThreshold:0.01,transcriptStabilityMs:1200},"noisy-room":{silenceMs:2000,speechThreshold:0.02,transcriptStabilityMs:1600},"short-command":{silenceMs:500,speechThreshold:0.016,transcriptStabilityMs:420}};var F=(c)=>{let n=c?.profile??"fast",o=c?.qualityProfile??"general",g=Hc[n],l=Gc[o];return{profile:n,qualityProfile:o,silenceMs:c?.silenceMs??l.silenceMs??g.silenceMs,speechThreshold:c?.speechThreshold??l.speechThreshold??g.speechThreshold,transcriptStabilityMs:c?.transcriptStabilityMs??l.transcriptStabilityMs??g.transcriptStabilityMs}};var Xc={chat:{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"short-command",profile:"balanced"}},default:{capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"general",profile:"fast"}},dictation:{audioConditioning:{enabled:!0,maxGain:2.25,noiseGateAttenuation:0.05,noiseGateThreshold:0.003,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"accent-heavy",profile:"long-form"}},"guided-intake":{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:"turn-scoped",turnDetection:{qualityProfile:"accent-heavy",profile:"long-form"}},"noisy-room":{audioConditioning:{enabled:!0,maxGain:3,noiseGateAttenuation:0.12,noiseGateThreshold:0.006,targetLevel:0.085},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"noisy-room",profile:"long-form",silenceMs:2100,speechThreshold:0.02,transcriptStabilityMs:1650}},"pstn-balanced":{audioConditioning:{enabled:!0,maxGain:2.8,noiseGateAttenuation:0.07,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"noisy-room",profile:"long-form",silenceMs:660,speechThreshold:0.012,transcriptStabilityMs:300}},"pstn-fast":{audioConditioning:{enabled:!0,maxGain:2.75,noiseGateAttenuation:0.06,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"noisy-room",profile:"long-form",silenceMs:620,speechThreshold:0.012,transcriptStabilityMs:280}},reliability:{audioConditioning:{enabled:!0,maxGain:2.9,noiseGateAttenuation:0.08,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"noisy-room",profile:"long-form"}}},r=(c="default")=>{let n=Xc[c];return{audioConditioning:t(n.audioConditioning),capture:{channelCount:n.capture?.channelCount??1,sampleRateHz:n.capture?.sampleRateHz??16000},connection:{...n.connection},name:c,sttLifecycle:n.sttLifecycle??"continuous",turnDetection:F(n.turnDetection)}};var Yc=(c)=>({assistantAudio:[...c.assistantAudio],assistantTexts:[...c.assistantTexts],call:c.call,error:c.error,isConnected:c.isConnected,isRecording:!1,partial:c.partial,reconnect:c.reconnect,recordingError:null,sessionId:c.sessionId,sessionMetadata:c.sessionMetadata,scenarioId:c.scenarioId,status:c.status,turns:[...c.turns]}),a=(c,n={})=>{let o=r(n.preset),g=k(c,{...o.connection,...n.connection}),l=null,i=Yc(g),C=new Set,V=()=>{for(let R of C)R()},I=()=>{if(i={...i,assistantAudio:[...g.assistantAudio],assistantTexts:[...g.assistantTexts],call:g.call,error:g.error,isConnected:g.isConnected,partial:g.partial,reconnect:g.reconnect,sessionId:g.sessionId,sessionMetadata:g.sessionMetadata,scenarioId:g.scenarioId,status:g.status,turns:[...g.turns]},n.autoStopOnComplete!==!1&&i.status==="completed"&&i.isRecording)l?.stop(),l=null,i={...i,isRecording:!1};V()},d=g.subscribe(I);I();let y=()=>{if(l)return l;return l=J({channelCount:n.capture?.channelCount??o.capture.channelCount,onLevel:n.capture?.onLevel,onAudio:(R)=>{if(n.capture?.onAudio){n.capture.onAudio(R,g.sendAudio);return}g.sendAudio(R)},sampleRateHz:n.capture?.sampleRateHz??o.capture.sampleRateHz}),l},h=()=>{l?.stop(),l=null,i={...i,isRecording:!1},V()},T=async()=>{if(i.isRecording)return;try{i={...i,recordingError:null},V(),await y().start(),i={...i,isRecording:!0},V()}catch(R){throw l=null,i={...i,isRecording:!1,recordingError:R instanceof Error?R.message:String(R)},V(),R}};return{bindHTMX(R){return Q(g,R)},callControl:(R)=>g.callControl(R),close:()=>{d(),h(),g.close()},endTurn:()=>g.endTurn(),get error(){return i.error},getServerSnapshot:()=>i,getSnapshot:()=>i,get isConnected(){return i.isConnected},get isRecording(){return i.isRecording},get partial(){return i.partial},get recordingError(){return i.recordingError},get reconnect(){return i.reconnect},sendAudio:(R)=>g.sendAudio(R),simulateDisconnect:()=>g.simulateDisconnect(),get sessionId(){return i.sessionId},get sessionMetadata(){return i.sessionMetadata},get scenarioId(){return i.scenarioId},startRecording:T,get status(){return i.status},stopRecording:h,subscribe:(R)=>{return C.add(R),()=>{C.delete(R)}},toggleRecording:async()=>{if(i.isRecording){h();return}await T()},get turns(){return i.turns},get assistantTexts(){return i.assistantTexts},get assistantAudio(){return i.assistantAudio},get call(){return i.call}}};var s=(c)=>String(c).replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'");var v=(c)=>{if(!c.isConnected)return"idle";if(c.isPlaying)return"speaking";if(c.isRecording&&c.hasActivePartial)return"listening";if(c.isRecording)return"listening";if(c.lastTranscriptAt&&!c.lastAssistantAt)return"thinking";if(c.lastTranscriptAt&&c.lastAssistantAt&&c.lastTranscriptAt>c.lastAssistantAt)return"thinking";return"idle"};var Qc={accent:"#3b82f6",background:"#0f172a",errorAccent:"#ef4444",fontFamily:'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',foreground:"#f8fafc",radius:16},Jc={callEnded:"Call ended",connecting:"Connecting…",endCall:"End call",idle:"Idle",listening:"Listening",mute:"Mute",speaking:"Speaking",startCall:"Start call",thinking:"Thinking",unmute:"Unmute"},qc=(c,n)=>{switch(c){case"listening":return n.listening;case"speaking":return n.speaking;case"thinking":return n.thinking;case"idle":return n.idle}},u=(c)=>{let n={...Qc,...c.theme},o={...Jc,...c.labels},g=c.state.assistantAudio.at(-1)?.receivedAt,l=c.state.turns.at(-1)?.committedAt,i=v({hasActivePartial:c.state.partial.length>0,isConnected:c.state.isConnected,isPlaying:!1,isRecording:c.state.isRecording,lastAssistantAt:g,lastTranscriptAt:l}),C=!c.state.isConnected&&c.state.status!=="idle"&&!c.state.error,V=c.state.error?"Error":C?o.connecting:c.state.status==="completed"?o.callEnded:qc(i,o);return{agentState:i,classes:{container:`absolute-voice-widget absolute-voice-widget--${i}`,dot:`absolute-voice-widget__dot${c.state.error?" absolute-voice-widget__dot--error":""}`},controls:{canEnd:c.state.isConnected,canMute:c.state.isRecording,canStart:!c.state.isRecording&&c.state.status!=="completed"},errorMessage:c.state.error??void 0,labels:o,partial:c.state.partial||void 0,statusLabel:V,theme:n,title:c.title??"Voice"}},Zc=(c)=>typeof c==="number"?`${c}px`:c,m=(c)=>{let n=c.theme,o=`background:${n.background};border-radius:${Zc(n.radius)};color:${n.foreground};font-family:${n.fontFamily};min-width:240px;padding:20px 22px;`,g=`background:${c.errorMessage?n.errorAccent:c.agentState==="idle"?"rgba(148,163,184,0.6)":n.accent};border-radius:50%;height:10px;width:10px;`,l=[];if(c.controls.canStart)l.push(`<button type="button" data-action="start" style="background:${n.accent};border:none;border-radius:12px;color:${n.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${s(c.labels.startCall)}</button>`);if(c.controls.canMute)l.push(`<button type="button" data-action="mute" style="background:transparent;border:1px solid rgba(255,255,255,0.18);border-radius:12px;color:${n.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${s(c.labels.mute)}</button>`);if(c.controls.canEnd)l.push(`<button type="button" data-action="end" style="background:${n.errorAccent};border:none;border-radius:12px;color:${n.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${s(c.labels.endCall)}</button>`);return`<div role="region" aria-live="polite" data-agent-state="${c.agentState}" class="${s(c.classes.container)}" style="${o}">
|
|
1
|
+
(()=>{var{defineProperty:H,getOwnPropertyNames:oc,getOwnPropertyDescriptor:lc}=Object,Ac=Object.prototype.hasOwnProperty;function Cc(c){return this[c]}var ic=(c)=>{var n=(Y??=new WeakMap).get(c),o;if(n)return n;if(n=H({},"__esModule",{value:!0}),c&&typeof c==="object"||typeof c==="function"){for(var g of oc(c))if(!Ac.call(n,g))H(n,g,{get:Cc.bind(c,g),enumerable:!(o=lc(c,g))||o.enumerable})}return Y.set(c,n),n},Y;var Tc=(c)=>c;function yc(c,n){this[c]=Tc.bind(null,n)}var Vc=(c,n)=>{for(var o in n)H(c,o,{get:n[o],enumerable:!0,configurable:!0,set:yc.bind(n,o)})};var Bc={};Vc(Bc,{mount:()=>p,default:()=>Kc,VOICE_EMBED_VERSION:()=>cc});var Ic=(c)=>{if(typeof c!=="string")return c;return document.querySelector(c)},Rc=(c,n,o,g)=>{let l=n??c.getAttribute("hx-get")??"";if(!l)return"";let i=new URL(l,window.location.origin);if(g)i.searchParams.set(o,g);else i.searchParams.delete(o);return`${i.pathname}${i.search}${i.hash}`},Q=(c,n)=>{if(typeof window>"u"||typeof document>"u")return()=>{};let o=Ic(n.element);if(!o)return()=>{};let g=n.eventName??"voice-refresh",l=n.sessionQueryParam??"sessionId",i=()=>{let V=window,I=Rc(o,n.route,l,c.sessionId);if(I)o.setAttribute("hx-get",I);V.htmx?.process?.(o),V.htmx?.trigger?.(o,g)},C=c.subscribe(i);return i(),()=>{C()}};var hc=(c)=>Math.max(-1,Math.min(1,c)),dc=(c)=>{let n=new Int16Array(c.length);for(let o=0;o<c.length;o+=1){let g=hc(c[o]??0);n[o]=g<0?g*32768:g*32767}return new Uint8Array(n.buffer)},Sc=(c)=>{let n=c instanceof Uint8Array?c:new Uint8Array(c);if(n.byteLength<2)return 0;let o=new Int16Array(n.buffer,n.byteOffset,Math.floor(n.byteLength/2));if(o.length===0)return 0;let g=0;for(let l of o){let i=l/32768;g+=i*i}return Math.min(1,Math.max(0,Math.sqrt(g/o.length)*5.5))},_c=(c,n,o)=>{if(n===o)return c;let g=n/o,l=Math.round(c.length/g),i=new Float32Array(l),C=0,V=0;while(C<i.length){let I=Math.round((C+1)*g),d=0,y=0;for(let h=V;h<I&&h<c.length;h+=1)d+=c[h]??0,y+=1;i[C]=y>0?d/y:0,C+=1,V=I}return i},J=(c)=>{let n=null,o=null,g=null,l=null;return{start:async()=>{if(typeof navigator>"u"||!navigator.mediaDevices?.getUserMedia)throw Error("Browser microphone capture requires navigator.mediaDevices.getUserMedia.");let V=(typeof window<"u"?window.AudioContext??window.webkitAudioContext:void 0)??AudioContext;if(!V)throw Error("Browser microphone capture requires AudioContext support.");l=await navigator.mediaDevices.getUserMedia({audio:{channelCount:c.channelCount??1}}),n=new V,o=n.createMediaStreamSource(l),g=n.createScriptProcessor(4096,1,1),g.onaudioprocess=(I)=>{let d=I.inputBuffer.getChannelData(0),y=_c(d,n?.sampleRate??48000,c.sampleRateHz??16000),h=dc(y);c.onLevel?.(Sc(h)),c.onAudio(h)},o.connect(g),g.connect(n.destination)},stop:()=>{g?.disconnect(),o?.disconnect(),l?.getTracks().forEach((V)=>V.stop()),n?.close(),c.onLevel?.(0),n=null,l=null,g=null,o=null}}};var G=(c)=>{if(typeof c==="string"&&c.trim())return c;if(c instanceof Error&&c.message.trim())return c.message;if(c&&typeof c==="object"){let n=c;for(let o of["message","reason","description"]){let g=n[o];if(typeof g==="string"&&g.trim())return g}if("error"in n)return G(n.error);if("cause"in n)return G(n.cause);try{return JSON.stringify(c)}catch{}}return"Unexpected error"},q=(c)=>{switch(c.type){case"audio":return{chunk:Uint8Array.from(atob(c.chunkBase64),(n)=>n.charCodeAt(0)),format:c.format,receivedAt:c.receivedAt,turnId:c.turnId,type:"audio"};case"assistant":return{text:c.text,type:"assistant"};case"complete":return{sessionId:c.sessionId,type:"complete"};case"connection":return{reconnect:c.reconnect,type:"connection"};case"call_lifecycle":return{event:c.event,sessionId:c.sessionId,type:"call_lifecycle"};case"error":return{message:G(c.message),type:"error"};case"final":return{transcript:c.transcript,type:"final"};case"partial":return{transcript:c.transcript,type:"partial"};case"replay":return{assistantTexts:c.assistantTexts,call:c.call,partial:c.partial,scenarioId:c.scenarioId,sessionId:c.sessionId,sessionMetadata:c.sessionMetadata,status:c.status,turns:c.turns,type:"replay"};case"session":return{sessionId:c.sessionId,sessionMetadata:c.sessionMetadata,scenarioId:c.scenarioId,status:c.status,type:"session"};case"turn":return{turn:c.turn,type:"turn"};default:return null}};var tc=Math.PI*2;var D=(c,n,o,g)=>{c.push({code:o,message:g,severity:n})};var wc=(c)=>c.length===0?void 0:c.reduce((n,o)=>n+o,0)/c.length,$=(c)=>c.length===0?void 0:Math.max(...c);var _=(c,n)=>{let o=c[n];return typeof o==="number"&&Number.isFinite(o)?o:void 0},N=(c,n)=>{let o=c[n];return typeof o==="boolean"?o:void 0},w=(c,n)=>{let o=c[n];return typeof o==="string"?o:void 0},X=(c)=>String(c.id??w(c,"ssrc")??_(c,"ssrc")??w(c,"trackIdentifier")??w(c,"mid")??"unknown"),Z=(c)=>c===void 0?void 0:c*1000;var Lc=(c)=>{let n={};for(let[o,g]of Object.entries(c))if(g===null||typeof g==="boolean"||typeof g==="number"||typeof g==="string")n[o]=g;return n};var z=(c={})=>{let n=c.stats??[],o=[],g=n.filter((A)=>A.type==="inbound-rtp"&&w(A,"kind")!=="video"),l=n.filter((A)=>A.type==="outbound-rtp"&&w(A,"kind")!=="video"),i=n.filter((A)=>A.type==="candidate-pair"),C=n.filter((A)=>(A.type==="track"||A.type==="media-source")&&w(A,"kind")==="audio"),V=i.filter((A)=>N(A,"selected")===!0||N(A,"nominated")===!0||w(A,"state")==="succeeded").length,I=C.filter((A)=>w(A,"readyState")!=="ended"&&w(A,"trackState")!=="ended"&&N(A,"ended")!==!0).length,d=C.filter((A)=>w(A,"readyState")==="ended"||w(A,"trackState")==="ended"||N(A,"ended")===!0).length,y=g.reduce((A,S)=>A+(_(S,"packetsReceived")??0),0),h=l.reduce((A,S)=>A+(_(S,"packetsSent")??0),0),T=[...g,...l].reduce((A,S)=>A+Math.max(0,_(S,"packetsLost")??0),0),L=y+T,R=L===0?0:T/L,x=g.reduce((A,S)=>A+(_(S,"bytesReceived")??0),0),b=l.reduce((A,S)=>A+(_(S,"bytesSent")??0),0),M=$(i.map((A)=>Z(_(A,"currentRoundTripTime")??_(A,"roundTripTime"))).filter((A)=>A!==void 0)),O=$([...g,...l].map((A)=>Z(_(A,"jitter"))).filter((A)=>A!==void 0)),W=$(g.map((A)=>{let S=_(A,"jitterBufferDelay"),U=_(A,"jitterBufferEmittedCount");return S!==void 0&&U!==void 0&&U>0?S/U*1000:void 0}).filter((A)=>A!==void 0)),P=C.map((A)=>_(A,"audioLevel")).filter((A)=>A!==void 0);if(c.requireConnectedCandidatePair&&i.length>0&&V===0)D(o,"error","media.webrtc_candidate_pair_missing","No active WebRTC candidate pair was observed.");if(c.requireLiveAudioTrack&&I===0)D(o,"error","media.webrtc_audio_track_missing","No live WebRTC audio track was observed.");if(c.maxPacketLossRatio!==void 0&&R>c.maxPacketLossRatio)D(o,"warning","media.webrtc_packet_loss",`Observed WebRTC packet loss ratio ${String(R)} above ${String(c.maxPacketLossRatio)}.`);if(c.maxRoundTripTimeMs!==void 0&&M!==void 0&&M>c.maxRoundTripTimeMs)D(o,"warning","media.webrtc_round_trip_time",`Observed WebRTC RTT ${String(M)}ms above ${String(c.maxRoundTripTimeMs)}ms.`);if(c.maxJitterMs!==void 0&&O!==void 0&&O>c.maxJitterMs)D(o,"warning","media.webrtc_jitter",`Observed WebRTC jitter ${String(O)}ms above ${String(c.maxJitterMs)}ms.`);return{activeCandidatePairs:V,audioLevelAverage:wc(P),bytesReceived:x,bytesSent:b,checkedAt:Date.now(),endedAudioTracks:d,inboundPackets:y,issues:o,jitterBufferDelayMs:W,jitterMs:O,liveAudioTracks:I,outboundPackets:h,packetLossRatio:R,packetsLost:T,roundTripTimeMs:M,status:o.some((A)=>A.severity==="error")?"fail":o.length>0?"warn":"pass",totalStats:n.length}},B=async(c)=>{return[...(await c.peerConnection.getStats(c.selector??null)).values()].map(Lc)};var K=(c={})=>{let n=c.stats??[],o=c.previousStats??[],g=[],l=new Map(o.map((T)=>[X(T),T])),C=n.filter((T)=>(T.type==="inbound-rtp"||T.type==="outbound-rtp")&&w(T,"kind")!=="video"&&w(T,"mediaType")!=="video").map((T)=>{let L=T.type==="outbound-rtp"?"outbound":"inbound",R=L==="outbound"?"packetsSent":"packetsReceived",x=L==="outbound"?"bytesSent":"bytesReceived",b=l.get(X(T)),M=_(T,R),O=b?_(b,R):void 0,W=_(T,x),P=b?_(b,x):void 0,A=T.timestamp!==void 0&&b?.timestamp!==void 0?T.timestamp-b.timestamp:void 0;return{bytesDelta:W!==void 0&&P!==void 0?W-P:void 0,currentPackets:M,direction:L,id:X(T),packetDelta:M!==void 0&&O!==void 0?M-O:void 0,previousPackets:O,timeDeltaMs:A}}),V=C.filter((T)=>T.direction==="inbound"),I=C.filter((T)=>T.direction==="outbound"),d=$(C.map((T)=>T.timeDeltaMs).filter((T)=>T!==void 0)),y=V.filter((T)=>c.maxInboundPacketStallMs!==void 0&&T.timeDeltaMs!==void 0&&T.timeDeltaMs>=c.maxInboundPacketStallMs&&T.packetDelta!==void 0&&T.packetDelta<=0).length,h=I.filter((T)=>c.maxOutboundPacketStallMs!==void 0&&T.timeDeltaMs!==void 0&&T.timeDeltaMs>=c.maxOutboundPacketStallMs&&T.packetDelta!==void 0&&T.packetDelta<=0).length;if(c.requireInboundAudio&&V.length===0)D(g,"error","media.webrtc_inbound_audio_missing","No inbound WebRTC audio RTP stream was observed.");if(c.requireOutboundAudio&&I.length===0)D(g,"error","media.webrtc_outbound_audio_missing","No outbound WebRTC audio RTP stream was observed.");if(c.maxGapMs!==void 0&&d!==void 0&&d>c.maxGapMs)D(g,"warning","media.webrtc_stream_gap",`Observed WebRTC stream sample gap ${String(d)}ms above ${String(c.maxGapMs)}ms.`);if(y>0)D(g,"error","media.webrtc_inbound_stalled",`${String(y)} inbound WebRTC audio stream(s) stopped receiving packets.`);if(h>0)D(g,"error","media.webrtc_outbound_stalled",`${String(h)} outbound WebRTC audio stream(s) stopped sending packets.`);return{checkedAt:Date.now(),inboundAudioStreams:V.length,issues:g,maxObservedGapMs:d,outboundAudioStreams:I.length,stalledInboundStreams:y,stalledOutboundStreams:h,status:g.some((T)=>T.severity==="error")?"fail":g.length>0?"warn":"pass",streams:C,totalStats:n.length}};var Uc="/api/voice/browser-media",bc=5000,Mc=async(c)=>c.peerConnection??await c.getPeerConnection?.()??null,Oc=async(c,n)=>{let o=n.fetch??globalThis.fetch;if(!o)return;await o(n.path??Uc,{body:JSON.stringify(c),headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"})},j=(c)=>{let n=null,o=[],g=async()=>{let C=await Mc(c);if(!C)return;let V=await B({peerConnection:C}),I=z({...c,stats:V}),d=c.continuity===!1?void 0:K({...c.continuity,previousStats:o,stats:V}),y={at:Date.now(),continuity:d,report:I,scenarioId:c.getScenarioId?.()??null,sessionId:c.getSessionId?.()??null};return o=V,c.onReport?.(y),await Oc(y,c),y},l=()=>{g().catch((C)=>{c.onError?.(C)})},i=()=>{if(n)clearInterval(n),n=null};return{close:i,reportOnce:g,start:()=>{if(n)return;l(),n=setInterval(l,c.intervalMs??bc)},stop:i}};var E=()=>{},Dc=()=>E,sc={callControl:E,close:E,endTurn:E,getReadyState:()=>3,getScenarioId:()=>"",getSessionId:()=>"",send:E,sendAudio:E,simulateDisconnect:E,start:()=>{},subscribe:Dc},Ec=()=>crypto.randomUUID(),xc=(c,n,o)=>{let{hostname:g,port:l,protocol:i}=window.location,C=i==="https:"?"wss:":"ws:",V=l?`:${l}`:"",I=new URL(`${C}//${g}${V}${c}`);if(I.searchParams.set("sessionId",n),o)I.searchParams.set("scenarioId",o);return I.toString()},Wc=(c)=>{if(!c||typeof c!=="object"||!("type"in c))return!1;switch(c.type){case"audio":case"assistant":case"call_lifecycle":case"complete":case"connection":case"error":case"final":case"partial":case"pong":case"replay":case"session":case"turn":return!0;default:return!1}},Pc=(c)=>{if(typeof c.data!=="string")return null;try{let n=JSON.parse(c.data);return Wc(n)?n:null}catch{return null}},f=(c,n={})=>{if(typeof window>"u")return sc;let o=new Set,g=n.reconnect!==!1,l=n.maxReconnectAttempts??10,i=n.pingInterval??30000,C={isConnected:!1,pendingMessages:[],scenarioId:n.scenarioId??null,pingInterval:null,reconnectAttempts:0,reconnectTimeout:null,sessionId:n.sessionId??Ec(),ws:null},V=(A)=>{o.forEach((S)=>S(A))},I=()=>{if(C.pingInterval)clearInterval(C.pingInterval),C.pingInterval=null;if(C.reconnectTimeout)clearTimeout(C.reconnectTimeout),C.reconnectTimeout=null},d=()=>{if(C.ws?.readyState!==1)return;while(C.pendingMessages.length>0){let A=C.pendingMessages.shift();if(A!==void 0)C.ws.send(A)}},y=()=>{let A=Date.now()+500;C.reconnectAttempts+=1,V({reconnect:{attempts:C.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:l,nextAttemptAt:A,status:"reconnecting"},type:"connection"}),C.reconnectTimeout=setTimeout(()=>{if(C.reconnectAttempts>l){V({reconnect:{attempts:C.reconnectAttempts,maxAttempts:l,status:"exhausted"},type:"connection"});return}h()},500)},h=()=>{let A=new WebSocket(xc(c,C.sessionId,C.scenarioId));A.binaryType="arraybuffer",A.onopen=()=>{let S=C.reconnectAttempts>0;if(C.isConnected=!0,d(),S)V({reconnect:{attempts:C.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:l,status:"resumed"},type:"connection"}),C.reconnectAttempts=0;o.forEach((U)=>U({scenarioId:C.scenarioId??void 0,sessionId:C.sessionId,status:"active",type:"session"})),C.pingInterval=setInterval(()=>{if(A.readyState===1)A.send(JSON.stringify({type:"ping"}))},i)},A.onmessage=(S)=>{let U=Pc(S);if(!U)return;if(U.type==="session")C.sessionId=U.sessionId,C.scenarioId=U.scenarioId??C.scenarioId;o.forEach((gc)=>gc(U))},A.onclose=(S)=>{if(C.isConnected=!1,I(),g&&S.code!==1000&&C.reconnectAttempts<l)y();else if(g&&S.code!==1000)V({reconnect:{attempts:C.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:l,status:"exhausted"},type:"connection"})},C.ws=A},T=(A)=>{if(C.ws?.readyState===1){C.ws.send(A);return}C.pendingMessages.push(A)},L=(A)=>{T(JSON.stringify(A))},R=(A={})=>{if(A.sessionId)C.sessionId=A.sessionId;if(A.scenarioId)C.scenarioId=A.scenarioId;L({type:"start",sessionId:C.sessionId,scenarioId:C.scenarioId??void 0})},x=(A)=>{T(A)},b=()=>{L({type:"end_turn"})},M=(A)=>{L({...A,type:"call_control"})},O=()=>{if(I(),C.ws)C.ws.close(1000),C.ws=null;C.isConnected=!1,o.clear()},W=()=>{if(C.ws?.readyState===1)C.ws.close(4000,"absolutejs-voice-reconnect-proof")},P=(A)=>{return o.add(A),()=>{o.delete(A)}};return h(),{callControl:M,close:O,endTurn:b,getReadyState:()=>C.ws?.readyState??3,getScenarioId:()=>C.scenarioId??"",getSessionId:()=>C.sessionId,send:L,sendAudio:x,simulateDisconnect:W,start:R,subscribe:P}};var Nc=()=>({attempts:0,maxAttempts:0,status:"idle"}),$c=()=>({assistantAudio:[],assistantTexts:[],call:null,error:null,isConnected:!1,sessionMetadata:null,scenarioId:null,partial:"",reconnect:Nc(),sessionId:null,status:"idle",turns:[]}),e=()=>{let c=$c(),n=new Set,o=()=>{n.forEach((l)=>l())};return{dispatch:(l)=>{switch(l.type){case"audio":c={...c,assistantAudio:[...c.assistantAudio,{chunk:l.chunk,format:l.format,receivedAt:l.receivedAt,turnId:l.turnId}]};break;case"assistant":c={...c,assistantTexts:[...c.assistantTexts,l.text]};break;case"complete":c={...c,sessionId:l.sessionId,status:"completed"};break;case"call_lifecycle":c={...c,call:{...c.call,disposition:l.event.type==="end"?l.event.disposition:c.call?.disposition,endedAt:l.event.type==="end"?l.event.at:c.call?.endedAt,events:[...c.call?.events??[],l.event],lastEventAt:l.event.at,startedAt:c.call?.startedAt??l.event.at},sessionId:l.sessionId};break;case"connected":c={...c,isConnected:!0,reconnect:c.reconnect.status==="reconnecting"?{...c.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:c.reconnect};break;case"connection":c={...c,reconnect:l.reconnect};break;case"disconnected":c={...c,isConnected:!1};break;case"error":c={...c,error:l.message};break;case"final":c={...c,partial:l.transcript.text,turns:c.turns.map((i)=>i)};break;case"partial":c={...c,partial:l.transcript.text};break;case"replay":c={...c,assistantTexts:[...l.assistantTexts],call:l.call??null,error:null,isConnected:l.status==="active",partial:l.partial,reconnect:c.reconnect.status==="reconnecting"?{...c.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:c.reconnect,scenarioId:l.scenarioId??c.scenarioId,sessionId:l.sessionId,sessionMetadata:l.sessionMetadata??c.sessionMetadata,status:l.status,turns:[...l.turns]};break;case"session":c={...c,error:null,scenarioId:l.scenarioId??c.scenarioId,isConnected:l.status==="active",sessionId:l.sessionId,sessionMetadata:l.sessionMetadata??c.sessionMetadata,status:l.status};break;case"turn":c={...c,partial:"",turns:[...c.turns,l.turn]};break}o()},getServerSnapshot:()=>c,getSnapshot:()=>c,subscribe:(l)=>{return n.add(l),()=>{n.delete(l)}}}};var k=(c,n={})=>{let o=f(c,n),g=e(),l=n.browserMedia&&typeof window<"u"?j({...n.browserMedia,getScenarioId:()=>n.browserMedia?n.browserMedia.getScenarioId?.()??o.getScenarioId():o.getScenarioId(),getSessionId:()=>n.browserMedia?n.browserMedia.getSessionId?.()??o.getSessionId():o.getSessionId()}):null,i=new Set,C=(y)=>Promise.resolve().then(()=>{if(!y?.sessionId&&!y?.scenarioId)return;o.start(y),l?.start()}),V=()=>{i.forEach((y)=>y())},I=()=>{if(!n.reconnectReportPath||typeof fetch>"u")return;let y=g.getSnapshot(),h=JSON.stringify({at:Date.now(),reconnect:y.reconnect,scenarioId:y.scenarioId,sessionId:o.getSessionId(),turnIds:y.turns.map((T)=>T.id)});fetch(n.reconnectReportPath,{body:h,headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"}).catch(()=>{})},d=o.subscribe((y)=>{let h=q(y);if(h){if(g.dispatch(h),y.type==="connection")I();V()}});return{callControl(y){o.callControl(y)},close(){d(),l?.close(),o.close(),g.dispatch({type:"disconnected"}),V()},endTurn(){o.endTurn()},get error(){return g.getSnapshot().error},getServerSnapshot(){return g.getServerSnapshot()},getSnapshot(){return g.getSnapshot()},get isConnected(){return g.getSnapshot().isConnected},get scenarioId(){return g.getSnapshot().scenarioId},get sessionMetadata(){return g.getSnapshot().sessionMetadata},start:C,get partial(){return g.getSnapshot().partial},get reconnect(){return g.getSnapshot().reconnect},get sessionId(){return o.getSessionId()},get status(){return g.getSnapshot().status},get turns(){return g.getSnapshot().turns},get assistantTexts(){return g.getSnapshot().assistantTexts},get assistantAudio(){return g.getSnapshot().assistantAudio},get call(){return g.getSnapshot().call},sendAudio(y){o.sendAudio(y)},simulateDisconnect(){o.simulateDisconnect()},subscribe(y){return i.add(y),()=>{i.delete(y)}}}};var t=(c)=>{if(!c||c.enabled===!1)return;return{enabled:!0,maxGain:c.maxGain??3,noiseGateAttenuation:c.noiseGateAttenuation??0.15,noiseGateThreshold:c.noiseGateThreshold??0.006,targetLevel:c.targetLevel??0.08}};var Hc={balanced:{qualityProfile:"general",silenceMs:1400,speechThreshold:0.012,transcriptStabilityMs:1000},fast:{qualityProfile:"general",silenceMs:700,speechThreshold:0.015,transcriptStabilityMs:450},"long-form":{qualityProfile:"general",silenceMs:2200,speechThreshold:0.01,transcriptStabilityMs:1500}},Gc={general:{},"accent-heavy":{silenceMs:1200,speechThreshold:0.01,transcriptStabilityMs:1200},"noisy-room":{silenceMs:2000,speechThreshold:0.02,transcriptStabilityMs:1600},"short-command":{silenceMs:500,speechThreshold:0.016,transcriptStabilityMs:420}};var F=(c)=>{let n=c?.profile??"fast",o=c?.qualityProfile??"general",g=Hc[n],l=Gc[o];return{profile:n,qualityProfile:o,silenceMs:c?.silenceMs??l.silenceMs??g.silenceMs,speechThreshold:c?.speechThreshold??l.speechThreshold??g.speechThreshold,transcriptStabilityMs:c?.transcriptStabilityMs??l.transcriptStabilityMs??g.transcriptStabilityMs}};var Xc={chat:{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"short-command",profile:"balanced"}},default:{capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"general",profile:"fast"}},dictation:{audioConditioning:{enabled:!0,maxGain:2.25,noiseGateAttenuation:0.05,noiseGateThreshold:0.003,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"accent-heavy",profile:"long-form"}},"guided-intake":{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:"turn-scoped",turnDetection:{qualityProfile:"accent-heavy",profile:"long-form"}},"noisy-room":{audioConditioning:{enabled:!0,maxGain:3,noiseGateAttenuation:0.12,noiseGateThreshold:0.006,targetLevel:0.085},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"noisy-room",profile:"long-form",silenceMs:2100,speechThreshold:0.02,transcriptStabilityMs:1650}},"pstn-balanced":{audioConditioning:{enabled:!0,maxGain:2.8,noiseGateAttenuation:0.07,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"noisy-room",profile:"long-form",silenceMs:660,speechThreshold:0.012,transcriptStabilityMs:300}},"pstn-fast":{audioConditioning:{enabled:!0,maxGain:2.75,noiseGateAttenuation:0.06,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"noisy-room",profile:"long-form",silenceMs:620,speechThreshold:0.012,transcriptStabilityMs:280}},reliability:{audioConditioning:{enabled:!0,maxGain:2.9,noiseGateAttenuation:0.08,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{qualityProfile:"noisy-room",profile:"long-form"}}},r=(c="default")=>{let n=Xc[c];return{audioConditioning:t(n.audioConditioning),capture:{channelCount:n.capture?.channelCount??1,sampleRateHz:n.capture?.sampleRateHz??16000},connection:{...n.connection},name:c,sttLifecycle:n.sttLifecycle??"continuous",turnDetection:F(n.turnDetection)}};var Yc=(c)=>({assistantAudio:[...c.assistantAudio],assistantTexts:[...c.assistantTexts],call:c.call,error:c.error,isConnected:c.isConnected,isRecording:!1,partial:c.partial,reconnect:c.reconnect,recordingError:null,sessionId:c.sessionId,sessionMetadata:c.sessionMetadata,scenarioId:c.scenarioId,status:c.status,turns:[...c.turns]}),a=(c,n={})=>{let o=r(n.preset),g=k(c,{...o.connection,...n.connection}),l=null,i=Yc(g),C=new Set,V=()=>{for(let R of C)R()},I=()=>{if(i={...i,assistantAudio:[...g.assistantAudio],assistantTexts:[...g.assistantTexts],call:g.call,error:g.error,isConnected:g.isConnected,partial:g.partial,reconnect:g.reconnect,sessionId:g.sessionId,sessionMetadata:g.sessionMetadata,scenarioId:g.scenarioId,status:g.status,turns:[...g.turns]},n.autoStopOnComplete!==!1&&i.status==="completed"&&i.isRecording)l?.stop(),l=null,i={...i,isRecording:!1};V()},d=g.subscribe(I);I();let y=()=>{if(l)return l;return l=J({channelCount:n.capture?.channelCount??o.capture.channelCount,onLevel:n.capture?.onLevel,onAudio:(R)=>{if(n.capture?.onAudio){n.capture.onAudio(R,g.sendAudio);return}g.sendAudio(R)},sampleRateHz:n.capture?.sampleRateHz??o.capture.sampleRateHz}),l},h=()=>{l?.stop(),l=null,i={...i,isRecording:!1},V()},T=async()=>{if(i.isRecording)return;try{i={...i,recordingError:null},V(),await y().start(),i={...i,isRecording:!0},V()}catch(R){throw l=null,i={...i,isRecording:!1,recordingError:R instanceof Error?R.message:String(R)},V(),R}};return{bindHTMX(R){return Q(g,R)},callControl:(R)=>g.callControl(R),close:()=>{d(),h(),g.close()},endTurn:()=>g.endTurn(),get error(){return i.error},getServerSnapshot:()=>i,getSnapshot:()=>i,get isConnected(){return i.isConnected},get isRecording(){return i.isRecording},get partial(){return i.partial},get recordingError(){return i.recordingError},get reconnect(){return i.reconnect},sendAudio:(R)=>g.sendAudio(R),simulateDisconnect:()=>g.simulateDisconnect(),get sessionId(){return i.sessionId},get sessionMetadata(){return i.sessionMetadata},get scenarioId(){return i.scenarioId},startRecording:T,get status(){return i.status},stopRecording:h,subscribe:(R)=>{return C.add(R),()=>{C.delete(R)}},toggleRecording:async()=>{if(i.isRecording){h();return}await T()},get turns(){return i.turns},get assistantTexts(){return i.assistantTexts},get assistantAudio(){return i.assistantAudio},get call(){return i.call}}};var s=(c)=>String(c).replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'");var v=(c)=>{if(!c.isConnected)return"idle";if(c.isPlaying)return"speaking";if(c.isRecording&&c.hasActivePartial)return"listening";if(c.isRecording)return"listening";if(c.lastTranscriptAt&&!c.lastAssistantAt)return"thinking";if(c.lastTranscriptAt&&c.lastAssistantAt&&c.lastTranscriptAt>c.lastAssistantAt)return"thinking";return"idle"};var Qc={accent:"#3b82f6",background:"#0f172a",errorAccent:"#ef4444",fontFamily:'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',foreground:"#f8fafc",radius:16},Jc={callEnded:"Call ended",connecting:"Connecting…",endCall:"End call",idle:"Idle",listening:"Listening",mute:"Mute",speaking:"Speaking",startCall:"Start call",thinking:"Thinking",unmute:"Unmute"},qc=(c,n)=>{switch(c){case"listening":return n.listening;case"speaking":return n.speaking;case"thinking":return n.thinking;case"idle":return n.idle}},u=(c)=>{let n={...Qc,...c.theme},o={...Jc,...c.labels},g=c.state.assistantAudio.at(-1)?.receivedAt,l=c.state.turns.at(-1)?.committedAt,i=v({hasActivePartial:c.state.partial.length>0,isConnected:c.state.isConnected,isPlaying:!1,isRecording:c.state.isRecording,lastAssistantAt:g,lastTranscriptAt:l}),C=!c.state.isConnected&&c.state.status!=="idle"&&!c.state.error,V=c.state.error?"Error":C?o.connecting:c.state.status==="completed"?o.callEnded:qc(i,o);return{agentState:i,classes:{container:`absolute-voice-widget absolute-voice-widget--${i}`,dot:`absolute-voice-widget__dot${c.state.error?" absolute-voice-widget__dot--error":""}`},controls:{canEnd:c.state.isConnected,canMute:c.state.isRecording,canStart:!c.state.isRecording&&c.state.status!=="completed"},errorMessage:c.state.error??void 0,labels:o,partial:c.state.partial||void 0,statusLabel:V,theme:n,title:c.title??"Voice"}},Zc=(c)=>typeof c==="number"?`${c}px`:c,m=(c)=>{let n=c.theme,o=`background:${n.background};border-radius:${Zc(n.radius)};color:${n.foreground};font-family:${n.fontFamily};min-width:240px;padding:20px 22px;`,g=`background:${c.errorMessage?n.errorAccent:c.agentState==="idle"?"rgba(148,163,184,0.6)":n.accent};border-radius:50%;height:10px;width:10px;`,l=[];if(c.controls.canStart)l.push(`<button type="button" data-action="start" style="background:${n.accent};border:none;border-radius:12px;color:${n.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${s(c.labels.startCall)}</button>`);if(c.controls.canMute)l.push(`<button type="button" data-action="mute" style="background:transparent;border:1px solid rgba(255,255,255,0.18);border-radius:12px;color:${n.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${s(c.labels.mute)}</button>`);if(c.controls.canEnd)l.push(`<button type="button" data-action="end" style="background:${n.errorAccent};border:none;border-radius:12px;color:${n.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${s(c.labels.endCall)}</button>`);return`<div role="region" aria-live="polite" data-agent-state="${c.agentState}" class="${s(c.classes.container)}" style="${o}">
|
|
2
2
|
<div style="align-items:center;display:flex;gap:10px;margin-bottom:12px;">
|
|
3
3
|
<span aria-hidden="true" class="${s(c.classes.dot)}" style="${g}"></span>
|
|
4
4
|
<strong style="font-size:15px;">${s(c.title)}</strong>
|
package/dist/react/index.d.ts
CHANGED
|
@@ -57,3 +57,24 @@ export { useVoiceAgentSquadStatus } from "./useVoiceAgentSquadStatus";
|
|
|
57
57
|
export { useVoiceTurnLatency } from "./useVoiceTurnLatency";
|
|
58
58
|
export { useVoiceTurnQuality } from "./useVoiceTurnQuality";
|
|
59
59
|
export { useVoiceWorkflowStatus } from "./useVoiceWorkflowStatus";
|
|
60
|
+
export type { VoiceAgentSquadStatusProps } from "./VoiceAgentSquadStatus";
|
|
61
|
+
export type { VoiceDeliveryRuntimeProps } from "./VoiceDeliveryRuntime";
|
|
62
|
+
export type { VoiceOpsActionCenterProps } from "./VoiceOpsActionCenter";
|
|
63
|
+
export type { VoiceOpsStatusProps } from "./VoiceOpsStatus";
|
|
64
|
+
export type { VoicePlatformCoverageProps } from "./VoicePlatformCoverage";
|
|
65
|
+
export type { VoiceProfileComparisonProps } from "./VoiceProfileComparison";
|
|
66
|
+
export type { VoiceProfileSwitchRecommendationProps } from "./VoiceProfileSwitchRecommendation";
|
|
67
|
+
export type { VoiceProofTrendsProps } from "./VoiceProofTrends";
|
|
68
|
+
export type { VoiceProviderCapabilitiesProps } from "./VoiceProviderCapabilities";
|
|
69
|
+
export type { VoiceProviderContractsProps } from "./VoiceProviderContracts";
|
|
70
|
+
export type { VoiceProviderSimulationControlsProps } from "./VoiceProviderSimulationControls";
|
|
71
|
+
export type { VoiceProviderStatusProps } from "./VoiceProviderStatus";
|
|
72
|
+
export type { VoiceReadinessFailuresProps } from "./VoiceReadinessFailures";
|
|
73
|
+
export type { VoiceReconnectProfileEvidenceProps } from "./VoiceReconnectProfileEvidence";
|
|
74
|
+
export type { VoiceRoutingStatusProps } from "./VoiceRoutingStatus";
|
|
75
|
+
export type { VoiceSessionObservabilityProps } from "./VoiceSessionObservability";
|
|
76
|
+
export type { VoiceSessionSnapshotProps } from "./VoiceSessionSnapshot";
|
|
77
|
+
export type { VoiceTraceTimelineProps } from "./VoiceTraceTimeline";
|
|
78
|
+
export type { VoiceTurnLatencyProps } from "./VoiceTurnLatency";
|
|
79
|
+
export type { VoiceTurnQualityProps } from "./VoiceTurnQuality";
|
|
80
|
+
export type { VoiceWidgetViewModel } from "./VoiceWidget";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type VoiceCallDebuggerClientOptions } from "../client/callDebugger";
|
|
2
1
|
import { type VoiceCallDebuggerLaunchOptions } from "../client/callDebuggerWidget";
|
|
3
2
|
export declare const createVoiceCallDebugger: (path: string, options?: VoiceCallDebuggerLaunchOptions) => {
|
|
4
3
|
getHTML: () => string;
|
|
@@ -9,4 +8,3 @@ export declare const createVoiceCallDebugger: (path: string, options?: VoiceCall
|
|
|
9
8
|
refresh: () => Promise<import("..").VoiceCallDebuggerReport | undefined>;
|
|
10
9
|
subscribe: (listener: () => void) => () => void;
|
|
11
10
|
};
|
|
12
|
-
export type { VoiceCallDebuggerClientOptions };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type VoiceSessionSnapshotClientOptions } from "../client/sessionSnapshot";
|
|
2
1
|
import { type VoiceSessionSnapshotWidgetOptions } from "../client/sessionSnapshotWidget";
|
|
3
2
|
export declare const createVoiceSessionSnapshot: (path: string, options?: VoiceSessionSnapshotWidgetOptions) => {
|
|
4
3
|
getHTML: () => string;
|
|
@@ -10,4 +9,3 @@ export declare const createVoiceSessionSnapshot: (path: string, options?: VoiceS
|
|
|
10
9
|
refresh: () => Promise<import("..").VoiceSessionSnapshot | undefined>;
|
|
11
10
|
subscribe: (listener: () => void) => () => void;
|
|
12
11
|
};
|
|
13
|
-
export type { VoiceSessionSnapshotClientOptions };
|
package/package.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { OnDestroy, OnInit } from "@angular/core";
|
|
2
|
-
import { type VoiceDeliveryRuntimeViewModel } from "../client/deliveryRuntimeWidget";
|
|
3
|
-
export declare class VoiceDeliveryRuntimeComponent implements OnDestroy, OnInit {
|
|
4
|
-
description?: string;
|
|
5
|
-
intervalMs?: number;
|
|
6
|
-
path: string;
|
|
7
|
-
title?: string;
|
|
8
|
-
private cleanup;
|
|
9
|
-
private store?;
|
|
10
|
-
model: import("@angular/core").WritableSignal<VoiceDeliveryRuntimeViewModel>;
|
|
11
|
-
ngOnInit(): void;
|
|
12
|
-
ngOnDestroy(): void;
|
|
13
|
-
deadLettered(): number;
|
|
14
|
-
tick(): void;
|
|
15
|
-
requeueDeadLetters(): void;
|
|
16
|
-
private options;
|
|
17
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { OnDestroy, OnInit } from "@angular/core";
|
|
2
|
-
import { type VoiceOpsStatusViewModel } from "../client/opsStatusWidget";
|
|
3
|
-
export declare class VoiceOpsStatusComponent implements OnDestroy, OnInit {
|
|
4
|
-
description?: string;
|
|
5
|
-
includeLinks: boolean;
|
|
6
|
-
intervalMs?: number;
|
|
7
|
-
path: string;
|
|
8
|
-
title?: string;
|
|
9
|
-
private cleanup;
|
|
10
|
-
private store?;
|
|
11
|
-
model: import("@angular/core").WritableSignal<VoiceOpsStatusViewModel>;
|
|
12
|
-
ngOnInit(): void;
|
|
13
|
-
ngOnDestroy(): void;
|
|
14
|
-
private options;
|
|
15
|
-
}
|