@devicai/ui 0.62.1 → 0.62.2
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/cjs/components/ChatDrawer/ChatDrawer.js +2 -1
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/LiveVoicePanel.js +1 -1
- package/dist/cjs/components/ChatDrawer/LiveVoicePanel.js.map +1 -1
- package/dist/cjs/utils/limitError.js +11 -0
- package/dist/cjs/utils/limitError.js.map +1 -0
- package/dist/cjs/voice/LiveVoiceController.js +9 -0
- package/dist/cjs/voice/LiveVoiceController.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.js +2 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/esm/components/ChatDrawer/LiveVoicePanel.js +1 -1
- package/dist/esm/components/ChatDrawer/LiveVoicePanel.js.map +1 -1
- package/dist/esm/utils/limitError.d.ts +6 -0
- package/dist/esm/utils/limitError.js +9 -0
- package/dist/esm/utils/limitError.js.map +1 -0
- package/dist/esm/voice/LiveVoiceController.js +9 -0
- package/dist/esm/voice/LiveVoiceController.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveVoicePanel.js","sources":["../../../../src/components/ChatDrawer/LiveVoicePanel.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { UseDevicLiveVoiceResult } from '../../hooks/useDevicLiveVoice';\nimport type { LiveVoiceInvitationProps } from './ChatDrawer.types';\nimport { useTranslations } from '../../i18n';\nimport './LiveVoicePanel.css';\nimport { LiveVoicePrompter } from './LiveVoicePrompter';\n\nexport interface LiveVoicePanelProps {\n voice: UseDevicLiveVoiceResult;\n canStart: boolean;\n recordSessions?: boolean;\n /** Close the invitation card; the drawer remembers it per assistant. */\n onDismiss?: () => void;\n /** A host's own invitation, in place of the default card. */\n invitation?: (props: LiveVoiceInvitationProps) => ReactNode;\n /** Rendered above the call box while voice is active: the composer's own banners. */\n children?: ReactNode;\n}\n\n/** `m:ss` of a running call, as the dictation timer formats it. */\nfunction formatSeconds(total: number): string {\n const seconds = Math.max(0, Math.floor(total));\n return `${Math.floor(seconds / 60)}:${(seconds % 60).toString().padStart(2, '0')}`;\n}\n\n/**\n * The live voice widget. Idle, it is an invitation card sitting above the\n * composer of a new conversation; once a call starts it takes the composer's\n * place — the same input area, the same rounded surface — with the transcript\n * prompter, one wave per speaker and the call controls where the send button\n * normally sits.\n */\nexport default function LiveVoicePanel({ voice, canStart, recordSessions, onDismiss, invitation, children }: LiveVoicePanelProps) {\n const t = useTranslations();\n const start = () => { if (canStart) void voice.start(); };\n\n if (voice.active) {\n // About to end for silence: the countdown takes the status line, and the\n // button next to it keeps the call.\n const idleIn = voice.idleEndsAt && voice.state === 'connected' ? Math.max(0, Math.ceil((voice.idleEndsAt - Date.now()) / 1000)) : undefined;\n const status = idleIn !== undefined ? t('Still there? The call ends in {seconds} s', { seconds: idleIn })\n : voice.state === 'connected' ? t('Live · {time}', { time: formatSeconds(voice.seconds) })\n : voice.state === 'reconnecting' ? t('Restoring voice…') : voice.state === 'closing' ? t('Closing voice…') : t('Connecting voice…');\n return <div className=\"devic-input-area devic-voice-area\" data-voice-state={voice.state} data-voice-idle={idleIn !== undefined ? 'true' : undefined}>\n {children}\n <section className=\"devic-voice-box\" aria-label={t('Voice mode')}>\n <LiveVoicePrompter voice={voice} />\n <div className=\"devic-voice-bar\">\n <span className=\"devic-voice-status\" role=\"status\"><i className=\"devic-voice-status-dot\" aria-hidden=\"true\" />{status}</span>\n {idleIn !== undefined && <button type=\"button\" className=\"devic-voice-text-btn devic-voice-still-here\" onClick={() => voice.stillHere()}>{t(\"I'm here\")}</button>}\n {voice.playbackBlocked && <button type=\"button\" className=\"devic-voice-text-btn\" onClick={() => void voice.play()}>{t('Enable audio')}</button>}\n {voice.state === 'connecting'\n ? <button type=\"button\" className=\"devic-voice-text-btn\" onClick={() => void voice.stop()}>{t('Cancel')}</button>\n : <>\n <button type=\"button\" className=\"devic-input-btn devic-voice-mute\" aria-pressed={voice.muted} disabled={voice.state !== 'connected'}\n title={voice.muted ? t('Unmute') : t('Mute')} aria-label={voice.muted ? t('Unmute') : t('Mute')} onClick={() => voice.mute(!voice.muted)}>\n {voice.muted ? <MicOffIcon /> : <MicIcon />}\n </button>\n <button type=\"button\" className=\"devic-voice-end\" disabled={voice.state === 'closing'} onClick={() => void voice.stop()}>\n <HangUpIcon />{t('End voice')}\n </button>\n </>}\n </div>\n </section>\n </div>;\n }\n\n if (invitation) return <>{invitation({ start, canStart, dismiss: () => onDismiss?.(), recordSessions, error: voice.error })}</>;\n\n return <section className=\"devic-live-voice\" aria-label={t('Voice mode')}>\n <div className=\"devic-voice-card\">\n <span className=\"devic-voice-card-icon\" aria-hidden=\"true\"><MicIcon /></span>\n <div className=\"devic-voice-card-copy\">\n <div className=\"devic-voice-card-title\">{t('Voice mode')}</div>\n <div className=\"devic-voice-card-subtitle\">\n {t('Talk to the assistant in real time.')}{recordSessions !== false && <> {t('Voice sessions are recorded according to the assistant settings.')}</>}\n </div>\n </div>\n <button className=\"devic-voice-start\" type=\"button\" disabled={!canStart} onClick={start}><MicIcon />{t('Start voice')}</button>\n {onDismiss && <button className=\"devic-voice-card-close\" type=\"button\" onClick={onDismiss} title={t('Hide voice mode')} aria-label={t('Hide voice mode')}><CloseIcon /></button>}\n </div>\n {voice.error && <div className=\"devic-voice-error\" role=\"alert\">{t(voice.error.message)}</div>}\n {!voice.error && voice.endReason === 'idle' && <div className=\"devic-voice-note\" role=\"status\">{t('The call ended after a while without anyone speaking.')}</div>}\n </section>;\n}\n\nfunction MicIcon() {\n return <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\" /><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" /><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" /><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n </svg>;\n}\nfunction MicOffIcon() {\n return <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" /><path d=\"M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6\" /><path d=\"M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23\" /><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" /><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n </svg>;\n}\nfunction CloseIcon() {\n return <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>;\n}\nfunction HangUpIcon() {\n return <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08a.996.996 0 0 1 0-1.41C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28-.79-.74-1.69-1.36-2.67-1.85-.33-.16-.56-.5-.56-.9v-3.1C15.15 9.25 13.6 9 12 9z\" />\n </svg>;\n}\n"],"names":["_jsxs","_jsx","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LiveVoicePanel.js","sources":["../../../../src/components/ChatDrawer/LiveVoicePanel.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { UseDevicLiveVoiceResult } from '../../hooks/useDevicLiveVoice';\nimport type { LiveVoiceInvitationProps } from './ChatDrawer.types';\nimport { useTranslations } from '../../i18n';\nimport './LiveVoicePanel.css';\nimport { LiveVoicePrompter } from './LiveVoicePrompter';\n\nexport interface LiveVoicePanelProps {\n voice: UseDevicLiveVoiceResult;\n canStart: boolean;\n recordSessions?: boolean;\n /** Close the invitation card; the drawer remembers it per assistant. */\n onDismiss?: () => void;\n /** A host's own invitation, in place of the default card. */\n invitation?: (props: LiveVoiceInvitationProps) => ReactNode;\n /** Rendered above the call box while voice is active: the composer's own banners. */\n children?: ReactNode;\n}\n\n/** `m:ss` of a running call, as the dictation timer formats it. */\nfunction formatSeconds(total: number): string {\n const seconds = Math.max(0, Math.floor(total));\n return `${Math.floor(seconds / 60)}:${(seconds % 60).toString().padStart(2, '0')}`;\n}\n\n/**\n * The live voice widget. Idle, it is an invitation card sitting above the\n * composer of a new conversation; once a call starts it takes the composer's\n * place — the same input area, the same rounded surface — with the transcript\n * prompter, one wave per speaker and the call controls where the send button\n * normally sits.\n */\nexport default function LiveVoicePanel({ voice, canStart, recordSessions, onDismiss, invitation, children }: LiveVoicePanelProps) {\n const t = useTranslations();\n const start = () => { if (canStart) void voice.start(); };\n\n if (voice.active) {\n // About to end for silence: the countdown takes the status line, and the\n // button next to it keeps the call.\n const idleIn = voice.idleEndsAt && voice.state === 'connected' ? Math.max(0, Math.ceil((voice.idleEndsAt - Date.now()) / 1000)) : undefined;\n const status = idleIn !== undefined ? t('Still there? The call ends in {seconds} s', { seconds: idleIn })\n : voice.state === 'connected' ? t('Live · {time}', { time: formatSeconds(voice.seconds) })\n : voice.state === 'reconnecting' ? t('Restoring voice…') : voice.state === 'closing' ? t('Closing voice…') : t('Connecting voice…');\n return <div className=\"devic-input-area devic-voice-area\" data-voice-state={voice.state} data-voice-idle={idleIn !== undefined ? 'true' : undefined}>\n {children}\n <section className=\"devic-voice-box\" aria-label={t('Voice mode')}>\n <LiveVoicePrompter voice={voice} />\n <div className=\"devic-voice-bar\">\n <span className=\"devic-voice-status\" role=\"status\"><i className=\"devic-voice-status-dot\" aria-hidden=\"true\" />{status}</span>\n {idleIn !== undefined && <button type=\"button\" className=\"devic-voice-text-btn devic-voice-still-here\" onClick={() => voice.stillHere()}>{t(\"I'm here\")}</button>}\n {voice.playbackBlocked && <button type=\"button\" className=\"devic-voice-text-btn\" onClick={() => void voice.play()}>{t('Enable audio')}</button>}\n {voice.state === 'connecting'\n ? <button type=\"button\" className=\"devic-voice-text-btn\" onClick={() => void voice.stop()}>{t('Cancel')}</button>\n : <>\n <button type=\"button\" className=\"devic-input-btn devic-voice-mute\" aria-pressed={voice.muted} disabled={voice.state !== 'connected'}\n title={voice.muted ? t('Unmute') : t('Mute')} aria-label={voice.muted ? t('Unmute') : t('Mute')} onClick={() => voice.mute(!voice.muted)}>\n {voice.muted ? <MicOffIcon /> : <MicIcon />}\n </button>\n <button type=\"button\" className=\"devic-voice-end\" disabled={voice.state === 'closing'} onClick={() => void voice.stop()}>\n <HangUpIcon />{t('End voice')}\n </button>\n </>}\n </div>\n </section>\n </div>;\n }\n\n if (invitation) return <>{invitation({ start, canStart, dismiss: () => onDismiss?.(), recordSessions, error: voice.error })}</>;\n\n return <section className=\"devic-live-voice\" aria-label={t('Voice mode')}>\n <div className=\"devic-voice-card\">\n <span className=\"devic-voice-card-icon\" aria-hidden=\"true\"><MicIcon /></span>\n <div className=\"devic-voice-card-copy\">\n <div className=\"devic-voice-card-title\">{t('Voice mode')}</div>\n <div className=\"devic-voice-card-subtitle\">\n {t('Talk to the assistant in real time.')}{recordSessions !== false && <> {t('Voice sessions are recorded according to the assistant settings.')}</>}\n </div>\n </div>\n <button className=\"devic-voice-start\" type=\"button\" disabled={!canStart} onClick={start}><MicIcon />{t('Start voice')}</button>\n {onDismiss && <button className=\"devic-voice-card-close\" type=\"button\" onClick={onDismiss} title={t('Hide voice mode')} aria-label={t('Hide voice mode')}><CloseIcon /></button>}\n </div>\n {voice.error && <div className=\"devic-voice-error\" role=\"alert\">{t(voice.error.message)}</div>}\n {!voice.error && voice.endReason === 'idle' && <div className=\"devic-voice-note\" role=\"status\">{t('The call ended after a while without anyone speaking.')}</div>}\n {!voice.error && voice.endReason === 'tenant_limit_exceeded' && <div className=\"devic-voice-note\" role=\"alert\">{t('The tenant or subtenant spending limit was reached.')}</div>}\n </section>;\n}\n\nfunction MicIcon() {\n return <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\" /><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" /><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" /><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n </svg>;\n}\nfunction MicOffIcon() {\n return <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" /><path d=\"M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6\" /><path d=\"M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23\" /><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" /><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n </svg>;\n}\nfunction CloseIcon() {\n return <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>;\n}\nfunction HangUpIcon() {\n return <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08a.996.996 0 0 1 0-1.41C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28-.79-.74-1.69-1.36-2.67-1.85-.33-.16-.56-.5-.56-.9v-3.1C15.15 9.25 13.6 9 12 9z\" />\n </svg>;\n}\n"],"names":["_jsxs","_jsx","_Fragment"],"mappings":";;;;AAmBA;AACA,SAAS,aAAa,CAAC,KAAa,EAAA;AAClC,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,CAAA,EAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAA,CAAA,EAAI,CAAC,OAAO,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA,CAAE;AACpF;AAEA;;;;;;AAMG;AACW,SAAU,cAAc,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAuB,EAAA;AAC9H,IAAA,MAAM,CAAC,GAAG,eAAe,EAAE;AAC3B,IAAA,MAAM,KAAK,GAAG,MAAK,EAAG,IAAI,QAAQ;AAAE,QAAA,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAEzD,IAAA,IAAI,KAAK,CAAC,MAAM,EAAE;;;AAGhB,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,CAAC,GAAG,SAAS;AAC3I,QAAA,MAAM,MAAM,GAAG,MAAM,KAAK,SAAS,GAAG,CAAC,CAAC,2CAA2C,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;cACpG,KAAK,CAAC,KAAK,KAAK,WAAW,GAAG,CAAC,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;AACzF,kBAAE,KAAK,CAAC,KAAK,KAAK,cAAc,GAAG,CAAC,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,SAAS,GAAG,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,mBAAmB,CAAC;AACrI,QAAA,OAAOA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,mCAAmC,EAAA,kBAAA,EAAmB,KAAK,CAAC,KAAK,EAAA,iBAAA,EAAmB,MAAM,KAAK,SAAS,GAAG,MAAM,GAAG,SAAS,EAAA,QAAA,EAAA,CAChJ,QAAQ,EACTA,IAAA,CAAA,SAAA,EAAA,EAAS,SAAS,EAAC,iBAAiB,EAAA,YAAA,EAAa,CAAC,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,CAC9DC,GAAA,CAAC,iBAAiB,EAAA,EAAC,KAAK,EAAE,KAAK,EAAA,CAAI,EACnCD,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,iBAAiB,EAAA,QAAA,EAAA,CAC9BA,IAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,oBAAoB,EAAC,IAAI,EAAC,QAAQ,EAAA,QAAA,EAAA,CAACC,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAC,wBAAwB,EAAA,aAAA,EAAa,MAAM,GAAG,EAAC,MAAM,CAAA,EAAA,CAAQ,EAC5H,MAAM,KAAK,SAAS,IAAIA,GAAA,CAAA,QAAA,EAAA,EAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,6CAA6C,EAAC,OAAO,EAAE,MAAM,KAAK,CAAC,SAAS,EAAE,EAAA,QAAA,EAAG,CAAC,CAAC,UAAU,CAAC,EAAA,CAAU,EAChK,KAAK,CAAC,eAAe,IAAIA,GAAA,CAAA,QAAA,EAAA,EAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,sBAAsB,EAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,IAAI,EAAE,EAAA,QAAA,EAAG,CAAC,CAAC,cAAc,CAAC,EAAA,CAAU,EAC9I,KAAK,CAAC,KAAK,KAAK;sCACbA,GAAA,CAAA,QAAA,EAAA,EAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,sBAAsB,EAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,IAAI,EAAE,EAAA,QAAA,EAAG,CAAC,CAAC,QAAQ,CAAC,EAAA;AACvG,sCAAED,IAAA,CAAAE,QAAA,EAAA,EAAA,QAAA,EAAA,CACAD,GAAA,CAAA,QAAA,EAAA,EAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,kCAAkC,EAAA,cAAA,EAAe,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,KAAK,WAAW,EACjI,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAA,YAAA,EAAc,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAA,QAAA,EACvI,KAAK,CAAC,KAAK,GAAGA,GAAA,CAAC,UAAU,EAAA,EAAA,CAAG,GAAGA,GAAA,CAAC,OAAO,EAAA,EAAA,CAAG,EAAA,CACpC,EACTD,IAAA,CAAA,QAAA,EAAA,EAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,iBAAiB,EAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,IAAI,EAAE,EAAA,QAAA,EAAA,CACrHC,GAAA,CAAC,UAAU,EAAA,EAAA,CAAG,EAAC,CAAC,CAAC,WAAW,CAAC,CAAA,EAAA,CACtB,CAAA,EAAA,CACR,CAAA,EAAA,CACD,CAAA,EAAA,CACE,IACN;IACR;AAEA,IAAA,IAAI,UAAU;QAAE,OAAOA,GAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAG,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,EAAA,CAAI;IAE/H,OAAOF,IAAA,CAAA,SAAA,EAAA,EAAS,SAAS,EAAC,kBAAkB,gBAAa,CAAC,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,CACtEA,cAAK,SAAS,EAAC,kBAAkB,EAAA,QAAA,EAAA,CAC/BC,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,uBAAuB,EAAA,aAAA,EAAa,MAAM,EAAA,QAAA,EAACA,GAAA,CAAC,OAAO,EAAA,EAAA,CAAG,EAAA,CAAO,EAC7ED,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,uBAAuB,EAAA,QAAA,EAAA,CACpCC,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,wBAAwB,YAAE,CAAC,CAAC,YAAY,CAAC,EAAA,CAAO,EAC/DD,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,2BAA2B,EAAA,QAAA,EAAA,CACvC,CAAC,CAAC,qCAAqC,CAAC,EAAE,cAAc,KAAK,KAAK,IAAIA,IAAA,CAAAE,QAAA,EAAA,EAAA,QAAA,EAAA,CAAA,GAAA,EAAI,CAAC,CAAC,kEAAkE,CAAC,IAAI,CAAA,EAAA,CAChJ,CAAA,EAAA,CACF,EACNF,IAAA,CAAA,QAAA,EAAA,EAAQ,SAAS,EAAC,mBAAmB,EAAC,IAAI,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAA,QAAA,EAAA,CAAEC,GAAA,CAAC,OAAO,EAAA,EAAA,CAAG,EAAC,CAAC,CAAC,aAAa,CAAC,CAAA,EAAA,CAAU,EAC9H,SAAS,IAAIA,GAAA,CAAA,QAAA,EAAA,EAAQ,SAAS,EAAC,wBAAwB,EAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAAA,YAAA,EAAc,CAAC,CAAC,iBAAiB,CAAC,EAAA,QAAA,EAAEA,GAAA,CAAC,SAAS,EAAA,EAAA,CAAG,EAAA,CAAS,CAAA,EAAA,CAC5K,EACL,KAAK,CAAC,KAAK,IAAIA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,mBAAmB,EAAC,IAAI,EAAC,OAAO,YAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAA,CAAO,EAC7F,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,MAAM,IAAIA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,kBAAkB,EAAC,IAAI,EAAC,QAAQ,EAAA,QAAA,EAAE,CAAC,CAAC,uDAAuD,CAAC,EAAA,CAAO,EAChK,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,uBAAuB,IAAIA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,kBAAkB,EAAC,IAAI,EAAC,OAAO,EAAA,QAAA,EAAE,CAAC,CAAC,qDAAqD,CAAC,EAAA,CAAO,CAAA,EAAA,CACvK;AACZ;AAEA,SAAS,OAAO,GAAA;AACd,IAAA,OAAOD,cAAK,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,iBAAa,MAAM,EAAA,QAAA,EAAA,CACtKC,cAAM,CAAC,EAAC,sDAAsD,EAAA,CAAG,EAAAA,GAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,4BAA4B,EAAA,CAAG,EAAAA,GAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EAAAA,cAAM,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,IACnL;AACR;AACA,SAAS,UAAU,GAAA;IACjB,OAAOD,IAAA,CAAA,KAAA,EAAA,EAAK,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,EAAA,aAAA,EAAa,MAAM,EAAA,QAAA,EAAA,CACtKC,GAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EAAAA,cAAM,CAAC,EAAC,wDAAwD,EAAA,CAAG,EAAAA,GAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,uDAAuD,GAAG,EAAAA,GAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EAAAA,GAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,CAAA,EAAA,CACtP;AACR;AACA,SAAS,SAAS,GAAA;AAChB,IAAA,OAAOD,IAAA,CAAA,KAAA,EAAA,EAAK,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,EAAA,aAAA,EAAa,MAAM,aAC/IC,GAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EAAAA,GAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,IACxE;AACR;AACA,SAAS,UAAU,GAAA;IACjB,OAAOA,GAAA,CAAA,KAAA,EAAA,EAAK,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,cAAc,EAAA,aAAA,EAAa,MAAM,EAAA,QAAA,EAC3FA,GAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,gXAAgX,EAAA,CAAG,EAAA,CACvX;AACR;;;;"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TenantLimitExceeded } from '../api/types';
|
|
2
|
+
/** A host's custom banner must not be bypassed by the same raw error above it.
|
|
3
|
+
* Unrelated errors and errors with no rendered banner remain visible. */
|
|
4
|
+
export declare function isRenderedLimitError(error: (Error & {
|
|
5
|
+
errorType?: string;
|
|
6
|
+
}) | null, limit: TenantLimitExceeded | null, bannerVisible: boolean): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** A host's custom banner must not be bypassed by the same raw error above it.
|
|
2
|
+
* Unrelated errors and errors with no rendered banner remain visible. */
|
|
3
|
+
function isRenderedLimitError(error, limit, bannerVisible) {
|
|
4
|
+
return !!(bannerVisible && error && limit &&
|
|
5
|
+
(error.errorType === 'TENANT_LIMIT_EXCEEDED' || error.message === limit.message));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export { isRenderedLimitError };
|
|
9
|
+
//# sourceMappingURL=limitError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limitError.js","sources":["../../../src/utils/limitError.ts"],"sourcesContent":["import type { TenantLimitExceeded } from '../api/types';\n\n/** A host's custom banner must not be bypassed by the same raw error above it.\n * Unrelated errors and errors with no rendered banner remain visible. */\nexport function isRenderedLimitError(error: (Error & { errorType?: string }) | null,\n limit: TenantLimitExceeded | null, bannerVisible: boolean): boolean {\n return !!(bannerVisible && error && limit &&\n (error.errorType === 'TENANT_LIMIT_EXCEEDED' || error.message === limit.message));\n}\n"],"names":[],"mappings":"AAEA;AACyE;SACzD,oBAAoB,CAAC,KAA8C,EACjF,KAAiC,EAAE,aAAsB,EAAA;AACzD,IAAA,OAAO,CAAC,EAAE,aAAa,IAAI,KAAK,IAAI,KAAK;AACvC,SAAC,KAAK,CAAC,SAAS,KAAK,uBAAuB,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,CAAC,CAAC;AACrF;;;;"}
|
|
@@ -178,6 +178,10 @@ class LiveVoiceController {
|
|
|
178
178
|
for (let i = 0; i < 35 && ticket === this.generation && !this.disposed; i++) {
|
|
179
179
|
const state = await this.client.getLiveSessionStatus(this.assistantId, sessionId);
|
|
180
180
|
if (state.status === 'closed') {
|
|
181
|
+
if (state.endReason === 'tenant_limit_exceeded') {
|
|
182
|
+
this.update({ state: 'idle', sessionId: undefined, endReason: state.endReason });
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
181
185
|
if (ticket === this.generation && !this.disposed)
|
|
182
186
|
await this.start(this.snapshot.chatUid, true);
|
|
183
187
|
return;
|
|
@@ -326,6 +330,11 @@ class LiveVoiceController {
|
|
|
326
330
|
if (warn ? this.snapshot.idleEndsAt !== endsAt : !!this.snapshot.idleEndsAt)
|
|
327
331
|
this.update({ idleEndsAt: warn ? endsAt : undefined });
|
|
328
332
|
}
|
|
333
|
+
if (state.endReason === 'tenant_limit_exceeded') {
|
|
334
|
+
this.update({ endReason: state.endReason });
|
|
335
|
+
void this.stop();
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
329
338
|
if (state.interrupted || state.restartRequested || (connectionLostAt && Date.now() - connectionLostAt > 5000)) {
|
|
330
339
|
void recover();
|
|
331
340
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveVoiceController.js","sources":["../../../src/voice/LiveVoiceController.ts"],"sourcesContent":["import type { DevicApiClient } from '../api/client';\nimport type { LiveVoiceContext, LiveVoiceTurn } from '../api/liveVoice.types';\n\nexport type LiveVoiceState = 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'closing' | 'error';\nexport interface LiveVoiceSnapshot {\n state: LiveVoiceState;\n chatUid?: string;\n sessionId?: string;\n muted: boolean;\n seconds: number;\n transcript: LiveVoiceTurn[];\n input?: MediaStream;\n output?: MediaStream;\n error?: Error;\n playbackBlocked?: boolean;\n /** Seconds of silence after which the server ends the call; 0 = never. */\n idleTimeoutSeconds?: number;\n /** Set while the call is about to end for silence: when it will, so a UI can count down. */\n idleEndsAt?: number;\n /** Why the server ended the last call, e.g. `idle`. */\n endReason?: string;\n}\nexport const initialVoiceSnapshot = (): LiveVoiceSnapshot => ({ state: 'idle', muted: false, seconds: 0, transcript: [] });\n\n/** No browser globals at import/constructor time; loaded only by start(). */\nexport class LiveVoiceController {\n private snapshot = initialVoiceSnapshot();\n private generation = 0;\n private attempts = 0;\n private disposeTransport: () => void = () => {};\n private audio?: HTMLAudioElement;\n private closing?: Promise<void>;\n private disposed = false;\n /** Last moment anyone spoke, or the person confirmed presence. */\n private lastActivity = 0;\n constructor(private client: DevicApiClient, private assistantId: string,\n private context: LiveVoiceContext, private changed: (value: LiveVoiceSnapshot) => void,\n private created: (chatUid: string) => void) {}\n\n private update(patch: Partial<LiveVoiceSnapshot>) {\n this.snapshot = { ...this.snapshot, ...patch };\n if (!this.disposed) this.changed(this.snapshot);\n }\n mute(muted: boolean) {\n this.snapshot.input?.getAudioTracks().forEach(track => { track.enabled = !muted && this.snapshot.state === 'connected'; });\n this.update({ muted });\n }\n async play() {\n try { await this.audio?.play(); this.update({ playbackBlocked: false }); }\n catch { this.update({ playbackBlocked: true }); }\n }\n /** The person is still there: restart the idle clock here and on the server. */\n stillHere() {\n this.lastActivity = Date.now();\n if (this.snapshot.idleEndsAt) this.update({ idleEndsAt: undefined });\n const id = this.snapshot.sessionId;\n if (id && this.snapshot.state === 'connected') void this.client.getLiveSessionStatus(this.assistantId, id, true).catch(() => {});\n }\n async start(chatUid?: string, recovering = false): Promise<void> {\n if (this.disposed || this.closing || (!recovering && !['idle', 'error'].includes(this.snapshot.state))) return;\n const generation = ++this.generation;\n const current = () => generation === this.generation && !this.disposed;\n if (!recovering) this.attempts = 0;\n this.update({ state: 'connecting', error: undefined, chatUid, sessionId: undefined,\n seconds: 0, idleEndsAt: undefined, endReason: undefined, ...(recovering ? {} : { transcript: [], muted: false }) });\n this.lastActivity = Date.now();\n let media: MediaStream | undefined;\n let peer: RTCPeerConnection | undefined;\n let channel: RTCDataChannel | undefined;\n let audio: HTMLAudioElement | undefined;\n let health: ReturnType<typeof setInterval> | undefined;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let connectDeadline: ReturnType<typeof setTimeout> | undefined;\n let backendReady = false;\n let lastTranscript = 0;\n let sessionId: string | undefined;\n let connectionLostAt = 0;\n let healthFailures = 0;\n let micCheck: ReturnType<typeof setInterval> | undefined;\n let micContext: AudioContext | undefined;\n let micAnalyser: AnalyserNode | undefined;\n let micQuiet = 0;\n const cleanup = () => {\n clearInterval(health); clearTimeout(deadline); clearTimeout(connectDeadline); clearInterval(micCheck);\n if (micContext) { try { void micContext.close().catch(() => {}); } catch { /* Already closed. */ } micContext = undefined; micAnalyser = undefined; }\n media?.getTracks().forEach(track => track.stop());\n if (channel) { channel.onclose = null; channel.onmessage = null; channel.close(); }\n if (peer) { peer.onconnectionstatechange = null; peer.ontrack = null; peer.close(); }\n if (audio) { audio.pause(); audio.srcObject = null; }\n this.audio = undefined;\n this.update({ input: undefined, output: undefined });\n };\n this.disposeTransport = cleanup;\n const ready = () => {\n if (!current() || !backendReady || peer?.connectionState !== 'connected') return;\n clearTimeout(connectDeadline);\n media?.getAudioTracks().forEach(track => { track.enabled = !this.snapshot.muted; });\n if (this.snapshot.state !== 'connected') { this.lastActivity = Date.now(); watchMicrophone(); }\n this.update({ state: 'connected' });\n };\n // A microphone that delivers nothing — ended track, system mute, or a\n // stream of exact digital silence — would otherwise keep a paid call open\n // with nobody able to speak. Analyse only; never route audio.\n const watchMicrophone = () => {\n if (micCheck) return;\n const track = media?.getAudioTracks()[0];\n if (!track) return;\n const samples = new Uint8Array(256);\n try {\n if (typeof AudioContext !== 'undefined') {\n micContext = new AudioContext(); micAnalyser = micContext.createAnalyser(); micAnalyser.fftSize = 256;\n micContext.createMediaStreamSource(media!).connect(micAnalyser); void micContext.resume().catch(() => {});\n }\n } catch { micAnalyser = undefined; }\n micCheck = setInterval(() => {\n if (!current() || this.snapshot.state !== 'connected') return;\n const fail = () => {\n this.update({ error: new Error('No microphone signal. Check your microphone and start again.') });\n void this.stop();\n };\n if (track.readyState === 'ended') { fail(); return; }\n if (this.snapshot.muted) { micQuiet = 0; return; }\n let silent = track.muted === true;\n if (micAnalyser && !silent) {\n try {\n micAnalyser.getByteTimeDomainData(samples);\n silent = samples.every(sample => sample === 128);\n } catch { silent = false; }\n }\n micQuiet = silent ? micQuiet + 1 : 0;\n if (micQuiet >= 15) fail();\n }, 1000);\n };\n const recover = async () => {\n if (!current()) return;\n ++this.generation;\n const ticket = this.generation;\n cleanup();\n this.update({ state: 'reconnecting' });\n try {\n if (!sessionId || ++this.attempts > 3) throw new Error('Voice connection interrupted. Please start again.');\n await this.client.closeLiveSession(this.assistantId, sessionId);\n // Never open another paid transport before the old one is confirmed closed.\n for (let i = 0; i < 35 && ticket === this.generation && !this.disposed; i++) {\n const state = await this.client.getLiveSessionStatus(this.assistantId, sessionId);\n if (state.status === 'closed') {\n if (ticket === this.generation && !this.disposed) await this.start(this.snapshot.chatUid, true);\n return;\n }\n await new Promise(resolve => setTimeout(resolve, 2000));\n }\n if (ticket === this.generation) throw new Error('Could not confirm the previous voice session closed.');\n } catch (error) {\n if (ticket === this.generation) this.update({ state: 'error', error: error as Error });\n }\n };\n try {\n if (typeof navigator === 'undefined' || !navigator.mediaDevices?.getUserMedia || typeof RTCPeerConnection === 'undefined')\n throw new Error('Voice requires microphone access on HTTPS or localhost.');\n media = await navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true }, video: false });\n if (!current()) { media.getTracks().forEach(track => track.stop()); return; }\n media.getAudioTracks().forEach(track => { track.enabled = false; });\n this.update({ input: media });\n peer = new RTCPeerConnection({ bundlePolicy: 'max-bundle' });\n audio = new Audio(); this.audio = audio; audio.autoplay = true;\n peer.ontrack = event => {\n if (!current()) return;\n const output = new MediaStream([event.track]);\n audio!.srcObject = output;\n this.update({ output }); void this.play();\n };\n peer.onconnectionstatechange = () => {\n ready();\n if (peer?.connectionState === 'disconnected') connectionLostAt ||= Date.now();\n else connectionLostAt = 0;\n if (peer?.connectionState === 'failed') void recover();\n };\n media.getTracks().forEach(track => peer!.addTrack(track, media!));\n channel = peer.createDataChannel('oai-events');\n channel.onmessage = message => {\n if (!current()) return;\n try {\n const event = JSON.parse(message.data);\n if (event.type === 'session.started') { backendReady = true; ready(); }\n if (['session.input_transcript.delta', 'session.output_transcript.delta'].includes(event.type) && typeof event.delta === 'string') {\n lastTranscript = Date.now(); this.lastActivity = lastTranscript;\n if (this.snapshot.idleEndsAt) this.update({ idleEndsAt: undefined });\n const role = event.type === 'session.input_transcript.delta' ? 'user' : 'assistant';\n const turns = this.snapshot.transcript.slice(-3).map(turn => ({ ...turn }));\n if (turns[turns.length - 1]?.role === role) turns[turns.length - 1].text = (turns[turns.length - 1].text + event.delta).slice(-2000);\n else turns.push({ role, text: event.delta.slice(-2000) });\n this.update({ transcript: turns });\n }\n if (event.type === 'session.closed' && sessionId) {\n void this.client.getLiveSessionStatus(this.assistantId, sessionId).then(state => {\n if (!current()) return;\n if (state.endReason) this.update({ endReason: state.endReason });\n if (state.restartRequested) void recover(); else void this.stop();\n }).catch(() => { if (current()) void this.stop(); });\n }\n if (event.type === 'error') { this.update({ error: new Error('Voice session failed.') }); void this.stop(); }\n } catch { /* Only lifecycle and spoken transcript events are accepted. */ }\n };\n channel.onclose = () => { if (current()) void recover(); };\n connectDeadline = setTimeout(() => {\n if (current()) { this.update({ error: new Error('Voice connection timed out.') }); void this.stop(); }\n }, 30000);\n await peer.setLocalDescription(await peer.createOffer());\n await new Promise<void>((resolve, reject) => {\n if (peer!.iceGatheringState === 'complete') return resolve();\n const done = () => {\n if (peer!.iceGatheringState !== 'complete') return;\n clearTimeout(timer); peer!.removeEventListener('icegatheringstatechange', done); resolve();\n };\n const timer = setTimeout(() => { peer!.removeEventListener('icegatheringstatechange', done); reject(new Error('Could not prepare the audio connection.')); }, 10000);\n peer!.addEventListener('icegatheringstatechange', done);\n });\n if (!current()) return;\n const result = await this.client.createLiveSession(this.assistantId, { ...this.context, chatUid, sdp: peer.localDescription!.sdp });\n sessionId = result.sessionId;\n if (!current()) { void this.client.closeLiveSession(this.assistantId, sessionId).catch(() => {}); return; }\n this.update({ sessionId, chatUid: result.chatUid, idleTimeoutSeconds: result.idleTimeoutSeconds || 0 }); this.created(result.chatUid);\n if (!current()) return;\n deadline = setTimeout(() => { void this.stop(); }, Math.max(1, Math.min(6000, result.maxDurationSeconds || 6000)) * 1000);\n await peer.setRemoteDescription({ type: 'answer', sdp: result.sdp });\n if (!current()) return;\n let busy = false;\n health = setInterval(async () => {\n if (!current() || busy) return;\n busy = true;\n try {\n const state = await this.client.getLiveSessionStatus(this.assistantId, sessionId!);\n if (!current()) return;\n healthFailures = 0;\n this.update({ seconds: state.seconds });\n // The server ends a silent call at idleTimeoutSeconds; warn for the\n // last 30 s (or half the window when it is short) so the person can\n // say \"I'm here\" instead of losing the call.\n const idle = this.snapshot.idleTimeoutSeconds || 0;\n if (idle > 0 && this.snapshot.state === 'connected') {\n const endsAt = this.lastActivity + idle * 1000;\n const warn = Date.now() >= endsAt - Math.min(30000, idle * 500);\n if (warn ? this.snapshot.idleEndsAt !== endsAt : !!this.snapshot.idleEndsAt) this.update({ idleEndsAt: warn ? endsAt : undefined });\n }\n if (state.interrupted || state.restartRequested || (connectionLostAt && Date.now() - connectionLostAt > 5000)) { void recover(); return; }\n if (state.status === 'closed') { void this.stop(); return; }\n backendReady = state.connected; ready();\n if (Date.now() - lastTranscript > 1500 && state.transcript?.length)\n this.update({ transcript: state.transcript.slice(-4).filter(t => t.role === 'user' || t.role === 'assistant').map(t => ({ role: t.role, text: t.text.slice(-2000) })) });\n } catch {\n if (current() && ++healthFailures >= 5) { this.update({ error: new Error('Voice status unavailable. Session stopped.')} ); void this.stop(); }\n } finally { busy = false; }\n }, 1000);\n } catch (error) {\n if (!current()) return;\n this.update({ error: error instanceof Error ? error : new Error(String(error)) });\n await this.stop();\n }\n }\n stop(): Promise<void> {\n if (this.closing) return this.closing;\n ++this.generation;\n this.disposeTransport();\n const id = this.snapshot.sessionId;\n this.update({ state: id ? 'closing' : (this.snapshot.error ? 'error' : 'idle') });\n this.closing = (async () => {\n if (id) {\n try { await this.client.closeLiveSession(this.assistantId, id); }\n catch (error) { this.update({ error: error as Error }); }\n }\n this.update({ state: this.snapshot.error ? 'error' : 'idle', sessionId: undefined });\n })().finally(() => { this.closing = undefined; });\n return this.closing;\n }\n dispose() { this.disposed = true; void this.stop(); }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LiveVoiceController.js","sources":["../../../src/voice/LiveVoiceController.ts"],"sourcesContent":["import type { DevicApiClient } from '../api/client';\nimport type { LiveVoiceContext, LiveVoiceTurn } from '../api/liveVoice.types';\n\nexport type LiveVoiceState = 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'closing' | 'error';\nexport interface LiveVoiceSnapshot {\n state: LiveVoiceState;\n chatUid?: string;\n sessionId?: string;\n muted: boolean;\n seconds: number;\n transcript: LiveVoiceTurn[];\n input?: MediaStream;\n output?: MediaStream;\n error?: Error;\n playbackBlocked?: boolean;\n /** Seconds of silence after which the server ends the call; 0 = never. */\n idleTimeoutSeconds?: number;\n /** Set while the call is about to end for silence: when it will, so a UI can count down. */\n idleEndsAt?: number;\n /** Why the server ended the last call, e.g. `idle`. */\n endReason?: string;\n}\nexport const initialVoiceSnapshot = (): LiveVoiceSnapshot => ({ state: 'idle', muted: false, seconds: 0, transcript: [] });\n\n/** No browser globals at import/constructor time; loaded only by start(). */\nexport class LiveVoiceController {\n private snapshot = initialVoiceSnapshot();\n private generation = 0;\n private attempts = 0;\n private disposeTransport: () => void = () => {};\n private audio?: HTMLAudioElement;\n private closing?: Promise<void>;\n private disposed = false;\n /** Last moment anyone spoke, or the person confirmed presence. */\n private lastActivity = 0;\n constructor(private client: DevicApiClient, private assistantId: string,\n private context: LiveVoiceContext, private changed: (value: LiveVoiceSnapshot) => void,\n private created: (chatUid: string) => void) {}\n\n private update(patch: Partial<LiveVoiceSnapshot>) {\n this.snapshot = { ...this.snapshot, ...patch };\n if (!this.disposed) this.changed(this.snapshot);\n }\n mute(muted: boolean) {\n this.snapshot.input?.getAudioTracks().forEach(track => { track.enabled = !muted && this.snapshot.state === 'connected'; });\n this.update({ muted });\n }\n async play() {\n try { await this.audio?.play(); this.update({ playbackBlocked: false }); }\n catch { this.update({ playbackBlocked: true }); }\n }\n /** The person is still there: restart the idle clock here and on the server. */\n stillHere() {\n this.lastActivity = Date.now();\n if (this.snapshot.idleEndsAt) this.update({ idleEndsAt: undefined });\n const id = this.snapshot.sessionId;\n if (id && this.snapshot.state === 'connected') void this.client.getLiveSessionStatus(this.assistantId, id, true).catch(() => {});\n }\n async start(chatUid?: string, recovering = false): Promise<void> {\n if (this.disposed || this.closing || (!recovering && !['idle', 'error'].includes(this.snapshot.state))) return;\n const generation = ++this.generation;\n const current = () => generation === this.generation && !this.disposed;\n if (!recovering) this.attempts = 0;\n this.update({ state: 'connecting', error: undefined, chatUid, sessionId: undefined,\n seconds: 0, idleEndsAt: undefined, endReason: undefined, ...(recovering ? {} : { transcript: [], muted: false }) });\n this.lastActivity = Date.now();\n let media: MediaStream | undefined;\n let peer: RTCPeerConnection | undefined;\n let channel: RTCDataChannel | undefined;\n let audio: HTMLAudioElement | undefined;\n let health: ReturnType<typeof setInterval> | undefined;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let connectDeadline: ReturnType<typeof setTimeout> | undefined;\n let backendReady = false;\n let lastTranscript = 0;\n let sessionId: string | undefined;\n let connectionLostAt = 0;\n let healthFailures = 0;\n let micCheck: ReturnType<typeof setInterval> | undefined;\n let micContext: AudioContext | undefined;\n let micAnalyser: AnalyserNode | undefined;\n let micQuiet = 0;\n const cleanup = () => {\n clearInterval(health); clearTimeout(deadline); clearTimeout(connectDeadline); clearInterval(micCheck);\n if (micContext) { try { void micContext.close().catch(() => {}); } catch { /* Already closed. */ } micContext = undefined; micAnalyser = undefined; }\n media?.getTracks().forEach(track => track.stop());\n if (channel) { channel.onclose = null; channel.onmessage = null; channel.close(); }\n if (peer) { peer.onconnectionstatechange = null; peer.ontrack = null; peer.close(); }\n if (audio) { audio.pause(); audio.srcObject = null; }\n this.audio = undefined;\n this.update({ input: undefined, output: undefined });\n };\n this.disposeTransport = cleanup;\n const ready = () => {\n if (!current() || !backendReady || peer?.connectionState !== 'connected') return;\n clearTimeout(connectDeadline);\n media?.getAudioTracks().forEach(track => { track.enabled = !this.snapshot.muted; });\n if (this.snapshot.state !== 'connected') { this.lastActivity = Date.now(); watchMicrophone(); }\n this.update({ state: 'connected' });\n };\n // A microphone that delivers nothing — ended track, system mute, or a\n // stream of exact digital silence — would otherwise keep a paid call open\n // with nobody able to speak. Analyse only; never route audio.\n const watchMicrophone = () => {\n if (micCheck) return;\n const track = media?.getAudioTracks()[0];\n if (!track) return;\n const samples = new Uint8Array(256);\n try {\n if (typeof AudioContext !== 'undefined') {\n micContext = new AudioContext(); micAnalyser = micContext.createAnalyser(); micAnalyser.fftSize = 256;\n micContext.createMediaStreamSource(media!).connect(micAnalyser); void micContext.resume().catch(() => {});\n }\n } catch { micAnalyser = undefined; }\n micCheck = setInterval(() => {\n if (!current() || this.snapshot.state !== 'connected') return;\n const fail = () => {\n this.update({ error: new Error('No microphone signal. Check your microphone and start again.') });\n void this.stop();\n };\n if (track.readyState === 'ended') { fail(); return; }\n if (this.snapshot.muted) { micQuiet = 0; return; }\n let silent = track.muted === true;\n if (micAnalyser && !silent) {\n try {\n micAnalyser.getByteTimeDomainData(samples);\n silent = samples.every(sample => sample === 128);\n } catch { silent = false; }\n }\n micQuiet = silent ? micQuiet + 1 : 0;\n if (micQuiet >= 15) fail();\n }, 1000);\n };\n const recover = async () => {\n if (!current()) return;\n ++this.generation;\n const ticket = this.generation;\n cleanup();\n this.update({ state: 'reconnecting' });\n try {\n if (!sessionId || ++this.attempts > 3) throw new Error('Voice connection interrupted. Please start again.');\n await this.client.closeLiveSession(this.assistantId, sessionId);\n // Never open another paid transport before the old one is confirmed closed.\n for (let i = 0; i < 35 && ticket === this.generation && !this.disposed; i++) {\n const state = await this.client.getLiveSessionStatus(this.assistantId, sessionId);\n if (state.status === 'closed') {\n if (state.endReason === 'tenant_limit_exceeded') {\n this.update({ state: 'idle', sessionId: undefined, endReason: state.endReason });\n return;\n }\n if (ticket === this.generation && !this.disposed) await this.start(this.snapshot.chatUid, true);\n return;\n }\n await new Promise(resolve => setTimeout(resolve, 2000));\n }\n if (ticket === this.generation) throw new Error('Could not confirm the previous voice session closed.');\n } catch (error) {\n if (ticket === this.generation) this.update({ state: 'error', error: error as Error });\n }\n };\n try {\n if (typeof navigator === 'undefined' || !navigator.mediaDevices?.getUserMedia || typeof RTCPeerConnection === 'undefined')\n throw new Error('Voice requires microphone access on HTTPS or localhost.');\n media = await navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true }, video: false });\n if (!current()) { media.getTracks().forEach(track => track.stop()); return; }\n media.getAudioTracks().forEach(track => { track.enabled = false; });\n this.update({ input: media });\n peer = new RTCPeerConnection({ bundlePolicy: 'max-bundle' });\n audio = new Audio(); this.audio = audio; audio.autoplay = true;\n peer.ontrack = event => {\n if (!current()) return;\n const output = new MediaStream([event.track]);\n audio!.srcObject = output;\n this.update({ output }); void this.play();\n };\n peer.onconnectionstatechange = () => {\n ready();\n if (peer?.connectionState === 'disconnected') connectionLostAt ||= Date.now();\n else connectionLostAt = 0;\n if (peer?.connectionState === 'failed') void recover();\n };\n media.getTracks().forEach(track => peer!.addTrack(track, media!));\n channel = peer.createDataChannel('oai-events');\n channel.onmessage = message => {\n if (!current()) return;\n try {\n const event = JSON.parse(message.data);\n if (event.type === 'session.started') { backendReady = true; ready(); }\n if (['session.input_transcript.delta', 'session.output_transcript.delta'].includes(event.type) && typeof event.delta === 'string') {\n lastTranscript = Date.now(); this.lastActivity = lastTranscript;\n if (this.snapshot.idleEndsAt) this.update({ idleEndsAt: undefined });\n const role = event.type === 'session.input_transcript.delta' ? 'user' : 'assistant';\n const turns = this.snapshot.transcript.slice(-3).map(turn => ({ ...turn }));\n if (turns[turns.length - 1]?.role === role) turns[turns.length - 1].text = (turns[turns.length - 1].text + event.delta).slice(-2000);\n else turns.push({ role, text: event.delta.slice(-2000) });\n this.update({ transcript: turns });\n }\n if (event.type === 'session.closed' && sessionId) {\n void this.client.getLiveSessionStatus(this.assistantId, sessionId).then(state => {\n if (!current()) return;\n if (state.endReason) this.update({ endReason: state.endReason });\n if (state.restartRequested) void recover(); else void this.stop();\n }).catch(() => { if (current()) void this.stop(); });\n }\n if (event.type === 'error') { this.update({ error: new Error('Voice session failed.') }); void this.stop(); }\n } catch { /* Only lifecycle and spoken transcript events are accepted. */ }\n };\n channel.onclose = () => { if (current()) void recover(); };\n connectDeadline = setTimeout(() => {\n if (current()) { this.update({ error: new Error('Voice connection timed out.') }); void this.stop(); }\n }, 30000);\n await peer.setLocalDescription(await peer.createOffer());\n await new Promise<void>((resolve, reject) => {\n if (peer!.iceGatheringState === 'complete') return resolve();\n const done = () => {\n if (peer!.iceGatheringState !== 'complete') return;\n clearTimeout(timer); peer!.removeEventListener('icegatheringstatechange', done); resolve();\n };\n const timer = setTimeout(() => { peer!.removeEventListener('icegatheringstatechange', done); reject(new Error('Could not prepare the audio connection.')); }, 10000);\n peer!.addEventListener('icegatheringstatechange', done);\n });\n if (!current()) return;\n const result = await this.client.createLiveSession(this.assistantId, { ...this.context, chatUid, sdp: peer.localDescription!.sdp });\n sessionId = result.sessionId;\n if (!current()) { void this.client.closeLiveSession(this.assistantId, sessionId).catch(() => {}); return; }\n this.update({ sessionId, chatUid: result.chatUid, idleTimeoutSeconds: result.idleTimeoutSeconds || 0 }); this.created(result.chatUid);\n if (!current()) return;\n deadline = setTimeout(() => { void this.stop(); }, Math.max(1, Math.min(6000, result.maxDurationSeconds || 6000)) * 1000);\n await peer.setRemoteDescription({ type: 'answer', sdp: result.sdp });\n if (!current()) return;\n let busy = false;\n health = setInterval(async () => {\n if (!current() || busy) return;\n busy = true;\n try {\n const state = await this.client.getLiveSessionStatus(this.assistantId, sessionId!);\n if (!current()) return;\n healthFailures = 0;\n this.update({ seconds: state.seconds });\n // The server ends a silent call at idleTimeoutSeconds; warn for the\n // last 30 s (or half the window when it is short) so the person can\n // say \"I'm here\" instead of losing the call.\n const idle = this.snapshot.idleTimeoutSeconds || 0;\n if (idle > 0 && this.snapshot.state === 'connected') {\n const endsAt = this.lastActivity + idle * 1000;\n const warn = Date.now() >= endsAt - Math.min(30000, idle * 500);\n if (warn ? this.snapshot.idleEndsAt !== endsAt : !!this.snapshot.idleEndsAt) this.update({ idleEndsAt: warn ? endsAt : undefined });\n }\n if (state.endReason === 'tenant_limit_exceeded') {\n this.update({ endReason: state.endReason }); void this.stop(); return;\n }\n if (state.interrupted || state.restartRequested || (connectionLostAt && Date.now() - connectionLostAt > 5000)) { void recover(); return; }\n if (state.status === 'closed') { void this.stop(); return; }\n backendReady = state.connected; ready();\n if (Date.now() - lastTranscript > 1500 && state.transcript?.length)\n this.update({ transcript: state.transcript.slice(-4).filter(t => t.role === 'user' || t.role === 'assistant').map(t => ({ role: t.role, text: t.text.slice(-2000) })) });\n } catch {\n if (current() && ++healthFailures >= 5) { this.update({ error: new Error('Voice status unavailable. Session stopped.')} ); void this.stop(); }\n } finally { busy = false; }\n }, 1000);\n } catch (error) {\n if (!current()) return;\n this.update({ error: error instanceof Error ? error : new Error(String(error)) });\n await this.stop();\n }\n }\n stop(): Promise<void> {\n if (this.closing) return this.closing;\n ++this.generation;\n this.disposeTransport();\n const id = this.snapshot.sessionId;\n this.update({ state: id ? 'closing' : (this.snapshot.error ? 'error' : 'idle') });\n this.closing = (async () => {\n if (id) {\n try { await this.client.closeLiveSession(this.assistantId, id); }\n catch (error) { this.update({ error: error as Error }); }\n }\n this.update({ state: this.snapshot.error ? 'error' : 'idle', sessionId: undefined });\n })().finally(() => { this.closing = undefined; });\n return this.closing;\n }\n dispose() { this.disposed = true; void this.stop(); }\n}\n"],"names":[],"mappings":"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"}
|