@absolutejs/voice 0.0.22-beta.463 → 0.0.22-beta.464
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/angular/index.js +265 -0
- package/dist/client/htmxBootstrap.js +330 -7
- package/dist/client/index.js +265 -0
- package/dist/generated/htmxBootstrapBundle.d.ts +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +591 -50
- package/dist/mediaPipelineRoutes.d.ts +55 -1
- package/dist/mediaPipelineSurfaces.d.ts +48 -0
- package/dist/react/index.js +265 -0
- package/dist/svelte/index.js +265 -0
- package/dist/testing/index.js +265 -0
- package/dist/vue/index.js +265 -0
- package/package.json +2 -2
package/dist/client/index.js
CHANGED
|
@@ -791,6 +791,8 @@ var serverMessageToAction = (message) => {
|
|
|
791
791
|
};
|
|
792
792
|
|
|
793
793
|
// node_modules/@absolutejs/media/dist/index.js
|
|
794
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
795
|
+
import { join } from "path";
|
|
794
796
|
var formatLabel = (format) => `${format.container}/${format.encoding}/${String(format.sampleRateHz)}hz/${String(format.channels)}ch`;
|
|
795
797
|
var formatMatches = (actual, expected) => actual.container === expected.container && actual.encoding === expected.encoding && actual.sampleRateHz === expected.sampleRateHz && actual.channels === expected.channels;
|
|
796
798
|
var pushIssue = (issues, severity, code, message) => {
|
|
@@ -1451,6 +1453,269 @@ var buildMediaPipelineCalibrationReport = (input = {}) => {
|
|
|
1451
1453
|
turnCommitFrames: turnCommitFrames.length
|
|
1452
1454
|
};
|
|
1453
1455
|
};
|
|
1456
|
+
var DEFAULT_METADATA_DENY = [
|
|
1457
|
+
"audioPayload",
|
|
1458
|
+
"auth",
|
|
1459
|
+
"authorization",
|
|
1460
|
+
"cookie",
|
|
1461
|
+
"email",
|
|
1462
|
+
"phone",
|
|
1463
|
+
"phoneNumber",
|
|
1464
|
+
"rawPayload",
|
|
1465
|
+
"secret",
|
|
1466
|
+
"token",
|
|
1467
|
+
"transcript",
|
|
1468
|
+
"utterance"
|
|
1469
|
+
];
|
|
1470
|
+
var DEFAULT_TRUNCATE = 8;
|
|
1471
|
+
var issueCodes = (issues) => Array.from(new Set(issues.map((issue) => issue.code)));
|
|
1472
|
+
var lastEventKind = (events) => events[events.length - 1]?.kind;
|
|
1473
|
+
var formatOptionalMs = (value) => value === undefined ? "n/a" : `${String(Math.round(value))}ms`;
|
|
1474
|
+
var formatRatio = (value) => `${(value * 100).toFixed(1)}%`;
|
|
1475
|
+
var escapeMarkdownCell = (value) => value.replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
1476
|
+
var renderIssuesTable = (issues) => {
|
|
1477
|
+
if (issues.length === 0) {
|
|
1478
|
+
return `- No issues.
|
|
1479
|
+
`;
|
|
1480
|
+
}
|
|
1481
|
+
const rows = issues.map((issue) => `| ${issue.severity} | ${escapeMarkdownCell(issue.code)} | ${escapeMarkdownCell(issue.message)} |`).join(`
|
|
1482
|
+
`);
|
|
1483
|
+
return `| Severity | Code | Message |
|
|
1484
|
+
| --- | --- | --- |
|
|
1485
|
+
${rows}
|
|
1486
|
+
`;
|
|
1487
|
+
};
|
|
1488
|
+
var summarizeMediaQualityReport = (report) => ({
|
|
1489
|
+
backpressureEvents: report.backpressureEvents,
|
|
1490
|
+
description: `${report.totalFrames} frame(s), ${report.gapCount} gap(s), speech ${formatRatio(report.speechRatio)}, status ${report.status}.`,
|
|
1491
|
+
driftMs: report.timestampDriftMs,
|
|
1492
|
+
frameCount: report.totalFrames,
|
|
1493
|
+
gapCount: report.gapCount,
|
|
1494
|
+
issueCodes: issueCodes(report.issues),
|
|
1495
|
+
issueCount: report.issues.length,
|
|
1496
|
+
jitterMs: report.jitterMs,
|
|
1497
|
+
silenceRatio: report.silenceRatio,
|
|
1498
|
+
speechRatio: report.speechRatio,
|
|
1499
|
+
status: report.status
|
|
1500
|
+
});
|
|
1501
|
+
var summarizeMediaTransportReport = (report) => ({
|
|
1502
|
+
backpressureEvents: report.backpressureEvents,
|
|
1503
|
+
description: `${report.name}: ${report.state}, in ${report.inputFrames}, out ${report.outputFrames}, backpressure ${report.backpressureEvents}.`,
|
|
1504
|
+
errors: report.events.filter((event) => event.kind === "error").length,
|
|
1505
|
+
inputFrames: report.inputFrames,
|
|
1506
|
+
lastEventKind: lastEventKind(report.events),
|
|
1507
|
+
name: report.name,
|
|
1508
|
+
outputFrames: report.outputFrames,
|
|
1509
|
+
state: report.state,
|
|
1510
|
+
status: report.status
|
|
1511
|
+
});
|
|
1512
|
+
var summarizeMediaProcessorGraphReport = (report) => {
|
|
1513
|
+
const errorIssueCodes = Array.from(new Set(report.errors.map((event) => event.kind)));
|
|
1514
|
+
return {
|
|
1515
|
+
backpressureEvents: report.backpressure.events.length,
|
|
1516
|
+
description: `${report.name}: ${report.state}, ${report.nodes.length} node(s), in ${report.inputFrames}, out ${report.emittedFrames}, dropped ${report.droppedFrames}.`,
|
|
1517
|
+
droppedFrames: report.droppedFrames,
|
|
1518
|
+
edgeCount: report.edges.length,
|
|
1519
|
+
edgeEventCount: report.edgeEvents.length,
|
|
1520
|
+
emittedFrames: report.emittedFrames,
|
|
1521
|
+
errorCount: report.errors.length,
|
|
1522
|
+
inputFrames: report.inputFrames,
|
|
1523
|
+
issueCodes: errorIssueCodes,
|
|
1524
|
+
lifecycleEventCount: report.lifecycleEvents.length,
|
|
1525
|
+
name: report.name,
|
|
1526
|
+
nodeCount: report.nodes.length,
|
|
1527
|
+
state: report.state,
|
|
1528
|
+
status: report.status,
|
|
1529
|
+
timingMaxMs: report.timing.maxNodeMs
|
|
1530
|
+
};
|
|
1531
|
+
};
|
|
1532
|
+
var renderMediaQualityMarkdown = (report, options = {}) => {
|
|
1533
|
+
const title = options.title ?? "Media Quality Report";
|
|
1534
|
+
const lines = [
|
|
1535
|
+
`# ${title}`,
|
|
1536
|
+
"",
|
|
1537
|
+
`Status: **${report.status}**`,
|
|
1538
|
+
"",
|
|
1539
|
+
"| Metric | Value |",
|
|
1540
|
+
"| --- | ---: |",
|
|
1541
|
+
`| Total frames | ${report.totalFrames} |`,
|
|
1542
|
+
`| Input audio | ${report.inputAudioFrames} |`,
|
|
1543
|
+
`| Assistant audio | ${report.assistantAudioFrames} |`,
|
|
1544
|
+
`| Gaps | ${report.gapCount} |`,
|
|
1545
|
+
`| Jitter | ${formatOptionalMs(report.jitterMs)} |`,
|
|
1546
|
+
`| Timestamp drift | ${formatOptionalMs(report.timestampDriftMs)} |`,
|
|
1547
|
+
`| Speech ratio | ${formatRatio(report.speechRatio)} |`,
|
|
1548
|
+
`| Silence ratio | ${formatRatio(report.silenceRatio)} |`,
|
|
1549
|
+
`| Backpressure events | ${report.backpressureEvents} |`,
|
|
1550
|
+
"",
|
|
1551
|
+
"## Issues",
|
|
1552
|
+
"",
|
|
1553
|
+
renderIssuesTable(report.issues).trimEnd()
|
|
1554
|
+
];
|
|
1555
|
+
return `${lines.join(`
|
|
1556
|
+
`)}
|
|
1557
|
+
`;
|
|
1558
|
+
};
|
|
1559
|
+
var renderMediaTransportMarkdown = (report, options = {}) => {
|
|
1560
|
+
const title = options.title ?? `Media Transport: ${report.name}`;
|
|
1561
|
+
const limit = options.redact?.truncateArraysAt ?? DEFAULT_TRUNCATE;
|
|
1562
|
+
const events = report.events.slice(-limit);
|
|
1563
|
+
const eventRows = events.length === 0 ? "- No transport events recorded." : ["| At | Kind | State | Buffered | Error |", "| --- | --- | --- | ---: | --- |"].concat(events.map((event) => `| ${event.at} | ${event.kind} | ${event.state} | ${event.bufferedFrames ?? ""} | ${escapeMarkdownCell(event.error ?? "")} |`)).join(`
|
|
1564
|
+
`);
|
|
1565
|
+
const lines = [
|
|
1566
|
+
`# ${title}`,
|
|
1567
|
+
"",
|
|
1568
|
+
`Status: **${report.status}** \xB7 State: **${report.state}**`,
|
|
1569
|
+
"",
|
|
1570
|
+
"| Metric | Value |",
|
|
1571
|
+
"| --- | ---: |",
|
|
1572
|
+
`| Input frames | ${report.inputFrames} |`,
|
|
1573
|
+
`| Output frames | ${report.outputFrames} |`,
|
|
1574
|
+
`| Backpressure events | ${report.backpressureEvents} |`,
|
|
1575
|
+
`| Connected | ${report.connected ? "yes" : "no"} |`,
|
|
1576
|
+
`| Closed | ${report.closed ? "yes" : "no"} |`,
|
|
1577
|
+
`| Failed | ${report.failed ? "yes" : "no"} |`,
|
|
1578
|
+
"",
|
|
1579
|
+
`## Last ${events.length} event(s)`,
|
|
1580
|
+
"",
|
|
1581
|
+
eventRows
|
|
1582
|
+
];
|
|
1583
|
+
return `${lines.join(`
|
|
1584
|
+
`)}
|
|
1585
|
+
`;
|
|
1586
|
+
};
|
|
1587
|
+
var renderMediaProcessorGraphMarkdown = (report, options = {}) => {
|
|
1588
|
+
const title = options.title ?? `Media Processor Graph: ${report.name}`;
|
|
1589
|
+
const limit = options.redact?.truncateArraysAt ?? DEFAULT_TRUNCATE;
|
|
1590
|
+
const nodeRows = report.nodes.map((node) => `| ${escapeMarkdownCell(node.name)} | ${node.kind} | ${node.status} | ${node.inputFrames} | ${node.emittedFrames} | ${node.droppedFrames} | ${node.errors.length} |`).join(`
|
|
1591
|
+
`);
|
|
1592
|
+
const edgeRows = report.edges.slice(0, limit).map((edge) => `| ${escapeMarkdownCell(edge.from)} | ${escapeMarkdownCell(edge.to)} | ${edge.status} | ${edge.emittedFrames} |`).join(`
|
|
1593
|
+
`);
|
|
1594
|
+
const issues = report.errors.map((event) => ({
|
|
1595
|
+
code: event.kind,
|
|
1596
|
+
message: event.error ?? `Processor graph ${event.kind} (state ${event.state}).`,
|
|
1597
|
+
severity: "error"
|
|
1598
|
+
}));
|
|
1599
|
+
const lines = [
|
|
1600
|
+
`# ${title}`,
|
|
1601
|
+
"",
|
|
1602
|
+
`Status: **${report.status}** \xB7 State: **${report.state}**`,
|
|
1603
|
+
"",
|
|
1604
|
+
"| Metric | Value |",
|
|
1605
|
+
"| --- | ---: |",
|
|
1606
|
+
`| Nodes | ${report.nodes.length} |`,
|
|
1607
|
+
`| Input frames | ${report.inputFrames} |`,
|
|
1608
|
+
`| Emitted frames | ${report.emittedFrames} |`,
|
|
1609
|
+
`| Dropped frames | ${report.droppedFrames} |`,
|
|
1610
|
+
`| Lifecycle events | ${report.lifecycleEvents.length} |`,
|
|
1611
|
+
`| Edge events | ${report.edgeEvents.length} |`,
|
|
1612
|
+
`| Backpressure events | ${report.backpressure.events.length} |`,
|
|
1613
|
+
`| Timing max | ${formatOptionalMs(report.timing.maxNodeMs)} |`,
|
|
1614
|
+
`| Timing average | ${formatOptionalMs(report.timing.averageNodeMs)} |`,
|
|
1615
|
+
"",
|
|
1616
|
+
"## Nodes",
|
|
1617
|
+
"",
|
|
1618
|
+
nodeRows ? `| Node | Kind | Status | In | Out | Dropped | Errors |
|
|
1619
|
+
| --- | --- | --- | ---: | ---: | ---: | ---: |
|
|
1620
|
+
${nodeRows}` : "- No nodes.",
|
|
1621
|
+
"",
|
|
1622
|
+
`## Edges (showing up to ${limit})`,
|
|
1623
|
+
"",
|
|
1624
|
+
edgeRows ? `| From | To | Status | Frames |
|
|
1625
|
+
| --- | --- | --- | ---: |
|
|
1626
|
+
${edgeRows}` : "- No edges.",
|
|
1627
|
+
"",
|
|
1628
|
+
"## Errors",
|
|
1629
|
+
"",
|
|
1630
|
+
renderIssuesTable(issues).trimEnd()
|
|
1631
|
+
];
|
|
1632
|
+
return `${lines.join(`
|
|
1633
|
+
`)}
|
|
1634
|
+
`;
|
|
1635
|
+
};
|
|
1636
|
+
var truncateArrays = (value, limit, seen) => {
|
|
1637
|
+
if (Array.isArray(value)) {
|
|
1638
|
+
const head = value.slice(0, limit).map((entry) => truncateArrays(entry, limit, seen));
|
|
1639
|
+
if (value.length > limit) {
|
|
1640
|
+
return [...head, { truncated: value.length - limit }];
|
|
1641
|
+
}
|
|
1642
|
+
return head;
|
|
1643
|
+
}
|
|
1644
|
+
if (value && typeof value === "object") {
|
|
1645
|
+
if (seen.has(value))
|
|
1646
|
+
return value;
|
|
1647
|
+
seen.add(value);
|
|
1648
|
+
const next = {};
|
|
1649
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
1650
|
+
next[key] = truncateArrays(entry, limit, seen);
|
|
1651
|
+
}
|
|
1652
|
+
return next;
|
|
1653
|
+
}
|
|
1654
|
+
return value;
|
|
1655
|
+
};
|
|
1656
|
+
var applyRedaction = (value, options, seen) => {
|
|
1657
|
+
const mode = options.mode ?? "omit";
|
|
1658
|
+
const maskValue = options.maskValue ?? "[redacted]";
|
|
1659
|
+
const allow = new Set(options.metadataAllow ?? []);
|
|
1660
|
+
const deny = new Set(options.metadataDeny ?? DEFAULT_METADATA_DENY);
|
|
1661
|
+
const walk = (input) => {
|
|
1662
|
+
if (Array.isArray(input)) {
|
|
1663
|
+
return input.map((entry) => walk(entry));
|
|
1664
|
+
}
|
|
1665
|
+
if (input && typeof input === "object") {
|
|
1666
|
+
if (seen.has(input))
|
|
1667
|
+
return input;
|
|
1668
|
+
seen.add(input);
|
|
1669
|
+
const next = {};
|
|
1670
|
+
for (const [key, entry] of Object.entries(input)) {
|
|
1671
|
+
if (allow.has(key)) {
|
|
1672
|
+
next[key] = entry;
|
|
1673
|
+
continue;
|
|
1674
|
+
}
|
|
1675
|
+
if (deny.has(key)) {
|
|
1676
|
+
if (mode === "mask")
|
|
1677
|
+
next[key] = maskValue;
|
|
1678
|
+
continue;
|
|
1679
|
+
}
|
|
1680
|
+
next[key] = walk(entry);
|
|
1681
|
+
}
|
|
1682
|
+
return next;
|
|
1683
|
+
}
|
|
1684
|
+
return input;
|
|
1685
|
+
};
|
|
1686
|
+
return walk(value);
|
|
1687
|
+
};
|
|
1688
|
+
var redactMediaReport = (report, options = {}) => {
|
|
1689
|
+
const limit = options.truncateArraysAt ?? DEFAULT_TRUNCATE;
|
|
1690
|
+
const truncated = truncateArrays(report, limit, new WeakSet);
|
|
1691
|
+
return applyRedaction(truncated, options, new WeakSet);
|
|
1692
|
+
};
|
|
1693
|
+
var buildArtifactPair = (report, summary, markdown, options) => {
|
|
1694
|
+
const jsonValue = options.redact ? redactMediaReport(report, options.redact) : report;
|
|
1695
|
+
return {
|
|
1696
|
+
json: JSON.stringify(jsonValue, null, 2),
|
|
1697
|
+
jsonValue,
|
|
1698
|
+
markdown,
|
|
1699
|
+
summary
|
|
1700
|
+
};
|
|
1701
|
+
};
|
|
1702
|
+
var buildMediaQualityArtifact = (report, options = {}) => buildArtifactPair(report, summarizeMediaQualityReport(report), renderMediaQualityMarkdown(report, options), options);
|
|
1703
|
+
var buildMediaTransportArtifact = (report, options = {}) => buildArtifactPair(report, summarizeMediaTransportReport(report), renderMediaTransportMarkdown(report, options), options);
|
|
1704
|
+
var buildMediaProcessorGraphArtifact = (report, options = {}) => buildArtifactPair(report, summarizeMediaProcessorGraphReport(report), renderMediaProcessorGraphMarkdown(report, options), options);
|
|
1705
|
+
var writeMediaArtifact = async (input) => {
|
|
1706
|
+
await mkdir(input.dir, { recursive: true });
|
|
1707
|
+
const jsonPath = join(input.dir, `${input.slug}.json`);
|
|
1708
|
+
const markdownPath = join(input.dir, `${input.slug}.md`);
|
|
1709
|
+
await Promise.all([
|
|
1710
|
+
writeFile(jsonPath, input.json, "utf8"),
|
|
1711
|
+
writeFile(markdownPath, input.markdown, "utf8")
|
|
1712
|
+
]);
|
|
1713
|
+
return {
|
|
1714
|
+
jsonPath,
|
|
1715
|
+
markdownPath,
|
|
1716
|
+
summary: input.summary
|
|
1717
|
+
};
|
|
1718
|
+
};
|
|
1454
1719
|
|
|
1455
1720
|
// src/client/browserMedia.ts
|
|
1456
1721
|
var DEFAULT_BROWSER_MEDIA_PATH = "/api/voice/browser-media";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const HTMX_BOOTSTRAP_BUNDLE = "var Ue=(e)=>{if(typeof e!==\"string\")return e;return document.querySelector(e)},Ne=(e,n,t,o)=>{let r=n??e.getAttribute(\"hx-get\")??\"\";if(!r)return\"\";let i=new URL(r,window.location.origin);if(o)i.searchParams.set(t,o);else i.searchParams.delete(t);return`${i.pathname}${i.search}${i.hash}`},de=(e,n)=>{if(typeof window>\"u\"||typeof document>\"u\")return()=>{};let t=Ue(n.element);if(!t)return()=>{};let o=n.eventName??\"voice-refresh\",r=n.sessionQueryParam??\"sessionId\",i=()=>{let l=window,g=Ne(t,n.route,r,e.sessionId);if(g)t.setAttribute(\"hx-get\",g);l.htmx?.process?.(t),l.htmx?.trigger?.(t,o)},c=e.subscribe(i);return i(),()=>{c()}};var He=(e)=>Math.max(-1,Math.min(1,e)),Ge=(e)=>{let n=new Int16Array(e.length);for(let t=0;t<e.length;t+=1){let o=He(e[t]??0);n[t]=o<0?o*32768:o*32767}return new Uint8Array(n.buffer)},Be=(e)=>{let n=e instanceof Uint8Array?e:new Uint8Array(e);if(n.byteLength<2)return 0;let t=new Int16Array(n.buffer,n.byteOffset,Math.floor(n.byteLength/2));if(t.length===0)return 0;let o=0;for(let r of t){let i=r/32768;o+=i*i}return Math.min(1,Math.max(0,Math.sqrt(o/t.length)*5.5))},We=(e,n,t)=>{if(n===t)return e;let o=n/t,r=Math.round(e.length/o),i=new Float32Array(r),c=0,l=0;while(c<i.length){let g=Math.round((c+1)*o),y=0,d=0;for(let h=l;h<g&&h<e.length;h+=1)y+=e[h]??0,d+=1;i[c]=d>0?y/d:0,c+=1,l=g}return i},ge=(e)=>{let n=null,t=null,o=null,r=null;return{start:async()=>{if(typeof navigator>\"u\"||!navigator.mediaDevices?.getUserMedia)throw Error(\"Browser microphone capture requires navigator.mediaDevices.getUserMedia.\");let l=(typeof window<\"u\"?window.AudioContext??window.webkitAudioContext:void 0)??AudioContext;if(!l)throw Error(\"Browser microphone capture requires AudioContext support.\");r=await navigator.mediaDevices.getUserMedia({audio:{channelCount:e.channelCount??1}}),n=new l,t=n.createMediaStreamSource(r),o=n.createScriptProcessor(4096,1,1),o.onaudioprocess=(g)=>{let y=g.inputBuffer.getChannelData(0),d=We(y,n?.sampleRate??48000,e.sampleRateHz??16000),h=Ge(d);e.onLevel?.(Be(h)),e.onAudio(h)},t.connect(o),o.connect(n.destination)},stop:()=>{o?.disconnect(),t?.disconnect(),r?.getTracks().forEach((l)=>l.stop()),n?.close(),e.onLevel?.(0),n=null,r=null,o=null,t=null}}};var ee=(e)=>{if(typeof e===\"string\"&&e.trim())return e;if(e instanceof Error&&e.message.trim())return e.message;if(e&&typeof e===\"object\"){let n=e;for(let t of[\"message\",\"reason\",\"description\"]){let o=n[t];if(typeof o===\"string\"&&o.trim())return o}if(\"error\"in n)return ee(n.error);if(\"cause\"in n)return ee(n.cause);try{return JSON.stringify(e)}catch{}}return\"Unexpected error\"},Ae=(e)=>{switch(e.type){case\"audio\":return{chunk:Uint8Array.from(atob(e.chunkBase64),(n)=>n.charCodeAt(0)),format:e.format,receivedAt:e.receivedAt,turnId:e.turnId,type:\"audio\"};case\"assistant\":return{text:e.text,type:\"assistant\"};case\"complete\":return{sessionId:e.sessionId,type:\"complete\"};case\"connection\":return{reconnect:e.reconnect,type:\"connection\"};case\"call_lifecycle\":return{event:e.event,sessionId:e.sessionId,type:\"call_lifecycle\"};case\"error\":return{message:ee(e.message),type:\"error\"};case\"final\":return{transcript:e.transcript,type:\"final\"};case\"partial\":return{transcript:e.transcript,type:\"partial\"};case\"replay\":return{assistantTexts:e.assistantTexts,call:e.call,partial:e.partial,scenarioId:e.scenarioId,sessionId:e.sessionId,sessionMetadata:e.sessionMetadata,status:e.status,turns:e.turns,type:\"replay\"};case\"session\":return{sessionId:e.sessionId,sessionMetadata:e.sessionMetadata,scenarioId:e.scenarioId,status:e.status,type:\"session\"};case\"turn\":return{turn:e.turn,type:\"turn\"};default:return null}};var H=(e,n,t,o)=>{e.push({code:t,message:o,severity:n})};var $e=(e)=>e.length===0?void 0:e.reduce((n,t)=>n+t,0)/e.length,K=(e)=>e.length===0?void 0:Math.max(...e);var b=(e,n)=>{let t=e[n];return typeof t===\"number\"&&Number.isFinite(t)?t:void 0},Z=(e,n)=>{let t=e[n];return typeof t===\"boolean\"?t:void 0},D=(e,n)=>{let t=e[n];return typeof t===\"string\"?t:void 0},ne=(e)=>String(e.id??D(e,\"ssrc\")??b(e,\"ssrc\")??D(e,\"trackIdentifier\")??D(e,\"mid\")??\"unknown\"),he=(e)=>e===void 0?void 0:e*1000;var ke=(e)=>{let n={};for(let[t,o]of Object.entries(e))if(o===null||typeof o===\"boolean\"||typeof o===\"number\"||typeof o===\"string\")n[t]=o;return n};var ye=(e={})=>{let n=e.stats??[],t=[],o=n.filter((s)=>s.type===\"inbound-rtp\"&&D(s,\"kind\")!==\"video\"),r=n.filter((s)=>s.type===\"outbound-rtp\"&&D(s,\"kind\")!==\"video\"),i=n.filter((s)=>s.type===\"candidate-pair\"),c=n.filter((s)=>(s.type===\"track\"||s.type===\"media-source\")&&D(s,\"kind\")===\"audio\"),l=i.filter((s)=>Z(s,\"selected\")===!0||Z(s,\"nominated\")===!0||D(s,\"state\")===\"succeeded\").length,g=c.filter((s)=>D(s,\"readyState\")!==\"ended\"&&D(s,\"trackState\")!==\"ended\"&&Z(s,\"ended\")!==!0).length,y=c.filter((s)=>D(s,\"readyState\")===\"ended\"||D(s,\"trackState\")===\"ended\"||Z(s,\"ended\")===!0).length,d=o.reduce((s,S)=>s+(b(S,\"packetsReceived\")??0),0),h=r.reduce((s,S)=>s+(b(S,\"packetsSent\")??0),0),a=[...o,...r].reduce((s,S)=>s+Math.max(0,b(S,\"packetsLost\")??0),0),M=d+a,C=M===0?0:a/M,I=o.reduce((s,S)=>s+(b(S,\"bytesReceived\")??0),0),w=r.reduce((s,S)=>s+(b(S,\"bytesSent\")??0),0),R=K(i.map((s)=>he(b(s,\"currentRoundTripTime\")??b(s,\"roundTripTime\"))).filter((s)=>s!==void 0)),u=K([...o,...r].map((s)=>he(b(s,\"jitter\"))).filter((s)=>s!==void 0)),O=K(o.map((s)=>{let S=b(s,\"jitterBufferDelay\"),L=b(s,\"jitterBufferEmittedCount\");return S!==void 0&&L!==void 0&&L>0?S/L*1000:void 0}).filter((s)=>s!==void 0)),U=c.map((s)=>b(s,\"audioLevel\")).filter((s)=>s!==void 0);if(e.requireConnectedCandidatePair&&i.length>0&&l===0)H(t,\"error\",\"media.webrtc_candidate_pair_missing\",\"No active WebRTC candidate pair was observed.\");if(e.requireLiveAudioTrack&&g===0)H(t,\"error\",\"media.webrtc_audio_track_missing\",\"No live WebRTC audio track was observed.\");if(e.maxPacketLossRatio!==void 0&&C>e.maxPacketLossRatio)H(t,\"warning\",\"media.webrtc_packet_loss\",`Observed WebRTC packet loss ratio ${String(C)} above ${String(e.maxPacketLossRatio)}.`);if(e.maxRoundTripTimeMs!==void 0&&R!==void 0&&R>e.maxRoundTripTimeMs)H(t,\"warning\",\"media.webrtc_round_trip_time\",`Observed WebRTC RTT ${String(R)}ms above ${String(e.maxRoundTripTimeMs)}ms.`);if(e.maxJitterMs!==void 0&&u!==void 0&&u>e.maxJitterMs)H(t,\"warning\",\"media.webrtc_jitter\",`Observed WebRTC jitter ${String(u)}ms above ${String(e.maxJitterMs)}ms.`);return{activeCandidatePairs:l,audioLevelAverage:$e(U),bytesReceived:I,bytesSent:w,checkedAt:Date.now(),endedAudioTracks:y,inboundPackets:d,issues:t,jitterBufferDelayMs:O,jitterMs:u,liveAudioTracks:g,outboundPackets:h,packetLossRatio:C,packetsLost:a,roundTripTimeMs:R,status:t.some((s)=>s.severity===\"error\")?\"fail\":t.length>0?\"warn\":\"pass\",totalStats:n.length}},Ce=async(e)=>{return[...(await e.peerConnection.getStats(e.selector??null)).values()].map(ke)};var fe=(e={})=>{let n=e.stats??[],t=e.previousStats??[],o=[],r=new Map(t.map((a)=>[ne(a),a])),c=n.filter((a)=>(a.type===\"inbound-rtp\"||a.type===\"outbound-rtp\")&&D(a,\"kind\")!==\"video\"&&D(a,\"mediaType\")!==\"video\").map((a)=>{let M=a.type===\"outbound-rtp\"?\"outbound\":\"inbound\",C=M===\"outbound\"?\"packetsSent\":\"packetsReceived\",I=M===\"outbound\"?\"bytesSent\":\"bytesReceived\",w=r.get(ne(a)),R=b(a,C),u=w?b(w,C):void 0,O=b(a,I),U=w?b(w,I):void 0,s=a.timestamp!==void 0&&w?.timestamp!==void 0?a.timestamp-w.timestamp:void 0;return{bytesDelta:O!==void 0&&U!==void 0?O-U:void 0,currentPackets:R,direction:M,id:ne(a),packetDelta:R!==void 0&&u!==void 0?R-u:void 0,previousPackets:u,timeDeltaMs:s}}),l=c.filter((a)=>a.direction===\"inbound\"),g=c.filter((a)=>a.direction===\"outbound\"),y=K(c.map((a)=>a.timeDeltaMs).filter((a)=>a!==void 0)),d=l.filter((a)=>e.maxInboundPacketStallMs!==void 0&&a.timeDeltaMs!==void 0&&a.timeDeltaMs>=e.maxInboundPacketStallMs&&a.packetDelta!==void 0&&a.packetDelta<=0).length,h=g.filter((a)=>e.maxOutboundPacketStallMs!==void 0&&a.timeDeltaMs!==void 0&&a.timeDeltaMs>=e.maxOutboundPacketStallMs&&a.packetDelta!==void 0&&a.packetDelta<=0).length;if(e.requireInboundAudio&&l.length===0)H(o,\"error\",\"media.webrtc_inbound_audio_missing\",\"No inbound WebRTC audio RTP stream was observed.\");if(e.requireOutboundAudio&&g.length===0)H(o,\"error\",\"media.webrtc_outbound_audio_missing\",\"No outbound WebRTC audio RTP stream was observed.\");if(e.maxGapMs!==void 0&&y!==void 0&&y>e.maxGapMs)H(o,\"warning\",\"media.webrtc_stream_gap\",`Observed WebRTC stream sample gap ${String(y)}ms above ${String(e.maxGapMs)}ms.`);if(d>0)H(o,\"error\",\"media.webrtc_inbound_stalled\",`${String(d)} inbound WebRTC audio stream(s) stopped receiving packets.`);if(h>0)H(o,\"error\",\"media.webrtc_outbound_stalled\",`${String(h)} outbound WebRTC audio stream(s) stopped sending packets.`);return{checkedAt:Date.now(),inboundAudioStreams:l.length,issues:o,maxObservedGapMs:y,outboundAudioStreams:g.length,stalledInboundStreams:d,stalledOutboundStreams:h,status:o.some((a)=>a.severity===\"error\")?\"fail\":o.length>0?\"warn\":\"pass\",streams:c,totalStats:n.length}};var qe=\"/api/voice/browser-media\",Xe=5000,ze=async(e)=>e.peerConnection??await e.getPeerConnection?.()??null,Ye=async(e,n)=>{let t=n.fetch??globalThis.fetch;if(!t)return;await t(n.path??qe,{body:JSON.stringify(e),headers:{\"Content-Type\":\"application/json\"},keepalive:!0,method:\"POST\"})},Te=(e)=>{let n=null,t=[],o=async()=>{let c=await ze(e);if(!c)return;let l=await Ce({peerConnection:c}),g=ye({...e,stats:l}),y=e.continuity===!1?void 0:fe({...e.continuity,previousStats:t,stats:l}),d={at:Date.now(),continuity:y,report:g,scenarioId:e.getScenarioId?.()??null,sessionId:e.getSessionId?.()??null};return t=l,e.onReport?.(d),await Ye(d,e),d},r=()=>{o().catch((c)=>{e.onError?.(c)})},i=()=>{if(n)clearInterval(n),n=null};return{close:i,reportOnce:o,start:()=>{if(n)return;r(),n=setInterval(r,e.intervalMs??Xe)},stop:i}};var B=()=>{},Je=()=>B,Qe={callControl:B,close:B,endTurn:B,getReadyState:()=>3,getScenarioId:()=>\"\",getSessionId:()=>\"\",send:B,sendAudio:B,simulateDisconnect:B,start:()=>{},subscribe:Je},Ze=()=>crypto.randomUUID(),Ke=(e,n,t)=>{let{hostname:o,port:r,protocol:i}=window.location,c=i===\"https:\"?\"wss:\":\"ws:\",l=r?`:${r}`:\"\",g=new URL(`${c}//${o}${l}${e}`);if(g.searchParams.set(\"sessionId\",n),t)g.searchParams.set(\"scenarioId\",t);return g.toString()},me=(e)=>{if(!e||typeof e!==\"object\"||!(\"type\"in e))return!1;switch(e.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}},je=(e)=>{if(typeof e.data!==\"string\")return null;try{let n=JSON.parse(e.data);return me(n)?n:null}catch{return null}},Se=(e,n={})=>{if(typeof window>\"u\")return Qe;let t=new Set,o=n.reconnect!==!1,r=n.maxReconnectAttempts??10,i=n.pingInterval??30000,c={isConnected:!1,pendingMessages:[],scenarioId:n.scenarioId??null,pingInterval:null,reconnectAttempts:0,reconnectTimeout:null,sessionId:n.sessionId??Ze(),ws:null},l=(s)=>{t.forEach((S)=>S(s))},g=()=>{if(c.pingInterval)clearInterval(c.pingInterval),c.pingInterval=null;if(c.reconnectTimeout)clearTimeout(c.reconnectTimeout),c.reconnectTimeout=null},y=()=>{if(c.ws?.readyState!==1)return;while(c.pendingMessages.length>0){let s=c.pendingMessages.shift();if(s!==void 0)c.ws.send(s)}},d=()=>{let s=Date.now()+500;c.reconnectAttempts+=1,l({reconnect:{attempts:c.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:r,nextAttemptAt:s,status:\"reconnecting\"},type:\"connection\"}),c.reconnectTimeout=setTimeout(()=>{if(c.reconnectAttempts>r){l({reconnect:{attempts:c.reconnectAttempts,maxAttempts:r,status:\"exhausted\"},type:\"connection\"});return}h()},500)},h=()=>{let s=new WebSocket(Ke(e,c.sessionId,c.scenarioId));s.binaryType=\"arraybuffer\",s.onopen=()=>{let S=c.reconnectAttempts>0;if(c.isConnected=!0,y(),S)l({reconnect:{attempts:c.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:r,status:\"resumed\"},type:\"connection\"}),c.reconnectAttempts=0;t.forEach((L)=>L({scenarioId:c.scenarioId??void 0,sessionId:c.sessionId,status:\"active\",type:\"session\"})),c.pingInterval=setInterval(()=>{if(s.readyState===1)s.send(JSON.stringify({type:\"ping\"}))},i)},s.onmessage=(S)=>{let L=je(S);if(!L)return;if(L.type===\"session\")c.sessionId=L.sessionId,c.scenarioId=L.scenarioId??c.scenarioId;t.forEach((X)=>X(L))},s.onclose=(S)=>{if(c.isConnected=!1,g(),o&&S.code!==1000&&c.reconnectAttempts<r)d();else if(o&&S.code!==1000)l({reconnect:{attempts:c.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:r,status:\"exhausted\"},type:\"connection\"})},c.ws=s},a=(s)=>{if(c.ws?.readyState===1){c.ws.send(s);return}c.pendingMessages.push(s)},M=(s)=>{a(JSON.stringify(s))},C=(s={})=>{if(s.sessionId)c.sessionId=s.sessionId;if(s.scenarioId)c.scenarioId=s.scenarioId;M({type:\"start\",sessionId:c.sessionId,scenarioId:c.scenarioId??void 0})},I=(s)=>{a(s)},w=()=>{M({type:\"end_turn\"})},R=(s)=>{M({...s,type:\"call_control\"})},u=()=>{if(g(),c.ws)c.ws.close(1000),c.ws=null;c.isConnected=!1,t.clear()},O=()=>{if(c.ws?.readyState===1)c.ws.close(4000,\"absolutejs-voice-reconnect-proof\")},U=(s)=>{return t.add(s),()=>{t.delete(s)}};return h(),{callControl:R,close:u,endTurn:w,getReadyState:()=>c.ws?.readyState??3,getScenarioId:()=>c.scenarioId??\"\",getSessionId:()=>c.sessionId,send:M,sendAudio:I,simulateDisconnect:O,start:C,subscribe:U}};var ve=()=>({attempts:0,maxAttempts:0,status:\"idle\"}),Fe=()=>({assistantAudio:[],assistantTexts:[],call:null,error:null,isConnected:!1,sessionMetadata:null,scenarioId:null,partial:\"\",reconnect:ve(),sessionId:null,status:\"idle\",turns:[]}),Me=()=>{let e=Fe(),n=new Set,t=()=>{n.forEach((r)=>r())};return{dispatch:(r)=>{switch(r.type){case\"audio\":e={...e,assistantAudio:[...e.assistantAudio,{chunk:r.chunk,format:r.format,receivedAt:r.receivedAt,turnId:r.turnId}]};break;case\"assistant\":e={...e,assistantTexts:[...e.assistantTexts,r.text]};break;case\"complete\":e={...e,sessionId:r.sessionId,status:\"completed\"};break;case\"call_lifecycle\":e={...e,call:{...e.call,disposition:r.event.type===\"end\"?r.event.disposition:e.call?.disposition,endedAt:r.event.type===\"end\"?r.event.at:e.call?.endedAt,events:[...e.call?.events??[],r.event],lastEventAt:r.event.at,startedAt:e.call?.startedAt??r.event.at},sessionId:r.sessionId};break;case\"connected\":e={...e,isConnected:!0,reconnect:e.reconnect.status===\"reconnecting\"?{...e.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:\"resumed\"}:e.reconnect};break;case\"connection\":e={...e,reconnect:r.reconnect};break;case\"disconnected\":e={...e,isConnected:!1};break;case\"error\":e={...e,error:r.message};break;case\"final\":e={...e,partial:r.transcript.text,turns:e.turns.map((i)=>i)};break;case\"partial\":e={...e,partial:r.transcript.text};break;case\"replay\":e={...e,assistantTexts:[...r.assistantTexts],call:r.call??null,error:null,isConnected:r.status===\"active\",partial:r.partial,reconnect:e.reconnect.status===\"reconnecting\"?{...e.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:\"resumed\"}:e.reconnect,scenarioId:r.scenarioId??e.scenarioId,sessionId:r.sessionId,sessionMetadata:r.sessionMetadata??e.sessionMetadata,status:r.status,turns:[...r.turns]};break;case\"session\":e={...e,error:null,scenarioId:r.scenarioId??e.scenarioId,isConnected:r.status===\"active\",sessionId:r.sessionId,sessionMetadata:r.sessionMetadata??e.sessionMetadata,status:r.status};break;case\"turn\":e={...e,partial:\"\",turns:[...e.turns,r.turn]};break}t()},getServerSnapshot:()=>e,getSnapshot:()=>e,subscribe:(r)=>{return n.add(r),()=>{n.delete(r)}}}};var Ie=(e,n={})=>{let t=Se(e,n),o=Me(),r=n.browserMedia&&typeof window<\"u\"?Te({...n.browserMedia,getScenarioId:()=>n.browserMedia?n.browserMedia.getScenarioId?.()??t.getScenarioId():t.getScenarioId(),getSessionId:()=>n.browserMedia?n.browserMedia.getSessionId?.()??t.getSessionId():t.getSessionId()}):null,i=new Set,c=(d)=>Promise.resolve().then(()=>{if(!d?.sessionId&&!d?.scenarioId)return;t.start(d),r?.start()}),l=()=>{i.forEach((d)=>d())},g=()=>{if(!n.reconnectReportPath||typeof fetch>\"u\")return;let d=o.getSnapshot(),h=JSON.stringify({at:Date.now(),reconnect:d.reconnect,scenarioId:d.scenarioId,sessionId:t.getSessionId(),turnIds:d.turns.map((a)=>a.id)});fetch(n.reconnectReportPath,{body:h,headers:{\"Content-Type\":\"application/json\"},keepalive:!0,method:\"POST\"}).catch(()=>{})},y=t.subscribe((d)=>{let h=Ae(d);if(h){if(o.dispatch(h),d.type===\"connection\")g();l()}});return{callControl(d){t.callControl(d)},close(){y(),r?.close(),t.close(),o.dispatch({type:\"disconnected\"}),l()},endTurn(){t.endTurn()},get error(){return o.getSnapshot().error},getServerSnapshot(){return o.getServerSnapshot()},getSnapshot(){return o.getSnapshot()},get isConnected(){return o.getSnapshot().isConnected},get scenarioId(){return o.getSnapshot().scenarioId},get sessionMetadata(){return o.getSnapshot().sessionMetadata},start:c,get partial(){return o.getSnapshot().partial},get reconnect(){return o.getSnapshot().reconnect},get sessionId(){return t.getSessionId()},get status(){return o.getSnapshot().status},get turns(){return o.getSnapshot().turns},get assistantTexts(){return o.getSnapshot().assistantTexts},get assistantAudio(){return o.getSnapshot().assistantAudio},get call(){return o.getSnapshot().call},sendAudio(d){t.sendAudio(d)},simulateDisconnect(){t.simulateDisconnect()},subscribe(d){return i.add(d),()=>{i.delete(d)}}}};var Ve=(e)=>{if(!e||e.enabled===!1)return;return{enabled:!0,maxGain:e.maxGain??3,noiseGateAttenuation:e.noiseGateAttenuation??0.15,noiseGateThreshold:e.noiseGateThreshold??0.006,targetLevel:e.targetLevel??0.08}};var pe={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}},en={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 we=(e)=>{let n=e?.profile??\"fast\",t=e?.qualityProfile??\"general\",o=pe[n],r=en[t];return{profile:n,qualityProfile:t,silenceMs:e?.silenceMs??r.silenceMs??o.silenceMs,speechThreshold:e?.speechThreshold??r.speechThreshold??o.speechThreshold,transcriptStabilityMs:e?.transcriptStabilityMs??r.transcriptStabilityMs??o.transcriptStabilityMs}};var nn={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\"}}},Le=(e=\"default\")=>{let n=nn[e];return{audioConditioning:Ve(n.audioConditioning),capture:{channelCount:n.capture?.channelCount??1,sampleRateHz:n.capture?.sampleRateHz??16000},connection:{...n.connection},name:e,sttLifecycle:n.sttLifecycle??\"continuous\",turnDetection:we(n.turnDetection)}};var on=(e)=>({assistantAudio:[...e.assistantAudio],assistantTexts:[...e.assistantTexts],call:e.call,error:e.error,isConnected:e.isConnected,isRecording:!1,partial:e.partial,reconnect:e.reconnect,recordingError:null,sessionId:e.sessionId,sessionMetadata:e.sessionMetadata,scenarioId:e.scenarioId,status:e.status,turns:[...e.turns]}),m=(e,n={})=>{let t=Le(n.preset),o=Ie(e,{...t.connection,...n.connection}),r=null,i=on(o),c=new Set,l=()=>{for(let C of c)C()},g=()=>{if(i={...i,assistantAudio:[...o.assistantAudio],assistantTexts:[...o.assistantTexts],call:o.call,error:o.error,isConnected:o.isConnected,partial:o.partial,reconnect:o.reconnect,sessionId:o.sessionId,sessionMetadata:o.sessionMetadata,scenarioId:o.scenarioId,status:o.status,turns:[...o.turns]},n.autoStopOnComplete!==!1&&i.status===\"completed\"&&i.isRecording)r?.stop(),r=null,i={...i,isRecording:!1};l()},y=o.subscribe(g);g();let d=()=>{if(r)return r;return r=ge({channelCount:n.capture?.channelCount??t.capture.channelCount,onLevel:n.capture?.onLevel,onAudio:(C)=>{if(n.capture?.onAudio){n.capture.onAudio(C,o.sendAudio);return}o.sendAudio(C)},sampleRateHz:n.capture?.sampleRateHz??t.capture.sampleRateHz}),r},h=()=>{r?.stop(),r=null,i={...i,isRecording:!1},l()},a=async()=>{if(i.isRecording)return;try{i={...i,recordingError:null},l(),await d().start(),i={...i,isRecording:!0},l()}catch(C){throw r=null,i={...i,isRecording:!1,recordingError:C instanceof Error?C.message:String(C)},l(),C}};return{bindHTMX(C){return de(o,C)},callControl:(C)=>o.callControl(C),close:()=>{y(),h(),o.close()},endTurn:()=>o.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:(C)=>o.sendAudio(C),simulateDisconnect:()=>o.simulateDisconnect(),get sessionId(){return i.sessionId},get sessionMetadata(){return i.sessionMetadata},get scenarioId(){return i.scenarioId},startRecording:a,get status(){return i.status},stopRecording:h,subscribe:(C)=>{return c.add(C),()=>{c.delete(C)}},toggleRecording:async()=>{if(i.isRecording){h();return}await a()},get turns(){return i.turns},get assistantTexts(){return i.assistantTexts},get assistantAudio(){return i.assistantAudio},get call(){return i.call}}};var tn=()=>({activeSourceCount:0,error:null,isActive:!1,isPlaying:!1,lastInterruptLatencyMs:void 0,lastPlaybackStopLatencyMs:void 0,processedChunkCount:0,queuedChunkCount:0}),cn=()=>{if(typeof window>\"u\")return typeof AudioContext>\"u\"?void 0:AudioContext;return window.AudioContext??window.webkitAudioContext},rn=(e,n)=>{let t=n.format;if(t.container!==\"raw\"||t.encoding!==\"pcm_s16le\")throw Error(`Unsupported assistant audio format: ${t.container}/${t.encoding}`);let o=n.chunk,r=Math.max(1,t.channels),i=Math.floor(o.byteLength/2),c=Math.max(1,Math.floor(i/r)),l=e.createBuffer(r,c,t.sampleRateHz),g=new DataView(o.buffer,o.byteOffset,o.byteLength);for(let y=0;y<r;y+=1){let d=l.getChannelData(y);for(let h=0;h<c;h+=1){let M=(h*r+y)*2;if(M+1>=o.byteLength){d[h]=0;continue}d[h]=g.getInt16(M,!0)/32768}}return l},j=(e,n={})=>{let t=new Set,o=new Set,r=(n.lookaheadMs??15)/1000,i=tn(),c=null,l=null,g=0,y=Promise.resolve(),d=null,h=null,a=null,M=null,C=()=>{for(let A of t)A()},I=(A)=>{i={...i,...A},C()},w=()=>{if(i.error!==null)I({error:null})},R=()=>{if(M!==null)clearTimeout(M),M=null},u=(A)=>{R(),d=null,I({activeSourceCount:o.size,isPlaying:!1,lastInterruptLatencyMs:A,lastPlaybackStopLatencyMs:i.lastPlaybackStopLatencyMs??A}),a?.(),a=null,h=null},O=(A)=>{if(!A)return 0;return Math.max(0,((A.baseLatency??0)+(A.outputLatency??0))*1000)},U=(A)=>{if(!l)return;let f=1;if(l.gain.setValueAtTime){l.gain.setValueAtTime(f,A?.currentTime??0);return}l.gain.value=f},s=(A)=>{if(!l)return;let f=0;if(l.gain.setValueAtTime){l.gain.setValueAtTime(f,A?.currentTime??0);return}l.gain.value=f},S=()=>{if(d===null||o.size>0)return;u(Date.now()-d)},L=async()=>{if(c)return c;if(n.createAudioContext)c=n.createAudioContext();else{let A=cn();if(!A)throw Error(\"Assistant audio playback requires AudioContext support.\");c=new A}if(c.createGain)l=c.createGain(),l.connect?.(c.destination);return g=c.currentTime,c},X=async(A)=>{let f=await L(),E=rn(f,A),V=f.createBufferSource();V.buffer=E,V.connect(l??f.destination),V.onended=()=>{o.delete(V),V.disconnect?.(),I({activeSourceCount:o.size,isPlaying:o.size>0&&i.isActive}),S()};let Y=Math.max(f.currentTime+r,g);g=Y+E.duration,o.add(V),I({activeSourceCount:o.size,isPlaying:!0}),V.start(Y)},_=(A)=>{for(let f of[...o])f.stop?.();if(g=c?c.currentTime:0,A?.forceClear){for(let f of o)f.disconnect?.();o.clear(),S()}},W=async()=>{if(!i.isActive)return;let A=e.assistantAudio.slice(i.processedChunkCount);if(A.length===0)return;try{w();for(let f of A)await X(f);I({processedChunkCount:e.assistantAudio.length,queuedChunkCount:i.queuedChunkCount+A.length})}catch(f){I({error:f instanceof Error?f.message:String(f)})}},P=()=>{return y=y.then(()=>W(),()=>W()),y},$=e.subscribe(()=>{if(n.autoStart&&!i.isActive&&e.assistantAudio.length>0){N.start();return}if(i.isActive)P()}),N={close:async()=>{if($(),_({forceClear:!0}),R(),a?.(),a=null,h=null,d=null,c&&c.state!==\"closed\")await c.close();c=null,l?.disconnect?.(),l=null,g=0,I({activeSourceCount:0,isActive:!1,isPlaying:!1})},get activeSourceCount(){return i.activeSourceCount},get error(){return i.error},getSnapshot:()=>i,get isActive(){return i.isActive},get isPlaying(){return i.isPlaying},interrupt:async()=>{let A=Date.now(),f=await L();d=A,s(f);let E=Date.now()-A+O(f);if(I({isActive:!1,isPlaying:o.size>0,lastPlaybackStopLatencyMs:E}),o.size===0){u(E);return}if(!h)h=new Promise((V)=>{a=V});R(),M=setTimeout(()=>{for(let V of o)V.disconnect?.();o.clear(),u(Date.now()-A)},250),_(),await h},get lastInterruptLatencyMs(){return i.lastInterruptLatencyMs},get lastPlaybackStopLatencyMs(){return i.lastPlaybackStopLatencyMs},pause:async()=>{if(!c){I({activeSourceCount:0,isActive:!1,isPlaying:!1});return}await c.suspend(),I({activeSourceCount:o.size,isActive:!1,isPlaying:!1})},get processedChunkCount(){return i.processedChunkCount},get queuedChunkCount(){return i.queuedChunkCount},start:async()=>{try{w();let A=await L();if(U(A),A.state===\"suspended\")await A.resume();I({activeSourceCount:o.size,isActive:!0,isPlaying:A.state===\"running\"}),await P()}catch(A){throw I({error:A instanceof Error?A.message:String(A),isActive:!1,isPlaying:!1}),A}},subscribe:(A)=>{return t.add(A),()=>{t.delete(A)}}};return N};var sn=()=>`barge-in:${Date.now()}:${crypto.randomUUID?.()??Math.random().toString(36).slice(2)}`,ln=(e,n)=>{let t=e.filter((c)=>c.status===\"stopped\"),o=t.map((c)=>c.latencyMs).filter((c)=>typeof c===\"number\"),r=t.filter((c)=>typeof c.latencyMs===\"number\"&&c.latencyMs>n).length,i=t.length-r;return{averageLatencyMs:o.length>0?Math.round(o.reduce((c,l)=>c+l,0)/o.length):void 0,events:[...e],failed:r,lastEvent:e.at(-1),passed:i,status:e.length===0?\"empty\":r>0?\"fail\":t.length===0?\"warn\":\"pass\",thresholdMs:n,total:t.length}},ue=(e={})=>{let n=new Set,t=e.thresholdMs??250,o=e.fetch??globalThis.fetch,r=[],i=()=>{for(let g of n)g()},c=(g)=>{if(!e.path||typeof o!==\"function\")return;o(e.path,{body:JSON.stringify(g),headers:{\"Content-Type\":\"application/json\"},method:\"POST\"}).catch(()=>{})},l=(g,y)=>{let d={at:Date.now(),id:sn(),latencyMs:y.latencyMs,playbackStopLatencyMs:y.playbackStopLatencyMs,reason:y.reason,sessionId:y.sessionId,status:g,thresholdMs:t};return r.push(d),c(d),i(),d};return{getSnapshot:()=>ln(r,t),recordRequested:(g)=>l(\"requested\",g),recordSkipped:(g)=>l(\"skipped\",g),recordStopped:(g)=>l(\"stopped\",g),subscribe:(g)=>{return n.add(g),()=>{n.delete(g)}}}};var an=0.08,dn=(e,n={})=>(n.enabled??!0)&&e>=(n.interruptThreshold??an),oe=(e,n,t={})=>{let o=e.partial,r=(c)=>{if(!n.isPlaying||t.enabled===!1){t.monitor?.recordSkipped({reason:c,sessionId:e.sessionId});return}t.monitor?.recordRequested({reason:c,sessionId:e.sessionId}),n.interrupt().then(()=>{t.monitor?.recordStopped({latencyMs:n.lastInterruptLatencyMs,playbackStopLatencyMs:n.lastPlaybackStopLatencyMs,reason:c,sessionId:e.sessionId})})},i=e.subscribe(()=>{if(t.interruptOnPartial===!1){o=e.partial;return}if(!o&&e.partial)r(\"partial-transcript\");o=e.partial});return{close:()=>{i()},handleLevel:(c)=>{if(dn(c,t))r(\"input-level\")},sendAudio:(c)=>{r(\"manual-audio\"),e.sendAudio(c)}}};var se=48,gn=320,An=88,hn=\"Guided test\",yn=\"General recording\",Cn=\"Pick a scenario to begin the demo.\",fn=\"I can walk you through a short guided voice test.\",Tn=\"I can capture one freeform recording and confirm that it landed.\",Sn=\"Choose a scenario to begin. Guided test asks follow-up prompts. General recording just captures what you say.\",Mn=\"Click Start general recording to capture one freeform answer.\",_e=\"Speak freely. When you pause, the recording will be captured.\",re=\"Recording saved. Start again if you want another capture.\",Ee=\"Guided test complete. Review the saved summary below.\",Pe=\"All prompts are covered. You can stop the microphone or keep speaking for extra detail.\",In=\"Ready. Start guided test or general recording to begin.\",Vn=\"Live. Answer the prompt, then click Stop microphone when finished.\",Re=[\"Start with a quick introduction about who you are.\",\"Now describe what you are trying to do or test.\",\"Finish with any detail that feels blocked, risky, or unclear.\"],De=(e,n,t)=>Math.min(t,Math.max(n,e)),q=(e)=>e.replaceAll(\"&\",\"&\").replaceAll(\"<\",\"<\").replaceAll(\">\",\">\").replaceAll('\"',\""\").replaceAll(\"'\",\"'\"),te=(e,n)=>{let t=e[n];if(typeof t===\"string\"&&t.trim())return t;return null},ie=(e)=>{if(typeof e===\"string\"&&e.trim())return e;if(e instanceof Error&&e.message.trim())return e.message;if(e&&typeof e===\"object\"){let n=e,t=te(n,\"message\")??te(n,\"reason\")??te(n,\"description\");if(t)return t;if(\"error\"in n)return ie(n.error);if(\"cause\"in n)return ie(n.cause);try{return JSON.stringify(e)}catch{}}return\"Unexpected error\"},wn=(e)=>{let n=[e.status];if(e.attempts>0||e.maxAttempts>0)n.push(`${e.attempts}/${e.maxAttempts} attempts`);if(e.nextAttemptAt){let t=Math.max(0,e.nextAttemptAt-Date.now());n.push(`retry in ${Math.ceil(t/100)/10}s`)}return n.join(\" \u00B7 \")},v=(e=se)=>Array.from({length:e},()=>0),be=(e,n,t=se)=>{let o=e.slice(-(t-1));o.push(De(n,0,1));while(o.length<t)o.unshift(0);return o},Ln=(e,n=gn,t=An)=>{let o=e.length>1?e:v(se),r=n/(o.length-1),i=t/2,c=t*0.34;if(Math.max(...o,0)<=0.015)return`M 0 ${i} L ${n} ${i}`;let g=o.map((d,h)=>{let a=h*0.76,M=Math.sin(a)*0.78+Math.sin(a*0.41)*0.22,C=d*c,I=r*h,w=De(i+M*C,8,t-8);return{x:I,y:w}});if(g.length===0)return`M 0 ${i} L ${n} ${i}`;let y=`M ${g[0]?.x??0} ${g[0]?.y??i}`;for(let d=1;d<g.length;d+=1){let h=g[d-1],a=g[d];if(!h||!a)continue;let M=(h.x+a.x)/2;y+=` Q ${M} ${h.y} ${a.x} ${a.y}`}return y},un=(e)=>{if(!e)return Re;try{let n=JSON.parse(e);if(Array.isArray(n)){let t=n.filter((o)=>typeof o===\"string\").map((o)=>o.trim()).filter(Boolean);if(t.length>0)return t}}catch{}return Re},ce=(e)=>{if(!e)return;let n=Number(e);return Number.isFinite(n)?n:void 0},Rn=(e,n,t)=>{if(!n)return null;let o=document.querySelector(n);return o instanceof t?o:null},x=(e,n,t,o)=>{let r=n?document.querySelector(n):null;if(r instanceof t)return r;let i=e.querySelector(`#${o}`);if(i instanceof t)return i;throw Error(`Voice HTMX bootstrap could not find the required element \"${o}\".`)},bn=(e)=>{if(!e.mode)return Cn;if(!e.hasStarted)return e.mode===\"guided\"?fn:Tn;if(e.status===\"completed\")return e.mode===\"guided\"?Ee:re;if(e.mode===\"general\")return _e;return e.guidedPrompts[e.turnCount]??Pe},_n=(e)=>{if(!e.mode)return Sn;if(e.status===\"completed\")return e.mode===\"guided\"?Ee:re;if(!e.hasStarted)return e.mode===\"guided\"?`Click Start guided test to begin. First prompt: ${e.guidedPrompts[0]??\"Answer the first prompt.\"}`:Mn;if(e.mode===\"general\")return e.turnCount===0?_e:re;return e.guidedPrompts[e.turnCount]??Pe},En=(e)=>{let n=e.dataset.voiceGuidedPath,t=e.dataset.voiceGeneralPath;if(!n||!t)throw Error(\"Voice HTMX bootstrap requires data-voice-guided-path and data-voice-general-path.\");let o=un(e.dataset.voiceGuidedPrompts),r=e.dataset.voiceGuidedLabel??hn,i=e.dataset.voiceGeneralLabel??yn,c=e.dataset.voiceReconnectReportPath,l=e.dataset.voiceBargeInPath,g=l?ue({path:l,thresholdMs:ce(e.dataset.voiceBargeInThresholdMs)}):null,y=ce(e.dataset.voiceBargeInRecentWindowMs)??4000,d=ce(e.dataset.voiceBargeInSpeechThreshold)??0.04,h=x(document,e.dataset.voiceSync,HTMLElement,\"voice-htmx-sync\"),a=x(e,e.dataset.voiceConnection,HTMLElement,\"metric-connection\"),M=x(e,e.dataset.voiceError,HTMLElement,\"status-error\"),C=x(e,e.dataset.voiceMicrophone,HTMLElement,\"status-mic\"),I=x(e,e.dataset.voicePrompt,HTMLElement,\"status-prompt\"),w=Rn(e,e.dataset.voiceReconnect,HTMLElement),R=x(e,e.dataset.voiceChat,HTMLElement,\"chat-list\"),u=x(e,e.dataset.voiceStartGuided,HTMLButtonElement,\"start-guided\"),O=x(e,e.dataset.voiceStartGeneral,HTMLButtonElement,\"start-general\"),U=x(e,e.dataset.voiceStop,HTMLButtonElement,\"stop-mic\"),s=x(e,e.dataset.voiceMonitor,HTMLElement,\"voice-monitor\"),S=x(e,e.dataset.voiceMonitorCopy,HTMLElement,\"voice-monitor-copy\"),L=x(e,e.dataset.voiceWaveGlow,SVGPathElement,\"voice-wave-glow\"),X=x(e,e.dataset.voiceWavePath,SVGPathElement,\"voice-wave-path\"),_=null,W={general:!1,guided:!1},P=!1,$=null,N=v(),A=null,f=null,E=m(n,{capture:{onAudio:(T,G)=>{if(A){A.sendAudio(T);return}G(T)},onLevel:(T)=>{A?.handleLevel(T),N=be(N,T),F()}},connection:{reconnectReportPath:c},preset:\"guided-intake\"}),V=m(t,{capture:{onAudio:(T,G)=>{if(f){f.sendAudio(T);return}G(T)},onLevel:(T)=>{f?.handleLevel(T),N=be(N,T),F()}},connection:{reconnectReportPath:c},preset:\"dictation\"}),Y=E.bindHTMX({element:h}),xe=V.bindHTMX({element:h}),J=j(E),Q=j(V);A=oe(E,J,{interruptThreshold:d,monitor:g??void 0}),f=oe(V,Q,{interruptThreshold:d,monitor:g??void 0});let z=()=>_===\"general\"?V:E,Dn=()=>_===\"general\"?Q:J,F=()=>{let T=Ln(N);L.setAttribute(\"d\",T),X.setAttribute(\"d\",T),S.innerHTML=`<span class=\"voice-live-dot\"></span>${P?\"Microphone live\":\"Microphone idle\"}`,S.classList.toggle(\"is-live\",P),s.classList.toggle(\"is-live\",P)},k=()=>{let T=z(),G=(_?W[_]:!1)||T.turns.length>0,ae=T.status;if(a.textContent=T.isConnected?\"Connected\":\"Waiting\",M.textContent=$||T.error||\"None\",w)w.textContent=wn(T.reconnect);C.textContent=P?Vn:In,I.textContent=_n({guidedPrompts:o,hasStarted:G,mode:_,status:ae,turnCount:T.turns.length}),u.hidden=P,O.hidden=P,U.hidden=!P,R.innerHTML=`<article class=\"voice-chat-message assistant\">\n <div class=\"voice-chat-role\">${q(_===\"general\"?i:_===\"guided\"?r:\"Voice demo\")}</div>\n <p class=\"voice-turn-text\">${q(bn({generalLabel:i,guidedLabel:r,guidedPrompts:o,hasStarted:G,mode:_,status:ae,turnCount:T.turns.length}))}</p>\n</article>${T.turns.map((p)=>`<div class=\"voice-chat-stack\">\n <article class=\"voice-chat-message user\">\n <div class=\"voice-chat-role\">You</div>\n <p class=\"voice-turn-text\">${q(p.text)}</p>\n </article>\n ${p.assistantText?`<article class=\"voice-chat-message assistant\">\n <div class=\"voice-chat-role\">${q(_===\"general\"?i:_===\"guided\"?r:\"Guide\")}</div>\n <p class=\"voice-turn-text\">${q(p.assistantText)}</p>\n </article>`:\"\"}\n</div>`).join(\"\")}${T.partial?`<article class=\"voice-chat-message user pending\">\n <div class=\"voice-chat-role\">Speaking</div>\n <p class=\"voice-turn-text\">${q(T.partial)}</p>\n</article>`:\"\"}`,F()},Oe=()=>{z().stopRecording(),P=!1,$=null,N=v(),k()},le=async(T)=>{_=T,W={...W,[T]:!0};try{await z().startRecording(),$=null,P=!0,k()}catch(G){z().stopRecording(),P=!1,N=v(),$=ie(G),k()}};E.subscribe(()=>{if(E.assistantAudio.length>0)J.start().catch(()=>{});k()}),V.subscribe(()=>{if(V.assistantAudio.length>0)Q.start().catch(()=>{});k()}),u.addEventListener(\"click\",()=>{le(\"guided\")}),O.addEventListener(\"click\",()=>{le(\"general\")}),U.addEventListener(\"click\",()=>{Oe()}),e.addEventListener(\"absolute-voice-simulate-disconnect\",()=>{z().simulateDisconnect()}),window.addEventListener(\"beforeunload\",()=>{E.stopRecording(),V.stopRecording(),A?.close(),f?.close(),J.close(),Q.close(),Y(),xe(),E.close(),V.close()}),k()},Pn=()=>{if(typeof window>\"u\"||typeof document>\"u\")return;let e=Array.from(document.querySelectorAll(\"[data-voice-htmx]\"));for(let n of e)if(n instanceof HTMLElement)En(n)};Pn();export{Pn as initVoiceHTMX};\n";
|
|
1
|
+
export declare const HTMX_BOOTSTRAP_BUNDLE = "var We=(e)=>{if(typeof e!==\"string\")return e;return document.querySelector(e)},$e=(e,n,c,o)=>{let s=n??e.getAttribute(\"hx-get\")??\"\";if(!s)return\"\";let t=new URL(s,window.location.origin);if(o)t.searchParams.set(c,o);else t.searchParams.delete(c);return`${t.pathname}${t.search}${t.hash}`},fe=(e,n)=>{if(typeof window>\"u\"||typeof document>\"u\")return()=>{};let c=We(n.element);if(!c)return()=>{};let o=n.eventName??\"voice-refresh\",s=n.sessionQueryParam??\"sessionId\",t=()=>{let r=window,d=$e(c,n.route,s,e.sessionId);if(d)c.setAttribute(\"hx-get\",d);r.htmx?.process?.(c),r.htmx?.trigger?.(c,o)},i=e.subscribe(t);return t(),()=>{i()}};var ke=(e)=>Math.max(-1,Math.min(1,e)),qe=(e)=>{let n=new Int16Array(e.length);for(let c=0;c<e.length;c+=1){let o=ke(e[c]??0);n[c]=o<0?o*32768:o*32767}return new Uint8Array(n.buffer)},Xe=(e)=>{let n=e instanceof Uint8Array?e:new Uint8Array(e);if(n.byteLength<2)return 0;let c=new Int16Array(n.buffer,n.byteOffset,Math.floor(n.byteLength/2));if(c.length===0)return 0;let o=0;for(let s of c){let t=s/32768;o+=t*t}return Math.min(1,Math.max(0,Math.sqrt(o/c.length)*5.5))},ze=(e,n,c)=>{if(n===c)return e;let o=n/c,s=Math.round(e.length/o),t=new Float32Array(s),i=0,r=0;while(i<t.length){let d=Math.round((i+1)*o),f=0,a=0;for(let A=r;A<d&&A<e.length;A+=1)f+=e[A]??0,a+=1;t[i]=a>0?f/a:0,i+=1,r=d}return t},Ae=(e)=>{let n=null,c=null,o=null,s=null;return{start:async()=>{if(typeof navigator>\"u\"||!navigator.mediaDevices?.getUserMedia)throw Error(\"Browser microphone capture requires navigator.mediaDevices.getUserMedia.\");let r=(typeof window<\"u\"?window.AudioContext??window.webkitAudioContext:void 0)??AudioContext;if(!r)throw Error(\"Browser microphone capture requires AudioContext support.\");s=await navigator.mediaDevices.getUserMedia({audio:{channelCount:e.channelCount??1}}),n=new r,c=n.createMediaStreamSource(s),o=n.createScriptProcessor(4096,1,1),o.onaudioprocess=(d)=>{let f=d.inputBuffer.getChannelData(0),a=ze(f,n?.sampleRate??48000,e.sampleRateHz??16000),A=qe(a);e.onLevel?.(Xe(A)),e.onAudio(A)},c.connect(o),o.connect(n.destination)},stop:()=>{o?.disconnect(),c?.disconnect(),s?.getTracks().forEach((r)=>r.stop()),n?.close(),e.onLevel?.(0),n=null,s=null,o=null,c=null}}};var ne=(e)=>{if(typeof e===\"string\"&&e.trim())return e;if(e instanceof Error&&e.message.trim())return e.message;if(e&&typeof e===\"object\"){let n=e;for(let c of[\"message\",\"reason\",\"description\"]){let o=n[c];if(typeof o===\"string\"&&o.trim())return o}if(\"error\"in n)return ne(n.error);if(\"cause\"in n)return ne(n.cause);try{return JSON.stringify(e)}catch{}}return\"Unexpected error\"},he=(e)=>{switch(e.type){case\"audio\":return{chunk:Uint8Array.from(atob(e.chunkBase64),(n)=>n.charCodeAt(0)),format:e.format,receivedAt:e.receivedAt,turnId:e.turnId,type:\"audio\"};case\"assistant\":return{text:e.text,type:\"assistant\"};case\"complete\":return{sessionId:e.sessionId,type:\"complete\"};case\"connection\":return{reconnect:e.reconnect,type:\"connection\"};case\"call_lifecycle\":return{event:e.event,sessionId:e.sessionId,type:\"call_lifecycle\"};case\"error\":return{message:ne(e.message),type:\"error\"};case\"final\":return{transcript:e.transcript,type:\"final\"};case\"partial\":return{transcript:e.transcript,type:\"partial\"};case\"replay\":return{assistantTexts:e.assistantTexts,call:e.call,partial:e.partial,scenarioId:e.scenarioId,sessionId:e.sessionId,sessionMetadata:e.sessionMetadata,status:e.status,turns:e.turns,type:\"replay\"};case\"session\":return{sessionId:e.sessionId,sessionMetadata:e.sessionMetadata,scenarioId:e.scenarioId,status:e.status,type:\"session\"};case\"turn\":return{turn:e.turn,type:\"turn\"};default:return null}};var{mkdir:pn,writeFile:ec}=(()=>({}));function H(e){if(typeof e!==\"string\")throw TypeError(\"Path must be a string. Received \"+JSON.stringify(e))}function Ce(e,n){var c=\"\",o=0,s=-1,t=0,i;for(var r=0;r<=e.length;++r){if(r<e.length)i=e.charCodeAt(r);else if(i===47)break;else i=47;if(i===47){if(s===r-1||t===1);else if(s!==r-1&&t===2){if(c.length<2||o!==2||c.charCodeAt(c.length-1)!==46||c.charCodeAt(c.length-2)!==46){if(c.length>2){var d=c.lastIndexOf(\"/\");if(d!==c.length-1){if(d===-1)c=\"\",o=0;else c=c.slice(0,d),o=c.length-1-c.lastIndexOf(\"/\");s=r,t=0;continue}}else if(c.length===2||c.length===1){c=\"\",o=0,s=r,t=0;continue}}if(n){if(c.length>0)c+=\"/..\";else c=\"..\";o=2}}else{if(c.length>0)c+=\"/\"+e.slice(s+1,r);else c=e.slice(s+1,r);o=r-s-1}s=r,t=0}else if(i===46&&t!==-1)++t;else t=-1}return c}function Ye(e,n){var c=n.dir||n.root,o=n.base||(n.name||\"\")+(n.ext||\"\");if(!c)return o;if(c===n.root)return c+o;return c+e+o}function ce(){var e=\"\",n=!1,c;for(var o=arguments.length-1;o>=-1&&!n;o--){var s;if(o>=0)s=arguments[o];else{if(c===void 0)c=process.cwd();s=c}if(H(s),s.length===0)continue;e=s+\"/\"+e,n=s.charCodeAt(0)===47}if(e=Ce(e,!n),n)if(e.length>0)return\"/\"+e;else return\"/\";else if(e.length>0)return e;else return\".\"}function ye(e){if(H(e),e.length===0)return\".\";var n=e.charCodeAt(0)===47,c=e.charCodeAt(e.length-1)===47;if(e=Ce(e,!n),e.length===0&&!n)e=\".\";if(e.length>0&&c)e+=\"/\";if(n)return\"/\"+e;return e}function Je(e){return H(e),e.length>0&&e.charCodeAt(0)===47}function Te(){if(arguments.length===0)return\".\";var e;for(var n=0;n<arguments.length;++n){var c=arguments[n];if(H(c),c.length>0)if(e===void 0)e=c;else e+=\"/\"+c}if(e===void 0)return\".\";return ye(e)}function Qe(e,n){if(H(e),H(n),e===n)return\"\";if(e=ce(e),n=ce(n),e===n)return\"\";var c=1;for(;c<e.length;++c)if(e.charCodeAt(c)!==47)break;var o=e.length,s=o-c,t=1;for(;t<n.length;++t)if(n.charCodeAt(t)!==47)break;var i=n.length,r=i-t,d=s<r?s:r,f=-1,a=0;for(;a<=d;++a){if(a===d){if(r>d){if(n.charCodeAt(t+a)===47)return n.slice(t+a+1);else if(a===0)return n.slice(t+a)}else if(s>d){if(e.charCodeAt(c+a)===47)f=a;else if(a===0)f=0}break}var A=e.charCodeAt(c+a),g=n.charCodeAt(t+a);if(A!==g)break;else if(A===47)f=a}var y=\"\";for(a=c+f+1;a<=o;++a)if(a===o||e.charCodeAt(a)===47)if(y.length===0)y+=\"..\";else y+=\"/..\";if(y.length>0)return y+n.slice(t+f);else{if(t+=f,n.charCodeAt(t)===47)++t;return n.slice(t)}}function Ze(e){return e}function Ke(e){if(H(e),e.length===0)return\".\";var n=e.charCodeAt(0),c=n===47,o=-1,s=!0;for(var t=e.length-1;t>=1;--t)if(n=e.charCodeAt(t),n===47){if(!s){o=t;break}}else s=!1;if(o===-1)return c?\"/\":\".\";if(c&&o===1)return\"//\";return e.slice(0,o)}function me(e,n){if(n!==void 0&&typeof n!==\"string\")throw TypeError('\"ext\" argument must be a string');H(e);var c=0,o=-1,s=!0,t;if(n!==void 0&&n.length>0&&n.length<=e.length){if(n.length===e.length&&n===e)return\"\";var i=n.length-1,r=-1;for(t=e.length-1;t>=0;--t){var d=e.charCodeAt(t);if(d===47){if(!s){c=t+1;break}}else{if(r===-1)s=!1,r=t+1;if(i>=0)if(d===n.charCodeAt(i)){if(--i===-1)o=t}else i=-1,o=r}}if(c===o)o=r;else if(o===-1)o=e.length;return e.slice(c,o)}else{for(t=e.length-1;t>=0;--t)if(e.charCodeAt(t)===47){if(!s){c=t+1;break}}else if(o===-1)s=!1,o=t+1;if(o===-1)return\"\";return e.slice(c,o)}}function je(e){H(e);var n=-1,c=0,o=-1,s=!0,t=0;for(var i=e.length-1;i>=0;--i){var r=e.charCodeAt(i);if(r===47){if(!s){c=i+1;break}continue}if(o===-1)s=!1,o=i+1;if(r===46){if(n===-1)n=i;else if(t!==1)t=1}else if(n!==-1)t=-1}if(n===-1||o===-1||t===0||t===1&&n===o-1&&n===c+1)return\"\";return e.slice(n,o)}function Fe(e){if(e===null||typeof e!==\"object\")throw TypeError('The \"pathObject\" argument must be of type Object. Received type '+typeof e);return Ye(\"/\",e)}function ve(e){H(e);var n={root:\"\",dir:\"\",base:\"\",ext:\"\",name:\"\"};if(e.length===0)return n;var c=e.charCodeAt(0),o=c===47,s;if(o)n.root=\"/\",s=1;else s=0;var t=-1,i=0,r=-1,d=!0,f=e.length-1,a=0;for(;f>=s;--f){if(c=e.charCodeAt(f),c===47){if(!d){i=f+1;break}continue}if(r===-1)d=!1,r=f+1;if(c===46){if(t===-1)t=f;else if(a!==1)a=1}else if(t!==-1)a=-1}if(t===-1||r===-1||a===0||a===1&&t===r-1&&t===i+1){if(r!==-1)if(i===0&&o)n.base=n.name=e.slice(1,r);else n.base=n.name=e.slice(i,r)}else{if(i===0&&o)n.name=e.slice(1,t),n.base=e.slice(1,r);else n.name=e.slice(i,t),n.base=e.slice(i,r);n.ext=e.slice(t,r)}if(i>0)n.dir=e.slice(0,i-1);else if(o)n.dir=\"/\";return n}var pe=\"/\",en=\":\",jn=((e)=>(e.posix=e,e))({resolve:ce,normalize:ye,isAbsolute:Je,join:Te,relative:Qe,_makeLong:Ze,dirname:Ke,basename:me,extname:je,format:Fe,parse:ve,sep:pe,delimiter:en,win32:null,posix:null});var G=(e,n,c,o)=>{e.push({code:c,message:o,severity:n})};var nn=(e)=>e.length===0?void 0:e.reduce((n,c)=>n+c,0)/e.length,m=(e)=>e.length===0?void 0:Math.max(...e);var u=(e,n)=>{let c=e[n];return typeof c===\"number\"&&Number.isFinite(c)?c:void 0},K=(e,n)=>{let c=e[n];return typeof c===\"boolean\"?c:void 0},D=(e,n)=>{let c=e[n];return typeof c===\"string\"?c:void 0},oe=(e)=>String(e.id??D(e,\"ssrc\")??u(e,\"ssrc\")??D(e,\"trackIdentifier\")??D(e,\"mid\")??\"unknown\"),Se=(e)=>e===void 0?void 0:e*1000;var cn=(e)=>{let n={};for(let[c,o]of Object.entries(e))if(o===null||typeof o===\"boolean\"||typeof o===\"number\"||typeof o===\"string\")n[c]=o;return n};var Me=(e={})=>{let n=e.stats??[],c=[],o=n.filter((l)=>l.type===\"inbound-rtp\"&&D(l,\"kind\")!==\"video\"),s=n.filter((l)=>l.type===\"outbound-rtp\"&&D(l,\"kind\")!==\"video\"),t=n.filter((l)=>l.type===\"candidate-pair\"),i=n.filter((l)=>(l.type===\"track\"||l.type===\"media-source\")&&D(l,\"kind\")===\"audio\"),r=t.filter((l)=>K(l,\"selected\")===!0||K(l,\"nominated\")===!0||D(l,\"state\")===\"succeeded\").length,d=i.filter((l)=>D(l,\"readyState\")!==\"ended\"&&D(l,\"trackState\")!==\"ended\"&&K(l,\"ended\")!==!0).length,f=i.filter((l)=>D(l,\"readyState\")===\"ended\"||D(l,\"trackState\")===\"ended\"||K(l,\"ended\")===!0).length,a=o.reduce((l,M)=>l+(u(M,\"packetsReceived\")??0),0),A=s.reduce((l,M)=>l+(u(M,\"packetsSent\")??0),0),g=[...o,...s].reduce((l,M)=>l+Math.max(0,u(M,\"packetsLost\")??0),0),y=a+g,C=y===0?0:g/y,I=o.reduce((l,M)=>l+(u(M,\"bytesReceived\")??0),0),L=s.reduce((l,M)=>l+(u(M,\"bytesSent\")??0),0),R=m(t.map((l)=>Se(u(l,\"currentRoundTripTime\")??u(l,\"roundTripTime\"))).filter((l)=>l!==void 0)),w=m([...o,...s].map((l)=>Se(u(l,\"jitter\"))).filter((l)=>l!==void 0)),x=m(o.map((l)=>{let M=u(l,\"jitterBufferDelay\"),b=u(l,\"jitterBufferEmittedCount\");return M!==void 0&&b!==void 0&&b>0?M/b*1000:void 0}).filter((l)=>l!==void 0)),U=i.map((l)=>u(l,\"audioLevel\")).filter((l)=>l!==void 0);if(e.requireConnectedCandidatePair&&t.length>0&&r===0)G(c,\"error\",\"media.webrtc_candidate_pair_missing\",\"No active WebRTC candidate pair was observed.\");if(e.requireLiveAudioTrack&&d===0)G(c,\"error\",\"media.webrtc_audio_track_missing\",\"No live WebRTC audio track was observed.\");if(e.maxPacketLossRatio!==void 0&&C>e.maxPacketLossRatio)G(c,\"warning\",\"media.webrtc_packet_loss\",`Observed WebRTC packet loss ratio ${String(C)} above ${String(e.maxPacketLossRatio)}.`);if(e.maxRoundTripTimeMs!==void 0&&R!==void 0&&R>e.maxRoundTripTimeMs)G(c,\"warning\",\"media.webrtc_round_trip_time\",`Observed WebRTC RTT ${String(R)}ms above ${String(e.maxRoundTripTimeMs)}ms.`);if(e.maxJitterMs!==void 0&&w!==void 0&&w>e.maxJitterMs)G(c,\"warning\",\"media.webrtc_jitter\",`Observed WebRTC jitter ${String(w)}ms above ${String(e.maxJitterMs)}ms.`);return{activeCandidatePairs:r,audioLevelAverage:nn(U),bytesReceived:I,bytesSent:L,checkedAt:Date.now(),endedAudioTracks:f,inboundPackets:a,issues:c,jitterBufferDelayMs:x,jitterMs:w,liveAudioTracks:d,outboundPackets:A,packetLossRatio:C,packetsLost:g,roundTripTimeMs:R,status:c.some((l)=>l.severity===\"error\")?\"fail\":c.length>0?\"warn\":\"pass\",totalStats:n.length}},Ie=async(e)=>{return[...(await e.peerConnection.getStats(e.selector??null)).values()].map(cn)};var Ve=(e={})=>{let n=e.stats??[],c=e.previousStats??[],o=[],s=new Map(c.map((g)=>[oe(g),g])),i=n.filter((g)=>(g.type===\"inbound-rtp\"||g.type===\"outbound-rtp\")&&D(g,\"kind\")!==\"video\"&&D(g,\"mediaType\")!==\"video\").map((g)=>{let y=g.type===\"outbound-rtp\"?\"outbound\":\"inbound\",C=y===\"outbound\"?\"packetsSent\":\"packetsReceived\",I=y===\"outbound\"?\"bytesSent\":\"bytesReceived\",L=s.get(oe(g)),R=u(g,C),w=L?u(L,C):void 0,x=u(g,I),U=L?u(L,I):void 0,l=g.timestamp!==void 0&&L?.timestamp!==void 0?g.timestamp-L.timestamp:void 0;return{bytesDelta:x!==void 0&&U!==void 0?x-U:void 0,currentPackets:R,direction:y,id:oe(g),packetDelta:R!==void 0&&w!==void 0?R-w:void 0,previousPackets:w,timeDeltaMs:l}}),r=i.filter((g)=>g.direction===\"inbound\"),d=i.filter((g)=>g.direction===\"outbound\"),f=m(i.map((g)=>g.timeDeltaMs).filter((g)=>g!==void 0)),a=r.filter((g)=>e.maxInboundPacketStallMs!==void 0&&g.timeDeltaMs!==void 0&&g.timeDeltaMs>=e.maxInboundPacketStallMs&&g.packetDelta!==void 0&&g.packetDelta<=0).length,A=d.filter((g)=>e.maxOutboundPacketStallMs!==void 0&&g.timeDeltaMs!==void 0&&g.timeDeltaMs>=e.maxOutboundPacketStallMs&&g.packetDelta!==void 0&&g.packetDelta<=0).length;if(e.requireInboundAudio&&r.length===0)G(o,\"error\",\"media.webrtc_inbound_audio_missing\",\"No inbound WebRTC audio RTP stream was observed.\");if(e.requireOutboundAudio&&d.length===0)G(o,\"error\",\"media.webrtc_outbound_audio_missing\",\"No outbound WebRTC audio RTP stream was observed.\");if(e.maxGapMs!==void 0&&f!==void 0&&f>e.maxGapMs)G(o,\"warning\",\"media.webrtc_stream_gap\",`Observed WebRTC stream sample gap ${String(f)}ms above ${String(e.maxGapMs)}ms.`);if(a>0)G(o,\"error\",\"media.webrtc_inbound_stalled\",`${String(a)} inbound WebRTC audio stream(s) stopped receiving packets.`);if(A>0)G(o,\"error\",\"media.webrtc_outbound_stalled\",`${String(A)} outbound WebRTC audio stream(s) stopped sending packets.`);return{checkedAt:Date.now(),inboundAudioStreams:r.length,issues:o,maxObservedGapMs:f,outboundAudioStreams:d.length,stalledInboundStreams:a,stalledOutboundStreams:A,status:o.some((g)=>g.severity===\"error\")?\"fail\":o.length>0?\"warn\":\"pass\",streams:i,totalStats:n.length}};var on=\"/api/voice/browser-media\",tn=5000,sn=async(e)=>e.peerConnection??await e.getPeerConnection?.()??null,rn=async(e,n)=>{let c=n.fetch??globalThis.fetch;if(!c)return;await c(n.path??on,{body:JSON.stringify(e),headers:{\"Content-Type\":\"application/json\"},keepalive:!0,method:\"POST\"})},Le=(e)=>{let n=null,c=[],o=async()=>{let i=await sn(e);if(!i)return;let r=await Ie({peerConnection:i}),d=Me({...e,stats:r}),f=e.continuity===!1?void 0:Ve({...e.continuity,previousStats:c,stats:r}),a={at:Date.now(),continuity:f,report:d,scenarioId:e.getScenarioId?.()??null,sessionId:e.getSessionId?.()??null};return c=r,e.onReport?.(a),await rn(a,e),a},s=()=>{o().catch((i)=>{e.onError?.(i)})},t=()=>{if(n)clearInterval(n),n=null};return{close:t,reportOnce:o,start:()=>{if(n)return;s(),n=setInterval(s,e.intervalMs??tn)},stop:t}};var W=()=>{},ln=()=>W,an={callControl:W,close:W,endTurn:W,getReadyState:()=>3,getScenarioId:()=>\"\",getSessionId:()=>\"\",send:W,sendAudio:W,simulateDisconnect:W,start:()=>{},subscribe:ln},dn=()=>crypto.randomUUID(),gn=(e,n,c)=>{let{hostname:o,port:s,protocol:t}=window.location,i=t===\"https:\"?\"wss:\":\"ws:\",r=s?`:${s}`:\"\",d=new URL(`${i}//${o}${r}${e}`);if(d.searchParams.set(\"sessionId\",n),c)d.searchParams.set(\"scenarioId\",c);return d.toString()},fn=(e)=>{if(!e||typeof e!==\"object\"||!(\"type\"in e))return!1;switch(e.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}},An=(e)=>{if(typeof e.data!==\"string\")return null;try{let n=JSON.parse(e.data);return fn(n)?n:null}catch{return null}},be=(e,n={})=>{if(typeof window>\"u\")return an;let c=new Set,o=n.reconnect!==!1,s=n.maxReconnectAttempts??10,t=n.pingInterval??30000,i={isConnected:!1,pendingMessages:[],scenarioId:n.scenarioId??null,pingInterval:null,reconnectAttempts:0,reconnectTimeout:null,sessionId:n.sessionId??dn(),ws:null},r=(l)=>{c.forEach((M)=>M(l))},d=()=>{if(i.pingInterval)clearInterval(i.pingInterval),i.pingInterval=null;if(i.reconnectTimeout)clearTimeout(i.reconnectTimeout),i.reconnectTimeout=null},f=()=>{if(i.ws?.readyState!==1)return;while(i.pendingMessages.length>0){let l=i.pendingMessages.shift();if(l!==void 0)i.ws.send(l)}},a=()=>{let l=Date.now()+500;i.reconnectAttempts+=1,r({reconnect:{attempts:i.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:s,nextAttemptAt:l,status:\"reconnecting\"},type:\"connection\"}),i.reconnectTimeout=setTimeout(()=>{if(i.reconnectAttempts>s){r({reconnect:{attempts:i.reconnectAttempts,maxAttempts:s,status:\"exhausted\"},type:\"connection\"});return}A()},500)},A=()=>{let l=new WebSocket(gn(e,i.sessionId,i.scenarioId));l.binaryType=\"arraybuffer\",l.onopen=()=>{let M=i.reconnectAttempts>0;if(i.isConnected=!0,f(),M)r({reconnect:{attempts:i.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:s,status:\"resumed\"},type:\"connection\"}),i.reconnectAttempts=0;c.forEach((b)=>b({scenarioId:i.scenarioId??void 0,sessionId:i.sessionId,status:\"active\",type:\"session\"})),i.pingInterval=setInterval(()=>{if(l.readyState===1)l.send(JSON.stringify({type:\"ping\"}))},t)},l.onmessage=(M)=>{let b=An(M);if(!b)return;if(b.type===\"session\")i.sessionId=b.sessionId,i.scenarioId=b.scenarioId??i.scenarioId;c.forEach((z)=>z(b))},l.onclose=(M)=>{if(i.isConnected=!1,d(),o&&M.code!==1000&&i.reconnectAttempts<s)a();else if(o&&M.code!==1000)r({reconnect:{attempts:i.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:s,status:\"exhausted\"},type:\"connection\"})},i.ws=l},g=(l)=>{if(i.ws?.readyState===1){i.ws.send(l);return}i.pendingMessages.push(l)},y=(l)=>{g(JSON.stringify(l))},C=(l={})=>{if(l.sessionId)i.sessionId=l.sessionId;if(l.scenarioId)i.scenarioId=l.scenarioId;y({type:\"start\",sessionId:i.sessionId,scenarioId:i.scenarioId??void 0})},I=(l)=>{g(l)},L=()=>{y({type:\"end_turn\"})},R=(l)=>{y({...l,type:\"call_control\"})},w=()=>{if(d(),i.ws)i.ws.close(1000),i.ws=null;i.isConnected=!1,c.clear()},x=()=>{if(i.ws?.readyState===1)i.ws.close(4000,\"absolutejs-voice-reconnect-proof\")},U=(l)=>{return c.add(l),()=>{c.delete(l)}};return A(),{callControl:R,close:w,endTurn:L,getReadyState:()=>i.ws?.readyState??3,getScenarioId:()=>i.scenarioId??\"\",getSessionId:()=>i.sessionId,send:y,sendAudio:I,simulateDisconnect:x,start:C,subscribe:U}};var hn=()=>({attempts:0,maxAttempts:0,status:\"idle\"}),Cn=()=>({assistantAudio:[],assistantTexts:[],call:null,error:null,isConnected:!1,sessionMetadata:null,scenarioId:null,partial:\"\",reconnect:hn(),sessionId:null,status:\"idle\",turns:[]}),we=()=>{let e=Cn(),n=new Set,c=()=>{n.forEach((s)=>s())};return{dispatch:(s)=>{switch(s.type){case\"audio\":e={...e,assistantAudio:[...e.assistantAudio,{chunk:s.chunk,format:s.format,receivedAt:s.receivedAt,turnId:s.turnId}]};break;case\"assistant\":e={...e,assistantTexts:[...e.assistantTexts,s.text]};break;case\"complete\":e={...e,sessionId:s.sessionId,status:\"completed\"};break;case\"call_lifecycle\":e={...e,call:{...e.call,disposition:s.event.type===\"end\"?s.event.disposition:e.call?.disposition,endedAt:s.event.type===\"end\"?s.event.at:e.call?.endedAt,events:[...e.call?.events??[],s.event],lastEventAt:s.event.at,startedAt:e.call?.startedAt??s.event.at},sessionId:s.sessionId};break;case\"connected\":e={...e,isConnected:!0,reconnect:e.reconnect.status===\"reconnecting\"?{...e.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:\"resumed\"}:e.reconnect};break;case\"connection\":e={...e,reconnect:s.reconnect};break;case\"disconnected\":e={...e,isConnected:!1};break;case\"error\":e={...e,error:s.message};break;case\"final\":e={...e,partial:s.transcript.text,turns:e.turns.map((t)=>t)};break;case\"partial\":e={...e,partial:s.transcript.text};break;case\"replay\":e={...e,assistantTexts:[...s.assistantTexts],call:s.call??null,error:null,isConnected:s.status===\"active\",partial:s.partial,reconnect:e.reconnect.status===\"reconnecting\"?{...e.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:\"resumed\"}:e.reconnect,scenarioId:s.scenarioId??e.scenarioId,sessionId:s.sessionId,sessionMetadata:s.sessionMetadata??e.sessionMetadata,status:s.status,turns:[...s.turns]};break;case\"session\":e={...e,error:null,scenarioId:s.scenarioId??e.scenarioId,isConnected:s.status===\"active\",sessionId:s.sessionId,sessionMetadata:s.sessionMetadata??e.sessionMetadata,status:s.status};break;case\"turn\":e={...e,partial:\"\",turns:[...e.turns,s.turn]};break}c()},getServerSnapshot:()=>e,getSnapshot:()=>e,subscribe:(s)=>{return n.add(s),()=>{n.delete(s)}}}};var Re=(e,n={})=>{let c=be(e,n),o=we(),s=n.browserMedia&&typeof window<\"u\"?Le({...n.browserMedia,getScenarioId:()=>n.browserMedia?n.browserMedia.getScenarioId?.()??c.getScenarioId():c.getScenarioId(),getSessionId:()=>n.browserMedia?n.browserMedia.getSessionId?.()??c.getSessionId():c.getSessionId()}):null,t=new Set,i=(a)=>Promise.resolve().then(()=>{if(!a?.sessionId&&!a?.scenarioId)return;c.start(a),s?.start()}),r=()=>{t.forEach((a)=>a())},d=()=>{if(!n.reconnectReportPath||typeof fetch>\"u\")return;let a=o.getSnapshot(),A=JSON.stringify({at:Date.now(),reconnect:a.reconnect,scenarioId:a.scenarioId,sessionId:c.getSessionId(),turnIds:a.turns.map((g)=>g.id)});fetch(n.reconnectReportPath,{body:A,headers:{\"Content-Type\":\"application/json\"},keepalive:!0,method:\"POST\"}).catch(()=>{})},f=c.subscribe((a)=>{let A=he(a);if(A){if(o.dispatch(A),a.type===\"connection\")d();r()}});return{callControl(a){c.callControl(a)},close(){f(),s?.close(),c.close(),o.dispatch({type:\"disconnected\"}),r()},endTurn(){c.endTurn()},get error(){return o.getSnapshot().error},getServerSnapshot(){return o.getServerSnapshot()},getSnapshot(){return o.getSnapshot()},get isConnected(){return o.getSnapshot().isConnected},get scenarioId(){return o.getSnapshot().scenarioId},get sessionMetadata(){return o.getSnapshot().sessionMetadata},start:i,get partial(){return o.getSnapshot().partial},get reconnect(){return o.getSnapshot().reconnect},get sessionId(){return c.getSessionId()},get status(){return o.getSnapshot().status},get turns(){return o.getSnapshot().turns},get assistantTexts(){return o.getSnapshot().assistantTexts},get assistantAudio(){return o.getSnapshot().assistantAudio},get call(){return o.getSnapshot().call},sendAudio(a){c.sendAudio(a)},simulateDisconnect(){c.simulateDisconnect()},subscribe(a){return t.add(a),()=>{t.delete(a)}}}};var ue=(e)=>{if(!e||e.enabled===!1)return;return{enabled:!0,maxGain:e.maxGain??3,noiseGateAttenuation:e.noiseGateAttenuation??0.15,noiseGateThreshold:e.noiseGateThreshold??0.006,targetLevel:e.targetLevel??0.08}};var yn={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}},Tn={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 _e=(e)=>{let n=e?.profile??\"fast\",c=e?.qualityProfile??\"general\",o=yn[n],s=Tn[c];return{profile:n,qualityProfile:c,silenceMs:e?.silenceMs??s.silenceMs??o.silenceMs,speechThreshold:e?.speechThreshold??s.speechThreshold??o.speechThreshold,transcriptStabilityMs:e?.transcriptStabilityMs??s.transcriptStabilityMs??o.transcriptStabilityMs}};var Sn={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\"}}},Ee=(e=\"default\")=>{let n=Sn[e];return{audioConditioning:ue(n.audioConditioning),capture:{channelCount:n.capture?.channelCount??1,sampleRateHz:n.capture?.sampleRateHz??16000},connection:{...n.connection},name:e,sttLifecycle:n.sttLifecycle??\"continuous\",turnDetection:_e(n.turnDetection)}};var Mn=(e)=>({assistantAudio:[...e.assistantAudio],assistantTexts:[...e.assistantTexts],call:e.call,error:e.error,isConnected:e.isConnected,isRecording:!1,partial:e.partial,reconnect:e.reconnect,recordingError:null,sessionId:e.sessionId,sessionMetadata:e.sessionMetadata,scenarioId:e.scenarioId,status:e.status,turns:[...e.turns]}),j=(e,n={})=>{let c=Ee(n.preset),o=Re(e,{...c.connection,...n.connection}),s=null,t=Mn(o),i=new Set,r=()=>{for(let C of i)C()},d=()=>{if(t={...t,assistantAudio:[...o.assistantAudio],assistantTexts:[...o.assistantTexts],call:o.call,error:o.error,isConnected:o.isConnected,partial:o.partial,reconnect:o.reconnect,sessionId:o.sessionId,sessionMetadata:o.sessionMetadata,scenarioId:o.scenarioId,status:o.status,turns:[...o.turns]},n.autoStopOnComplete!==!1&&t.status===\"completed\"&&t.isRecording)s?.stop(),s=null,t={...t,isRecording:!1};r()},f=o.subscribe(d);d();let a=()=>{if(s)return s;return s=Ae({channelCount:n.capture?.channelCount??c.capture.channelCount,onLevel:n.capture?.onLevel,onAudio:(C)=>{if(n.capture?.onAudio){n.capture.onAudio(C,o.sendAudio);return}o.sendAudio(C)},sampleRateHz:n.capture?.sampleRateHz??c.capture.sampleRateHz}),s},A=()=>{s?.stop(),s=null,t={...t,isRecording:!1},r()},g=async()=>{if(t.isRecording)return;try{t={...t,recordingError:null},r(),await a().start(),t={...t,isRecording:!0},r()}catch(C){throw s=null,t={...t,isRecording:!1,recordingError:C instanceof Error?C.message:String(C)},r(),C}};return{bindHTMX(C){return fe(o,C)},callControl:(C)=>o.callControl(C),close:()=>{f(),A(),o.close()},endTurn:()=>o.endTurn(),get error(){return t.error},getServerSnapshot:()=>t,getSnapshot:()=>t,get isConnected(){return t.isConnected},get isRecording(){return t.isRecording},get partial(){return t.partial},get recordingError(){return t.recordingError},get reconnect(){return t.reconnect},sendAudio:(C)=>o.sendAudio(C),simulateDisconnect:()=>o.simulateDisconnect(),get sessionId(){return t.sessionId},get sessionMetadata(){return t.sessionMetadata},get scenarioId(){return t.scenarioId},startRecording:g,get status(){return t.status},stopRecording:A,subscribe:(C)=>{return i.add(C),()=>{i.delete(C)}},toggleRecording:async()=>{if(t.isRecording){A();return}await g()},get turns(){return t.turns},get assistantTexts(){return t.assistantTexts},get assistantAudio(){return t.assistantAudio},get call(){return t.call}}};var In=()=>({activeSourceCount:0,error:null,isActive:!1,isPlaying:!1,lastInterruptLatencyMs:void 0,lastPlaybackStopLatencyMs:void 0,processedChunkCount:0,queuedChunkCount:0}),Vn=()=>{if(typeof window>\"u\")return typeof AudioContext>\"u\"?void 0:AudioContext;return window.AudioContext??window.webkitAudioContext},Ln=(e,n)=>{let c=n.format;if(c.container!==\"raw\"||c.encoding!==\"pcm_s16le\")throw Error(`Unsupported assistant audio format: ${c.container}/${c.encoding}`);let o=n.chunk,s=Math.max(1,c.channels),t=Math.floor(o.byteLength/2),i=Math.max(1,Math.floor(t/s)),r=e.createBuffer(s,i,c.sampleRateHz),d=new DataView(o.buffer,o.byteOffset,o.byteLength);for(let f=0;f<s;f+=1){let a=r.getChannelData(f);for(let A=0;A<i;A+=1){let y=(A*s+f)*2;if(y+1>=o.byteLength){a[A]=0;continue}a[A]=d.getInt16(y,!0)/32768}}return r},F=(e,n={})=>{let c=new Set,o=new Set,s=(n.lookaheadMs??15)/1000,t=In(),i=null,r=null,d=0,f=Promise.resolve(),a=null,A=null,g=null,y=null,C=()=>{for(let h of c)h()},I=(h)=>{t={...t,...h},C()},L=()=>{if(t.error!==null)I({error:null})},R=()=>{if(y!==null)clearTimeout(y),y=null},w=(h)=>{R(),a=null,I({activeSourceCount:o.size,isPlaying:!1,lastInterruptLatencyMs:h,lastPlaybackStopLatencyMs:t.lastPlaybackStopLatencyMs??h}),g?.(),g=null,A=null},x=(h)=>{if(!h)return 0;return Math.max(0,((h.baseLatency??0)+(h.outputLatency??0))*1000)},U=(h)=>{if(!r)return;let T=1;if(r.gain.setValueAtTime){r.gain.setValueAtTime(T,h?.currentTime??0);return}r.gain.value=T},l=(h)=>{if(!r)return;let T=0;if(r.gain.setValueAtTime){r.gain.setValueAtTime(T,h?.currentTime??0);return}r.gain.value=T},M=()=>{if(a===null||o.size>0)return;w(Date.now()-a)},b=async()=>{if(i)return i;if(n.createAudioContext)i=n.createAudioContext();else{let h=Vn();if(!h)throw Error(\"Assistant audio playback requires AudioContext support.\");i=new h}if(i.createGain)r=i.createGain(),r.connect?.(i.destination);return d=i.currentTime,i},z=async(h)=>{let T=await b(),E=Ln(T,h),V=T.createBufferSource();V.buffer=E,V.connect(r??T.destination),V.onended=()=>{o.delete(V),V.disconnect?.(),I({activeSourceCount:o.size,isPlaying:o.size>0&&t.isActive}),M()};let J=Math.max(T.currentTime+s,d);d=J+E.duration,o.add(V),I({activeSourceCount:o.size,isPlaying:!0}),V.start(J)},_=(h)=>{for(let T of[...o])T.stop?.();if(d=i?i.currentTime:0,h?.forceClear){for(let T of o)T.disconnect?.();o.clear(),M()}},$=async()=>{if(!t.isActive)return;let h=e.assistantAudio.slice(t.processedChunkCount);if(h.length===0)return;try{L();for(let T of h)await z(T);I({processedChunkCount:e.assistantAudio.length,queuedChunkCount:t.queuedChunkCount+h.length})}catch(T){I({error:T instanceof Error?T.message:String(T)})}},P=()=>{return f=f.then(()=>$(),()=>$()),f},k=e.subscribe(()=>{if(n.autoStart&&!t.isActive&&e.assistantAudio.length>0){N.start();return}if(t.isActive)P()}),N={close:async()=>{if(k(),_({forceClear:!0}),R(),g?.(),g=null,A=null,a=null,i&&i.state!==\"closed\")await i.close();i=null,r?.disconnect?.(),r=null,d=0,I({activeSourceCount:0,isActive:!1,isPlaying:!1})},get activeSourceCount(){return t.activeSourceCount},get error(){return t.error},getSnapshot:()=>t,get isActive(){return t.isActive},get isPlaying(){return t.isPlaying},interrupt:async()=>{let h=Date.now(),T=await b();a=h,l(T);let E=Date.now()-h+x(T);if(I({isActive:!1,isPlaying:o.size>0,lastPlaybackStopLatencyMs:E}),o.size===0){w(E);return}if(!A)A=new Promise((V)=>{g=V});R(),y=setTimeout(()=>{for(let V of o)V.disconnect?.();o.clear(),w(Date.now()-h)},250),_(),await A},get lastInterruptLatencyMs(){return t.lastInterruptLatencyMs},get lastPlaybackStopLatencyMs(){return t.lastPlaybackStopLatencyMs},pause:async()=>{if(!i){I({activeSourceCount:0,isActive:!1,isPlaying:!1});return}await i.suspend(),I({activeSourceCount:o.size,isActive:!1,isPlaying:!1})},get processedChunkCount(){return t.processedChunkCount},get queuedChunkCount(){return t.queuedChunkCount},start:async()=>{try{L();let h=await b();if(U(h),h.state===\"suspended\")await h.resume();I({activeSourceCount:o.size,isActive:!0,isPlaying:h.state===\"running\"}),await P()}catch(h){throw I({error:h instanceof Error?h.message:String(h),isActive:!1,isPlaying:!1}),h}},subscribe:(h)=>{return c.add(h),()=>{c.delete(h)}}};return N};var bn=()=>`barge-in:${Date.now()}:${crypto.randomUUID?.()??Math.random().toString(36).slice(2)}`,wn=(e,n)=>{let c=e.filter((i)=>i.status===\"stopped\"),o=c.map((i)=>i.latencyMs).filter((i)=>typeof i===\"number\"),s=c.filter((i)=>typeof i.latencyMs===\"number\"&&i.latencyMs>n).length,t=c.length-s;return{averageLatencyMs:o.length>0?Math.round(o.reduce((i,r)=>i+r,0)/o.length):void 0,events:[...e],failed:s,lastEvent:e.at(-1),passed:t,status:e.length===0?\"empty\":s>0?\"fail\":c.length===0?\"warn\":\"pass\",thresholdMs:n,total:c.length}},Pe=(e={})=>{let n=new Set,c=e.thresholdMs??250,o=e.fetch??globalThis.fetch,s=[],t=()=>{for(let d of n)d()},i=(d)=>{if(!e.path||typeof o!==\"function\")return;o(e.path,{body:JSON.stringify(d),headers:{\"Content-Type\":\"application/json\"},method:\"POST\"}).catch(()=>{})},r=(d,f)=>{let a={at:Date.now(),id:bn(),latencyMs:f.latencyMs,playbackStopLatencyMs:f.playbackStopLatencyMs,reason:f.reason,sessionId:f.sessionId,status:d,thresholdMs:c};return s.push(a),i(a),t(),a};return{getSnapshot:()=>wn(s,c),recordRequested:(d)=>r(\"requested\",d),recordSkipped:(d)=>r(\"skipped\",d),recordStopped:(d)=>r(\"stopped\",d),subscribe:(d)=>{return n.add(d),()=>{n.delete(d)}}}};var Rn=0.08,un=(e,n={})=>(n.enabled??!0)&&e>=(n.interruptThreshold??Rn),te=(e,n,c={})=>{let o=e.partial,s=(i)=>{if(!n.isPlaying||c.enabled===!1){c.monitor?.recordSkipped({reason:i,sessionId:e.sessionId});return}c.monitor?.recordRequested({reason:i,sessionId:e.sessionId}),n.interrupt().then(()=>{c.monitor?.recordStopped({latencyMs:n.lastInterruptLatencyMs,playbackStopLatencyMs:n.lastPlaybackStopLatencyMs,reason:i,sessionId:e.sessionId})})},t=e.subscribe(()=>{if(c.interruptOnPartial===!1){o=e.partial;return}if(!o&&e.partial)s(\"partial-transcript\");o=e.partial});return{close:()=>{t()},handleLevel:(i)=>{if(un(i,c))s(\"input-level\")},sendAudio:(i)=>{s(\"manual-audio\"),e.sendAudio(i)}}};var ae=48,_n=320,En=88,Pn=\"Guided test\",Dn=\"General recording\",On=\"Pick a scenario to begin the demo.\",xn=\"I can walk you through a short guided voice test.\",Un=\"I can capture one freeform recording and confirm that it landed.\",Nn=\"Choose a scenario to begin. Guided test asks follow-up prompts. General recording just captures what you say.\",Hn=\"Click Start general recording to capture one freeform answer.\",xe=\"Speak freely. When you pause, the recording will be captured.\",re=\"Recording saved. Start again if you want another capture.\",Ue=\"Guided test complete. Review the saved summary below.\",Ne=\"All prompts are covered. You can stop the microphone or keep speaking for extra detail.\",Gn=\"Ready. Start guided test or general recording to begin.\",Bn=\"Live. Answer the prompt, then click Stop microphone when finished.\",De=[\"Start with a quick introduction about who you are.\",\"Now describe what you are trying to do or test.\",\"Finish with any detail that feels blocked, risky, or unclear.\"],He=(e,n,c)=>Math.min(c,Math.max(n,e)),X=(e)=>e.replaceAll(\"&\",\"&\").replaceAll(\"<\",\"<\").replaceAll(\">\",\">\").replaceAll('\"',\""\").replaceAll(\"'\",\"'\"),ie=(e,n)=>{let c=e[n];if(typeof c===\"string\"&&c.trim())return c;return null},le=(e)=>{if(typeof e===\"string\"&&e.trim())return e;if(e instanceof Error&&e.message.trim())return e.message;if(e&&typeof e===\"object\"){let n=e,c=ie(n,\"message\")??ie(n,\"reason\")??ie(n,\"description\");if(c)return c;if(\"error\"in n)return le(n.error);if(\"cause\"in n)return le(n.cause);try{return JSON.stringify(e)}catch{}}return\"Unexpected error\"},Wn=(e)=>{let n=[e.status];if(e.attempts>0||e.maxAttempts>0)n.push(`${e.attempts}/${e.maxAttempts} attempts`);if(e.nextAttemptAt){let c=Math.max(0,e.nextAttemptAt-Date.now());n.push(`retry in ${Math.ceil(c/100)/10}s`)}return n.join(\" \u00B7 \")},v=(e=ae)=>Array.from({length:e},()=>0),Oe=(e,n,c=ae)=>{let o=e.slice(-(c-1));o.push(He(n,0,1));while(o.length<c)o.unshift(0);return o},$n=(e,n=_n,c=En)=>{let o=e.length>1?e:v(ae),s=n/(o.length-1),t=c/2,i=c*0.34;if(Math.max(...o,0)<=0.015)return`M 0 ${t} L ${n} ${t}`;let d=o.map((a,A)=>{let g=A*0.76,y=Math.sin(g)*0.78+Math.sin(g*0.41)*0.22,C=a*i,I=s*A,L=He(t+y*C,8,c-8);return{x:I,y:L}});if(d.length===0)return`M 0 ${t} L ${n} ${t}`;let f=`M ${d[0]?.x??0} ${d[0]?.y??t}`;for(let a=1;a<d.length;a+=1){let A=d[a-1],g=d[a];if(!A||!g)continue;let y=(A.x+g.x)/2;f+=` Q ${y} ${A.y} ${g.x} ${g.y}`}return f},kn=(e)=>{if(!e)return De;try{let n=JSON.parse(e);if(Array.isArray(n)){let c=n.filter((o)=>typeof o===\"string\").map((o)=>o.trim()).filter(Boolean);if(c.length>0)return c}}catch{}return De},se=(e)=>{if(!e)return;let n=Number(e);return Number.isFinite(n)?n:void 0},qn=(e,n,c)=>{if(!n)return null;let o=document.querySelector(n);return o instanceof c?o:null},O=(e,n,c,o)=>{let s=n?document.querySelector(n):null;if(s instanceof c)return s;let t=e.querySelector(`#${o}`);if(t instanceof c)return t;throw Error(`Voice HTMX bootstrap could not find the required element \"${o}\".`)},Xn=(e)=>{if(!e.mode)return On;if(!e.hasStarted)return e.mode===\"guided\"?xn:Un;if(e.status===\"completed\")return e.mode===\"guided\"?Ue:re;if(e.mode===\"general\")return xe;return e.guidedPrompts[e.turnCount]??Ne},zn=(e)=>{if(!e.mode)return Nn;if(e.status===\"completed\")return e.mode===\"guided\"?Ue:re;if(!e.hasStarted)return e.mode===\"guided\"?`Click Start guided test to begin. First prompt: ${e.guidedPrompts[0]??\"Answer the first prompt.\"}`:Hn;if(e.mode===\"general\")return e.turnCount===0?xe:re;return e.guidedPrompts[e.turnCount]??Ne},Yn=(e)=>{let n=e.dataset.voiceGuidedPath,c=e.dataset.voiceGeneralPath;if(!n||!c)throw Error(\"Voice HTMX bootstrap requires data-voice-guided-path and data-voice-general-path.\");let o=kn(e.dataset.voiceGuidedPrompts),s=e.dataset.voiceGuidedLabel??Pn,t=e.dataset.voiceGeneralLabel??Dn,i=e.dataset.voiceReconnectReportPath,r=e.dataset.voiceBargeInPath,d=r?Pe({path:r,thresholdMs:se(e.dataset.voiceBargeInThresholdMs)}):null,f=se(e.dataset.voiceBargeInRecentWindowMs)??4000,a=se(e.dataset.voiceBargeInSpeechThreshold)??0.04,A=O(document,e.dataset.voiceSync,HTMLElement,\"voice-htmx-sync\"),g=O(e,e.dataset.voiceConnection,HTMLElement,\"metric-connection\"),y=O(e,e.dataset.voiceError,HTMLElement,\"status-error\"),C=O(e,e.dataset.voiceMicrophone,HTMLElement,\"status-mic\"),I=O(e,e.dataset.voicePrompt,HTMLElement,\"status-prompt\"),L=qn(e,e.dataset.voiceReconnect,HTMLElement),R=O(e,e.dataset.voiceChat,HTMLElement,\"chat-list\"),w=O(e,e.dataset.voiceStartGuided,HTMLButtonElement,\"start-guided\"),x=O(e,e.dataset.voiceStartGeneral,HTMLButtonElement,\"start-general\"),U=O(e,e.dataset.voiceStop,HTMLButtonElement,\"stop-mic\"),l=O(e,e.dataset.voiceMonitor,HTMLElement,\"voice-monitor\"),M=O(e,e.dataset.voiceMonitorCopy,HTMLElement,\"voice-monitor-copy\"),b=O(e,e.dataset.voiceWaveGlow,SVGPathElement,\"voice-wave-glow\"),z=O(e,e.dataset.voiceWavePath,SVGPathElement,\"voice-wave-path\"),_=null,$={general:!1,guided:!1},P=!1,k=null,N=v(),h=null,T=null,E=j(n,{capture:{onAudio:(S,B)=>{if(h){h.sendAudio(S);return}B(S)},onLevel:(S)=>{h?.handleLevel(S),N=Oe(N,S),p()}},connection:{reconnectReportPath:i},preset:\"guided-intake\"}),V=j(c,{capture:{onAudio:(S,B)=>{if(T){T.sendAudio(S);return}B(S)},onLevel:(S)=>{T?.handleLevel(S),N=Oe(N,S),p()}},connection:{reconnectReportPath:i},preset:\"dictation\"}),J=E.bindHTMX({element:A}),Ge=V.bindHTMX({element:A}),Q=F(E),Z=F(V);h=te(E,Q,{interruptThreshold:a,monitor:d??void 0}),T=te(V,Z,{interruptThreshold:a,monitor:d??void 0});let Y=()=>_===\"general\"?V:E,Qn=()=>_===\"general\"?Z:Q,p=()=>{let S=$n(N);b.setAttribute(\"d\",S),z.setAttribute(\"d\",S),M.innerHTML=`<span class=\"voice-live-dot\"></span>${P?\"Microphone live\":\"Microphone idle\"}`,M.classList.toggle(\"is-live\",P),l.classList.toggle(\"is-live\",P)},q=()=>{let S=Y(),B=(_?$[_]:!1)||S.turns.length>0,ge=S.status;if(g.textContent=S.isConnected?\"Connected\":\"Waiting\",y.textContent=k||S.error||\"None\",L)L.textContent=Wn(S.reconnect);C.textContent=P?Bn:Gn,I.textContent=zn({guidedPrompts:o,hasStarted:B,mode:_,status:ge,turnCount:S.turns.length}),w.hidden=P,x.hidden=P,U.hidden=!P,R.innerHTML=`<article class=\"voice-chat-message assistant\">\n <div class=\"voice-chat-role\">${X(_===\"general\"?t:_===\"guided\"?s:\"Voice demo\")}</div>\n <p class=\"voice-turn-text\">${X(Xn({generalLabel:t,guidedLabel:s,guidedPrompts:o,hasStarted:B,mode:_,status:ge,turnCount:S.turns.length}))}</p>\n</article>${S.turns.map((ee)=>`<div class=\"voice-chat-stack\">\n <article class=\"voice-chat-message user\">\n <div class=\"voice-chat-role\">You</div>\n <p class=\"voice-turn-text\">${X(ee.text)}</p>\n </article>\n ${ee.assistantText?`<article class=\"voice-chat-message assistant\">\n <div class=\"voice-chat-role\">${X(_===\"general\"?t:_===\"guided\"?s:\"Guide\")}</div>\n <p class=\"voice-turn-text\">${X(ee.assistantText)}</p>\n </article>`:\"\"}\n</div>`).join(\"\")}${S.partial?`<article class=\"voice-chat-message user pending\">\n <div class=\"voice-chat-role\">Speaking</div>\n <p class=\"voice-turn-text\">${X(S.partial)}</p>\n</article>`:\"\"}`,p()},Be=()=>{Y().stopRecording(),P=!1,k=null,N=v(),q()},de=async(S)=>{_=S,$={...$,[S]:!0};try{await Y().startRecording(),k=null,P=!0,q()}catch(B){Y().stopRecording(),P=!1,N=v(),k=le(B),q()}};E.subscribe(()=>{if(E.assistantAudio.length>0)Q.start().catch(()=>{});q()}),V.subscribe(()=>{if(V.assistantAudio.length>0)Z.start().catch(()=>{});q()}),w.addEventListener(\"click\",()=>{de(\"guided\")}),x.addEventListener(\"click\",()=>{de(\"general\")}),U.addEventListener(\"click\",()=>{Be()}),e.addEventListener(\"absolute-voice-simulate-disconnect\",()=>{Y().simulateDisconnect()}),window.addEventListener(\"beforeunload\",()=>{E.stopRecording(),V.stopRecording(),h?.close(),T?.close(),Q.close(),Z.close(),J(),Ge(),E.close(),V.close()}),q()},Jn=()=>{if(typeof window>\"u\"||typeof document>\"u\")return;let e=Array.from(document.querySelectorAll(\"[data-voice-htmx]\"));for(let n of e)if(n instanceof HTMLElement)Yn(n)};Jn();export{Jn as initVoiceHTMX};\n";
|
package/dist/index.d.ts
CHANGED
|
@@ -16,11 +16,13 @@ export type { VoiceRealtimeChannelAssertionInput, VoiceRealtimeChannelAssertionR
|
|
|
16
16
|
export { assertVoiceRealtimeProviderContractEvidence, buildVoiceRealtimeProviderContractMatrix, createVoiceRealtimeProviderContractMatrixPreset, createVoiceRealtimeProviderContractRoutes, evaluateVoiceRealtimeProviderContractEvidence, renderVoiceRealtimeProviderContractHTML, } from "./realtimeProviderContracts";
|
|
17
17
|
export type { VoiceRealtimeProviderContractAssertionInput, VoiceRealtimeProviderContractAssertionReport, VoiceRealtimeProviderContractCapability, VoiceRealtimeProviderContractCheck, VoiceRealtimeProviderContractDefinition, VoiceRealtimeProviderContractMatrixPresetOptions, VoiceRealtimeProviderContractMatrixInput, VoiceRealtimeProviderContractMatrixReport, VoiceRealtimeProviderContractRoutesOptions, VoiceRealtimeProviderContractRow, VoiceRealtimeProviderPresetProvider, VoiceRealtimeProviderContractStatus, } from "./realtimeProviderContracts";
|
|
18
18
|
export { buildVoiceDiagnosticsMarkdown, createVoiceDiagnosticsRoutes, resolveVoiceDiagnosticsTraceFilter, } from "./diagnosticsRoutes";
|
|
19
|
-
export { assertVoiceMediaPipelineEvidence, buildVoiceMediaPipelineReport, createVoiceMediaPipelineRoutes, evaluateVoiceMediaPipelineEvidence, renderVoiceMediaPipelineHTML, renderVoiceMediaPipelineMarkdown, } from "./mediaPipelineRoutes";
|
|
19
|
+
export { assertVoiceMediaPipelineEvidence, buildVoiceMediaPipelineReport, createVoiceMediaPipelineRoutes, evaluateVoiceMediaPipelineEvidence, renderVoiceMediaPipelineHTML, renderVoiceMediaPipelineMarkdown, summarizeVoiceMediaPipelineReport, } from "./mediaPipelineRoutes";
|
|
20
20
|
export { buildVoiceTelephonyMediaReport, createVoiceTelephonyMediaRoutes, getLatestVoiceTelephonyMediaReport, renderVoiceTelephonyMediaHTML, } from "./telephonyMediaRoutes";
|
|
21
21
|
export { createVoiceBrowserMediaRoutes, getLatestVoiceBrowserMediaReport, renderVoiceBrowserMediaHTML, summarizeVoiceBrowserMedia, } from "./browserMediaRoutes";
|
|
22
22
|
export { assertVoiceBrowserCallProfileEvidence, buildVoiceBrowserCallProfileReport, createVoiceBrowserCallProfileRoutes, evaluateVoiceBrowserCallProfileEvidence, renderVoiceBrowserCallProfileHTML, renderVoiceBrowserCallProfileMarkdown, } from "./browserCallProfiles";
|
|
23
|
-
export type { VoiceMediaPipelineAssertionInput, VoiceMediaPipelineAssertionReport, VoiceMediaPipelineReport, VoiceMediaPipelineReportOptions, VoiceMediaPipelineRoutesOptions, } from "./mediaPipelineRoutes";
|
|
23
|
+
export type { VoiceMediaPipelineAssertionInput, VoiceMediaPipelineAssertionReport, VoiceMediaPipelineCalibrationSummary, VoiceMediaPipelineProofArtifactLinks, VoiceMediaPipelineProofSummary, VoiceMediaPipelineProofSummaryOptions, VoiceMediaPipelineReport, VoiceMediaPipelineReportOptions, VoiceMediaPipelineRoutesOptions, } from "./mediaPipelineRoutes";
|
|
24
|
+
export { buildVoiceMediaPipelineIncidentEvents, buildVoiceMediaPipelineReadinessChecks, extractVoiceMediaPipelineIssueEntries, writeVoiceMediaPipelineArtifacts, } from "./mediaPipelineSurfaces";
|
|
25
|
+
export type { VoiceMediaPipelineArtifactKind, VoiceMediaPipelineArtifactRecord, VoiceMediaPipelineArtifactWriteOptions, VoiceMediaPipelineArtifactWriteResult, VoiceMediaPipelineIncidentOptions, VoiceMediaPipelineIssueEntry, VoiceMediaPipelineIssueSource, VoiceMediaPipelineReadinessOptions, } from "./mediaPipelineSurfaces";
|
|
24
26
|
export type { VoiceTelephonyMediaCarrierInput, VoiceTelephonyMediaCarrierReport, VoiceTelephonyMediaReport, VoiceTelephonyMediaRoutesOptions, VoiceTelephonyMediaTraceReportOptions, VoiceTelephonyMediaStatus, } from "./telephonyMediaRoutes";
|
|
25
27
|
export type { VoiceBrowserMediaReport, VoiceBrowserMediaRoutesOptions, VoiceBrowserMediaSample, VoiceBrowserMediaStatus, } from "./browserMediaRoutes";
|
|
26
28
|
export type { VoiceBrowserCallProfileAssertionInput, VoiceBrowserCallProfileAssertionReport, VoiceBrowserCallProfileFrameworkEvidence, VoiceBrowserCallProfileFrameworkSummary, VoiceBrowserCallProfileReport, VoiceBrowserCallProfileReportInput, VoiceBrowserCallProfileRoutesOptions, VoiceBrowserCallProfileStatus, VoiceBrowserCallProfileSummary, } from "./browserCallProfiles";
|