@absolutejs/voice 0.0.22-beta.534 → 0.0.22-beta.535
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 +347 -347
- package/dist/angular/voice-cost-dashboard.service.d.ts +1 -1
- package/dist/angular/voice-replay-timeline.service.d.ts +1 -1
- package/dist/client/agentSquadStatusWidget.d.ts +3 -3
- package/dist/client/browserVoiceSupport.d.ts +1 -1
- package/dist/client/callDebugger.d.ts +2 -2
- package/dist/client/callDebuggerWidget.d.ts +3 -3
- package/dist/client/campaignDialerProof.d.ts +4 -4
- package/dist/client/deliveryRuntime.d.ts +4 -4
- package/dist/client/deliveryRuntimeWidget.d.ts +3 -3
- package/dist/client/htmxAttributes.d.ts +1 -5
- package/dist/client/htmxBootstrap.js +82 -82
- package/dist/client/htmxDashboardRenderers.d.ts +17 -17
- package/dist/client/index.js +2478 -2484
- package/dist/client/liveOps.d.ts +2 -2
- package/dist/client/liveOpsWidget.d.ts +3 -3
- package/dist/client/opsActionCenter.d.ts +3 -3
- package/dist/client/opsActionCenterWidget.d.ts +3 -3
- package/dist/client/opsActionHistory.d.ts +2 -2
- package/dist/client/opsActionHistoryWidget.d.ts +2 -2
- package/dist/client/opsStatus.d.ts +2 -2
- package/dist/client/opsStatusWidget.d.ts +4 -4
- package/dist/client/platformCoverage.d.ts +2 -2
- package/dist/client/platformCoverageWidget.d.ts +3 -3
- package/dist/client/profileComparison.d.ts +2 -2
- package/dist/client/profileComparisonWidget.d.ts +3 -3
- package/dist/client/profileSwitchRecommendation.d.ts +2 -2
- package/dist/client/profileSwitchRecommendationWidget.d.ts +3 -3
- package/dist/client/proofTrends.d.ts +2 -2
- package/dist/client/proofTrendsWidget.d.ts +3 -3
- package/dist/client/providerCapabilities.d.ts +2 -2
- package/dist/client/providerCapabilitiesWidget.d.ts +3 -3
- package/dist/client/providerContracts.d.ts +2 -2
- package/dist/client/providerContractsWidget.d.ts +3 -3
- package/dist/client/providerSimulationControls.d.ts +1 -1
- package/dist/client/providerSimulationControlsWidget.d.ts +4 -4
- package/dist/client/providerStatus.d.ts +2 -2
- package/dist/client/providerStatusWidget.d.ts +3 -3
- package/dist/client/readinessFailures.d.ts +2 -2
- package/dist/client/readinessFailuresWidget.d.ts +3 -3
- package/dist/client/reconnectProfileEvidence.d.ts +2 -2
- package/dist/client/reconnectProfileEvidenceWidget.d.ts +3 -3
- package/dist/client/routingStatus.d.ts +2 -2
- package/dist/client/routingStatusWidget.d.ts +3 -3
- package/dist/client/sessionObservability.d.ts +2 -2
- package/dist/client/sessionObservabilityWidget.d.ts +3 -3
- package/dist/client/sessionSnapshot.d.ts +2 -2
- package/dist/client/sessionSnapshotWidget.d.ts +2 -2
- package/dist/client/traceTimeline.d.ts +2 -2
- package/dist/client/traceTimelineWidget.d.ts +3 -3
- package/dist/client/turnLatency.d.ts +4 -4
- package/dist/client/turnLatencyWidget.d.ts +3 -3
- package/dist/client/turnQuality.d.ts +2 -2
- package/dist/client/turnQualityWidget.d.ts +3 -3
- package/dist/client/workflowStatus.d.ts +2 -2
- package/dist/core/agent.d.ts +1 -1
- package/dist/core/agentSquadContract.d.ts +2 -2
- package/dist/core/agentState.d.ts +1 -1
- package/dist/core/aiScorecard.d.ts +1 -1
- package/dist/core/assistant.d.ts +1 -1
- package/dist/core/assistantHealth.d.ts +3 -3
- package/dist/core/assistantMemory.d.ts +7 -7
- package/dist/core/audioConditioning.d.ts +1 -1
- package/dist/core/audit.d.ts +6 -6
- package/dist/core/auditDeliveryRoutes.d.ts +7 -7
- package/dist/core/auditExport.d.ts +10 -10
- package/dist/core/auditRoutes.d.ts +5 -5
- package/dist/core/auditSinks.d.ts +7 -7
- package/dist/core/bargeInRoutes.d.ts +6 -6
- package/dist/core/bookingFlow.d.ts +1 -1
- package/dist/core/browserCallProfiles.d.ts +3 -3
- package/dist/core/browserMediaRoutes.d.ts +5 -5
- package/dist/core/callDebugger.d.ts +1 -1
- package/dist/core/callDisposition.d.ts +1 -1
- package/dist/core/callScorecard.d.ts +1 -1
- package/dist/core/campaign.d.ts +5 -5
- package/dist/core/campaignControls.d.ts +1 -1
- package/dist/core/campaignDialers.d.ts +4 -4
- package/dist/core/campaignTemplate.d.ts +1 -1
- package/dist/core/competitiveCoverage.d.ts +2 -2
- package/dist/core/conversationSimulator.d.ts +1 -1
- package/dist/core/correction.d.ts +1 -1
- package/dist/core/dataControl.d.ts +5 -5
- package/dist/core/deliveryRuntime.d.ts +7 -7
- package/dist/core/deliverySinkRoutes.d.ts +7 -7
- package/dist/core/demoReadyRoutes.d.ts +1 -1
- package/dist/core/dncRegistry.d.ts +1 -1
- package/dist/core/dtmfCollector.d.ts +1 -1
- package/dist/core/evalRoutes.d.ts +16 -16
- package/dist/core/fileStore.d.ts +18 -18
- package/dist/core/guardrails.d.ts +2 -2
- package/dist/core/handoff.d.ts +4 -4
- package/dist/core/handoffHealth.d.ts +4 -4
- package/dist/core/htmx.d.ts +1 -1
- package/dist/core/incidentBundle.d.ts +1 -1
- package/dist/core/incidentTimeline.d.ts +11 -11
- package/dist/core/latencySlo.d.ts +1 -1
- package/dist/core/liveCoach.d.ts +1 -1
- package/dist/core/liveLatency.d.ts +3 -3
- package/dist/core/liveOps.d.ts +6 -6
- package/dist/core/mediaPipelineRoutes.d.ts +4 -4
- package/dist/core/monitor.d.ts +1 -1
- package/dist/core/multilingualProof.d.ts +1 -1
- package/dist/core/observabilityExport.d.ts +15 -15
- package/dist/core/operationalStatus.d.ts +3 -3
- package/dist/core/operationsRecord.d.ts +8 -8
- package/dist/core/ops.d.ts +58 -58
- package/dist/core/opsActionAuditRoutes.d.ts +10 -10
- package/dist/core/opsConsoleRoutes.d.ts +3 -3
- package/dist/core/opsRecovery.d.ts +4 -4
- package/dist/core/opsSinks.d.ts +6 -6
- package/dist/core/opsStatusRoutes.d.ts +3 -3
- package/dist/core/opsWebhook.d.ts +9 -9
- package/dist/core/otelExporter.d.ts +1 -1
- package/dist/core/outcomeContract.d.ts +6 -6
- package/dist/core/pathway.d.ts +2 -2
- package/dist/core/pathwayRuntime.d.ts +2 -2
- package/dist/core/phoneAgent.d.ts +2 -2
- package/dist/core/phoneAgentProductionSmoke.d.ts +7 -7
- package/dist/core/platformCoverage.d.ts +1 -1
- package/dist/core/postCallSurvey.d.ts +1 -1
- package/dist/core/postgresStore.d.ts +8 -8
- package/dist/core/productionReadiness.d.ts +9 -9
- package/dist/core/profileSwitchRecommendation.d.ts +9 -9
- package/dist/core/proofAssertions.d.ts +1 -1
- package/dist/core/proofPack.d.ts +12 -12
- package/dist/core/proofRunner.d.ts +2 -2
- package/dist/core/proofTrends.d.ts +26 -26
- package/dist/core/providerCapabilities.d.ts +5 -5
- package/dist/core/providerDecisionTraces.d.ts +4 -4
- package/dist/core/providerHealth.d.ts +3 -3
- package/dist/core/providerOrchestration.d.ts +4 -4
- package/dist/core/providerRouterTraces.d.ts +2 -2
- package/dist/core/providerRoutingContract.d.ts +2 -2
- package/dist/core/providerSlo.d.ts +5 -5
- package/dist/core/providerStackRecommendations.d.ts +8 -8
- package/dist/core/qualityRoutes.d.ts +3 -3
- package/dist/core/queue.d.ts +26 -26
- package/dist/core/realtimeChannel.d.ts +5 -5
- package/dist/core/realtimeProviderContracts.d.ts +3 -3
- package/dist/core/reconnectContract.d.ts +16 -16
- package/dist/core/recordingStore.d.ts +2 -2
- package/dist/core/reminderScheduler.d.ts +1 -1
- package/dist/core/resilienceRoutes.d.ts +1 -1
- package/dist/core/routing.d.ts +1 -1
- package/dist/core/sessionObservability.d.ts +2 -2
- package/dist/core/sessionReplay.d.ts +12 -12
- package/dist/core/sessionSnapshot.d.ts +1 -1
- package/dist/core/simulationSuite.d.ts +4 -4
- package/dist/core/sloCalibration.d.ts +12 -12
- package/dist/core/sqliteStore.d.ts +8 -8
- package/dist/core/telephonyMediaRoutes.d.ts +4 -4
- package/dist/core/telephonyOutcome.d.ts +2 -2
- package/dist/core/toolContract.d.ts +10 -10
- package/dist/core/toolRuntime.d.ts +1 -1
- package/dist/core/trace.d.ts +18 -18
- package/dist/core/traceDeliveryRoutes.d.ts +7 -7
- package/dist/core/traceTimeline.d.ts +3 -3
- package/dist/core/turnLatency.d.ts +4 -4
- package/dist/core/turnQuality.d.ts +5 -5
- package/dist/core/types.d.ts +7 -2
- package/dist/core/voiceMonitoring.d.ts +11 -11
- package/dist/core/webhookVerification.d.ts +4 -4
- package/dist/core/whisperChannel.d.ts +4 -4
- package/dist/core/workflowContract.d.ts +13 -13
- package/dist/core/zeroDataRetention.d.ts +3 -13
- package/dist/drizzle/assistantMemory.d.ts +95 -0
- package/dist/drizzle/eval.d.ts +61 -0
- package/dist/drizzle/handoff.d.ts +62 -0
- package/dist/drizzle/index.d.ts +1029 -0
- package/dist/drizzle/index.js +3028 -0
- package/dist/drizzle/observabilityExport.d.ts +61 -0
- package/dist/drizzle/proofTrends.d.ts +126 -0
- package/dist/drizzle/runtimeStorage.d.ts +1311 -0
- package/dist/drizzle/shared.d.ts +75 -0
- package/dist/embed/index.js +72 -72
- package/dist/embed/voice-widget.js +2 -2
- package/dist/index.js +7034 -7101
- package/dist/react/index.js +2148 -2150
- package/dist/svelte/createVoiceAgentSquadStatus.d.ts +2 -2
- package/dist/svelte/createVoiceCallDebugger.d.ts +1 -1
- package/dist/svelte/createVoiceCallPlayer.d.ts +8 -8
- package/dist/svelte/createVoiceCampaignDialerProof.d.ts +2 -2
- package/dist/svelte/createVoiceCostDashboard.d.ts +4 -4
- package/dist/svelte/createVoiceDeliveryRuntime.d.ts +3 -3
- package/dist/svelte/createVoiceLiveAgentConsole.d.ts +4 -4
- package/dist/svelte/createVoiceLiveOps.d.ts +4 -4
- package/dist/svelte/createVoiceOpsActionCenter.d.ts +2 -2
- package/dist/svelte/createVoiceOpsStatus.d.ts +2 -2
- package/dist/svelte/createVoiceProviderCapabilities.d.ts +1 -1
- package/dist/svelte/createVoiceProviderContracts.d.ts +1 -1
- package/dist/svelte/createVoiceProviderSimulationControls.d.ts +1 -1
- package/dist/svelte/createVoiceProviderStatus.d.ts +1 -1
- package/dist/svelte/createVoiceReplayTimeline.d.ts +1 -1
- package/dist/svelte/createVoiceRoutingStatus.d.ts +1 -1
- package/dist/svelte/createVoiceSessionObservability.d.ts +1 -1
- package/dist/svelte/createVoiceSessionSnapshot.d.ts +1 -1
- package/dist/svelte/createVoiceTraceTimeline.d.ts +1 -1
- package/dist/svelte/createVoiceTurnLatency.d.ts +2 -2
- package/dist/svelte/createVoiceTurnQuality.d.ts +1 -1
- package/dist/svelte/createVoiceWidget.d.ts +2 -2
- package/dist/svelte/createVoiceWorkflowStatus.d.ts +1 -1
- package/dist/svelte/index.js +1518 -1522
- package/dist/telephony/matrix.d.ts +3 -3
- package/dist/telephony/plivo.d.ts +2 -2
- package/dist/telephony/security.d.ts +3 -3
- package/dist/telephony/telnyx.d.ts +1 -1
- package/dist/telephony/twilio.d.ts +2 -2
- package/dist/testing/benchmark.d.ts +6 -6
- package/dist/testing/corrected.d.ts +4 -4
- package/dist/testing/duplex.d.ts +2 -2
- package/dist/testing/fixtures.d.ts +1 -1
- package/dist/testing/index.js +1382 -1388
- package/dist/testing/review.d.ts +4 -4
- package/dist/testing/sessionBenchmark.d.ts +10 -10
- package/dist/testing/telephony.d.ts +3 -3
- package/dist/testing/tts.d.ts +1 -1
- package/dist/vue/VoiceCostDashboard.d.ts +2 -2
- package/dist/vue/index.js +2110 -2112
- package/dist/vue/useVoiceController.d.ts +5 -5
- package/dist/vue/useVoiceDeliveryRuntime.d.ts +1 -1
- package/dist/vue/useVoiceStream.d.ts +5 -5
- package/package.json +28 -6
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type PgDatabase, type PgQueryResultHKT } from "drizzle-orm/pg-core";
|
|
2
|
+
export declare const voiceDocumentTable: (name: string) => import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
3
|
+
name: string;
|
|
4
|
+
schema: undefined;
|
|
5
|
+
columns: {
|
|
6
|
+
id: import("drizzle-orm/pg-core").PgColumn<{
|
|
7
|
+
name: "id";
|
|
8
|
+
tableName: string;
|
|
9
|
+
dataType: "string";
|
|
10
|
+
columnType: "PgText";
|
|
11
|
+
data: string;
|
|
12
|
+
driverParam: string;
|
|
13
|
+
notNull: true;
|
|
14
|
+
hasDefault: false;
|
|
15
|
+
isPrimaryKey: true;
|
|
16
|
+
isAutoincrement: false;
|
|
17
|
+
hasRuntimeDefault: false;
|
|
18
|
+
enumValues: [string, ...string[]];
|
|
19
|
+
baseColumn: never;
|
|
20
|
+
identity: undefined;
|
|
21
|
+
generated: undefined;
|
|
22
|
+
}, {}, {}>;
|
|
23
|
+
payload: import("drizzle-orm/pg-core").PgColumn<{
|
|
24
|
+
name: "payload";
|
|
25
|
+
tableName: string;
|
|
26
|
+
dataType: "json";
|
|
27
|
+
columnType: "PgJsonb";
|
|
28
|
+
data: unknown;
|
|
29
|
+
driverParam: unknown;
|
|
30
|
+
notNull: true;
|
|
31
|
+
hasDefault: false;
|
|
32
|
+
isPrimaryKey: false;
|
|
33
|
+
isAutoincrement: false;
|
|
34
|
+
hasRuntimeDefault: false;
|
|
35
|
+
enumValues: undefined;
|
|
36
|
+
baseColumn: never;
|
|
37
|
+
identity: undefined;
|
|
38
|
+
generated: undefined;
|
|
39
|
+
}, {}, {}>;
|
|
40
|
+
sortAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
41
|
+
name: "sort_at";
|
|
42
|
+
tableName: string;
|
|
43
|
+
dataType: "number";
|
|
44
|
+
columnType: "PgBigInt53";
|
|
45
|
+
data: number;
|
|
46
|
+
driverParam: string | number;
|
|
47
|
+
notNull: true;
|
|
48
|
+
hasDefault: false;
|
|
49
|
+
isPrimaryKey: false;
|
|
50
|
+
isAutoincrement: false;
|
|
51
|
+
hasRuntimeDefault: false;
|
|
52
|
+
enumValues: undefined;
|
|
53
|
+
baseColumn: never;
|
|
54
|
+
identity: undefined;
|
|
55
|
+
generated: undefined;
|
|
56
|
+
}, {}, {}>;
|
|
57
|
+
};
|
|
58
|
+
dialect: "pg";
|
|
59
|
+
}>;
|
|
60
|
+
export type VoiceDrizzleDocumentTable = ReturnType<typeof voiceDocumentTable>;
|
|
61
|
+
export type VoiceDrizzleDatabase = PgDatabase<PgQueryResultHKT>;
|
|
62
|
+
export type VoiceDrizzleStoreOptions = {
|
|
63
|
+
db: VoiceDrizzleDatabase;
|
|
64
|
+
};
|
|
65
|
+
export declare const createVoiceDrizzleRecordStore: <T>(input: {
|
|
66
|
+
db: VoiceDrizzleDatabase;
|
|
67
|
+
decorate: (id: string, value: T) => T;
|
|
68
|
+
getSortAt: (value: T) => number;
|
|
69
|
+
table: VoiceDrizzleDocumentTable;
|
|
70
|
+
}) => {
|
|
71
|
+
get: (id: string) => Promise<T | undefined>;
|
|
72
|
+
list: () => Promise<T[]>;
|
|
73
|
+
remove: (id: string) => Promise<void>;
|
|
74
|
+
set: (id: string, value: T) => Promise<void>;
|
|
75
|
+
};
|
package/dist/embed/index.js
CHANGED
|
@@ -460,14 +460,14 @@ var createVoiceBrowserMediaReporter = (options) => {
|
|
|
460
460
|
return {
|
|
461
461
|
close: stop,
|
|
462
462
|
reportOnce,
|
|
463
|
+
stop,
|
|
463
464
|
start: () => {
|
|
464
465
|
if (interval) {
|
|
465
466
|
return;
|
|
466
467
|
}
|
|
467
468
|
run();
|
|
468
469
|
interval = setInterval(run, options.intervalMs ?? DEFAULT_BROWSER_MEDIA_INTERVAL_MS);
|
|
469
|
-
}
|
|
470
|
-
stop
|
|
470
|
+
}
|
|
471
471
|
};
|
|
472
472
|
};
|
|
473
473
|
|
|
@@ -485,14 +485,14 @@ var NOOP_CONNECTION = {
|
|
|
485
485
|
callControl: noop,
|
|
486
486
|
close: noop,
|
|
487
487
|
endTurn: noop,
|
|
488
|
-
getReadyState: () => WS_CLOSED,
|
|
489
|
-
getScenarioId: () => "",
|
|
490
|
-
getSessionId: () => "",
|
|
491
488
|
send: noop,
|
|
492
489
|
sendAudio: noop,
|
|
493
490
|
simulateDisconnect: noop,
|
|
494
|
-
|
|
495
|
-
|
|
491
|
+
subscribe: noopUnsubscribe,
|
|
492
|
+
getReadyState: () => WS_CLOSED,
|
|
493
|
+
getScenarioId: () => "",
|
|
494
|
+
getSessionId: () => "",
|
|
495
|
+
start: () => {}
|
|
496
496
|
};
|
|
497
497
|
var createSessionId = () => crypto.randomUUID();
|
|
498
498
|
var buildWsUrl = (path, sessionId, scenarioId) => {
|
|
@@ -689,9 +689,9 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
689
689
|
state.scenarioId = input.scenarioId;
|
|
690
690
|
}
|
|
691
691
|
send({
|
|
692
|
-
|
|
692
|
+
scenarioId: state.scenarioId ?? undefined,
|
|
693
693
|
sessionId: state.sessionId,
|
|
694
|
-
|
|
694
|
+
type: "start"
|
|
695
695
|
});
|
|
696
696
|
};
|
|
697
697
|
const sendAudio = (audio) => {
|
|
@@ -731,14 +731,14 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
731
731
|
callControl,
|
|
732
732
|
close,
|
|
733
733
|
endTurn,
|
|
734
|
-
getReadyState: () => state.ws?.readyState ?? WS_CLOSED,
|
|
735
|
-
getScenarioId: () => state.scenarioId ?? "",
|
|
736
|
-
getSessionId: () => state.sessionId,
|
|
737
734
|
send,
|
|
738
735
|
sendAudio,
|
|
739
736
|
simulateDisconnect,
|
|
740
737
|
start,
|
|
741
|
-
subscribe
|
|
738
|
+
subscribe,
|
|
739
|
+
getReadyState: () => state.ws?.readyState ?? WS_CLOSED,
|
|
740
|
+
getScenarioId: () => state.scenarioId ?? "",
|
|
741
|
+
getSessionId: () => state.sessionId
|
|
742
742
|
};
|
|
743
743
|
};
|
|
744
744
|
|
|
@@ -754,11 +754,11 @@ var createInitialState = () => ({
|
|
|
754
754
|
call: null,
|
|
755
755
|
error: null,
|
|
756
756
|
isConnected: false,
|
|
757
|
-
sessionMetadata: null,
|
|
758
|
-
scenarioId: null,
|
|
759
757
|
partial: "",
|
|
760
758
|
reconnect: createInitialReconnectState(),
|
|
759
|
+
scenarioId: null,
|
|
761
760
|
sessionId: null,
|
|
761
|
+
sessionMetadata: null,
|
|
762
762
|
status: "idle",
|
|
763
763
|
turns: []
|
|
764
764
|
});
|
|
@@ -961,6 +961,16 @@ var createVoiceStream = (path, options = {}) => {
|
|
|
961
961
|
}
|
|
962
962
|
});
|
|
963
963
|
return {
|
|
964
|
+
start,
|
|
965
|
+
get assistantAudio() {
|
|
966
|
+
return store.getSnapshot().assistantAudio;
|
|
967
|
+
},
|
|
968
|
+
get assistantTexts() {
|
|
969
|
+
return store.getSnapshot().assistantTexts;
|
|
970
|
+
},
|
|
971
|
+
get call() {
|
|
972
|
+
return store.getSnapshot().call;
|
|
973
|
+
},
|
|
964
974
|
callControl(message) {
|
|
965
975
|
connection.callControl(message);
|
|
966
976
|
},
|
|
@@ -986,48 +996,38 @@ var createVoiceStream = (path, options = {}) => {
|
|
|
986
996
|
get isConnected() {
|
|
987
997
|
return store.getSnapshot().isConnected;
|
|
988
998
|
},
|
|
989
|
-
get scenarioId() {
|
|
990
|
-
return store.getSnapshot().scenarioId;
|
|
991
|
-
},
|
|
992
|
-
get sessionMetadata() {
|
|
993
|
-
return store.getSnapshot().sessionMetadata;
|
|
994
|
-
},
|
|
995
|
-
start,
|
|
996
999
|
get partial() {
|
|
997
1000
|
return store.getSnapshot().partial;
|
|
998
1001
|
},
|
|
999
1002
|
get reconnect() {
|
|
1000
1003
|
return store.getSnapshot().reconnect;
|
|
1001
1004
|
},
|
|
1002
|
-
get
|
|
1003
|
-
return
|
|
1004
|
-
},
|
|
1005
|
-
get status() {
|
|
1006
|
-
return store.getSnapshot().status;
|
|
1007
|
-
},
|
|
1008
|
-
get turns() {
|
|
1009
|
-
return store.getSnapshot().turns;
|
|
1010
|
-
},
|
|
1011
|
-
get assistantTexts() {
|
|
1012
|
-
return store.getSnapshot().assistantTexts;
|
|
1013
|
-
},
|
|
1014
|
-
get assistantAudio() {
|
|
1015
|
-
return store.getSnapshot().assistantAudio;
|
|
1016
|
-
},
|
|
1017
|
-
get call() {
|
|
1018
|
-
return store.getSnapshot().call;
|
|
1005
|
+
get scenarioId() {
|
|
1006
|
+
return store.getSnapshot().scenarioId;
|
|
1019
1007
|
},
|
|
1020
1008
|
sendAudio(audio) {
|
|
1021
1009
|
connection.sendAudio(audio);
|
|
1022
1010
|
},
|
|
1011
|
+
get sessionId() {
|
|
1012
|
+
return connection.getSessionId();
|
|
1013
|
+
},
|
|
1014
|
+
get sessionMetadata() {
|
|
1015
|
+
return store.getSnapshot().sessionMetadata;
|
|
1016
|
+
},
|
|
1023
1017
|
simulateDisconnect() {
|
|
1024
1018
|
connection.simulateDisconnect();
|
|
1025
1019
|
},
|
|
1020
|
+
get status() {
|
|
1021
|
+
return store.getSnapshot().status;
|
|
1022
|
+
},
|
|
1026
1023
|
subscribe(subscriber) {
|
|
1027
1024
|
subscribers.add(subscriber);
|
|
1028
1025
|
return () => {
|
|
1029
1026
|
subscribers.delete(subscriber);
|
|
1030
1027
|
};
|
|
1028
|
+
},
|
|
1029
|
+
get turns() {
|
|
1030
|
+
return store.getSnapshot().turns;
|
|
1031
1031
|
}
|
|
1032
1032
|
};
|
|
1033
1033
|
};
|
|
@@ -1072,12 +1072,12 @@ var TURN_PROFILE_DEFAULTS = {
|
|
|
1072
1072
|
}
|
|
1073
1073
|
};
|
|
1074
1074
|
var QUALITY_PROFILE_DEFAULTS = {
|
|
1075
|
-
general: {},
|
|
1076
1075
|
"accent-heavy": {
|
|
1077
1076
|
silenceMs: 1200,
|
|
1078
1077
|
speechThreshold: 0.01,
|
|
1079
1078
|
transcriptStabilityMs: 1200
|
|
1080
1079
|
},
|
|
1080
|
+
general: {},
|
|
1081
1081
|
"noisy-room": {
|
|
1082
1082
|
silenceMs: 2000,
|
|
1083
1083
|
speechThreshold: 0.02,
|
|
@@ -1126,8 +1126,8 @@ var PRESET_INPUTS = {
|
|
|
1126
1126
|
},
|
|
1127
1127
|
sttLifecycle: "continuous",
|
|
1128
1128
|
turnDetection: {
|
|
1129
|
-
|
|
1130
|
-
|
|
1129
|
+
profile: "balanced",
|
|
1130
|
+
qualityProfile: "short-command"
|
|
1131
1131
|
}
|
|
1132
1132
|
},
|
|
1133
1133
|
default: {
|
|
@@ -1142,8 +1142,8 @@ var PRESET_INPUTS = {
|
|
|
1142
1142
|
},
|
|
1143
1143
|
sttLifecycle: "continuous",
|
|
1144
1144
|
turnDetection: {
|
|
1145
|
-
|
|
1146
|
-
|
|
1145
|
+
profile: "fast",
|
|
1146
|
+
qualityProfile: "general"
|
|
1147
1147
|
}
|
|
1148
1148
|
},
|
|
1149
1149
|
dictation: {
|
|
@@ -1165,8 +1165,8 @@ var PRESET_INPUTS = {
|
|
|
1165
1165
|
},
|
|
1166
1166
|
sttLifecycle: "continuous",
|
|
1167
1167
|
turnDetection: {
|
|
1168
|
-
|
|
1169
|
-
|
|
1168
|
+
profile: "long-form",
|
|
1169
|
+
qualityProfile: "accent-heavy"
|
|
1170
1170
|
}
|
|
1171
1171
|
},
|
|
1172
1172
|
"guided-intake": {
|
|
@@ -1188,8 +1188,8 @@ var PRESET_INPUTS = {
|
|
|
1188
1188
|
},
|
|
1189
1189
|
sttLifecycle: "turn-scoped",
|
|
1190
1190
|
turnDetection: {
|
|
1191
|
-
|
|
1192
|
-
|
|
1191
|
+
profile: "long-form",
|
|
1192
|
+
qualityProfile: "accent-heavy"
|
|
1193
1193
|
}
|
|
1194
1194
|
},
|
|
1195
1195
|
"noisy-room": {
|
|
@@ -1211,8 +1211,8 @@ var PRESET_INPUTS = {
|
|
|
1211
1211
|
},
|
|
1212
1212
|
sttLifecycle: "continuous",
|
|
1213
1213
|
turnDetection: {
|
|
1214
|
-
qualityProfile: "noisy-room",
|
|
1215
1214
|
profile: "long-form",
|
|
1215
|
+
qualityProfile: "noisy-room",
|
|
1216
1216
|
silenceMs: 2100,
|
|
1217
1217
|
speechThreshold: 0.02,
|
|
1218
1218
|
transcriptStabilityMs: 1650
|
|
@@ -1237,8 +1237,8 @@ var PRESET_INPUTS = {
|
|
|
1237
1237
|
},
|
|
1238
1238
|
sttLifecycle: "continuous",
|
|
1239
1239
|
turnDetection: {
|
|
1240
|
-
qualityProfile: "noisy-room",
|
|
1241
1240
|
profile: "long-form",
|
|
1241
|
+
qualityProfile: "noisy-room",
|
|
1242
1242
|
silenceMs: 660,
|
|
1243
1243
|
speechThreshold: 0.012,
|
|
1244
1244
|
transcriptStabilityMs: 300
|
|
@@ -1263,8 +1263,8 @@ var PRESET_INPUTS = {
|
|
|
1263
1263
|
},
|
|
1264
1264
|
sttLifecycle: "continuous",
|
|
1265
1265
|
turnDetection: {
|
|
1266
|
-
qualityProfile: "noisy-room",
|
|
1267
1266
|
profile: "long-form",
|
|
1267
|
+
qualityProfile: "noisy-room",
|
|
1268
1268
|
silenceMs: 620,
|
|
1269
1269
|
speechThreshold: 0.012,
|
|
1270
1270
|
transcriptStabilityMs: 280
|
|
@@ -1289,8 +1289,8 @@ var PRESET_INPUTS = {
|
|
|
1289
1289
|
},
|
|
1290
1290
|
sttLifecycle: "continuous",
|
|
1291
1291
|
turnDetection: {
|
|
1292
|
-
|
|
1293
|
-
|
|
1292
|
+
profile: "long-form",
|
|
1293
|
+
qualityProfile: "noisy-room"
|
|
1294
1294
|
}
|
|
1295
1295
|
}
|
|
1296
1296
|
};
|
|
@@ -1430,11 +1430,22 @@ var createVoiceController = (path, options = {}) => {
|
|
|
1430
1430
|
stream.close();
|
|
1431
1431
|
};
|
|
1432
1432
|
return {
|
|
1433
|
+
close,
|
|
1434
|
+
startRecording,
|
|
1435
|
+
stopRecording,
|
|
1436
|
+
get assistantAudio() {
|
|
1437
|
+
return state.assistantAudio;
|
|
1438
|
+
},
|
|
1439
|
+
get assistantTexts() {
|
|
1440
|
+
return state.assistantTexts;
|
|
1441
|
+
},
|
|
1433
1442
|
bindHTMX(bindingOptions) {
|
|
1434
1443
|
return bindVoiceHTMX(stream, bindingOptions);
|
|
1435
1444
|
},
|
|
1445
|
+
get call() {
|
|
1446
|
+
return state.call;
|
|
1447
|
+
},
|
|
1436
1448
|
callControl: (message) => stream.callControl(message),
|
|
1437
|
-
close,
|
|
1438
1449
|
endTurn: () => stream.endTurn(),
|
|
1439
1450
|
get error() {
|
|
1440
1451
|
return state.error;
|
|
@@ -1450,28 +1461,26 @@ var createVoiceController = (path, options = {}) => {
|
|
|
1450
1461
|
get partial() {
|
|
1451
1462
|
return state.partial;
|
|
1452
1463
|
},
|
|
1464
|
+
get reconnect() {
|
|
1465
|
+
return state.reconnect;
|
|
1466
|
+
},
|
|
1453
1467
|
get recordingError() {
|
|
1454
1468
|
return state.recordingError;
|
|
1455
1469
|
},
|
|
1456
|
-
get
|
|
1457
|
-
return state.
|
|
1470
|
+
get scenarioId() {
|
|
1471
|
+
return state.scenarioId;
|
|
1458
1472
|
},
|
|
1459
1473
|
sendAudio: (audio) => stream.sendAudio(audio),
|
|
1460
|
-
simulateDisconnect: () => stream.simulateDisconnect(),
|
|
1461
1474
|
get sessionId() {
|
|
1462
1475
|
return state.sessionId;
|
|
1463
1476
|
},
|
|
1464
1477
|
get sessionMetadata() {
|
|
1465
1478
|
return state.sessionMetadata;
|
|
1466
1479
|
},
|
|
1467
|
-
|
|
1468
|
-
return state.scenarioId;
|
|
1469
|
-
},
|
|
1470
|
-
startRecording,
|
|
1480
|
+
simulateDisconnect: () => stream.simulateDisconnect(),
|
|
1471
1481
|
get status() {
|
|
1472
1482
|
return state.status;
|
|
1473
1483
|
},
|
|
1474
|
-
stopRecording,
|
|
1475
1484
|
subscribe: (subscriber) => {
|
|
1476
1485
|
subscribers.add(subscriber);
|
|
1477
1486
|
return () => {
|
|
@@ -1487,15 +1496,6 @@ var createVoiceController = (path, options = {}) => {
|
|
|
1487
1496
|
},
|
|
1488
1497
|
get turns() {
|
|
1489
1498
|
return state.turns;
|
|
1490
|
-
},
|
|
1491
|
-
get assistantTexts() {
|
|
1492
|
-
return state.assistantTexts;
|
|
1493
|
-
},
|
|
1494
|
-
get assistantAudio() {
|
|
1495
|
-
return state.assistantAudio;
|
|
1496
|
-
},
|
|
1497
|
-
get call() {
|
|
1498
|
-
return state.call;
|
|
1499
1499
|
}
|
|
1500
1500
|
};
|
|
1501
1501
|
};
|
|
@@ -1652,7 +1652,7 @@ var mount = (target, options = {}) => {
|
|
|
1652
1652
|
});
|
|
1653
1653
|
host.innerHTML = renderVoiceWidgetHTML(model);
|
|
1654
1654
|
for (const button of host.querySelectorAll("button[data-action]")) {
|
|
1655
|
-
const action = button.dataset
|
|
1655
|
+
const { action } = button.dataset;
|
|
1656
1656
|
button.addEventListener("click", () => {
|
|
1657
1657
|
if (action === "start")
|
|
1658
1658
|
controller.startRecording();
|
|
@@ -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,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}">
|
|
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 yc=(c)=>c;function Tc(c,n){this[c]=yc.bind(null,n)}var Vc=(c,n)=>{for(var o in n)H(c,o,{get:n[o],enumerable:!0,configurable:!0,set:Tc.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)),Sc=(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)},dc=(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),S=0,T=0;for(let h=V;h<I&&h<c.length;h+=1)S+=c[h]??0,T+=1;i[C]=T>0?S/T: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 S=I.inputBuffer.getChannelData(0),T=_c(S,n?.sampleRate??48000,c.sampleRateHz??16000),h=Sc(T);c.onLevel?.(dc(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,S=C.filter((A)=>w(A,"readyState")==="ended"||w(A,"trackState")==="ended"||N(A,"ended")===!0).length,T=g.reduce((A,d)=>A+(_(d,"packetsReceived")??0),0),h=l.reduce((A,d)=>A+(_(d,"packetsSent")??0),0),y=[...g,...l].reduce((A,d)=>A+Math.max(0,_(d,"packetsLost")??0),0),L=T+y,R=L===0?0:y/L,x=g.reduce((A,d)=>A+(_(d,"bytesReceived")??0),0),U=l.reduce((A,d)=>A+(_(d,"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 d=_(A,"jitterBufferDelay"),b=_(A,"jitterBufferEmittedCount");return d!==void 0&&b!==void 0&&b>0?d/b*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:U,checkedAt:Date.now(),endedAudioTracks:S,inboundPackets:T,issues:o,jitterBufferDelayMs:W,jitterMs:O,liveAudioTracks:I,outboundPackets:h,packetLossRatio:R,packetsLost:y,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((y)=>[X(y),y])),C=n.filter((y)=>(y.type==="inbound-rtp"||y.type==="outbound-rtp")&&w(y,"kind")!=="video"&&w(y,"mediaType")!=="video").map((y)=>{let L=y.type==="outbound-rtp"?"outbound":"inbound",R=L==="outbound"?"packetsSent":"packetsReceived",x=L==="outbound"?"bytesSent":"bytesReceived",U=l.get(X(y)),M=_(y,R),O=U?_(U,R):void 0,W=_(y,x),P=U?_(U,x):void 0,A=y.timestamp!==void 0&&U?.timestamp!==void 0?y.timestamp-U.timestamp:void 0;return{bytesDelta:W!==void 0&&P!==void 0?W-P:void 0,currentPackets:M,direction:L,id:X(y),packetDelta:M!==void 0&&O!==void 0?M-O:void 0,previousPackets:O,timeDeltaMs:A}}),V=C.filter((y)=>y.direction==="inbound"),I=C.filter((y)=>y.direction==="outbound"),S=$(C.map((y)=>y.timeDeltaMs).filter((y)=>y!==void 0)),T=V.filter((y)=>c.maxInboundPacketStallMs!==void 0&&y.timeDeltaMs!==void 0&&y.timeDeltaMs>=c.maxInboundPacketStallMs&&y.packetDelta!==void 0&&y.packetDelta<=0).length,h=I.filter((y)=>c.maxOutboundPacketStallMs!==void 0&&y.timeDeltaMs!==void 0&&y.timeDeltaMs>=c.maxOutboundPacketStallMs&&y.packetDelta!==void 0&&y.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&&S!==void 0&&S>c.maxGapMs)D(g,"warning","media.webrtc_stream_gap",`Observed WebRTC stream sample gap ${String(S)}ms above ${String(c.maxGapMs)}ms.`);if(T>0)D(g,"error","media.webrtc_inbound_stalled",`${String(T)} 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:S,outboundAudioStreams:I.length,stalledInboundStreams:T,stalledOutboundStreams:h,status:g.some((y)=>y.severity==="error")?"fail":g.length>0?"warn":"pass",streams:C,totalStats:n.length}};var bc="/api/voice/browser-media",Uc=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??bc,{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}),S=c.continuity===!1?void 0:K({...c.continuity,previousStats:o,stats:V}),T={at:Date.now(),continuity:S,report:I,scenarioId:c.getScenarioId?.()??null,sessionId:c.getSessionId?.()??null};return o=V,c.onReport?.(T),await Oc(T,c),T},l=()=>{g().catch((C)=>{c.onError?.(C)})},i=()=>{if(n)clearInterval(n),n=null};return{close:i,reportOnce:g,stop:i,start:()=>{if(n)return;l(),n=setInterval(l,c.intervalMs??Uc)}}};var E=()=>{},Dc=()=>E,sc={callControl:E,close:E,endTurn:E,send:E,sendAudio:E,simulateDisconnect:E,subscribe:Dc,getReadyState:()=>3,getScenarioId:()=>"",getSessionId:()=>"",start:()=>{}},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((d)=>d(A))},I=()=>{if(C.pingInterval)clearInterval(C.pingInterval),C.pingInterval=null;if(C.reconnectTimeout)clearTimeout(C.reconnectTimeout),C.reconnectTimeout=null},S=()=>{if(C.ws?.readyState!==1)return;while(C.pendingMessages.length>0){let A=C.pendingMessages.shift();if(A!==void 0)C.ws.send(A)}},T=()=>{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 d=C.reconnectAttempts>0;if(C.isConnected=!0,S(),d)V({reconnect:{attempts:C.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:l,status:"resumed"},type:"connection"}),C.reconnectAttempts=0;o.forEach((b)=>b({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=(d)=>{let b=Pc(d);if(!b)return;if(b.type==="session")C.sessionId=b.sessionId,C.scenarioId=b.scenarioId??C.scenarioId;o.forEach((gc)=>gc(b))},A.onclose=(d)=>{if(C.isConnected=!1,I(),g&&d.code!==1000&&C.reconnectAttempts<l)T();else if(g&&d.code!==1000)V({reconnect:{attempts:C.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:l,status:"exhausted"},type:"connection"})},C.ws=A},y=(A)=>{if(C.ws?.readyState===1){C.ws.send(A);return}C.pendingMessages.push(A)},L=(A)=>{y(JSON.stringify(A))},R=(A={})=>{if(A.sessionId)C.sessionId=A.sessionId;if(A.scenarioId)C.scenarioId=A.scenarioId;L({scenarioId:C.scenarioId??void 0,sessionId:C.sessionId,type:"start"})},x=(A)=>{y(A)},U=()=>{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:U,send:L,sendAudio:x,simulateDisconnect:W,start:R,subscribe:P,getReadyState:()=>C.ws?.readyState??3,getScenarioId:()=>C.scenarioId??"",getSessionId:()=>C.sessionId}};var Nc=()=>({attempts:0,maxAttempts:0,status:"idle"}),$c=()=>({assistantAudio:[],assistantTexts:[],call:null,error:null,isConnected:!1,partial:"",reconnect:Nc(),scenarioId:null,sessionId:null,sessionMetadata: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=(T)=>Promise.resolve().then(()=>{if(!T?.sessionId&&!T?.scenarioId)return;o.start(T),l?.start()}),V=()=>{i.forEach((T)=>T())},I=()=>{if(!n.reconnectReportPath||typeof fetch>"u")return;let T=g.getSnapshot(),h=JSON.stringify({at:Date.now(),reconnect:T.reconnect,scenarioId:T.scenarioId,sessionId:o.getSessionId(),turnIds:T.turns.map((y)=>y.id)});fetch(n.reconnectReportPath,{body:h,headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"}).catch(()=>{})},S=o.subscribe((T)=>{let h=q(T);if(h){if(g.dispatch(h),T.type==="connection")I();V()}});return{start:C,get assistantAudio(){return g.getSnapshot().assistantAudio},get assistantTexts(){return g.getSnapshot().assistantTexts},get call(){return g.getSnapshot().call},callControl(T){o.callControl(T)},close(){S(),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 partial(){return g.getSnapshot().partial},get reconnect(){return g.getSnapshot().reconnect},get scenarioId(){return g.getSnapshot().scenarioId},sendAudio(T){o.sendAudio(T)},get sessionId(){return o.getSessionId()},get sessionMetadata(){return g.getSnapshot().sessionMetadata},simulateDisconnect(){o.simulateDisconnect()},get status(){return g.getSnapshot().status},subscribe(T){return i.add(T),()=>{i.delete(T)}},get turns(){return g.getSnapshot().turns}}};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={"accent-heavy":{silenceMs:1200,speechThreshold:0.01,transcriptStabilityMs:1200},general:{},"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:{profile:"balanced",qualityProfile:"short-command"}},default:{capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"fast",qualityProfile:"general"}},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:{profile:"long-form",qualityProfile:"accent-heavy"}},"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:{profile:"long-form",qualityProfile:"accent-heavy"}},"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:{profile:"long-form",qualityProfile:"noisy-room",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:{profile:"long-form",qualityProfile:"noisy-room",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:{profile:"long-form",qualityProfile:"noisy-room",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:{profile:"long-form",qualityProfile:"noisy-room"}}},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()},S=g.subscribe(I);I();let T=()=>{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()},y=async()=>{if(i.isRecording)return;try{i={...i,recordingError:null},V(),await T().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{close:()=>{S(),h(),g.close()},startRecording:y,stopRecording:h,get assistantAudio(){return i.assistantAudio},get assistantTexts(){return i.assistantTexts},bindHTMX(R){return Q(g,R)},get call(){return i.call},callControl:(R)=>g.callControl(R),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 reconnect(){return i.reconnect},get recordingError(){return i.recordingError},get scenarioId(){return i.scenarioId},sendAudio:(R)=>g.sendAudio(R),get sessionId(){return i.sessionId},get sessionMetadata(){return i.sessionMetadata},simulateDisconnect:()=>g.simulateDisconnect(),get status(){return i.status},subscribe:(R)=>{return C.add(R),()=>{C.delete(R)}},toggleRecording:async()=>{if(i.isRecording){h();return}await y()},get turns(){return i.turns}}};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>
|
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
${c.partial?`<p style="font-size:13px;margin:8px 0 12px;opacity:0.85;word-break:break-word;">“${s(c.partial)}”</p>`:""}
|
|
8
8
|
<div style="display:flex;gap:10px;">${l.join("")}</div>
|
|
9
9
|
${c.errorMessage?`<p style="color:${n.errorAccent};font-size:12px;margin-top:12px;">${s(c.errorMessage)}</p>`:""}
|
|
10
|
-
</div>`};var zc=(c)=>{if(typeof c!=="string")return c;let n=document.querySelector(c);if(!n)throw Error(`AbsoluteVoice.mount: no element matches "${c}"`);return n},p=(c,n={})=>{let o=zc(c),g=a(n.path??"/voice",n.controllerOptions),l=null,i=null,C=()=>{let I=u({...n.labels!==void 0?{labels:n.labels}:{},state:{assistantAudio:g.assistantAudio,error:g.error,isConnected:g.isConnected,isRecording:g.isRecording,partial:g.partial,status:g.status,turns:g.turns},...n.theme!==void 0?{theme:n.theme}:{},...n.title!==void 0?{title:n.title}:{}});o.innerHTML=m(I);for(let
|
|
10
|
+
</div>`};var zc=(c)=>{if(typeof c!=="string")return c;let n=document.querySelector(c);if(!n)throw Error(`AbsoluteVoice.mount: no element matches "${c}"`);return n},p=(c,n={})=>{let o=zc(c),g=a(n.path??"/voice",n.controllerOptions),l=null,i=null,C=()=>{let I=u({...n.labels!==void 0?{labels:n.labels}:{},state:{assistantAudio:g.assistantAudio,error:g.error,isConnected:g.isConnected,isRecording:g.isRecording,partial:g.partial,status:g.status,turns:g.turns},...n.theme!==void 0?{theme:n.theme}:{},...n.title!==void 0?{title:n.title}:{}});o.innerHTML=m(I);for(let S of o.querySelectorAll("button[data-action]")){let{action:T}=S.dataset;S.addEventListener("click",()=>{if(T==="start")g.startRecording();else if(T==="mute")g.stopRecording();else if(T==="end")g.close()})}if(g.error&&g.error!==l)l=g.error,n.onError?.(g.error);if(g.status!==i)i=g.status,n.onStatusChange?.(g.status)},V=g.subscribe(C);if(C(),n.autoStart)g.startRecording();return{controller:g,async end(){await g.close()},mute(){g.stopRecording()},async start(){await g.startRecording()},unmount(){V(),g.close(),o.innerHTML=""}}},cc="0.0.22-beta.516",nc={mount:p,version:cc};if(typeof globalThis<"u")globalThis.AbsoluteVoice=nc;var Kc=nc;})();
|