@runtypelabs/persona 4.25.0 → 4.26.0
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/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-Db61aI9J.d.cts → types-BwKTZhg9.d.cts} +14 -0
- package/dist/animations/{types-Db61aI9J.d.ts → types-BwKTZhg9.d.ts} +14 -0
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/animations-extra.d.cts +14 -0
- package/dist/animations-extra.d.ts +14 -0
- package/dist/approval-ui-QAKWNFNM.js +1 -0
- package/dist/approval-ui.cjs +2 -2
- package/dist/approval-ui.d.cts +180 -8
- package/dist/approval-ui.d.ts +180 -8
- package/dist/approval-ui.js +2 -2
- package/dist/{artifacts-ui-IGB5YKLO.js → artifacts-ui-NJGMM27I.js} +1 -1
- package/dist/artifacts-ui.cjs +4 -4
- package/dist/artifacts-ui.d.cts +180 -8
- package/dist/artifacts-ui.d.ts +180 -8
- package/dist/artifacts-ui.js +5 -5
- package/dist/chunk-2ANTRKTV.js +1 -0
- package/dist/chunk-4HPTPUC6.js +1 -0
- package/dist/chunk-6V3MNEKB.js +1 -0
- package/dist/chunk-HGUCGM3K.js +9 -0
- package/dist/chunk-IO5VVUKP.js +3 -0
- package/dist/chunk-J4J3Y2P2.js +1 -0
- package/dist/chunk-K6HKIP5K.js +1 -0
- package/dist/chunk-K7NA7G7J.js +1 -0
- package/dist/chunk-MXUTS3LB.js +1 -0
- package/dist/chunk-PDPVORUF.js +1 -0
- package/dist/chunk-QPPJUSZH.js +1 -0
- package/dist/chunk-QRKGQPU7.js +1 -0
- package/dist/chunk-S6PBWE75.js +1 -0
- package/dist/chunk-T7QM7YMF.js +1 -0
- package/dist/chunk-TR2H475E.js +1 -0
- package/dist/chunk-UPO4GUFC.js +1 -0
- package/dist/chunk-ZC66NAIR.js +1 -0
- package/dist/client-history-YPEG45Q4.js +1 -0
- package/dist/client-history.js +1 -0
- package/dist/client-stream-42FOI3EC.js +4 -0
- package/dist/client-stream.js +5 -0
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.js +1 -1
- package/dist/context-mentions-E7HJYWO6.js +161 -0
- package/dist/{context-mentions-inline-I2RDEBAK.js → context-mentions-inline-QVESLW55.js} +1 -1
- package/dist/context-mentions.cjs +7 -7
- package/dist/context-mentions.d.cts +180 -8
- package/dist/context-mentions.d.ts +180 -8
- package/dist/context-mentions.js +8 -8
- package/dist/event-stream-view-FOIJHFQO.js +1 -0
- package/dist/event-stream-view.cjs +1 -1
- package/dist/event-stream-view.d.cts +183 -31
- package/dist/event-stream-view.d.ts +183 -31
- package/dist/event-stream-view.js +1 -1
- package/dist/forms-ui.d.cts +221 -667
- package/dist/forms-ui.d.ts +221 -667
- package/dist/history-shell-QDQ44PSE.js +3 -0
- package/dist/history-shell.js +3 -0
- package/dist/{history-view-BD6OXLNA.js → history-view-NCFBI5GR.js} +2 -2
- package/dist/history-view.cjs +2 -2
- package/dist/history-view.d.cts +35 -1
- package/dist/history-view.d.ts +35 -1
- package/dist/history-view.js +2 -2
- package/dist/index.cjs +80 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +227 -738
- package/dist/index.d.ts +227 -738
- package/dist/index.global.js +3 -215
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +81 -75
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/launcher.global.js +3 -67
- package/dist/launcher.global.js.map +1 -1
- package/dist/markdown-parsers.js +22 -22
- package/dist/runtype-tts-entry-NFBVWR7N.js +1 -0
- package/dist/runtype-tts.js +1 -1
- package/dist/session-actions-ISSKSI66.js +1 -0
- package/dist/session-actions.js +1 -0
- package/dist/session-reconnect.d.cts +180 -8
- package/dist/session-reconnect.d.ts +180 -8
- package/dist/smart-dom-reader.cjs +13 -13
- package/dist/smart-dom-reader.d.cts +180 -8
- package/dist/smart-dom-reader.d.ts +180 -8
- package/dist/smart-dom-reader.js +11 -11
- package/dist/theme-editor-preview.cjs +116 -98
- package/dist/theme-editor-preview.d.cts +182 -8
- package/dist/theme-editor-preview.d.ts +182 -8
- package/dist/theme-editor-preview.js +49 -54
- package/dist/theme-editor.cjs +2 -2
- package/dist/theme-editor.d.cts +181 -23
- package/dist/theme-editor.d.ts +181 -23
- package/dist/theme-editor.js +2 -2
- package/dist/theme-reference.d.cts +14 -0
- package/dist/theme-reference.d.ts +14 -0
- package/dist/ui-extras-entry-WAYFKVNW.js +3 -0
- package/dist/ui-extras.js +72 -0
- package/dist/voice-runtime-UOQOFAFY.js +17 -0
- package/dist/voice-runtime.cjs +17 -1
- package/dist/voice-runtime.d.cts +11650 -232
- package/dist/voice-runtime.d.ts +11650 -232
- package/dist/voice-runtime.js +17 -1
- package/dist/voice-worklet-player.cjs +19 -4
- package/dist/voice-worklet-player.d.cts +9 -10
- package/dist/voice-worklet-player.d.ts +9 -10
- package/dist/voice-worklet-player.js +19 -4
- package/dist/webmcp-polyfill.js +1 -1
- package/dist/webmcp-runtime-V6ZWW3PI.js +6 -0
- package/dist/webmcp-runtime.cjs +2 -2
- package/dist/webmcp-runtime.d.cts +1 -33
- package/dist/webmcp-runtime.d.ts +1 -33
- package/dist/webmcp-runtime.js +2 -2
- package/dist/widget.css +1 -1
- package/package.json +11 -5
- package/src/approval-paused-tool-settle.test.ts +221 -0
- package/src/client-approve.test.ts +311 -0
- package/src/client-history-eager.ts +9 -0
- package/src/client-history-loader.ts +23 -0
- package/src/client-history.ts +579 -0
- package/src/client-resume.ts +177 -0
- package/src/client-stream-eager.ts +12 -0
- package/src/client-stream-loader.ts +25 -0
- package/src/client-stream.ts +1880 -0
- package/src/client.test.ts +31 -1
- package/src/client.ts +293 -2607
- package/src/components/approval-actions.test.ts +27 -0
- package/src/components/approval-actions.ts +27 -3
- package/src/components/message-bubble.test.ts +19 -0
- package/src/components/message-bubble.ts +2 -0
- package/src/components/registry.ts +6 -6
- package/src/components/tool-bubble.test.ts +9 -0
- package/src/components/tool-bubble.ts +1 -0
- package/src/history-shell-bundle.test.ts +54 -0
- package/src/history-shell-eager.ts +12 -0
- package/src/history-shell-loader.ts +27 -0
- package/src/history-shell.ts +2362 -0
- package/src/history-view-loader.ts +2 -0
- package/src/history-view.ts +3 -0
- package/src/index-core.ts +6 -0
- package/src/index-global.ts +90 -248
- package/src/index.ts +13 -0
- package/src/install.ts +6 -4
- package/src/internal/runtype-history-provider.test.ts +1 -0
- package/src/internal/runtype-history-provider.ts +28 -13
- package/src/plugins/registry.ts +8 -8
- package/src/session-actions-chunk.test.ts +55 -0
- package/src/session-actions-eager.ts +11 -0
- package/src/session-actions-loader.ts +37 -0
- package/src/session-actions.ts +909 -0
- package/src/session-history.test.ts +3 -1
- package/src/session.ts +852 -1536
- package/src/session.voice.test.ts +1170 -5
- package/src/styles/widget.css +58 -0
- package/src/theme-editor/state.ts +91 -91
- package/src/types.ts +198 -5
- package/src/ui-ask-user-sheet.ts +382 -0
- package/src/ui-extras-eager.ts +10 -0
- package/src/ui-extras-entry.ts +9 -0
- package/src/ui-extras-loader.ts +26 -0
- package/src/ui.artifact-rail-resize.test.ts +2 -1
- package/src/ui.ask-user-chunk.test.ts +93 -0
- package/src/ui.history-chunk.test.ts +2 -1
- package/src/ui.history-config-provider.test.ts +2 -1
- package/src/ui.history-confirm-fallback.test.ts +142 -0
- package/src/ui.history-controller.test.ts +2 -1
- package/src/ui.history-lifecycle.test.ts +2 -1
- package/src/ui.history-render-hooks.test.ts +2 -1
- package/src/ui.history-shell.test.ts +2 -1
- package/src/ui.rail-overlay.test.ts +2 -1
- package/src/ui.rail-resize.test.ts +2 -1
- package/src/ui.rail-trigger-pending.test.ts +2 -1
- package/src/ui.ts +340 -2770
- package/src/utils/attachment-manager.ts +67 -67
- package/src/utils/constants.ts +3 -0
- package/src/utils/context-mention-controller.ts +323 -323
- package/src/utils/context-mention-manager.ts +40 -40
- package/src/utils/context-mention-orchestrator.ts +28 -0
- package/src/utils/event-stream-buffer.ts +50 -50
- package/src/utils/event-stream-store.ts +43 -43
- package/src/utils/throughput-tracker.ts +34 -34
- package/src/utils/virtual-scroller.ts +67 -67
- package/src/utils/visitor-store.test.ts +50 -0
- package/src/utils/visitor-store.ts +23 -5
- package/src/voice/__fixtures__/voice-wire/README.md +1 -0
- package/src/voice/__fixtures__/voice-wire/client/cancel.json +3 -0
- package/src/voice/__fixtures__/voice-wire/client/context.json +4 -0
- package/src/voice/__fixtures__/voice-wire/client/delegation_result.json +6 -0
- package/src/voice/__fixtures__/voice-wire/client/delegation_update.json +6 -0
- package/src/voice/__fixtures__/voice-wire/client/ping.json +3 -0
- package/src/voice/__fixtures__/voice-wire/client/playback_progress.json +5 -0
- package/src/voice/__fixtures__/voice-wire/client/start.json +3 -0
- package/src/voice/__fixtures__/voice-wire/server/artifact.json +11 -0
- package/src/voice/__fixtures__/voice-wire/server/attached.json +4 -0
- package/src/voice/__fixtures__/voice-wire/server/audio_clear.json +4 -0
- package/src/voice/__fixtures__/voice-wire/server/audio_end.json +3 -0
- package/src/voice/__fixtures__/voice-wire/server/delegation_cancelled.json +5 -0
- package/src/voice/__fixtures__/voice-wire/server/delegation_completed.json +8 -0
- package/src/voice/__fixtures__/voice-wire/server/delegation_started.json +15 -0
- package/src/voice/__fixtures__/voice-wire/server/error.json +6 -0
- package/src/voice/__fixtures__/voice-wire/server/metrics.json +10 -0
- package/src/voice/__fixtures__/voice-wire/server/pong.json +3 -0
- package/src/voice/__fixtures__/voice-wire/server/session_config.json +16 -0
- package/src/voice/__fixtures__/voice-wire/server/transcript_final.json +7 -0
- package/src/voice/__fixtures__/voice-wire/server/transcript_interim.json +4 -0
- package/src/voice/__fixtures__/voice-wire/server/transcript_partial.json +6 -0
- package/src/voice/__fixtures__/voice-wire/server/transcript_update.json +10 -0
- package/src/voice/__fixtures__/voice-wire/server/warning.json +5 -0
- package/src/voice/audio-playback-manager.test.ts +57 -0
- package/src/voice/audio-playback-manager.ts +120 -98
- package/src/voice/browser-voice-provider.ts +37 -37
- package/src/voice/fallback-speech-engine.ts +22 -16
- package/src/voice/keyed-voice-transcript.ts +314 -0
- package/src/voice/mic-state-styles.ts +182 -0
- package/src/voice/read-aloud-controller.ts +46 -44
- package/src/voice/runtype-speech-engine.ts +35 -33
- package/src/voice/runtype-voice-provider.ts +670 -189
- package/src/voice/session-voice-wiring.ts +266 -0
- package/src/voice/voice-delegation.test.ts +71 -0
- package/src/voice/voice-delegation.ts +364 -0
- package/src/voice/voice-turn-tracker.ts +6 -6
- package/src/voice/voice.test.ts +981 -8
- package/src/voice/worklet-playback-engine.test.ts +81 -0
- package/src/voice/worklet-playback-engine.ts +21 -3
- package/src/voice-runtime-loader.ts +4 -1
- package/src/voice-runtime.ts +7 -0
- package/src/webmcp-runtime-entry.ts +41 -39
- package/dist/approval-ui-3NMYNXBD.js +0 -1
- package/dist/chunk-5EIIHQLQ.js +0 -1
- package/dist/chunk-7CO4T5KB.js +0 -1
- package/dist/chunk-EFJBUH5F.js +0 -1
- package/dist/chunk-R2TMIMDI.js +0 -3
- package/dist/chunk-UTVLOTWB.js +0 -9
- package/dist/context-mentions-45MODWOY.js +0 -161
- package/dist/event-stream-view-GL3ADRY2.js +0 -1
- package/dist/runtype-tts-entry-UJAEF7NZ.js +0 -1
- package/dist/voice-runtime-7DA7MJH4.js +0 -1
- package/dist/webmcp-runtime-JI7T4QYF.js +0 -6
package/dist/voice-runtime.js
CHANGED
|
@@ -1 +1,17 @@
|
|
|
1
|
-
var m=class{constructor(t=24e3,e={}){this.ctx=null;this.nextStartTime=0;this.activeSources=[];this.finishedCallbacks=[];this.startedCallbacks=[];this.playing=!1;this.streamEnded=!1;this.pendingCount=0;this.started=!1;this.userPaused=!1;this.pendingBuffers=[];this.pendingSamples=0;this.remainder=null;this.sampleRate=t;let i=Math.max(0,e.prebufferMs??0);this.waterlineSamples=Math.round(t*i/1e3),this.buffering=this.waterlineSamples>0}ensureContext(){if(!this.ctx){let e=typeof window<"u"?window:void 0;if(!e)throw new Error("AudioPlaybackManager requires a browser environment");let i=e.AudioContext||e.webkitAudioContext;this.ctx=new i({sampleRate:this.sampleRate})}let t=this.ctx;return t.state==="suspended"&&!this.userPaused&&t.resume(),t}enqueue(t){if(t.length===0)return;let e=t;if(this.remainder){let s=new Uint8Array(this.remainder.length+t.length);s.set(this.remainder),s.set(t,this.remainder.length),e=s,this.remainder=null}if(e.length%2!==0&&(this.remainder=new Uint8Array([e[e.length-1]]),e=e.subarray(0,e.length-1)),e.length===0)return;let i=this.pcmToFloat32(e);i.length!==0&&(this.buffering?(this.pendingBuffers.push(i),this.pendingSamples+=i.length,this.pendingSamples>=this.waterlineSamples&&this.releaseBuffer()):this.scheduleSamples(i))}markStreamEnd(){this.pendingBuffers.length>0&&this.releaseBuffer(),this.streamEnded=!0,this.checkFinished()}flush(){for(let t of this.activeSources)try{t.stop(),t.disconnect()}catch{}this.activeSources=[],this.pendingCount=0,this.nextStartTime=0,this.playing=!1,this.streamEnded=!1,this.finishedCallbacks=[],this.startedCallbacks=[],this.remainder=null,this.pendingBuffers=[],this.pendingSamples=0,this.buffering=this.waterlineSamples>0,this.started=!1}isPlaying(){return this.playing}onFinished(t){this.finishedCallbacks.push(t)}onStarted(t){this.startedCallbacks.push(t)}pause(){this.userPaused=!0,this.ctx&&this.ctx.state==="running"&&this.ctx.suspend()}resume(){this.userPaused=!1,this.ctx&&this.ctx.state==="suspended"&&this.ctx.resume()}async destroy(){this.flush(),this.ctx&&(await this.ctx.close(),this.ctx=null)}releaseBuffer(){this.buffering=!1;let t=this.pendingBuffers;this.pendingBuffers=[],this.pendingSamples=0;for(let e of t)this.scheduleSamples(e)}scheduleSamples(t){if(t.length===0)return;let e=this.ensureContext(),i=e.createBuffer(1,t.length,this.sampleRate);i.getChannelData(0).set(t);let s=e.createBufferSource();s.buffer=i,s.connect(e.destination);let n=e.currentTime;if(this.nextStartTime===0?this.nextStartTime=n:this.nextStartTime<n&&(this.nextStartTime=n,this.waterlineSamples>0&&(this.buffering=!0)),s.start(this.nextStartTime),this.nextStartTime+=i.duration,this.activeSources.push(s),this.pendingCount++,this.playing=!0,!this.started){this.started=!0;let l=this.startedCallbacks.slice();this.startedCallbacks=[];for(let c of l)c()}s.onended=()=>{let l=this.activeSources.indexOf(s);l!==-1&&this.activeSources.splice(l,1),this.pendingCount--,this.checkFinished()}}checkFinished(){if(this.streamEnded&&this.pendingCount<=0&&this.pendingBuffers.length===0){this.playing=!1,this.streamEnded=!1;let t=this.finishedCallbacks.slice();this.finishedCallbacks=[];for(let e of t)e()}}pcmToFloat32(t){let e=Math.floor(t.length/2),i=new Float32Array(e),s=new DataView(t.buffer,t.byteOffset,t.byteLength);for(let n=0;n<e;n++){let l=s.getInt16(n*2,!0);i[n]=l/32768}return i}};var g=16e3,S=24e3,k=4096,C=4,E=1380533830,A=3e4,x=5e3,P=3e4,T=3e4,M=6e5;function V(r){return r.byteLength>=44&&new DataView(r).getUint32(0,!1)===E?new Uint8Array(r,44):new Uint8Array(r)}function b(r){let t=r.replace(/\/+$/,"");return/^wss?:\/\//i.test(t)?t:/^https?:\/\//i.test(t)?t.replace(/^http/i,"ws"):`${typeof window<"u"&&window.location?.protocol==="https:"?"wss:":"ws:"}//${t}`}function R(r){return b(r).replace(/^ws/i,"http")}function _(r){return typeof r!="number"||!Number.isFinite(r)?P:Math.min(M,Math.max(T,Math.round(r)))}var f=class{constructor(t){this.config=t;this.type="runtype";this.ws=null;this.captureContext=null;this.levelCallbacks=[];this.mediaStream=null;this.sourceNode=null;this.processor=null;this.playback=null;this.callLive=!1;this.isSpeaking=!1;this.callGeneration=0;this.intentionalClose=!1;this.lastPrewarmAt=Number.NEGATIVE_INFINITY;this.attached=null;this.resultCallbacks=[];this.errorCallbacks=[];this.statusCallbacks=[];this.transcriptCallbacks=[];this.metricsCallbacks=[]}async connect(){}prewarm(){if(this.callLive||this.attached)return;let t=this.config?.agentId,e=this.config?.clientToken,i=this.config?.host;if(!t||!e||!i)return;let s=Date.now();if(!(s-this.lastPrewarmAt<A)){this.lastPrewarmAt=s;try{this.config?.prewarmMode==="attach"?this.attach(i,t,e):this.requestPrewarm(i,t,e)}catch{}}}requestPrewarm(t,e,i){if(typeof fetch!="function")return;let s=`${R(t)}/v1/client/agents/${encodeURIComponent(e)}/voice/prewarm`;fetch(s,{method:"POST",headers:{Authorization:`Bearer ${i}`},keepalive:!0}).catch(()=>{})}attach(t,e,i){let s=new URLSearchParams({clientCapabilities:"attach"}),n=this.config?.attachIdleMs,l=_(n);n!==void 0&&s.set("attachIdleMs",String(l));let c=new WebSocket(`${this.voiceSocketUrl(t,e)}?${s}`,["runtype.bearer","runtype.attach",i]);c.binaryType="arraybuffer";let u=()=>{},d=new Promise(o=>{u=o}),a={ws:c,state:"connecting",ready:d,settle:u,openedAt:0,idleTimer:void 0};this.attached=a,c.onopen=()=>{this.attached===a&&(a.state=c.protocol==="runtype.attach"?"attached":"live",a.openedAt=Date.now(),this.armAttachIdle(a,l),a.state==="attached"&&c.send('{"type":"ping"}'),a.settle())},c.onmessage=o=>{if(this.attached!==a||typeof o.data!="string")return;let h;try{h=JSON.parse(o.data)}catch{return}h.type==="attached"&&typeof h.idleMs=="number"&&this.armAttachIdle(a,h.idleMs-(Date.now()-a.openedAt))},c.onerror=()=>{},c.onclose=()=>{this.attached===a&&this.releaseAttached()}}armAttachIdle(t,e){clearTimeout(t.idleTimer),t.idleTimer=setTimeout(()=>{this.attached===t&&this.releaseAttached()},Math.max(0,e))}releaseAttached(){let t=this.attached;if(!t)return;this.attached=null,clearTimeout(t.idleTimer);let{ws:e}=t;if(e.onopen=null,e.onmessage=null,e.onerror=null,e.onclose=null,t.settle(),e.readyState===WebSocket.CONNECTING||e.readyState===WebSocket.OPEN)try{e.close(1e3,"prewarm released")}catch{}}async takeAttachedSocket(){let t=this.attached;if(!t)return null;if(t.state==="connecting"){let e;await Promise.race([t.ready,new Promise(i=>{e=setTimeout(i,x)})]),clearTimeout(e)}return this.attached!==t?null:t.state==="connecting"||t.ws.readyState!==WebSocket.OPEN?(this.releaseAttached(),null):(this.attached=null,clearTimeout(t.idleTimer),{ws:t.ws,live:t.state==="live"})}voiceSocketUrl(t,e){return`${b(t)}/ws/agents/${encodeURIComponent(e)}/voice`}async startListening(){if(this.callLive)return;let t=this.config?.agentId,e=this.config?.clientToken,i=this.config?.host;if(!t)throw new Error("Runtype voice requires an agentId");if(!e)throw new Error("Runtype voice requires a clientToken");if(!i)throw new Error("Runtype voice requires a host (or widget apiUrl)");let s=++this.callGeneration;this.intentionalClose=!1,this.callLive=!0;try{let n=await navigator.mediaDevices.getUserMedia({audio:{sampleRate:g,channelCount:1,echoCancellation:!0}});if(s!==this.callGeneration){n.getTracks().forEach(o=>o.stop());return}this.mediaStream=n;let l=window.AudioContext||window.webkitAudioContext,c=new l({sampleRate:g});c.state==="suspended"&&await c.resume().catch(()=>{}),this.captureContext=c;let u=this.config?.createPlaybackEngine?await this.config.createPlaybackEngine():new m(S);if(s!==this.callGeneration){u.destroy(),n.getTracks().forEach(o=>o.stop()),c.close().catch(()=>{});return}this.playback=u,u.onFinished(()=>{s===this.callGeneration&&(this.isSpeaking=!1,this.ws&&this.ws.readyState===WebSocket.OPEN&&this.emitStatus("listening"))});let d=await this.takeAttachedSocket();if(s!==this.callGeneration){d?.ws.close(1e3,"client ended call");return}if(d){let{ws:o}=d;this.ws=o,this.bindCallSocket(o,s),d.live||o.send('{"type":"start"}'),this.emitStatus("listening"),this.startCapture(c,n,o,s);return}let a=new WebSocket(this.voiceSocketUrl(i,t),["runtype.bearer",e]);a.binaryType="arraybuffer",this.ws=a,a.onopen=()=>{s===this.callGeneration&&(this.emitStatus("listening"),this.startCapture(c,n,a,s))},this.bindCallSocket(a,s)}catch(n){throw this.cleanup(),this.emitError(n),this.emitStatus("error"),n}}bindCallSocket(t,e){t.onmessage=i=>this.handleMessage(i,e),t.onerror=()=>{e===this.callGeneration&&(this.emitError(new Error("Voice connection failed")),this.emitStatus("error"),this.cleanup())},t.onclose=i=>{if(this.intentionalClose){this.intentionalClose=!1;return}if(e===this.callGeneration){if(i.code!==1e3){let s=i.code?` (code ${i.code})`:"";this.emitError(new Error(`Voice connection closed${s}`)),this.emitStatus("error")}else this.emitStatus("idle");this.cleanup()}}}async stopListening(){this.cleanup(),this.emitStatus("idle")}async disconnect(){this.cleanup(),this.emitStatus("disconnected"),this.resultCallbacks=[],this.errorCallbacks=[],this.statusCallbacks=[],this.transcriptCallbacks=[],this.metricsCallbacks=[]}stopPlayback(){this.playback&&this.playback.flush(),this.isSpeaking=!1,this.ws&&this.ws.readyState===WebSocket.OPEN&&this.emitStatus("listening")}getInterruptionMode(){return"barge-in"}isBargeInActive(){return this.callLive}onLevel(t){this.levelCallbacks.push(t)}async deactivateBargeIn(){this.cleanup(),this.emitStatus("idle")}startCapture(t,e,i,s){let n=t.createMediaStreamSource(e);this.sourceNode=n;let l=t.createScriptProcessor(k,1,1);this.processor=l,l.onaudioprocess=c=>{if(s!==this.callGeneration||i.readyState!==WebSocket.OPEN)return;let u=c.inputBuffer.getChannelData(0),d=new Int16Array(u.length),a=0;for(let o=0;o<u.length;o++){let h=Math.max(-1,Math.min(1,u[o]));a+=h*h,d[o]=h<0?h*32768:h*32767}if(i.send(d.buffer),this.levelCallbacks.length>0){let o=Math.sqrt(a/u.length),h=Math.max(0,Math.min(1,o*C));for(let w of this.levelCallbacks)w(h)}},n.connect(l),l.connect(t.destination)}handleMessage(t,e){if(e!==this.callGeneration)return;if(t.data instanceof ArrayBuffer){this.handleAudioFrame(t.data,e);return}let i;try{i=JSON.parse(t.data)}catch{return}switch(i.type){case"transcript_interim":this.emitStatus("listening"),this.emitTranscript("user",i.text??"",!1);break;case"transcript_final":{let s=i.role==="assistant"?"assistant":"user";this.emitStatus(s==="user"?"processing":"speaking"),this.emitTranscript(s,i.text??"",!0);break}case"audio_end":this.playback?this.playback.markStreamEnd():(this.isSpeaking=!1,this.emitStatus("listening"));break;case"metrics":this.emitMetrics({llmMs:i.llm_ms,ttsMs:i.tts_ms,firstAudioMs:i.first_audio_ms,totalMs:i.total_ms});break;case"error":this.emitError(new Error(i.error||"Voice error")),this.emitStatus("error");break}}handleAudioFrame(t,e){if(e!==this.callGeneration||!this.playback)return;let i=V(t);i.length!==0&&(this.isSpeaking||(this.isSpeaking=!0,this.emitStatus("speaking")),this.playback.enqueue(i))}cleanup(){if(this.callGeneration+=1,this.callLive=!1,this.isSpeaking=!1,this.releaseAttached(),this.processor&&(this.processor.onaudioprocess=null,this.processor.disconnect(),this.processor=null),this.sourceNode&&(this.sourceNode.disconnect(),this.sourceNode=null),this.mediaStream&&(this.mediaStream.getTracks().forEach(t=>t.stop()),this.mediaStream=null),this.captureContext&&(this.captureContext.close().catch(()=>{}),this.captureContext=null),this.playback&&(this.playback.destroy(),this.playback=null),this.ws){this.intentionalClose=!0;try{this.ws.close(1e3,"client ended call")}catch{}this.ws=null}}onResult(t){this.resultCallbacks.push(t)}onError(t){this.errorCallbacks.push(t)}onStatusChange(t){this.statusCallbacks.push(t)}onTranscript(t){this.transcriptCallbacks.push(t)}onMetrics(t){this.metricsCallbacks.push(t)}emitStatus(t){this.statusCallbacks.forEach(e=>e(t))}emitError(t){this.errorCallbacks.forEach(e=>e(t))}emitTranscript(t,e,i){this.transcriptCallbacks.forEach(s=>s(t,e,i))}emitMetrics(t){this.metricsCallbacks.forEach(e=>e(t))}};var p=class{constructor(t={}){this.config=t;this.type="browser";this.recognition=null;this.resultCallbacks=[];this.errorCallbacks=[];this.statusCallbacks=[];this.isListening=!1;this.w=typeof window<"u"?window:void 0}async connect(){this.statusCallbacks.forEach(t=>t("connected"))}async startListening(){try{if(this.isListening)throw new Error("Already listening");if(!this.w)throw new Error("Window object not available");let t=this.w.SpeechRecognition||this.w.webkitSpeechRecognition;if(!t)throw new Error("Browser speech recognition not supported");this.recognition=new t,this.recognition.lang=this.config?.language||"en-US",this.recognition.continuous=this.config?.continuous||!1,this.recognition.interimResults=!0,this.recognition.onresult=e=>{let i=Array.from(e.results).map(n=>n[0]).map(n=>n.transcript).join(""),s=e.results[e.results.length-1].isFinal;this.resultCallbacks.forEach(n=>n({text:i,confidence:s?.8:.5,provider:"browser"})),s&&!this.config?.continuous&&this.stopListening()},this.recognition.onerror=e=>{this.errorCallbacks.forEach(i=>i(new Error(e.error))),this.statusCallbacks.forEach(i=>i("error"))},this.recognition.onstart=()=>{this.isListening=!0,this.statusCallbacks.forEach(e=>e("listening"))},this.recognition.onend=()=>{this.isListening=!1,this.statusCallbacks.forEach(e=>e("idle"))},this.recognition.start()}catch(t){throw this.errorCallbacks.forEach(e=>e(t)),this.statusCallbacks.forEach(e=>e("error")),t}}async stopListening(){this.recognition&&(this.recognition.stop(),this.recognition=null),this.isListening=!1,this.statusCallbacks.forEach(t=>t("idle"))}onResult(t){this.resultCallbacks.push(t)}onError(t){this.errorCallbacks.push(t)}onStatusChange(t){this.statusCallbacks.push(t)}async disconnect(){await this.stopListening(),this.statusCallbacks.forEach(t=>t("disconnected"))}static isSupported(){return"SpeechRecognition"in window||"webkitSpeechRecognition"in window}};function v(r){switch(r.type){case"runtype":if(!r.runtype)throw new Error("Runtype voice provider requires configuration");return new f(r.runtype);case"browser":if(!p.isSupported())throw new Error("Browser speech recognition not supported");return new p(r.browser||{});case"custom":{let t=r.custom;if(!t)throw new Error("Custom voice provider requires a `custom` provider instance or factory");let e=typeof t=="function"?t():t;if(!e||typeof e.startListening!="function")throw new Error("Custom voice provider `custom` must be a VoiceProvider (or a factory returning one)");return e}default:throw new Error(`Unknown voice provider type: ${r.type}`)}}function y(r){if(r?.type==="custom"&&r.custom)return v({type:"custom",custom:r.custom});if(r?.type==="runtype"&&r.runtype)return v({type:"runtype",runtype:r.runtype});if(p.isSupported())return v({type:"browser",browser:r?.browser||{language:"en-US"}});throw new Error("No supported voice providers available")}function L(r){try{return y(r),!0}catch{return!1}}export{p as BrowserVoiceProvider,f as RuntypeVoiceProvider,y as createBestAvailableVoiceProvider,v as createVoiceProvider,L as isVoiceSupported};
|
|
1
|
+
var V=class{#e=null;#r=0;#d=[];#i=[];#a=[];#c=!1;#g=!1;#f=0;#n=!1;#m=!1;#l;#t=[];#y=0;#C=!1;#o;#u;#h;#p=null;constructor(e=24e3,t={}){this.#u=e;let s=Math.max(0,t.prebufferMs??0);this.#h=Math.round(e*s/1e3),this.#l=this.#h>0}#b(){if(!this.#e){let t=typeof window<"u"?window:void 0;if(!t)throw new Error("AudioPlaybackManager requires a browser environment");let s=t.AudioContext||t.webkitAudioContext;this.#e=new s({sampleRate:this.#u})}let e=this.#e;return e.state==="suspended"&&!this.#m&&e.resume(),e}enqueue(e){if(e.length===0)return;let t=e;if(this.#p){let n=new Uint8Array(this.#p.length+e.length);n.set(this.#p),n.set(e,this.#p.length),t=n,this.#p=null}if(t.length%2!==0&&(this.#p=new Uint8Array([t[t.length-1]]),t=t.subarray(0,t.length-1)),t.length===0)return;let s=this.#k(t);s.length!==0&&(this.#l?(this.#t.push(s),this.#y+=s.length,clearTimeout(this.#o),this.#y>=this.#h?this.#v():this.#C&&(this.#o=setTimeout(()=>this.#v(),this.#h/this.#u*1e3))):this.#w(s))}markStreamEnd(){this.#t.length>0&&this.#v(),this.#g=!0,this.#S()}flush(){for(let e of this.#d){e.onended=null;try{e.stop(),e.disconnect()}catch{}}this.#d=[],this.#f=0,this.#r=0,this.#c=!1,this.#g=!1,this.#i=[],this.#a=[],this.#p=null,this.#t=[],this.#y=0,this.#l=this.#h>0,this.#n=!1,clearTimeout(this.#o)}setContinuousMode(e){this.#C=e}isPlaying(){return this.#c}onFinished(e){this.#i.push(e)}onStarted(e){this.#a.push(e)}pause(){this.#m=!0,this.#e&&this.#e.state==="running"&&this.#e.suspend()}resume(){this.#m=!1,this.#e&&this.#e.state==="suspended"&&this.#e.resume()}async destroy(){this.flush(),this.#e&&(await this.#e.close(),this.#e=null)}#v(){this.#l=!1;let e=this.#t;this.#t=[],this.#y=0;for(let t of e)this.#w(t)}#w(e){if(e.length===0)return;let t=this.#b(),s=t.createBuffer(1,e.length,this.#u);s.getChannelData(0).set(e);let n=t.createBufferSource();n.buffer=s,n.connect(t.destination);let r=t.currentTime;if(this.#r===0?this.#r=r:this.#r<r&&(this.#r=r,this.#h>0&&(this.#l=!0)),n.start(this.#r),this.#r+=s.duration,this.#d.push(n),this.#f++,this.#c=!0,!this.#n){this.#n=!0;let l=this.#a.slice();this.#a=[];for(let d of l)d()}n.onended=()=>{let l=this.#d.indexOf(n);l!==-1&&(this.#d.splice(l,1),this.#f--,this.#S())}}#S(){if(this.#g&&this.#f<=0&&this.#t.length===0){this.#c=!1,this.#g=!1;let e=this.#i.slice();this.#i=[];for(let t of e)t()}}#k(e){let t=Math.floor(e.length/2),s=new Float32Array(t),n=new DataView(e.buffer,e.byteOffset,e.byteLength);for(let r=0;r<t;r++){let l=n.getInt16(r*2,!0);s[r]=l/32768}return s}};var J="4.26.0";var Y=J;var U=16e3,he=24e3,ge=4096,fe=U*2*8,me=4,ye=1380533830,be=3e4,ve=5e3,we=3e4,Se=3e4,ke=6e5,Ae="full-duplex-v1",Ce=300,Me=2e3,Te=2e3,xe="runtype-browser-v1",Ee=54e4,Pe="You're talking to an AI assistant. Voice is processed by OpenAI.",Ie=8e3,Ve=4e3,_e=12,Z=2e3;function je(i,e){let t="Conversation so far:",s=e.slice(0,Ve).trim(),n=Ie-(s?s.length+2:0)-t.length,r=[];for(let d of i.slice(-_e).reverse()){let a=d.content.replace(/\s+/g," ").trim();if(!a)continue;a.length>Z&&(a=`${a.slice(0,Z-1)}\u2026`);let o=`${d.role==="user"?"User":"Assistant"}: ${a}`;if(o.length+1>n)break;n-=o.length+1,r.unshift(o)}let l=r.length>0?[`${t}
|
|
2
|
+
${r.join(`
|
|
3
|
+
`)}`]:[];return s&&l.push(s),l.join(`
|
|
4
|
+
|
|
5
|
+
`)}function Re(i){return i.byteLength>=44&&new DataView(i).getUint32(0,!1)===ye?new Uint8Array(i,44):new Uint8Array(i)}function Q(i){let e=i.replace(/\/+$/,"");return/^wss?:\/\//i.test(e)?e:/^https?:\/\//i.test(e)?e.replace(/^http/i,"ws"):`${typeof window<"u"&&window.location?.protocol==="https:"?"wss:":"ws:"}//${e}`}function Le(i){return Q(i).replace(/^ws/i,"http")}function Oe(i){return typeof i!="number"||!Number.isFinite(i)?we:Math.min(ke,Math.max(Se,Math.round(i)))}var P=class{constructor(e){this.config=e;this.type="runtype";this.#e=null;this.#r=null;this.#d=[];this.#i=null;this.#a=null;this.#c=null;this.#g=[];this.#f=0;this.#n=null;this.#m=!1;this.#l=!1;this.#t=0;this.#y=!1;this.#C=Number.NEGATIVE_INFINITY;this.#o=null;this.#u=!1;this.#h=!1;this.#p=0;this.#b=0;this.#w=!1;this.bridge=null;this.#S=!1;this.#k=new Set;this.#M=new Map;this.#x=new Set;this.#_=!1;this.#E=null;this.#j=null;this.#R=Promise.resolve();this.#L=new Set;this.#T=!1;this.#O=new Set;this.#D=new Set;this.#z=[];this.#N=[];this.#B=[];this.#q=[];this.#U=[]}#e;#r;#d;#i;#a;#c;#g;#f;#n;#m;#l;#t;#y;#C;#o;#u;#h;#p;#b;#v;#w;#S;#k;#M;#x;#V;#_;#E;#j;#R;#L;#T;#O;#D;#z;#N;#B;#q;#U;async connect(){}setSessionBridge(e){this.bridge=e}prewarm(){if(this.#m||this.#o)return;let e=this.config?.agentId,t=this.config?.clientToken,s=this.config?.host;if(!e||!t||!s)return;let n=Date.now();if(!(n-this.#C<be)){this.#C=n;try{this.config?.prewarmMode==="attach"?this.#te(s,e,t):this.#ee(s,e,t)}catch{}}}#ee(e,t,s){if(typeof fetch!="function")return;let n=`${Le(e)}/v1/client/agents/${encodeURIComponent(t)}/voice/prewarm`;fetch(n,{method:"POST",headers:{Authorization:`Bearer ${s}`},keepalive:!0}).catch(()=>{})}#te(e,t,s){let n=new URLSearchParams,r=this.config?.attachIdleMs,l=Oe(r);r!==void 0&&n.set("attachIdleMs",String(l));let d=new WebSocket(this.#G(e,t,n),["runtype.bearer","runtype.attach",s]);d.binaryType="arraybuffer";let a=()=>{},o=new Promise(u=>{a=u}),c={ws:d,state:"connecting",ready:o,settle:a,openedAt:0,idleTimer:void 0};this.#o=c,d.onopen=()=>{this.#o===c&&(c.state=d.protocol==="runtype.attach"?"attached":"live",c.openedAt=Date.now(),this.#X(c,l),c.state==="attached"&&d.send('{"type":"ping"}'),c.settle())},d.onmessage=u=>{if(this.#o!==c||typeof u.data!="string")return;let g;try{g=JSON.parse(u.data)}catch{return}g.type==="attached"&&typeof g.idleMs=="number"&&this.#X(c,g.idleMs-(Date.now()-c.openedAt))},d.onerror=()=>{},d.onclose=()=>{this.#o===c&&this.#P()}}#X(e,t){clearTimeout(e.idleTimer),e.idleTimer=setTimeout(()=>{this.#o===e&&this.#P()},Math.max(0,t))}#P(){let e=this.#o;if(!e)return;this.#o=null,clearTimeout(e.idleTimer);let{ws:t}=e;if(t.onopen=null,t.onmessage=null,t.onerror=null,t.onclose=null,e.settle(),t.readyState===WebSocket.CONNECTING||t.readyState===WebSocket.OPEN)try{t.close(1e3,"prewarm released")}catch{}}async#se(){let e=this.#o;if(!e)return null;if(e.state==="connecting"){let t;await Promise.race([e.ready,new Promise(s=>{t=setTimeout(s,ve)})]),clearTimeout(t)}return this.#o!==e?null:e.state==="connecting"||e.ws.readyState!==WebSocket.OPEN?(this.#P(),null):(this.#o=null,clearTimeout(e.idleTimer),{ws:e.ws,live:e.state==="live"})}#G(e,t,s){let n=["partial_transcript","context"];this.bridge&&this.config?.clientDelegation!==!1&&n.push("client_delegation","delegation_update"),s&&n.unshift("attach");let r=new URLSearchParams({voiceProtocol:xe,clientVersion:`persona/${Y}`,voiceCapabilities:Ae,clientCapabilities:n.join(",")});return s?.forEach((l,d)=>r.set(d,l)),`${Q(e)}/ws/agents/${encodeURIComponent(t)}/voice?${r}`}async startListening(){if(this.#m)return;let e=this.config?.agentId,t=this.config?.clientToken,s=this.config?.host;if(!e)throw new Error("Runtype voice requires an agentId");if(!t)throw new Error("Runtype voice requires a clientToken");if(!s)throw new Error("Runtype voice requires a host (or widget apiUrl)");let n=++this.#t;this.#y=!1,this.#m=!0;try{let r=await navigator.mediaDevices.getUserMedia({audio:{sampleRate:U,channelCount:1,echoCancellation:!0}});if(n!==this.#t){r.getTracks().forEach(u=>u.stop());return}this.#i=r;let l=window.AudioContext||window.webkitAudioContext,d=new l({sampleRate:U});d.state==="suspended"&&await d.resume().catch(()=>{}),this.#r=d;let a=this.config?.createPlaybackEngine?await this.config.createPlaybackEngine():new V(he);if(n!==this.#t){a.destroy(),r.getTracks().forEach(u=>u.stop()),d.close().catch(()=>{});return}this.#n=a,this.#F(),this.#ie(d,r,n);let o=await this.#se();if(n!==this.#t){o?.ws.close(1e3,"client ended call");return}if(o){let{ws:u}=o;this.#e=u,this.#K(u,n),o.live||u.send('{"type":"start"}'),this.#W(u),this.#s("listening");return}let c=new WebSocket(this.#G(s,e),["runtype.bearer",t]);c.binaryType="arraybuffer",this.#e=c,c.onopen=()=>{n===this.#t&&(this.#W(c),this.#s("listening"))},this.#K(c,n)}catch(r){throw this.#A(),this.#I(r),this.#s("error"),r}}#K(e,t){e.onmessage=s=>this.#ne(s,t),e.onerror=()=>{t===this.#t&&(this.#I(new Error("Voice connection failed")),this.#s("error"),this.#A())},e.onclose=s=>{if(this.#y){this.#y=!1;return}if(t===this.#t){if(s.code!==1e3){let n=s.code?` (code ${s.code})`:"";this.#I(new Error(`Voice connection closed${n}`)),this.#s("error")}else this.#s("idle");this.#A()}}}getDisclosure(){let e=this.config?.disclosureText;return this.#m&&this.#u&&e!==!1?e||Pe:null}async stopListening(){this.#A(),this.#s("idle")}async disconnect(){this.#A(),this.#s("disconnected"),this.#z=[],this.#N=[],this.#B=[],this.#q=[],this.#U=[]}stopPlayback(){this.#Q();let e=this.#e;e&&e.readyState===WebSocket.OPEN&&(this.#u&&(this.#p=Date.now()+Me,e.send('{"type":"cancel"}')),this.#s("listening"))}getInterruptionMode(){return"barge-in"}isBargeInActive(){return this.#m}onLevel(e){this.#d.push(e)}async deactivateBargeIn(){this.#A(),this.#s("idle")}#ie(e,t,s){let n=e.createMediaStreamSource(t);this.#a=n;let r=e.createScriptProcessor(ge,1,1);this.#c=r,r.onaudioprocess=l=>{if(s!==this.#t)return;let d=this.#e,a=d?.readyState===WebSocket.OPEN;if(d&&!a&&d.readyState!==WebSocket.CONNECTING)return;let o=l.inputBuffer.getChannelData(0),c=new Int16Array(o.length),u=0;for(let g=0;g<o.length;g++){let f=Math.max(-1,Math.min(1,o[g]));u+=f*f,c[g]=f<0?f*32768:f*32767}if(d&&a)this.#W(d),d.send(c.buffer);else for(this.#g.push(c.buffer),this.#f+=c.byteLength;this.#f>fe;)this.#f-=this.#g.shift().byteLength;if(this.#d.length>0){let g=Math.sqrt(u/o.length),f=Math.max(0,Math.min(1,g*me));for(let p of this.#d)p(f)}},n.connect(r),r.connect(e.destination)}#W(e){for(let t of this.#g)e.send(t);this.#g=[],this.#f=0}#ne(e,t){if(t!==this.#t)return;if(e.data instanceof ArrayBuffer){this.#ce(e.data,t);return}let s;try{s=JSON.parse(e.data)}catch{return}switch(s.type){case"session_config":s.speechMode&&(this.#u=s.speechMode==="speech_to_speech",this.#n?.setContinuousMode?.(this.#u)),Array.isArray(s.capabilities)&&(this.#k=new Set(s.capabilities)),typeof s.callId=="string"&&(this.#V=s.callId),this.#S=this.#u&&this.#k.has("client_delegation")&&!!this.bridge,this.#u&&!this.#l&&this.#s("listening"),this.#k.has("context")&&!this.#_&&(this.#_=!0,this.#E=this.#re());break;case"transcript_update":{let n=s.role==="assistant"?"assistant":"user",r=s.utteranceId??s.turnId;if(!r||n==="assistant"&&this.#$())break;let l=String(r);if(n==="user")s.final===!0&&this.#J(t),this.#T=!1;else if(this.#T&&!this.#O.has(l)&&(this.#D.add(l),this.#T=!1),this.#O.add(l),this.#D.has(l))break;this.#H(n,s.text??"",s.final===!0,{turnId:l,...typeof s.startMs=="number"&&{startMs:s.startMs},...typeof s.endMs=="number"&&{endMs:s.endMs},...this.#S&&{caption:!0}});break}case"delegation_started":case"delegation_completed":{let n=String(s.delegationId??s.turnId);if(s.type==="delegation_started"){this.#J(t);let r=s.input;this.#S&&r&&this.#ae(n,{delegationId:n,userText:String(r.text??""),userUtteranceIds:Array.isArray(r.userUtteranceIds)?r.userUtteranceIds.filter(l=>typeof l=="string"):[],messages:Array.isArray(r.messages)?r.messages:[]},t)}else s.speak!==!1&&this.#L.has(n)&&(this.#T=!0);this.#h=s.type==="delegation_started",!this.#l&&!this.#$()&&this.#s(this.#h?"processing":"listening");break}case"delegation_cancelled":this.#Y(String(s.delegationId),s.reason!=="session_ending"&&s.reason!=="provider_cancelled");break;case"warning":console.warn(`[Persona voice] ${s.code}: ${s.message??""}`,this.#V??""),s.delegationId&&(s.code==="UNKNOWN_DELEGATION"||s.code==="LATE_RESULT_LIMIT")&&this.#Y(String(s.delegationId));break;case"audio_clear":this.#Q(),this.#p=0,this.#s("listening");break;case"transcript_interim":this.#s("listening"),this.#H("user",s.text??"",!1);break;case"transcript_final":{let n=s.role==="assistant"?"assistant":"user";this.#s(n==="user"?"processing":"speaking"),this.#H(n,s.text??"",!0);break}case"audio_end":this.#n?this.#n.markStreamEnd():(this.#l=!1,this.#s("listening"));break;case"metrics":this.#de({llmMs:s.llm_ms,ttsMs:s.tts_ms,firstAudioMs:s.first_audio_ms,totalMs:s.total_ms});break;case"error":this.#I(new Error(s.error||"Voice error")),this.#s("error");break}}async#re(){let e=this.bridge?.getHistory()??[],t="";try{let s=this.config?.callContext;t=String((typeof s=="function"?await s():s)??"")}catch{}return je(e,t)}#J(e){let t=this.#E;if(!t)return;this.#E=null;let s=!1,n=t.then(r=>{let l=this.#e;s||!r||e!==this.#t||l?.readyState!==WebSocket.OPEN||l.send(JSON.stringify({type:"context",text:r}))});this.#j={done:n,drop:()=>s=!0}}async#oe(){let e=this.#j;if(!e)return;let t,s=await Promise.race([e.done.then(()=>!1),new Promise(n=>{t=setTimeout(()=>n(!0),Te)})]);clearTimeout(t),s&&e.drop()}#Y(e,t=!1){this.#x.add(e),this.bridge?.dropDelegation?.(e,t),this.#M.get(e)?.abort()}#ae(e,t,s){let n=this.bridge,r=(l,d,a)=>{let o=this.#e;return s!==this.#t||o?.readyState!==WebSocket.OPEN||this.#x.has(e)?!1:(o.send(JSON.stringify({type:l,delegationId:e,status:d,text:a})),!0)};this.#R=this.#R.then(async()=>{if(s!==this.#t||this.#x.has(e))return;let l=await n.runDelegatedTurn(t).catch(()=>({status:"failed",text:""}));await this.#oe();let d=!!l.followUp,a=d&&this.#k.has("delegation_update");if(!r(a?"delegation_update":"delegation_result",d&&!a?"completed":l.status,l.text)||(l.status!=="failed"&&this.#L.add(e),!l.followUp))return;let c=new AbortController;this.#M.set(e,c),l.followUp({signal:c.signal,approvalTimeoutMs:this.config?.approvalTimeoutMs&&Math.min(this.config.approvalTimeoutMs,Ee),readBack:a,onUpdate:u=>r("delegation_update","pending_approval",u)}).then(u=>{this.#M.delete(e),a&&u&&!c.signal.aborted&&r("delegation_result",u.status,u.text)})})}#ce(e,t){if(t!==this.#t||!this.#n||this.#$())return;let s=Re(e);s.length!==0&&(this.#l||(this.#l=!0,this.#s("speaking")),this.#F(),this.#n.enqueue(s),this.#u&&this.#le(s.length))}#$(){return Date.now()<this.#p}#F(){if(this.#w||!this.#n)return;this.#w=!0;let e=this.#t;this.#n.onFinished(()=>{e===this.#t&&(this.#w=!1,this.#Z())})}#le(e){let t=Date.now();this.#b=Math.max(t,this.#b)+e/48,clearTimeout(this.#v),this.#v=setTimeout(()=>this.#Z(),this.#b-t+Ce)}#Z(){this.#l=!1,this.#b=0,this.#e&&this.#e.readyState===WebSocket.OPEN&&this.#s(this.#h?"processing":"listening")}#Q(){this.#n?.flush(),this.#w=!1,this.#F(),this.#l=!1,this.#b=0,clearTimeout(this.#v)}#A(){this.#t+=1,this.#m=!1,this.#l=!1,this.#P(),this.#u=!1,this.#h=!1,this.#S=!1,this.#k=new Set;for(let e of this.#M.values())e.abort();if(this.#M.clear(),this.#x.clear(),this.#V=void 0,this.#_=!1,this.#E=null,this.#j=null,this.#R=Promise.resolve(),this.#L.clear(),this.#T=!1,this.#O.clear(),this.#D.clear(),this.#w=!1,this.#p=0,this.#b=0,clearTimeout(this.#v),this.#g=[],this.#f=0,this.#c&&(this.#c.onaudioprocess=null,this.#c.disconnect(),this.#c=null),this.#a&&(this.#a.disconnect(),this.#a=null),this.#i&&(this.#i.getTracks().forEach(e=>e.stop()),this.#i=null),this.#r&&(this.#r.close().catch(()=>{}),this.#r=null),this.#n&&(this.#n.destroy(),this.#n=null),this.#e){this.#y=!0;try{this.#e.close(1e3,"client ended call")}catch{}this.#e=null}}onResult(e){this.#z.push(e)}onError(e){this.#N.push(e)}onStatusChange(e){this.#B.push(e)}onTranscript(e){this.#q.push(e)}onMetrics(e){this.#U.push(e)}#s(e){this.#B.forEach(t=>t(e))}#I(e){this.#N.forEach(t=>t(e))}#H(e,t,s,n){this.#q.forEach(r=>r(e,t,s,n))}#de(e){this.#U.forEach(t=>t(e))}};var M=class{constructor(e={}){this.config=e;this.type="browser";this.#e=null;this.#r=[];this.#d=[];this.#i=[];this.#a=!1;this.#c=typeof window<"u"?window:void 0}#e;#r;#d;#i;#a;#c;async connect(){this.#i.forEach(e=>e("connected"))}async startListening(){try{if(this.#a)throw new Error("Already listening");if(!this.#c)throw new Error("Window object not available");let e=this.#c.SpeechRecognition||this.#c.webkitSpeechRecognition;if(!e)throw new Error("Browser speech recognition not supported");this.#e=new e,this.#e.lang=this.config?.language||"en-US",this.#e.continuous=this.config?.continuous||!1,this.#e.interimResults=!0,this.#e.onresult=t=>{let s=Array.from(t.results).map(r=>r[0]).map(r=>r.transcript).join(""),n=t.results[t.results.length-1].isFinal;this.#r.forEach(r=>r({text:s,confidence:n?.8:.5,provider:"browser"})),n&&!this.config?.continuous&&this.stopListening()},this.#e.onerror=t=>{this.#d.forEach(s=>s(new Error(t.error))),this.#i.forEach(s=>s("error"))},this.#e.onstart=()=>{this.#a=!0,this.#i.forEach(t=>t("listening"))},this.#e.onend=()=>{this.#a=!1,this.#i.forEach(t=>t("idle"))},this.#e.start()}catch(e){throw this.#d.forEach(t=>t(e)),this.#i.forEach(t=>t("error")),e}}async stopListening(){this.#e&&(this.#e.stop(),this.#e=null),this.#a=!1,this.#i.forEach(e=>e("idle"))}onResult(e){this.#r.push(e)}onError(e){this.#d.push(e)}onStatusChange(e){this.#i.push(e)}async disconnect(){await this.stopListening(),this.#i.forEach(e=>e("disconnected"))}static isSupported(){return"SpeechRecognition"in window||"webkitSpeechRecognition"in window}};function _(i){switch(i.type){case"runtype":if(!i.runtype)throw new Error("Runtype voice provider requires configuration");return new P(i.runtype);case"browser":if(!M.isSupported())throw new Error("Browser speech recognition not supported");return new M(i.browser||{});case"custom":{let e=i.custom;if(!e)throw new Error("Custom voice provider requires a `custom` provider instance or factory");let t=typeof e=="function"?e():e;if(!t||typeof t.startListening!="function")throw new Error("Custom voice provider `custom` must be a VoiceProvider (or a factory returning one)");return t}default:throw new Error(`Unknown voice provider type: ${i.type}`)}}function ee(i){if(i?.type==="custom"&&i.custom)return _({type:"custom",custom:i.custom});if(i?.type==="runtype"&&i.runtype)return _({type:"runtype",runtype:i.runtype});if(M.isSupported())return _({type:"browser",browser:i?.browser||{language:"en-US"}});throw new Error("No supported voice providers available")}function De(i){try{return ee(i),!0}catch{return!1}}var te=i=>i.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,""),W=class{constructor(e){this.host=e;this.turns=new Map;this.latestId=null;this.cancelled=new Set}apply(e,t,s,n,r,l){let d=this.host;t=t.trim();let a=this.turns.get(n);if(a||(a={},this.turns.set(n,a),this.latestId=n),e==="user"){a.userFinal=s;let o=a.userId?d.find(a.userId):void 0;if(o){let c=a.userStartMs===void 0&&r!==void 0;c&&(a.userStartMs=r),d.upsert({...o,content:t,voiceProcessing:!s,...c&&this.placeBefore(this.startedAfter(r))})}else{a.userStartMs=r;let c=a.assistantId?d.find(a.assistantId):void 0;a.userId=d.inject({role:"user",content:t,streaming:!1,voiceProcessing:!s,voiceCaption:l,...this.placeBefore(this.startedAfter(r)??c)}).id}}else if(!this.cancelled.has(n)){a.assistantFinal=s;let o=a.assistantId?d.find(a.assistantId):void 0;if(o){let c=a.assistantStartMs===void 0&&r!==void 0;c&&(a.assistantStartMs=r),d.upsert({...o,content:t,streaming:!s,voiceProcessing:!s,...c&&this.placeBefore(this.startedAfter(r))})}else t&&(a.assistantStartMs=r,a.assistantId=d.inject({role:"assistant",content:t,streaming:!s,voiceProcessing:!s,voiceCaption:l,...this.placeBefore(this.startedAfter(r))}).id);s&&a.assistantId&&d.markSpoken(a.assistantId)}this.sync()}claimUserTurn(e,t=[]){let s=t[t.length-1];for(let r of t)r!==s&&(this.turns.has(r)||this.turns.set(r,{}),this.turns.get(r).claimed=!0);let n;if(s){if(n=this.turns.get(s),n||(n={},this.turns.set(s,n)),n.claimed)return null;(!n.userId||!this.host.find(n.userId))&&(n.userFinal=!0,n.userId=this.host.inject({role:"user",content:e.trim()}).id)}else{let r=te(e),l=[...this.turns.values()].reverse().flatMap(d=>{let a=d.userId&&!d.claimed?this.host.find(d.userId):void 0;return a?[{turn:d,text:te(a.content)}]:[]}).filter(({text:d})=>d&&r);n=(l.find(({text:d})=>d===r)??l.find(({text:d})=>d.startsWith(r)||r.startsWith(d)))?.turn}return n?(n.claimed=!0,n.userId):null}cancel(){let e=this.inFlight();if(e.length===0){let t=this.awaiting();if(!t)return;e=[t]}for(let t of e)this.cancelled.add(t);this.closeReplies(e),this.sync()}fail(e){let t=this.awaiting(),s=this.inFlight();if(!t&&s.length===0)return;for(let l of s)this.turns.get(l).assistantFinal=!0;this.closeReplies(s);let n=this.host.inject({role:"assistant",content:e,streaming:!1,voiceProcessing:!1}),r=t?this.turns.get(t):void 0;r&&(r.assistantId=n.id,r.assistantFinal=!0),this.sync()}settle(){if(this.turns.size===0)return;let e=this.pending(),t=new Set;for(let s of this.turns.values())s.userId&&t.add(s.userId),s.assistantId&&(t.add(s.assistantId),this.host.markSpoken(s.assistantId));this.turns.clear(),this.latestId=null,this.host.settle(t),e&&this.host.setStreaming(!1)}startedAfter(e){if(e===void 0)return;let t;for(let s of this.turns.values())for(let[n,r]of[[s.userId,s.userStartMs],[s.assistantId,s.assistantStartMs]])n&&r!==void 0&&r>e&&(!t||r<t.start)&&(t={start:r,id:n});return t&&this.host.find(t.id)}placeBefore(e){if(!e)return;let t=e.sequence??0,s=t-1;for(let n of this.turns.values())for(let r of[n.userId,n.assistantId]){let l=r?this.host.find(r):void 0,d=l?.sequence;l?.createdAt===e.createdAt&&d!==void 0&&d>s&&d<t&&(s=d)}return{createdAt:e.createdAt,sequence:(s+t)/2}}closeReplies(e){let t=new Set;for(let s of e){let n=this.turns.get(s)?.assistantId;n&&(t.add(n),this.host.markSpoken(n))}t.size>0&&this.host.settle(t)}inFlight(){let e=[];for(let[t,s]of this.turns)s.assistantId&&!s.assistantFinal&&!this.cancelled.has(t)&&e.push(t);return e}awaiting(){let e=this.latestId;if(!e)return null;let t=this.turns.get(e);return t?.userFinal&&!t.assistantId&&!t.claimed&&!this.cancelled.has(e)?e:null}pending(){return this.awaiting()!==null||this.inFlight().length>0}sync(){this.host.setStreaming(this.pending())}};var Ne="I need your answer in the chat before I can continue.";var se="no|nope|never ?mind|decline(?: it| that)?|cancel(?: it| that| this)?(?: (?:the|my|that|this) (?:[a-z]+ )?(?:order|request))?|don'?t (?:do|place) (?:it|that|the (?:[a-z]+ )?order)",Be=new RegExp(`^(?:${se})(?: (?:${se}))?(?: thanks| thank you)?$`),qe=i=>Be.test(i.toLowerCase().replace(/[^a-z' ]+/g," ").replace(/\s+/g," ").trim()),ie="Briefly tell the user what you're about to do and ask them to approve or decline it in the chat. Don't claim it's done.",ne=()=>new Promise(i=>setTimeout(i,50)),$=(i,e)=>i.length>e?`${i.slice(0,e-1).trimEnd()}\u2026`:i,x=i=>i.replace(/^webmcp:/,"").replace(/([a-z\d])([A-Z])/g,"$1 $2").replace(/[_\-.]+/g," ").trim().toLowerCase();function F(i,e=0){if(i==null||i==="")return"";if(typeof i!="object")return String(i);if(e>2)return"";if(Array.isArray(i))return i.map(r=>F(r,e+1)).filter(Boolean).join(", ");let t=i,s=t.quantity??t.qty??t.count,n=t.name??t.item??t.product??t.title;return s!=null&&n!=null&&typeof n!="object"?`${s} ${n}`:Object.entries(t).filter(([r])=>!r.startsWith("_")).map(([r,l])=>{let d=F(l,e+1);return d&&(e?`${x(r)} ${d}`:`${x(r)}: ${d}`)}).filter(Boolean).join(e?", ":"; ")}function re(i){let e=i.length>1?"These actions need the user's approval in the chat before they happen:":"This action needs the user's approval in the chat before it happens:",t=1e3-e.length-ie.length-2,s=i.map(n=>{let r=[x(n.toolName)];n.description&&r.push(`(${$(n.description.trim(),160)})`);let l=F(n.parameters);return l&&r.push(`with ${l}`),n.reason&&r.push(`because: ${$(n.reason.trim(),160)}`),$(`- ${r.join(" ")}`,Math.floor(t/i.length)-1)});return`${e}
|
|
6
|
+
${s.join(`
|
|
7
|
+
`)}
|
|
8
|
+
|
|
9
|
+
${ie}`}var j=i=>i.variant==="approval"&&i.approval?.status==="pending";function Ue(i){let e=null,t=null,s=()=>i.track(e??t),n=[],r=new Map,l=new Map,d=(p,m)=>{r.set(p,[...r.get(p)??[],m]),r.size>32&&r.delete(r.keys().next().value)},a=p=>i.messages().find(m=>m.id===p),o=p=>p.approvals.filter(m=>a(m)?.approval?.status==="pending"),c=p=>x(a(p)?.approval?.toolName??""),u=(p,m,v)=>{p.outcome={status:m,text:v};for(let w of o(p))i.decide(w)},g=p=>p.flatMap(m=>i.messages().find(v=>v.id===m)??[]).filter(m=>!m.variant&&m.content.trim()).map(m=>m.content.trim()).join(`
|
|
10
|
+
|
|
11
|
+
`),f=async p=>{do await ne();while(i.busy()&&!(p&&(i.parked()||p.failed)))};return{getHistory:()=>i.messages().flatMap(p=>(p.role==="user"||p.role==="assistant")&&!p.variant&&!p.voiceProcessing&&!p.voiceCaption&&p.content?[{role:p.role,content:p.content}]:[]),dropDelegation(p,m){l.set(p,!!m),l.size>32&&l.delete(l.keys().next().value);let v=m&&n.find(w=>w.delegationId===p);v&&!v.outcome&&u(v,"timeout","");for(let w of r.get(p)??[])w.dropped=!0,w.ids.length&&i.unspoken(w.ids)},async runDelegatedTurn({delegationId:p,userText:m,userUtteranceIds:v}){let w=n.filter(h=>o(h).length),E=w.flatMap(o);if(E.length===1&&qe(m)){let h=c(E[0]);return u(w[0],"denied",""),{status:"denied",text:`Okay, I cancelled the ${h} request. Nothing was done.`}}let H=i.parked()&&i.messages().every(h=>!j(h)||E.includes(h.id));i.busy()&&!H&&await f();let oe=new Set(i.messages().map(h=>h.id)),R=()=>i.messages().filter(h=>!oe.has(h.id)&&h.variant==="approval"),k={ids:[],failed:!1};d(p,k),e=k,s();try{await i.send(m,i.claim(m,v)??void 0),await f(k)}catch{k.failed=!0}finally{e=null,s()}let ae=k.ids.flatMap(h=>i.messages().find(b=>b.id===h)??[]),T=g(k.ids),I=k.failed?[]:R().filter(j),ce=new Set(I.map(h=>x(h.approval.toolName)));for(let h of w){if(h.outcome)continue;for(let S of o(h).filter(L=>ce.has(c(L))))h.replaced.add(S),i.decide(S);let b=c(h.approvals[0]);h.approvals.every(S=>h.replaced.has(S))?h.outcome={status:"cancelled",text:`The earlier ${b} request was replaced by the new one; it was not done.`}:H&&h.approvals.every(S=>a(S)?.approval?.status==="denied")&&(h.outcome={status:"cancelled",text:`The earlier ${b} request was replaced by the new one; it was not done.`})}if(I.length){let h=new Set(I.map(S=>S.id)),b={delegationId:p,approvals:[...h],at:Date.now(),replaced:new Set};return n.push(b),l.get(p)&&u(b,"timeout",""),T=`${T}
|
|
12
|
+
|
|
13
|
+
${re(I.map(S=>S.approval))}`.trim(),{status:"pending_approval",text:T,followUp:async({signal:S,approvalTimeoutMs:L=3e5,readBack:z=!0,onUpdate:le})=>{let A={ids:[],failed:!1};r.delete(p),d(p,A);let X=()=>R().filter(y=>h.has(y.id)||A.ids.includes(y.id)),de=()=>R().filter(y=>j(y)&&!h.has(y.id)&&!n.some(C=>C.approvals.includes(y.id))&&(A.ids.includes(y.id)||y.approval?.toolType==="webmcp"&&t===A)),G=()=>{t=A,s()};z&&G();try{for(;!S.aborted&&!b.outcome&&(e||i.busy()||X().some(j));){z&&t!==A&&!o(b).length&&G();let y=de();if(y.length){for(let C of y)h.add(C.id),b.approvals.push(C.id);b.at=Date.now(),le?.(re(y.map(C=>C.approval)))}if(Date.now()-b.at>=L&&o(b).length&&(!i.busy()||i.parked())){u(b,"timeout",`That ${c(b.approvals[0])} request expired, so nothing was done.`);break}await ne()}}finally{t===A&&(t=null,s()),n.splice(n.indexOf(b),1)}if(S.aborted)return null;if(b.outcome)return b.outcome;if(A.failed)return{status:"failed",text:`The ${c(b.approvals[0])} request didn't complete.`};let K=X(),O=y=>K.filter(y).map(C=>x(C.approval.toolName)).join(", "),D=K.some(y=>y.approval?.status==="approved"),N=O(y=>y.approval?.status==="denied"&&!b.replaced.has(y.id)),B=O(y=>b.replaced.has(y.id)),q=O(y=>y.approval?.status==="timeout"),ue=[D?g(A.ids):"",N&&`The user declined the ${N} request in the chat, so ${D?"that part was not done":"nothing was done"}.`,B&&`The earlier ${B} request was replaced by the new one; it was not done.`,q&&`The ${q} request timed out, so it was not done.`].filter(Boolean).join(`
|
|
14
|
+
|
|
15
|
+
`);return{status:D?"completed":N?"denied":B?"cancelled":q?"timeout":"completed",text:ue}}}}return!k.failed&&i.parked()||ae.some(h=>h.agentMetadata?.awaitingLocalTool&&!h.agentMetadata.askUserQuestionAnswered&&!h.toolCall?.name?.startsWith("webmcp:"))?{status:k.failed?"failed":"completed",text:`${T}
|
|
16
|
+
|
|
17
|
+
${Ne}`.trim()}:{status:!k.failed&&T?"completed":"failed",text:T}}}}var We=(i,e,t,s)=>{let n=i.session;try{i.keyed=t?new t({find:o=>n.messages.find(c=>c.id===o),inject:o=>n.injectMessage(o),upsert:o=>n.upsertMessage(o),settle:o=>{n.messages=n.messages.map(c=>o.has(c.id)?{...c,streaming:!1,voiceProcessing:!1}:c),n.callbacks.onMessagesChanged([...n.messages])},setStreaming:o=>{(o||!i.busy())&&i.setStreaming(o)},markSpoken:o=>{n.ttsSpokenMessageIds.add(o)}}):null,s&&e.setSessionBridge&&e.setSessionBridge(s({messages:()=>n.messages,busy:()=>i.busy(),parked:()=>n.webMcpApprovalResolvers.size>0,claim:(o,c)=>i.keyed?.claimUserTurn(o,c)??null,send:(o,c)=>n.sendMessage(o,{viaVoice:!0,voiceTurn:{userMessageId:c}}),track:o=>{i.setDelegation(o)},unspoken:o=>{for(let c of o)n.ttsSpokenMessageIds.delete(c);n.streaming||n.speakLatestAssistantMessage(o)},decide:o=>{if(n.webMcpApprovalResolvers.has(o))return n.resolveWebMcpApproval(o,"denied");let c=n.messages.find(u=>u.id===o)?.approval;c?.status==="pending"&&n.resolveApproval(c,"denied")}}));let r=i.generation(),l=()=>i.provider()===e&&r===i.generation(),a=(n.config.voiceRecognition??{}).processingErrorText??"Voice processing failed. Please try again.";e.onResult(o=>{l()&&o.provider!=="runtype"&&o.text&&o.text.trim()&&n.sendMessage(o.text,{viaVoice:!0})}),e.onTranscript&&e.onTranscript((o,c,u,g)=>{if(l()){if(g?.turnId){i.keyed?.apply(o,c,u,g.turnId,g.startMs,g.caption);return}if(o==="user"){if(i.pendingUser)n.upsertMessage({id:i.pendingUser,role:"user",content:c,createdAt:new Date().toISOString(),streaming:!1,voiceProcessing:!u});else{let f=n.injectMessage({role:"user",content:c,streaming:!1,voiceProcessing:!u});i.pendingUser=f.id}if(u){i.turns().start(g?.turnId),i.pendingUser=null;let f=n.injectMessage({role:"assistant",content:"",streaming:!0,voiceProcessing:!0});i.pendingAssistant=f.id,i.setStreaming(!0)}}else{if(!i.turns().accepts(g?.turnId))return;if(i.pendingAssistant)n.upsertMessage({id:i.pendingAssistant,role:"assistant",content:c,createdAt:new Date().toISOString(),streaming:!u,voiceProcessing:!u});else{let f=n.injectMessage({role:"assistant",content:c,streaming:!u,voiceProcessing:!u});i.pendingAssistant=f.id}u&&(i.pendingAssistant&&n.ttsSpokenMessageIds.add(i.pendingAssistant),i.setStreaming(!1),i.pendingAssistant=null)}}}),e.onLevel&&e.onLevel(o=>{l()&&i.setLevel(Number.isFinite(o)?Math.max(0,Math.min(1,o)):0)}),e.onMetrics&&e.onMetrics(o=>{l()&&n.config.voiceRecognition?.onMetrics?.(o)}),e.onError(o=>{l()&&(console.error("Voice error:",o),i.pendingAssistant&&(n.upsertMessage({id:i.pendingAssistant,role:"assistant",content:a,createdAt:new Date().toISOString(),streaming:!1,voiceProcessing:!1}),i.setStreaming(!1),i.pendingUser=null,i.pendingAssistant=null),i.keyed?.fail(a))}),e.onStatusChange(o=>{l()&&(i.setStatus(o),(o==="listening"||o==="idle"||o==="disconnected")&&i.settlePending(o!=="listening"),(o==="idle"||o==="disconnected")&&i.keyed?.settle(),n.callbacks.onVoiceStatusChanged?.(o))}),e.connect()}catch(r){console.error("Failed to setup voice:",r)}};var $e=i=>{let e=a=>{if(i.original)return;let o=i.config().voiceRecognition??{};i.original={backgroundColor:a.style.backgroundColor,color:a.style.color,borderColor:a.style.borderColor,iconName:o.iconName??"mic",iconSize:parseFloat(o.iconSize??"")||i.iconFallbackPx}},t=(a,o,c)=>{let u=a.querySelector("svg");u&&u.remove();let g=i.original?.iconSize??(parseFloat(i.config().voiceRecognition?.iconSize??"")||i.iconFallbackPx),f=i.renderIcon(o,g,c,1.5);f&&a.appendChild(f)},s=a=>{a.classList.remove("persona-voice-recording","persona-voice-processing","persona-voice-speaking")};return{recording:()=>{let a=i.mic();if(!a)return;e(a);let o=i.config().voiceRecognition??{},c=o.recordingBackgroundColor,u=o.recordingIconColor,g=o.recordingBorderColor;if(s(a),a.classList.add("persona-voice-recording"),i.setMicState("recording"),a.style.backgroundColor=c??"var(--persona-voice-recording-bg, #ef4444)",a.style.color=u??"var(--persona-voice-recording-indicator, #ffffff)",u){let f=a.querySelector("svg");f&&f.setAttribute("stroke",u)}g&&(a.style.borderColor=g),a.setAttribute("aria-label","Stop voice recognition")},processing:()=>{let a=i.mic();if(!a)return;e(a);let o=i.config().voiceRecognition??{},c=i.session().getVoiceInterruptionMode(),u=i.original,g=o.processingIconName??"loader",f=o.processingIconColor??u?.color??"",p=o.processingBackgroundColor??u?.backgroundColor??"",m=o.processingBorderColor??u?.borderColor??"";s(a),a.classList.add("persona-voice-processing"),i.setMicState("processing"),a.style.backgroundColor=p,a.style.borderColor=m;let v=f||"currentColor";a.style.color=v,t(a,g,v),a.setAttribute("aria-label","Processing voice input"),c==="none"&&(a.style.cursor="default")},speaking:()=>{let a=i.mic();if(!a)return;e(a);let o=i.config().voiceRecognition??{},c=i.session().getVoiceInterruptionMode(),u=i.original,g=c==="cancel"?"square":c==="barge-in"?"mic":"volume-2",f=o.speakingIconName??g,p=o.speakingIconColor??(c==="barge-in"?o.recordingIconColor??u?.color??"":u?.color??""),m=o.speakingBackgroundColor??(c==="barge-in"?o.recordingBackgroundColor??"var(--persona-voice-recording-bg, #ef4444)":u?.backgroundColor??""),v=o.speakingBorderColor??(c==="barge-in"?o.recordingBorderColor??"":u?.borderColor??"");s(a),a.classList.add("persona-voice-speaking"),i.setMicState("speaking"),a.style.backgroundColor=m,a.style.borderColor=v;let w=p||"currentColor";a.style.color=w,t(a,f,w);let E=c==="cancel"?"Stop playback and re-record":c==="barge-in"?"Speak to interrupt":"Agent is speaking";a.setAttribute("aria-label",E),c==="none"&&(a.style.cursor="default"),c==="barge-in"&&a.classList.add("persona-voice-recording")},reset:()=>{let a=i.mic();if(!a)return;s(a),i.setMicState("idle");let o=i.original;o&&(a.style.backgroundColor=o.backgroundColor??"",a.style.color=o.color??"",a.style.borderColor=o.borderColor??"",t(a,o.iconName,o.color||"currentColor"),i.original=null),a.style.cursor="",a.setAttribute("aria-label","Start voice recognition")}}};export{M as BrowserVoiceProvider,W as KeyedVoiceTranscript,P as RuntypeVoiceProvider,ee as createBestAvailableVoiceProvider,$e as createMicStateStyles,_ as createVoiceProvider,Ue as createVoiceSessionBridge,De as isVoiceSupported,We as wireSessionVoice};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var g=Object.defineProperty;var
|
|
1
|
+
"use strict";var g=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var v=(n,e)=>{for(var t in e)g(n,t,{get:e[t],enumerable:!0})},k=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of w(e))!E.call(n,s)&&s!==t&&g(n,s,{get:()=>e[s],enumerable:!(i=P(e,s))||i.enumerable});return n};var A=n=>k(g({},"__esModule",{value:!0}),n);var R={};v(R,{FallbackSpeechEngine:()=>m,RuntypeSpeechEngine:()=>y,createPcmStreamPlayer:()=>b,createWorkletPlaybackEngine:()=>S});module.exports=A(R);var x=`
|
|
2
2
|
class PersonaPcmPlayerProcessor extends AudioWorkletProcessor {
|
|
3
3
|
constructor(options) {
|
|
4
4
|
super()
|
|
@@ -17,9 +17,16 @@ class PersonaPcmPlayerProcessor extends AudioWorkletProcessor {
|
|
|
17
17
|
// consumer can flip UI from loading\u2192playing only when audio is truly audible.
|
|
18
18
|
// A mid-reply underrun re-buffers (waiting=true) but must NOT re-signal.
|
|
19
19
|
this.startedSignaled = false
|
|
20
|
+
// Continuous (speech-to-speech) streams never send eos, so a tail held below
|
|
21
|
+
// the waterline is released once input has been quiet for one waterline.
|
|
22
|
+
this.continuous = false
|
|
23
|
+
this.idle = 0
|
|
20
24
|
this.port.onmessage = (e) => {
|
|
21
25
|
const msg = e.data
|
|
22
|
-
if (msg.type === '
|
|
26
|
+
if (msg.type === 'continuous') {
|
|
27
|
+
this.continuous = msg.enabled
|
|
28
|
+
} else if (msg.type === 'push') {
|
|
29
|
+
this.idle = 0
|
|
23
30
|
this.eosSeen = false
|
|
24
31
|
this.chunks.push(msg.samples)
|
|
25
32
|
this.buffered += msg.samples.length
|
|
@@ -55,7 +62,15 @@ class PersonaPcmPlayerProcessor extends AudioWorkletProcessor {
|
|
|
55
62
|
}
|
|
56
63
|
process(inputs, outputs) {
|
|
57
64
|
const out = outputs[0][0]
|
|
58
|
-
if (!out
|
|
65
|
+
if (!out) return true
|
|
66
|
+
if (this.waiting) {
|
|
67
|
+
// outputs are pre-zeroed: silence while (re)buffering
|
|
68
|
+
if (!this.continuous || this.buffered === 0) return true
|
|
69
|
+
this.idle += out.length
|
|
70
|
+
if (this.idle < this.waterline) return true
|
|
71
|
+
this.waiting = false
|
|
72
|
+
this.signalStarted()
|
|
73
|
+
}
|
|
59
74
|
let i = 0
|
|
60
75
|
while (i < out.length && this.buffered > 0) {
|
|
61
76
|
const chunk = this.chunks[0]
|
|
@@ -77,4 +92,4 @@ class PersonaPcmPlayerProcessor extends AudioWorkletProcessor {
|
|
|
77
92
|
}
|
|
78
93
|
}
|
|
79
94
|
registerProcessor('persona-pcm-player', PersonaPcmPlayerProcessor)
|
|
80
|
-
`;function C(
|
|
95
|
+
`;function C(n){let e=n.length>>1,t=new Float32Array(e),i=new DataView(n.buffer,n.byteOffset,n.byteLength);for(let s=0;s<e;s++)t[s]=i.getInt16(s*2,!0)/32768;return t}async function b(n={}){let e=n.prebufferMs??150,t=Math.max(1,Math.round(24e3*e/1e3)),i=window.AudioContext||window.webkitAudioContext,s=new i({sampleRate:24e3});s.state==="suspended"&&await s.resume().catch(()=>{});let o=URL.createObjectURL(new Blob([x],{type:"application/javascript"}));try{await s.audioWorklet.addModule(o)}catch(a){throw s.close().catch(()=>{}),a}finally{URL.revokeObjectURL(o)}let r=new AudioWorkletNode(s,"persona-pcm-player",{numberOfInputs:0,numberOfOutputs:1,outputChannelCount:[1],processorOptions:{waterlineSamples:t}});r.connect(s.destination);let u=[],f=[],l=null;return r.port.onmessage=a=>{let h=a.data?.type;if(h==="started"){let c=f.slice();f=[],c.forEach(d=>d())}else if(h==="drained"){let c=u.slice();u=[],c.forEach(d=>d())}},{enqueue(a){let h=a;if(l){let d=new Uint8Array(l.length+a.length);d.set(l),d.set(a,l.length),h=d,l=null}if(h.length%2!==0&&(l=new Uint8Array([h[h.length-1]]),h=h.subarray(0,h.length-1)),h.length===0)return;let c=C(h);c.length!==0&&r.port.postMessage({type:"push",samples:c},[c.buffer])},setContinuousMode(a){r.port.postMessage({type:"continuous",enabled:a})},markStreamEnd(){r.port.postMessage({type:"eos"})},flush(){l=null,u=[],f=[],r.port.postMessage({type:"clear"})},onFinished(a){u.push(a)},onStarted(a){f.push(a)},pause(){s.state==="running"&&s.suspend()},resume(){s.state==="suspended"&&s.resume()},destroy(){r.port.onmessage=null;try{r.disconnect()}catch{}return s.close().catch(()=>{})}}}function S(){return b()}var p=class{#e=null;#i=0;#t=[];#s=[];#r=[];#o=!1;#u=!1;#c=0;#p=!1;#y=!1;#l;#a=[];#d=0;#b=!1;#m;#f;#h;#n=null;constructor(e=24e3,t={}){this.#f=e;let i=Math.max(0,t.prebufferMs??0);this.#h=Math.round(e*i/1e3),this.#l=this.#h>0}#w(){if(!this.#e){let t=typeof window<"u"?window:void 0;if(!t)throw new Error("AudioPlaybackManager requires a browser environment");let i=t.AudioContext||t.webkitAudioContext;this.#e=new i({sampleRate:this.#f})}let e=this.#e;return e.state==="suspended"&&!this.#y&&e.resume(),e}enqueue(e){if(e.length===0)return;let t=e;if(this.#n){let s=new Uint8Array(this.#n.length+e.length);s.set(this.#n),s.set(e,this.#n.length),t=s,this.#n=null}if(t.length%2!==0&&(this.#n=new Uint8Array([t[t.length-1]]),t=t.subarray(0,t.length-1)),t.length===0)return;let i=this.#E(t);i.length!==0&&(this.#l?(this.#a.push(i),this.#d+=i.length,clearTimeout(this.#m),this.#d>=this.#h?this.#g():this.#b&&(this.#m=setTimeout(()=>this.#g(),this.#h/this.#f*1e3))):this.#S(i))}markStreamEnd(){this.#a.length>0&&this.#g(),this.#u=!0,this.#P()}flush(){for(let e of this.#t){e.onended=null;try{e.stop(),e.disconnect()}catch{}}this.#t=[],this.#c=0,this.#i=0,this.#o=!1,this.#u=!1,this.#s=[],this.#r=[],this.#n=null,this.#a=[],this.#d=0,this.#l=this.#h>0,this.#p=!1,clearTimeout(this.#m)}setContinuousMode(e){this.#b=e}isPlaying(){return this.#o}onFinished(e){this.#s.push(e)}onStarted(e){this.#r.push(e)}pause(){this.#y=!0,this.#e&&this.#e.state==="running"&&this.#e.suspend()}resume(){this.#y=!1,this.#e&&this.#e.state==="suspended"&&this.#e.resume()}async destroy(){this.flush(),this.#e&&(await this.#e.close(),this.#e=null)}#g(){this.#l=!1;let e=this.#a;this.#a=[],this.#d=0;for(let t of e)this.#S(t)}#S(e){if(e.length===0)return;let t=this.#w(),i=t.createBuffer(1,e.length,this.#f);i.getChannelData(0).set(e);let s=t.createBufferSource();s.buffer=i,s.connect(t.destination);let o=t.currentTime;if(this.#i===0?this.#i=o:this.#i<o&&(this.#i=o,this.#h>0&&(this.#l=!0)),s.start(this.#i),this.#i+=i.duration,this.#t.push(s),this.#c++,this.#o=!0,!this.#p){this.#p=!0;let r=this.#r.slice();this.#r=[];for(let u of r)u()}s.onended=()=>{let r=this.#t.indexOf(s);r!==-1&&(this.#t.splice(r,1),this.#c--,this.#P())}}#P(){if(this.#u&&this.#c<=0&&this.#a.length===0){this.#o=!1,this.#u=!1;let e=this.#s.slice();this.#s=[];for(let t of e)t()}}#E(e){let t=Math.floor(e.length/2),i=new Float32Array(t),s=new DataView(e.buffer,e.byteOffset,e.byteLength);for(let o=0;o<t;o++){let r=s.getInt16(o*2,!0);i[o]=r/32768}return i}};function O(n){return n.replace(/\/+$/,"")}var y=class{constructor(e){this.id="runtype-tts";this.supportsPause=!0;this.#e=null;this.#i=null;this.#t=0;this.#s=e}#e;#i;#t;#s;#r(){return this.#i??=Promise.resolve(this.#s.createPlaybackEngine?this.#s.createPlaybackEngine():new p(24e3,{prebufferMs:this.#s.prebufferMs??200})).then(e=>this.#e=e)}speak(e,t){let i=++this.#t;this.#o(i,e,t)}async#o(e,t,i){try{let s=await this.#r();if(e!==this.#t)return;s.flush(),s.resume(),s.onStarted(()=>{e===this.#t&&i.onStart?.()}),s.onFinished(()=>{e===this.#t&&i.onEnd?.()});let o=`${O(this.#s.host)}/v1/agents/${encodeURIComponent(this.#s.agentId)}/speak`,r=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.#s.clientToken}`},body:JSON.stringify({text:t.text,voice:t.voice??this.#s.voice,format:"pcm"})});if(e!==this.#t)return;if(!r.ok||!r.body)throw new Error(await M(r));let u=r.body.getReader();for(;;){let{done:f,value:l}=await u.read();if(e!==this.#t){await u.cancel().catch(()=>{});return}if(f)break;l&&l.byteLength>0&&s.enqueue(l)}s.markStreamEnd()}catch(s){if(e!==this.#t)return;let o=s instanceof Error?s:new Error(String(s));this.#s.onError?.(o),i.onError?.(o)}}pause(){this.#e?.pause()}resume(){this.#e?.resume()}stop(){this.#t++,this.#e?.flush()}destroy(){this.#t++,this.#e?.destroy(),this.#e=null,this.#i=null}};async function M(n){try{let e=await n.json();return e.detail?`${e.error??`Runtype TTS ${n.status}`}: ${e.detail}`:e.error??`Runtype TTS request failed (${n.status})`}catch{return`Runtype TTS request failed (${n.status})`}}var m=class{constructor(e,t,i={}){this.id="fallback";this.#i=e,this.#t=t,this.#s=i,this.#e=e}#e;#i;#t;#s;get supportsPause(){return this.#e.supportsPause}speak(e,t){this.#e=this.#i;let i=!1;this.#i.speak(e,{onStart:()=>{i=!0,t.onStart?.()},onEnd:()=>t.onEnd?.(),onError:s=>{if(i){t.onError?.(s);return}this.#s.onFallback?.(s),this.#e=this.#t,this.#t.speak(e,t)}})}pause(){this.#e.pause()}resume(){this.#e.resume()}stop(){this.#e.stop()}destroy(){this.#i.destroy?.(),this.#t.destroy?.()}};0&&(module.exports={FallbackSpeechEngine,RuntypeSpeechEngine,createPcmStreamPlayer,createWorkletPlaybackEngine});
|
|
@@ -67,6 +67,13 @@ interface VoicePlaybackEngine {
|
|
|
67
67
|
onFinished(callback: () => void): void;
|
|
68
68
|
/** Release all audio resources. */
|
|
69
69
|
destroy(): Promise<void> | void;
|
|
70
|
+
/**
|
|
71
|
+
* Optional. Speech-to-speech calls stream reply audio with no end-of-stream
|
|
72
|
+
* marker, so an engine that holds audio below a prebuffer waterline must, while
|
|
73
|
+
* continuous, release that held tail on its own (e.g. after a short input gap)
|
|
74
|
+
* instead of waiting for {@link markStreamEnd}. Engines without a prebuffer can omit it.
|
|
75
|
+
*/
|
|
76
|
+
setContinuousMode?(enabled: boolean): void;
|
|
70
77
|
}
|
|
71
78
|
/**
|
|
72
79
|
* A {@link VoicePlaybackEngine} that also supports pause/resume. Returned by
|
|
@@ -172,16 +179,11 @@ interface RuntypeSpeechEngineOptions {
|
|
|
172
179
|
}
|
|
173
180
|
/** Streaming `SpeechEngine` backed by Runtype's `/v1/agents/:id/speak`. */
|
|
174
181
|
declare class RuntypeSpeechEngine implements SpeechEngine {
|
|
175
|
-
private
|
|
182
|
+
#private;
|
|
176
183
|
readonly id = "runtype-tts";
|
|
177
184
|
readonly supportsPause = true;
|
|
178
|
-
private player;
|
|
179
|
-
private playerPromise;
|
|
180
|
-
private generation;
|
|
181
185
|
constructor(opts: RuntypeSpeechEngineOptions);
|
|
182
|
-
private ensurePlayer;
|
|
183
186
|
speak(request: SpeechRequest, callbacks: SpeechCallbacks): void;
|
|
184
|
-
private run;
|
|
185
187
|
pause(): void;
|
|
186
188
|
resume(): void;
|
|
187
189
|
stop(): void;
|
|
@@ -198,11 +200,8 @@ interface FallbackSpeechEngineOptions {
|
|
|
198
200
|
}
|
|
199
201
|
/** A `SpeechEngine` that falls back from `primary` to `fallback` per utterance. */
|
|
200
202
|
declare class FallbackSpeechEngine implements SpeechEngine {
|
|
201
|
-
private
|
|
202
|
-
private readonly fallback;
|
|
203
|
-
private readonly options;
|
|
203
|
+
#private;
|
|
204
204
|
readonly id = "fallback";
|
|
205
|
-
private active;
|
|
206
205
|
constructor(primary: SpeechEngine, fallback: SpeechEngine, options?: FallbackSpeechEngineOptions);
|
|
207
206
|
get supportsPause(): boolean;
|
|
208
207
|
speak(request: SpeechRequest, callbacks: SpeechCallbacks): void;
|
|
@@ -67,6 +67,13 @@ interface VoicePlaybackEngine {
|
|
|
67
67
|
onFinished(callback: () => void): void;
|
|
68
68
|
/** Release all audio resources. */
|
|
69
69
|
destroy(): Promise<void> | void;
|
|
70
|
+
/**
|
|
71
|
+
* Optional. Speech-to-speech calls stream reply audio with no end-of-stream
|
|
72
|
+
* marker, so an engine that holds audio below a prebuffer waterline must, while
|
|
73
|
+
* continuous, release that held tail on its own (e.g. after a short input gap)
|
|
74
|
+
* instead of waiting for {@link markStreamEnd}. Engines without a prebuffer can omit it.
|
|
75
|
+
*/
|
|
76
|
+
setContinuousMode?(enabled: boolean): void;
|
|
70
77
|
}
|
|
71
78
|
/**
|
|
72
79
|
* A {@link VoicePlaybackEngine} that also supports pause/resume. Returned by
|
|
@@ -172,16 +179,11 @@ interface RuntypeSpeechEngineOptions {
|
|
|
172
179
|
}
|
|
173
180
|
/** Streaming `SpeechEngine` backed by Runtype's `/v1/agents/:id/speak`. */
|
|
174
181
|
declare class RuntypeSpeechEngine implements SpeechEngine {
|
|
175
|
-
private
|
|
182
|
+
#private;
|
|
176
183
|
readonly id = "runtype-tts";
|
|
177
184
|
readonly supportsPause = true;
|
|
178
|
-
private player;
|
|
179
|
-
private playerPromise;
|
|
180
|
-
private generation;
|
|
181
185
|
constructor(opts: RuntypeSpeechEngineOptions);
|
|
182
|
-
private ensurePlayer;
|
|
183
186
|
speak(request: SpeechRequest, callbacks: SpeechCallbacks): void;
|
|
184
|
-
private run;
|
|
185
187
|
pause(): void;
|
|
186
188
|
resume(): void;
|
|
187
189
|
stop(): void;
|
|
@@ -198,11 +200,8 @@ interface FallbackSpeechEngineOptions {
|
|
|
198
200
|
}
|
|
199
201
|
/** A `SpeechEngine` that falls back from `primary` to `fallback` per utterance. */
|
|
200
202
|
declare class FallbackSpeechEngine implements SpeechEngine {
|
|
201
|
-
private
|
|
202
|
-
private readonly fallback;
|
|
203
|
-
private readonly options;
|
|
203
|
+
#private;
|
|
204
204
|
readonly id = "fallback";
|
|
205
|
-
private active;
|
|
206
205
|
constructor(primary: SpeechEngine, fallback: SpeechEngine, options?: FallbackSpeechEngineOptions);
|
|
207
206
|
get supportsPause(): boolean;
|
|
208
207
|
speak(request: SpeechRequest, callbacks: SpeechCallbacks): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var b=`
|
|
2
2
|
class PersonaPcmPlayerProcessor extends AudioWorkletProcessor {
|
|
3
3
|
constructor(options) {
|
|
4
4
|
super()
|
|
@@ -17,9 +17,16 @@ class PersonaPcmPlayerProcessor extends AudioWorkletProcessor {
|
|
|
17
17
|
// consumer can flip UI from loading\u2192playing only when audio is truly audible.
|
|
18
18
|
// A mid-reply underrun re-buffers (waiting=true) but must NOT re-signal.
|
|
19
19
|
this.startedSignaled = false
|
|
20
|
+
// Continuous (speech-to-speech) streams never send eos, so a tail held below
|
|
21
|
+
// the waterline is released once input has been quiet for one waterline.
|
|
22
|
+
this.continuous = false
|
|
23
|
+
this.idle = 0
|
|
20
24
|
this.port.onmessage = (e) => {
|
|
21
25
|
const msg = e.data
|
|
22
|
-
if (msg.type === '
|
|
26
|
+
if (msg.type === 'continuous') {
|
|
27
|
+
this.continuous = msg.enabled
|
|
28
|
+
} else if (msg.type === 'push') {
|
|
29
|
+
this.idle = 0
|
|
23
30
|
this.eosSeen = false
|
|
24
31
|
this.chunks.push(msg.samples)
|
|
25
32
|
this.buffered += msg.samples.length
|
|
@@ -55,7 +62,15 @@ class PersonaPcmPlayerProcessor extends AudioWorkletProcessor {
|
|
|
55
62
|
}
|
|
56
63
|
process(inputs, outputs) {
|
|
57
64
|
const out = outputs[0][0]
|
|
58
|
-
if (!out
|
|
65
|
+
if (!out) return true
|
|
66
|
+
if (this.waiting) {
|
|
67
|
+
// outputs are pre-zeroed: silence while (re)buffering
|
|
68
|
+
if (!this.continuous || this.buffered === 0) return true
|
|
69
|
+
this.idle += out.length
|
|
70
|
+
if (this.idle < this.waterline) return true
|
|
71
|
+
this.waiting = false
|
|
72
|
+
this.signalStarted()
|
|
73
|
+
}
|
|
59
74
|
let i = 0
|
|
60
75
|
while (i < out.length && this.buffered > 0) {
|
|
61
76
|
const chunk = this.chunks[0]
|
|
@@ -77,4 +92,4 @@ class PersonaPcmPlayerProcessor extends AudioWorkletProcessor {
|
|
|
77
92
|
}
|
|
78
93
|
}
|
|
79
94
|
registerProcessor('persona-pcm-player', PersonaPcmPlayerProcessor)
|
|
80
|
-
`;function
|
|
95
|
+
`;function S(r){let e=r.length>>1,t=new Float32Array(e),i=new DataView(r.buffer,r.byteOffset,r.byteLength);for(let s=0;s<e;s++)t[s]=i.getInt16(s*2,!0)/32768;return t}async function g(r={}){let e=r.prebufferMs??150,t=Math.max(1,Math.round(24e3*e/1e3)),i=window.AudioContext||window.webkitAudioContext,s=new i({sampleRate:24e3});s.state==="suspended"&&await s.resume().catch(()=>{});let o=URL.createObjectURL(new Blob([b],{type:"application/javascript"}));try{await s.audioWorklet.addModule(o)}catch(a){throw s.close().catch(()=>{}),a}finally{URL.revokeObjectURL(o)}let n=new AudioWorkletNode(s,"persona-pcm-player",{numberOfInputs:0,numberOfOutputs:1,outputChannelCount:[1],processorOptions:{waterlineSamples:t}});n.connect(s.destination);let u=[],f=[],l=null;return n.port.onmessage=a=>{let h=a.data?.type;if(h==="started"){let c=f.slice();f=[],c.forEach(d=>d())}else if(h==="drained"){let c=u.slice();u=[],c.forEach(d=>d())}},{enqueue(a){let h=a;if(l){let d=new Uint8Array(l.length+a.length);d.set(l),d.set(a,l.length),h=d,l=null}if(h.length%2!==0&&(l=new Uint8Array([h[h.length-1]]),h=h.subarray(0,h.length-1)),h.length===0)return;let c=S(h);c.length!==0&&n.port.postMessage({type:"push",samples:c},[c.buffer])},setContinuousMode(a){n.port.postMessage({type:"continuous",enabled:a})},markStreamEnd(){n.port.postMessage({type:"eos"})},flush(){l=null,u=[],f=[],n.port.postMessage({type:"clear"})},onFinished(a){u.push(a)},onStarted(a){f.push(a)},pause(){s.state==="running"&&s.suspend()},resume(){s.state==="suspended"&&s.resume()},destroy(){n.port.onmessage=null;try{n.disconnect()}catch{}return s.close().catch(()=>{})}}}function P(){return g()}var p=class{#e=null;#i=0;#t=[];#s=[];#r=[];#o=!1;#u=!1;#c=0;#p=!1;#y=!1;#l;#a=[];#d=0;#b=!1;#m;#f;#h;#n=null;constructor(e=24e3,t={}){this.#f=e;let i=Math.max(0,t.prebufferMs??0);this.#h=Math.round(e*i/1e3),this.#l=this.#h>0}#w(){if(!this.#e){let t=typeof window<"u"?window:void 0;if(!t)throw new Error("AudioPlaybackManager requires a browser environment");let i=t.AudioContext||t.webkitAudioContext;this.#e=new i({sampleRate:this.#f})}let e=this.#e;return e.state==="suspended"&&!this.#y&&e.resume(),e}enqueue(e){if(e.length===0)return;let t=e;if(this.#n){let s=new Uint8Array(this.#n.length+e.length);s.set(this.#n),s.set(e,this.#n.length),t=s,this.#n=null}if(t.length%2!==0&&(this.#n=new Uint8Array([t[t.length-1]]),t=t.subarray(0,t.length-1)),t.length===0)return;let i=this.#E(t);i.length!==0&&(this.#l?(this.#a.push(i),this.#d+=i.length,clearTimeout(this.#m),this.#d>=this.#h?this.#g():this.#b&&(this.#m=setTimeout(()=>this.#g(),this.#h/this.#f*1e3))):this.#S(i))}markStreamEnd(){this.#a.length>0&&this.#g(),this.#u=!0,this.#P()}flush(){for(let e of this.#t){e.onended=null;try{e.stop(),e.disconnect()}catch{}}this.#t=[],this.#c=0,this.#i=0,this.#o=!1,this.#u=!1,this.#s=[],this.#r=[],this.#n=null,this.#a=[],this.#d=0,this.#l=this.#h>0,this.#p=!1,clearTimeout(this.#m)}setContinuousMode(e){this.#b=e}isPlaying(){return this.#o}onFinished(e){this.#s.push(e)}onStarted(e){this.#r.push(e)}pause(){this.#y=!0,this.#e&&this.#e.state==="running"&&this.#e.suspend()}resume(){this.#y=!1,this.#e&&this.#e.state==="suspended"&&this.#e.resume()}async destroy(){this.flush(),this.#e&&(await this.#e.close(),this.#e=null)}#g(){this.#l=!1;let e=this.#a;this.#a=[],this.#d=0;for(let t of e)this.#S(t)}#S(e){if(e.length===0)return;let t=this.#w(),i=t.createBuffer(1,e.length,this.#f);i.getChannelData(0).set(e);let s=t.createBufferSource();s.buffer=i,s.connect(t.destination);let o=t.currentTime;if(this.#i===0?this.#i=o:this.#i<o&&(this.#i=o,this.#h>0&&(this.#l=!0)),s.start(this.#i),this.#i+=i.duration,this.#t.push(s),this.#c++,this.#o=!0,!this.#p){this.#p=!0;let n=this.#r.slice();this.#r=[];for(let u of n)u()}s.onended=()=>{let n=this.#t.indexOf(s);n!==-1&&(this.#t.splice(n,1),this.#c--,this.#P())}}#P(){if(this.#u&&this.#c<=0&&this.#a.length===0){this.#o=!1,this.#u=!1;let e=this.#s.slice();this.#s=[];for(let t of e)t()}}#E(e){let t=Math.floor(e.length/2),i=new Float32Array(t),s=new DataView(e.buffer,e.byteOffset,e.byteLength);for(let o=0;o<t;o++){let n=s.getInt16(o*2,!0);i[o]=n/32768}return i}};function w(r){return r.replace(/\/+$/,"")}var y=class{constructor(e){this.id="runtype-tts";this.supportsPause=!0;this.#e=null;this.#i=null;this.#t=0;this.#s=e}#e;#i;#t;#s;#r(){return this.#i??=Promise.resolve(this.#s.createPlaybackEngine?this.#s.createPlaybackEngine():new p(24e3,{prebufferMs:this.#s.prebufferMs??200})).then(e=>this.#e=e)}speak(e,t){let i=++this.#t;this.#o(i,e,t)}async#o(e,t,i){try{let s=await this.#r();if(e!==this.#t)return;s.flush(),s.resume(),s.onStarted(()=>{e===this.#t&&i.onStart?.()}),s.onFinished(()=>{e===this.#t&&i.onEnd?.()});let o=`${w(this.#s.host)}/v1/agents/${encodeURIComponent(this.#s.agentId)}/speak`,n=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.#s.clientToken}`},body:JSON.stringify({text:t.text,voice:t.voice??this.#s.voice,format:"pcm"})});if(e!==this.#t)return;if(!n.ok||!n.body)throw new Error(await E(n));let u=n.body.getReader();for(;;){let{done:f,value:l}=await u.read();if(e!==this.#t){await u.cancel().catch(()=>{});return}if(f)break;l&&l.byteLength>0&&s.enqueue(l)}s.markStreamEnd()}catch(s){if(e!==this.#t)return;let o=s instanceof Error?s:new Error(String(s));this.#s.onError?.(o),i.onError?.(o)}}pause(){this.#e?.pause()}resume(){this.#e?.resume()}stop(){this.#t++,this.#e?.flush()}destroy(){this.#t++,this.#e?.destroy(),this.#e=null,this.#i=null}};async function E(r){try{let e=await r.json();return e.detail?`${e.error??`Runtype TTS ${r.status}`}: ${e.detail}`:e.error??`Runtype TTS request failed (${r.status})`}catch{return`Runtype TTS request failed (${r.status})`}}var m=class{constructor(e,t,i={}){this.id="fallback";this.#i=e,this.#t=t,this.#s=i,this.#e=e}#e;#i;#t;#s;get supportsPause(){return this.#e.supportsPause}speak(e,t){this.#e=this.#i;let i=!1;this.#i.speak(e,{onStart:()=>{i=!0,t.onStart?.()},onEnd:()=>t.onEnd?.(),onError:s=>{if(i){t.onError?.(s);return}this.#s.onFallback?.(s),this.#e=this.#t,this.#t.speak(e,t)}})}pause(){this.#e.pause()}resume(){this.#e.resume()}stop(){this.#e.stop()}destroy(){this.#i.destroy?.(),this.#t.destroy?.()}};export{m as FallbackSpeechEngine,y as RuntypeSpeechEngine,g as createPcmStreamPlayer,P as createWorkletPlaybackEngine};
|
package/dist/webmcp-polyfill.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var Ke=Object.defineProperty;var we=e=>{throw TypeError(e)};var Xe=(e,t,n)=>t in e?Ke(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var re=(e,t,n)=>Xe(e,typeof t!="symbol"?t+"":t,n),ie=(e,t,n)=>t.has(e)||we("Cannot "+n);var u=(e,t,n)=>(ie(e,t,"read from private field"),n?n.call(e):t.get(e)),M=(e,t,n)=>t.has(e)?we("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),L=(e,t,n,o)=>(ie(e,t,"write to private field"),o?o.call(e,n):t.set(e,n),n),R=(e,t,n)=>(ie(e,t,"access private method"),n);var Qe="Failed to parse input arguments",ve="Tool was executed but the invocation failed. For example, the script function threw an error";var et=/^[A-Za-z0-9_.-]{1,128}$/u;function K(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Z(e){if(typeof e=="symbol")throw new TypeError("Symbol values cannot be converted to a DOMString");return String(e)}function Ee(e){let t=Reflect.get(e,"name"),n=Reflect.get(e,"description"),o=Reflect.get(e,"title");if(t===void 0)throw new TypeError('Tool "name" is required');if(n===void 0)throw new TypeError('Tool "description" is required');let r=Reflect.get(e,"annotations"),i=K(r)?r:{},s=Reflect.get(e,"inputSchema"),a=Reflect.get(e,"outputSchema"),h=Reflect.get(e,"execute");return{name:Z(t),...o===void 0?{}:{title:Z(o).toWellFormed()},description:Z(n),...s===void 0?{}:{inputSchema:s},...a===void 0?{}:{outputSchema:a},execute:h,...r===void 0?{}:{annotations:{...i.title===void 0?{}:{title:Z(i.title).toWellFormed()},readOnlyHint:!!i.readOnlyHint,...i.destructiveHint===void 0?{}:{destructiveHint:!!i.destructiveHint},...i.idempotentHint===void 0?{}:{idempotentHint:!!i.idempotentHint},...i.openWorldHint===void 0?{}:{openWorldHint:!!i.openWorldHint},untrustedContentHint:!!i.untrustedContentHint}}}}function D(e){return new DOMException(e,"UnknownError")}function Se(e){return D(e instanceof Error?`${ve}: ${e.message}`:ve)}function z(e){return new DOMException(e,"InvalidStateError")}function Te(e){if(e.name==="")throw z('Tool "name" must be a non-empty string');if(typeof e.name!="string"||!et.test(e.name))throw z('Tool "name" must be 1\u2013128 characters and contain only ASCII alphanumeric, underscore, hyphen, or period');if(typeof e.description!="string"||e.description.length===0)throw z('Tool "description" must be a non-empty string');if(typeof e.execute!="function")throw new TypeError('Tool "execute" must be a function')}function Me(e){return{readOnlyHint:e.readOnlyHint??!1,untrustedContentHint:e.untrustedContentHint??!1}}function Oe(e){try{let t=JSON.parse(e);if(Array.isArray(t)||K(t))return t}catch{}throw D(Qe)}function xe(e){if(typeof e=="object"&&e!==null||typeof e=="function")try{let t=JSON.stringify(e);if(t)return t}catch{}return String(e)||"Operation succeeded"}function se(e,t,n=()=>t?.reason){return t?t.aborted?Promise.reject(n()):new Promise((o,r)=>{let i=()=>{s(),r(n())},s=()=>t.removeEventListener("abort",i);t.addEventListener("abort",i,{once:!0}),e.then(a=>{s(),o(a)},a=>{s(),r(a)})}):e}function tt(e){let t=e.origin==="null"?e:new URL(e.origin),n=t.protocol;if(["https:","wss:","file:","chrome-extension:","moz-extension:"].includes(n))return!0;let o=t.hostname.toLowerCase(),r=o.split("."),i=r.length===4&&r.every(s=>/^\d{1,3}$/u.test(s)&&Number(s)<=255)&&Number(r[0])===127;return o==="::1"||o==="[::1]"||o==="localhost"||o==="localhost."||o.endsWith(".localhost")||o.endsWith(".localhost.")||i}function ae(e){for(let t of e??[]){let n;try{n=new URL(t)}catch{throw new DOMException(`Invalid or untrustworthy origin: ${String(t)}`,"SecurityError")}if(!tt(n))throw new DOMException(`Invalid or untrustworthy origin: ${t}`,"SecurityError")}}function V(e){if(nt(),!e)return;let t=e.defaultView?.DOMException??DOMException,n=!1;try{let i=e.defaultView;n=!!(i&&i.document===e)}catch{}if(!n)throw new t("The associated document is not fully active","InvalidStateError");let o=Reflect.get(e,"permissionsPolicy")??Reflect.get(e,"featurePolicy");if(o&&typeof o=="object"){let i=Reflect.get(o,"features"),s=Reflect.get(o,"allowsFeature");if(typeof i=="function"&&typeof s=="function"){let a=Reflect.apply(i,o,[]);if(Array.isArray(a)&&a.includes("tools")){if(Reflect.apply(s,o,["tools"])===!0)return;throw new t("WebMCP is disabled by Permissions Policy","NotAllowedError")}}}let r=e.defaultView;if(!(!r||r.parent===r)){try{r.parent.document;return}catch{}throw new t("WebMCP in cross-origin frames requires native Permissions Policy support","NotAllowedError")}}function nt(){if(globalThis.originAgentCluster===!1&&globalThis.location?.protocol!=="file:")throw new DOMException("","SecurityError")}function Pe(e){try{if(new URL(String(e)).origin!=="null")return}catch{}throw new DOMException(`Unsupported tool origin: ${String(e)}`,"NotSupportedError")}function Ae(e){if(e===null||typeof e!="object"&&typeof e!="function")throw new TypeError("inputSchema must be an object");let t=JSON.stringify(e);if(t===void 0)throw new TypeError("inputSchema must be JSON-serializable");return t}var ge=new WeakSet,le=new WeakMap,F=new WeakMap;function We(e){return e.isTrusted&&(ge.has(e)||e.eventPhase!==Event.NONE&&e.target instanceof HTMLFormElement&&F.has(e.target))}function ot(e,t){if(!We(e))throw new DOMException("respondWith() is only available during an agent-invoked submit event","InvalidStateError");if(!e.defaultPrevented)throw new DOMException("respondWith() requires preventDefault() during an agent-invoked submit event","InvalidStateError");if(e.eventPhase===Event.NONE)throw new DOMException("respondWith() is only available while the submit event is being dispatched","InvalidStateError");ge.add(e);let n=Promise.resolve(t);le.set(e,n),e.target instanceof HTMLFormElement&&F.get(e.target)?.respond(e)}var _e=new Set(["email","password","search","tel","text","url"]),rt=new Set([..._e,"date","datetime-local","month","number","time","week"]);function $e(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function ye(e){return Reflect.get(HTMLFormElement.prototype,"elements",e)}function ce(e,t){return Reflect.apply(Element.prototype.getAttribute,e,[t])}function fe(e,t){return Reflect.apply(Element.prototype.hasAttribute,e,[t])}function it(e){return Reflect.get(Node.prototype,"isConnected",e)}function st(e){return Reflect.get(Element.prototype,"shadowRoot",e)}function at(e){return Reflect.apply(HTMLFormElement.prototype.checkValidity,e,[])}function ct(e,t){Reflect.apply(HTMLFormElement.prototype.requestSubmit,e,t?[t]:[])}function ut(e){return[...ye(e)].filter(t=>$e(t)&&!t.matches(":disabled")&&!("readOnly"in t&&t.readOnly&&(t instanceof HTMLTextAreaElement||rt.has(t.type))))}function qe(e){let t=new Map;for(let n of ut(e)){let o=n.name.trim(),r=t.get(o);r?r.push(n):t.set(o,[n])}return t}function Ue(e){return[...e.labels??[]].map(t=>{let n=t.cloneNode(!0);return n instanceof HTMLElement?(n.querySelectorAll("button, input, meter, output, progress, select, textarea").forEach(o=>o.remove()),n.textContent?.trim()??""):""}).filter(Boolean).join("; ")}function lt(e,t){for(let n=t[0]?.parentElement;n&&n!==e;n=n.parentElement)if(n instanceof HTMLFieldSetElement&&t.every(o=>n.contains(o)))return n}function ft(e,t){if(t.length===1){let n=t[0];return n&&(n.getAttribute("toolparamdescription")||Ue(n)||n.getAttribute("aria-description"))||void 0}return lt(e,t)?.getAttribute("toolparamdescription")||void 0}function m(e,t,n,o){let r=ft(t,n),i=r&&o?`${r} (${o})`:r||o;return i?{...e,description:i}:e}function Ce(e,t){let n=e.getAttribute(t);if(n===null||n.trim()==="")return;let o=Number(n);return Number.isFinite(o)?o:void 0}function pt(e,t){let n=e/t;return Math.abs(n-Math.round(n))<Number.EPSILON*16}function ze(e){let t=e.getAttribute("pattern");if(t!==null)try{return new RegExp(t,"v"),t}catch{return}}function Ie(e,t=!0){let n={type:"number"},o=Ce(e,"min"),r=Ce(e,"max");o!==void 0&&(n.minimum=o),r!==void 0&&(n.maximum=r);let i=e.getAttribute("step");if(i!=="any"){let a=i===null||i===""?1:Number(i),h=Number.isFinite(a)&&a>0?a:1,g=Number(e.getAttribute("value"));pt(o??(Number.isFinite(g)?g:0),h)&&(n.multipleOf=h)}let s=t?ze(e):void 0;return s!==void 0&&(n.pattern=s),n}function Le(e,t){let n=e.getAttribute("step"),o=n===null||n===""?60:Number(n),r=Number.isFinite(o)&&o>0?o:60;return r<1?`${t}(:[0-5][0-9](\\.[0-9]{1,3})?)?$`:r<60?`${t}(:[0-5][0-9])?$`:`${t}$`}function dt(e){return{anyOf:e.map(t=>({type:"string",const:t.value,title:t.textContent??""})),enum:e.map(t=>t.value)}}function ue(e){return{anyOf:e.map(t=>{let n=Ue(t);return{type:"string",const:t.value,...n?{title:n}:{}}}),enum:e.map(t=>t.value)}}function Ve(e,t){let n=t[0];if(n){if(t.length>1)return t.every(o=>o instanceof HTMLInputElement)?t.every(o=>o.type==="checkbox")?m({type:"array",items:{type:"string",...ue(t)},uniqueItems:!0},e,t):t.every(o=>o.type==="radio")?m({type:"string",...ue(t)},e,t):void 0:void 0;if(n instanceof HTMLTextAreaElement)return m({type:"string"},e,t);if(n instanceof HTMLSelectElement){let o=dt([...n.options]);return m(n.multiple?{type:"array",items:{type:"string",...o},uniqueItems:!0}:{type:"string",...o},e,t)}if(_e.has(n.type)){let o={type:"string"},r=ze(n);return r!==void 0&&(o.pattern=r),m(o,e,t)}if(n.type==="hidden")return n.getAttribute("toolparamdescription")?m({type:"string"},e,t):void 0;if(n.type==="number")return m(Ie(n),e,t);if(n.type==="range"){let o=Ie(n,!1);return o.minimum??(o.minimum=0),o.maximum??(o.maximum=100),m(o,e,t)}if(n.type==="checkbox")return m({type:"boolean"},e,t);if(n.type==="radio")return m({type:"string",...ue([n])},e,t);if(n.type==="date")return m({type:"string",format:"date"},e,t,"Dates MUST be provided in 'YYYY-MM-DD' format.");if(n.type==="month")return m({type:"string",format:"^[0-9]{4}-(0[1-9]|1[0-2])$"},e,t);if(n.type==="week")return m({type:"string",format:"^[0-9]{4}-W(0[1-9]|[1-4][0-9]|5[0-3])$"},e,t);if(n.type==="time")return m({type:"string",format:Le(n,"^([01][0-9]|2[0-3]):[0-5][0-9]")},e,t);if(n.type==="datetime-local")return m({type:"string",format:Le(n,"^[0-9]{4}-(0[1-9]|1[0-2])-[0-9]{2}T([01][0-9]|2[0-3]):[0-5][0-9]")},e,t);if(n.type==="color")return m({type:"string",format:"^#[0-9a-zA-Z]{6}$"},e,t)}}function mt(e){let t={},n=[];for(let[o,r]of qe(e)){if(!o)continue;let i=Ve(e,r);i&&(Object.defineProperty(t,o,{configurable:!0,enumerable:!0,value:i,writable:!0}),r.some(s=>s.required)&&n.push(o))}return{type:"object",properties:t,required:n}}function ht(e){return{name:ce(e,"toolname")??"",title:ce(e,"tooltitle")??"",description:ce(e,"tooldescription")??"",inputSchema:mt(e),autosubmit:fe(e,"toolautosubmit")}}function b(e){if(typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return String(e)}function Be(e){if(typeof e=="boolean")return e;if(typeof e=="number"&&Number.isInteger(e))return e!==0;if(typeof e=="string"){if(e==="1"||e.toLowerCase()==="true")return!0;if(e==="0"||e.toLowerCase()==="false")return!1}}function Re(e,t){if(!Array.isArray(e))return!1;let n=new Set(t);for(let o of e){let r=b(o);if(r===void 0||!n.delete(r))return!1}return!0}function gt(e,t){if(t==="")return e.type!=="number"&&e.type!=="range";let n=e.ownerDocument.createElement("input");return n.type=e.type,n.value=t,n.value!==""}function yt(e,t,n){let o=t[0];if(!o||!Ve(e,t))return!1;if(t.length>1){if(!t.every(i=>i instanceof HTMLInputElement))return!1;if(t.every(i=>i.type==="checkbox"))return Re(n,new Set(t.map(i=>i.value)));if(t.every(i=>i.type==="radio")){let i=b(n);return i!==void 0&&t.some(s=>s.value===i)}return!1}if(o instanceof HTMLSelectElement){let i=new Set([...o.options].map(a=>a.value));if(o.multiple)return Re(n,i);let s=b(n);return s!==void 0&&i.has(s)}if(o instanceof HTMLTextAreaElement)return b(n)!==void 0;if(o.type==="checkbox")return Be(n)!==void 0;if(o.type==="radio"){let i=b(n);return i!==void 0&&o.value===i}let r=b(n);return r!==void 0&>(o,r)}function N(e){e.dispatchEvent(new Event("input",{bubbles:!0,composed:!0})),e.dispatchEvent(new Event("change",{bubbles:!0}))}function bt(e,t){let n=e instanceof HTMLInputElement?HTMLInputElement.prototype:HTMLTextAreaElement.prototype;Object.getOwnPropertyDescriptor(n,"value")?.set?.call(e,t)}function X(e,t){Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"checked")?.set?.call(e,t)}function wt(e,t){let n=e[0];if(!n)return;if(e.length>1&&e.every(r=>r instanceof HTMLInputElement)){if(e.every(s=>s.type==="checkbox")&&Array.isArray(t)){let s=new Set(t.map(b));for(let a of e){let h=s.has(a.value);a.checked!==h&&(X(a,h),N(a))}return}let r=b(t),i=e.find(s=>s.value===r);i&&!i.checked&&(X(i,!0),N(i));return}if(n instanceof HTMLSelectElement){if(n.multiple&&Array.isArray(t)){let i=new Set(t.map(b)),s=!1;for(let a of n.options){let h=i.has(a.value);a.selected!==h&&(a.selected=h,s=!0)}s&&N(n);return}let r=b(t);r!==void 0&&n.value!==r&&(n.value=r,N(n));return}if(n instanceof HTMLInputElement&&n.type==="checkbox"){let r=Be(t);r!==void 0&&n.checked!==r&&(X(n,r),N(n));return}if(n instanceof HTMLInputElement&&n.type==="radio"){b(t)===n.value&&!n.checked&&(X(n,!0),N(n));return}let o=b(t);o!==void 0&&n.value!==o&&(bt(n,o),N(n))}function vt(e,t){if(Array.isArray(t))throw new TypeError("Declarative tool input must be an object");let n=qe(e);for(let[o,r]of Object.entries(t)){let i=n.get(o);if(!i||!yt(e,i,r))throw new TypeError(`Invalid value for declarative form parameter "${o}"`)}for(let[o,r]of Object.entries(t))wt(n.get(o)??[],r)}function Et(e){return[...ye(e)].find(t=>!t.matches(":disabled")&&(t instanceof HTMLButtonElement&&t.type==="submit"||t instanceof HTMLInputElement&&["image","submit"].includes(t.type)))}function St(e){let t=[...ye(e)].filter(n=>$e(n)&&n.willValidate&&!n.validity.valid).map(n=>`${n.name.trim()||"{unknown}"}: ${n.validationMessage}`).join(". ");return new DOMException(`Form validation failed: ${t}`,"UnknownError")}function De(e){let t=new Event("toolactivated");return Object.defineProperty(t,"toolName",{enumerable:!0,value:e}),t}function Tt(e,t,n,o){let{form:r}=e;return e.cancelPending?.(new DOMException("Tool execution cancelled","UnknownError")),new Promise((i,s)=>{let a=!1,h=()=>{Reflect.apply(EventTarget.prototype.removeEventListener,r,["invalid",S,!0]),F.delete(r),e.cancelPending===O&&delete e.cancelPending},g=d=>{a||(a=!0,h(),d())},O=d=>g(()=>s(d)),$=d=>{d.then(y=>g(()=>i(y)),y=>g(()=>s(y)))},S=d=>{d.isTrusted&&queueMicrotask(()=>{at(r)||O(St(r))})};if(F.set(r,{complete(d){queueMicrotask(()=>{let y=le.get(d);y?$(y):d.defaultPrevented?O(new DOMException("preventDefault() requires respondWith()","UnknownError")):g(()=>i(void 0))})},direct(){g(()=>i(void 0))},respond(d){queueMicrotask(()=>{let y=le.get(d);y&&$(y)})}}),e.cancelPending=O,Reflect.apply(EventTarget.prototype.addEventListener,r,["invalid",S,!0]),!n){o?.focus(),window.dispatchEvent(De(t));return}try{ct(r,o),window.dispatchEvent(De(t))}catch(d){O(d)}})}function Mt(e,t){let n=!0,o=new Map,r=new Map,i=new Map,s=c=>{if(!(c instanceof SubmitEvent)||!c.isTrusted||!(c.target instanceof HTMLFormElement))return;let f=F.get(c.target);f&&(ge.add(c),f.complete(c))},a=c=>{if(!c.isTrusted||!(c.target instanceof HTMLFormElement))return;let f=c.target;queueMicrotask(()=>{c.defaultPrevented||o.get(f)?.cancelPending?.(new DOMException("Tool execution cancelled by form reset","UnknownError"))})};function h(c){i.get(c)?.disconnect(),i.delete(c),c.removeEventListener("reset",a,!0),c.removeEventListener("submit",s,!0)}function g(c){if(i.has(c))return;let f=new MutationObserver(O);i.set(c,f),f.observe(c,{attributes:!0,characterData:!0,childList:!0,subtree:!0}),c.addEventListener("reset",a,!0),c.addEventListener("submit",s,!0)}function O(){g(e);for(let l of i.keys())l instanceof ShadowRoot&&!Reflect.get(Node.prototype,"isConnected",l.host)&&h(l);let c=new Set,f=new Map,Y=new Map;for(let l of i.keys())for(let p of l.querySelectorAll("*")){let G=st(p);if(G&&g(G),!(p instanceof HTMLFormElement)||!fe(p,"toolname")||!fe(p,"tooldescription")||!it(p))continue;let w=p;c.add(w);let I=ht(w),x=JSON.stringify(I),q=r.get(w);if(q===x)continue;let Ze=q!==void 0;r.delete(w);let U=Y.get(I.name);if(U&&!Ze){r.set(w,x);continue}if(U){let be=f.get(U);be&&(r.set(U,be.fingerprint),f.delete(U))}Y.set(I.name,w),f.set(w,{definition:I,fingerprint:x})}for(let l of r.keys())c.has(l)||r.delete(l);for(let[l,p]of o)f.get(l)?.fingerprint!==p.fingerprint&&(p.cancelPending?.(new DOMException("Tool execution cancelled because its form changed","UnknownError")),p.controller.abort(),o.delete(l));for(let[l,{definition:p,fingerprint:G}]of f){if(o.has(l))continue;let w=new AbortController,I={controller:w,fingerprint:G,form:l};o.set(l,I),t.registerTool({name:p.name,title:p.title,description:p.description,inputSchema:p.inputSchema,execute(x){let q=Et(l);if(!p.autosubmit&&!q)throw new DOMException("A declarative form without toolautosubmit requires a submit button","UnknownError");return vt(l,x),Tt(I,p.name,p.autosubmit,q)}},{signal:w.signal}).catch(x=>{w.abort(),x?.name!=="AbortError"&&console.error(`[webmcp] declarative form tool "${p.name}" was not registered:`,x)})}}let $=()=>{},S=e.defaultView?.Element.prototype,d=S?Object.getOwnPropertyDescriptor(S,"attachShadow"):void 0;if(S&&d?.configurable){let c=S.attachShadow,f=function(Y){let l=c.call(this,Y);return n&&l.mode==="open"&&Reflect.get(Node.prototype,"ownerDocument",this)===e&&Reflect.get(Node.prototype,"isConnected",this)&&g(l),l};Object.defineProperty(S,"attachShadow",{...d,value:f}),$=()=>{S.attachShadow===f&&Object.defineProperty(S,"attachShadow",d)}}let y=()=>{},C=e.defaultView?.HTMLFormElement.prototype,oe=C?Object.getOwnPropertyDescriptor(C,"submit"):void 0;if(C&&oe?.configurable){let c=C.submit,f=function(){c.call(this),n&&F.get(this)?.direct()};Object.defineProperty(C,"submit",{...oe,value:f}),y=()=>{C.submit===f&&Object.defineProperty(C,"submit",oe)}}return O(),()=>{n=!1,y(),$();for(let c of i.keys())h(c);r.clear();for(let c of o.values())c.cancelPending?.(new DOMException("Tool execution cancelled","UnknownError")),c.controller.abort();o.clear()}}var Ot="__isWebMCPPolyfill",Q=Symbol("registeredInputSchema"),B=Symbol("registrationSignal"),Ne=Symbol("registrationAbort"),te=[],ee=null,pe=null;function je(){return typeof globalThis.origin=="string"?globalThis.origin:globalThis.location?.origin??""}function W(e,t,n){let o=Object.getOwnPropertyDescriptor(e,t);try{Object.defineProperty(e,t,n)}catch(r){throw Ge(),r}te.push({target:e,key:t,previous:o})}var v,j,P,J,H,A,E,de,me,he,ke,T=(ke=class extends EventTarget{constructor(t){super();M(this,E);M(this,v,new Map);M(this,j,null);M(this,P,null);M(this,J,t=>{u(this,P)?.call(this,t)});M(this,H);M(this,A);L(this,A,t),L(this,H,t?.defaultView?.DOMException??DOMException),Object.defineProperty(this,Ot,{value:!0,enumerable:!1,writable:!1,configurable:!1})}get ontoolchange(){return u(this,P)}set ontoolchange(t){let n=typeof t=="function"?t:null;if(n===null){L(this,P,null),super.removeEventListener("toolchange",u(this,J));return}u(this,P)===null&&super.addEventListener("toolchange",u(this,J)),L(this,P,n)}async registerTool(t,n={}){V(u(this,A));let o=n?.signal,r=Pt(t,u(this,v));if(o?.throwIfAborted(),ae(n?.exposedTo),o?.throwIfAborted(),n?.exposedTo?.length)throw new(u(this,H))("Cross-document tool exposure requires native WebMCP","NotSupportedError");if(u(this,v).set(r.name,r),o){let i=()=>{R(this,E,de).call(this,r.name,r)&&R(this,E,he).call(this)};r[B]=o,r[Ne]=i,o.addEventListener("abort",i,{once:!0})}if(await R(this,E,he).call(this),o?.aborted)throw o.reason}async getTools(t={}){if(V(u(this,A)),ae(t?.fromOrigins),t?.fromOrigins?.length)throw new(u(this,H))("Cross-document tool discovery requires native WebMCP","NotSupportedError");let n=[...u(this,v).values()].map(o=>{let r=o[Q],i=r===void 0?void 0:JSON.parse(r);return{name:o.name,title:o.title??"",description:o.description,...K(i)?{inputSchema:i}:{},origin:je(),window:globalThis.window,...o.annotations?{annotations:Me(o.annotations)}:{}}}).sort((o,r)=>o.name<r.name?-1:o.name>r.name?1:0);return await new Promise(o=>setTimeout(o,0)),n}async executeTool(t,n,o={}){if(V(u(this,A)),t===null||typeof t!="object")throw new TypeError("RegisteredTool must be an object");for(let r of["name","description","window","origin"])if(!(r in t))throw new TypeError(`RegisteredTool.${r} is required`);if(Pe(t.origin),t.window!==globalThis.window||t.origin!==je())throw D(`Tool not found: ${t.name}`);return R(this,E,me).call(this,t.name,n,o)}static getTestingShim(t){return u(t,j)??L(t,j,new xt(t)),u(t,j)}static getToolInfos(t){return[...u(t,v).values()].map(n=>({name:n.name,description:n.description,...n[Q]===void 0?{}:{inputSchema:n[Q]}}))}static executeToolForTesting(t,n,o,r){var i;return V(u(t,A)),R(i=t,E,me).call(i,n,o,r)}static dispose(t){var n;for(let o of u(t,v).keys())R(n=t,E,de).call(n,o);t.ontoolchange=null,u(t,j)?.dispose()}},v=new WeakMap,j=new WeakMap,P=new WeakMap,J=new WeakMap,H=new WeakMap,A=new WeakMap,E=new WeakSet,de=function(t,n){let o=u(this,v).get(t);if(!o||n&&o!==n)return!1;let r=o[B],i=o[Ne];return r&&i&&r.removeEventListener("abort",i),u(this,v).delete(t)},me=async function(t,n,o){o?.signal?.throwIfAborted();let r=u(this,v).get(t);if(!r)throw D(`Tool not found: ${t}`);let i=Oe(n);if(o?.signal?.throwIfAborted(),r[B]?.aborted)throw D("Tool unregistered");let s;try{let a=r[B];s=await se(se(Promise.resolve(r.execute(i)),a,()=>D("Tool unregistered")),o?.signal)}catch(a){throw o?.signal?.aborted&&a===o.signal.reason||r[B]?.aborted?a:Se(a)}return xe(s)},he=async function(){await new Promise(t=>setTimeout(t,0)),this.dispatchEvent(new Event("toolchange")),u(this,j)?.dispatchToolChange()},ke),_=function(){throw new TypeError("Illegal constructor")};Object.defineProperty(_,"name",{value:"ModelContext"});Object.defineProperty(_,"prototype",{value:T.prototype,writable:!1});Object.setPrototypeOf(_,EventTarget);Object.defineProperty(T.prototype,"constructor",{configurable:!0,writable:!0,value:_});Object.defineProperty(T.prototype,Symbol.toStringTag,{configurable:!0,value:"ModelContext"});for(let e of["registerTool","getTools","executeTool","ontoolchange"]){let t=Object.getOwnPropertyDescriptor(T.prototype,e);t&&Object.defineProperty(T.prototype,e,{...t,enumerable:!0})}var k,Fe,xt=(Fe=class extends EventTarget{constructor(t){super();re(this,"_ontoolchange",null);re(this,"ontoolchangeListener",t=>{this._ontoolchange?.call(this,t)});M(this,k);L(this,k,t)}listTools(){return T.getToolInfos(u(this,k))}executeTool(t,n,o){return T.executeToolForTesting(u(this,k),t,n,o)}get ontoolchange(){return this._ontoolchange}set ontoolchange(t){let n=typeof t=="function"?t:null;if(n===null){this._ontoolchange=null,super.removeEventListener("toolchange",this.ontoolchangeListener);return}this._ontoolchange===null&&super.addEventListener("toolchange",this.ontoolchangeListener),this._ontoolchange=n}dispatchToolChange(){this.dispatchEvent(new Event("toolchange"))}dispose(){this.ontoolchange=null}},k=new WeakMap,Fe);function Pt(e,t){if(!e||typeof e!="object")throw new TypeError("registerTool(tool) requires a tool object");let n=Ee(e);if(Te(n),t.has(n.name))throw z(`Tool already registered: ${n.name}`);let o=n.inputSchema===void 0?void 0:Ae(n.inputSchema);return{name:n.name,...n.title===void 0?{}:{title:n.title},description:n.description,...n.inputSchema===void 0?{}:{inputSchema:n.inputSchema},...n.annotations===void 0?{}:{annotations:n.annotations},execute:r=>Reflect.apply(n.execute,void 0,[r]),...o!==void 0?{[Q]:o}:{}}}var ne=!1,Je=new WeakMap,{modelContext:Ye}={modelContext(){if(!(this instanceof Document))throw new TypeError("Illegal invocation");return Je.get(this)}};Object.defineProperty(Ye,"name",{value:"get modelContext"});function He(e,t){Je.set(e,t),!Object.hasOwn(Document.prototype,"modelContext")&&W(Document.prototype,"modelContext",{configurable:!0,enumerable:!0,get:Ye})}function At(e,t){W(e,"modelContext",{configurable:!0,enumerable:!0,get(){return ne||(ne=!0,console.warn("[WebMCPPolyfill] navigator.modelContext is deprecated. The May 27, 2026 WebMCP draft moved the modelContext getter from Navigator to Document \u2014 use document.modelContext instead. See https://github.com/webmachinelearning/webmcp/pull/184.")),t}})}function Ct(){let e=SubmitEvent.prototype;"agentInvoked"in e||W(e,"agentInvoked",{configurable:!0,enumerable:!0,get(){return We(this)}}),"respondWith"in e||W(e,"respondWith",{configurable:!0,enumerable:!0,writable:!0,value(t){ot(this,t)}})}function It(e){if(globalThis.isSecureContext===!1)return;let t=typeof navigator>"u"?null:navigator,n=typeof document>"u"?null:document;if(!t||!n||typeof window>"u"||n.modelContext)return;let o=t.modelContext;if(te.length>0&&Ge(),o){He(n,o);return}let r=Object.getOwnPropertyDescriptor(window,"ModelContext");if(r&&!r.configurable){if(!Object.is(Reflect.get(window,"ModelContext"),_))throw new TypeError("Cannot install ModelContext over a non-configurable global")}else W(window,"ModelContext",{configurable:!0,enumerable:!1,writable:!0,value:_});let i=new T(n);ee=i,He(n,i),ne=!1,At(t,i),Ct(),e?.installTestingShim&&!t.modelContextTesting&&W(t,"modelContextTesting",{configurable:!0,enumerable:!0,writable:!1,value:T.getTestingShim(i)}),pe=Mt(n,i)}function Ge(){pe?.(),pe=null,ee&&T.dispose(ee),ee=null;for(let{target:e,key:t,previous:n}of[...te].reverse())n?Object.defineProperty(e,t,n):Reflect.deleteProperty(e,t);te.length=0,ne=!1}export{It as initializeWebMCPPolyfill};
|
|
1
|
+
var Le="Failed to parse input arguments",ne="Tool was executed but the invocation failed. For example, the script function threw an error";var Re=/^[A-Za-z0-9_.-]{1,128}$/u;function W(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function F(e){if(typeof e=="symbol")throw new TypeError("Symbol values cannot be converted to a DOMString");return String(e)}function oe(e){let t=Reflect.get(e,"name"),n=Reflect.get(e,"description"),o=Reflect.get(e,"title");if(t===void 0)throw new TypeError('Tool "name" is required');if(n===void 0)throw new TypeError('Tool "description" is required');let r=Reflect.get(e,"annotations"),i=W(r)?r:{},s=Reflect.get(e,"inputSchema"),c=Reflect.get(e,"outputSchema"),m=Reflect.get(e,"execute");return{name:F(t),...o===void 0?{}:{title:F(o).toWellFormed()},description:F(n),...s===void 0?{}:{inputSchema:s},...c===void 0?{}:{outputSchema:c},execute:m,...r===void 0?{}:{annotations:{...i.title===void 0?{}:{title:F(i.title).toWellFormed()},readOnlyHint:!!i.readOnlyHint,...i.destructiveHint===void 0?{}:{destructiveHint:!!i.destructiveHint},...i.idempotentHint===void 0?{}:{idempotentHint:!!i.idempotentHint},...i.openWorldHint===void 0?{}:{openWorldHint:!!i.openWorldHint},untrustedContentHint:!!i.untrustedContentHint}}}}function O(e){return new DOMException(e,"UnknownError")}function re(e){return O(e instanceof Error?`${ne}: ${e.message}`:ne)}function D(e){return new DOMException(e,"InvalidStateError")}function ie(e){if(e.name==="")throw D('Tool "name" must be a non-empty string');if(typeof e.name!="string"||!Re.test(e.name))throw D('Tool "name" must be 1\u2013128 characters and contain only ASCII alphanumeric, underscore, hyphen, or period');if(typeof e.description!="string"||e.description.length===0)throw D('Tool "description" must be a non-empty string');if(typeof e.execute!="function")throw new TypeError('Tool "execute" must be a function')}function se(e){return{readOnlyHint:e.readOnlyHint??!1,untrustedContentHint:e.untrustedContentHint??!1}}function ae(e){try{let t=JSON.parse(e);if(Array.isArray(t)||W(t))return t}catch{}throw O(Le)}function ce(e){if(typeof e=="object"&&e!==null||typeof e=="function")try{let t=JSON.stringify(e);if(t)return t}catch{}return String(e)||"Operation succeeded"}function B(e,t,n=()=>t?.reason){return t?t.aborted?Promise.reject(n()):new Promise((o,r)=>{let i=()=>{s(),r(n())},s=()=>t.removeEventListener("abort",i);t.addEventListener("abort",i,{once:!0}),e.then(c=>{s(),o(c)},c=>{s(),r(c)})}):e}function De(e){let t=e.origin==="null"?e:new URL(e.origin),n=t.protocol;if(["https:","wss:","file:","chrome-extension:","moz-extension:"].includes(n))return!0;let o=t.hostname.toLowerCase(),r=o.split("."),i=r.length===4&&r.every(s=>/^\d{1,3}$/u.test(s)&&Number(s)<=255)&&Number(r[0])===127;return o==="::1"||o==="[::1]"||o==="localhost"||o==="localhost."||o.endsWith(".localhost")||o.endsWith(".localhost.")||i}function J(e){for(let t of e??[]){let n;try{n=new URL(t)}catch{throw new DOMException(`Invalid or untrustworthy origin: ${String(t)}`,"SecurityError")}if(!De(n))throw new DOMException(`Invalid or untrustworthy origin: ${t}`,"SecurityError")}}function N(e){if(Ne(),!e)return;let t=e.defaultView?.DOMException??DOMException,n=!1;try{let i=e.defaultView;n=!!(i&&i.document===e)}catch{}if(!n)throw new t("The associated document is not fully active","InvalidStateError");let o=Reflect.get(e,"permissionsPolicy")??Reflect.get(e,"featurePolicy");if(o&&typeof o=="object"){let i=Reflect.get(o,"features"),s=Reflect.get(o,"allowsFeature");if(typeof i=="function"&&typeof s=="function"){let c=Reflect.apply(i,o,[]);if(Array.isArray(c)&&c.includes("tools")){if(Reflect.apply(s,o,["tools"])===!0)return;throw new t("WebMCP is disabled by Permissions Policy","NotAllowedError")}}}let r=e.defaultView;if(!(!r||r.parent===r)){try{r.parent.document;return}catch{}throw new t("WebMCP in cross-origin frames requires native Permissions Policy support","NotAllowedError")}}function Ne(){if(globalThis.originAgentCluster===!1&&globalThis.location?.protocol!=="file:")throw new DOMException("","SecurityError")}function ue(e){try{if(new URL(String(e)).origin!=="null")return}catch{}throw new DOMException(`Unsupported tool origin: ${String(e)}`,"NotSupportedError")}function le(e){if(e===null||typeof e!="object"&&typeof e!="function")throw new TypeError("inputSchema must be an object");let t=JSON.stringify(e);if(t===void 0)throw new TypeError("inputSchema must be JSON-serializable");return t}var Q=new WeakSet,Z=new WeakMap,P=new WeakMap;function we(e){return e.isTrusted&&(Q.has(e)||e.eventPhase!==Event.NONE&&e.target instanceof HTMLFormElement&&P.has(e.target))}function je(e,t){if(!we(e))throw new DOMException("respondWith() is only available during an agent-invoked submit event","InvalidStateError");if(!e.defaultPrevented)throw new DOMException("respondWith() requires preventDefault() during an agent-invoked submit event","InvalidStateError");if(e.eventPhase===Event.NONE)throw new DOMException("respondWith() is only available while the submit event is being dispatched","InvalidStateError");Q.add(e);let n=Promise.resolve(t);Z.set(e,n),e.target instanceof HTMLFormElement&&P.get(e.target)?.respond(e)}var ve=new Set(["email","password","search","tel","text","url"]),He=new Set([...ve,"date","datetime-local","month","number","time","week"]);function Ee(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function ee(e){return Reflect.get(HTMLFormElement.prototype,"elements",e)}function Y(e,t){return Reflect.apply(Element.prototype.getAttribute,e,[t])}function K(e,t){return Reflect.apply(Element.prototype.hasAttribute,e,[t])}function ke(e){return Reflect.get(Node.prototype,"isConnected",e)}function Fe(e){return Reflect.get(Element.prototype,"shadowRoot",e)}function We(e){return Reflect.apply(HTMLFormElement.prototype.checkValidity,e,[])}function _e(e,t){Reflect.apply(HTMLFormElement.prototype.requestSubmit,e,t?[t]:[])}function $e(e){return[...ee(e)].filter(t=>Ee(t)&&!t.matches(":disabled")&&!("readOnly"in t&&t.readOnly&&(t instanceof HTMLTextAreaElement||He.has(t.type))))}function Se(e){let t=new Map;for(let n of $e(e)){let o=n.name.trim(),r=t.get(o);r?r.push(n):t.set(o,[n])}return t}function Te(e){return[...e.labels??[]].map(t=>{let n=t.cloneNode(!0);return n instanceof HTMLElement?(n.querySelectorAll("button, input, meter, output, progress, select, textarea").forEach(o=>o.remove()),n.textContent?.trim()??""):""}).filter(Boolean).join("; ")}function qe(e,t){for(let n=t[0]?.parentElement;n&&n!==e;n=n.parentElement)if(n instanceof HTMLFieldSetElement&&t.every(o=>n.contains(o)))return n}function Ue(e,t){if(t.length===1){let n=t[0];return n&&(n.getAttribute("toolparamdescription")||Te(n)||n.getAttribute("aria-description"))||void 0}return qe(e,t)?.getAttribute("toolparamdescription")||void 0}function d(e,t,n,o){let r=Ue(t,n),i=r&&o?`${r} (${o})`:r||o;return i?{...e,description:i}:e}function fe(e,t){let n=e.getAttribute(t);if(n===null||n.trim()==="")return;let o=Number(n);return Number.isFinite(o)?o:void 0}function ze(e,t){let n=e/t;return Math.abs(n-Math.round(n))<Number.EPSILON*16}function Me(e){let t=e.getAttribute("pattern");if(t!==null)try{return new RegExp(t,"v"),t}catch{return}}function pe(e,t=!0){let n={type:"number"},o=fe(e,"min"),r=fe(e,"max");o!==void 0&&(n.minimum=o),r!==void 0&&(n.maximum=r);let i=e.getAttribute("step");if(i!=="any"){let c=i===null||i===""?1:Number(i),m=Number.isFinite(c)&&c>0?c:1,h=Number(e.getAttribute("value"));ze(o??(Number.isFinite(h)?h:0),m)&&(n.multipleOf=m)}let s=t?Me(e):void 0;return s!==void 0&&(n.pattern=s),n}function de(e,t){let n=e.getAttribute("step"),o=n===null||n===""?60:Number(n),r=Number.isFinite(o)&&o>0?o:60;return r<1?`${t}(:[0-5][0-9](\\.[0-9]{1,3})?)?$`:r<60?`${t}(:[0-5][0-9])?$`:`${t}$`}function Ve(e){return{anyOf:e.map(t=>({type:"string",const:t.value,title:t.textContent??""})),enum:e.map(t=>t.value)}}function G(e){return{anyOf:e.map(t=>{let n=Te(t);return{type:"string",const:t.value,...n?{title:n}:{}}}),enum:e.map(t=>t.value)}}function Oe(e,t){let n=t[0];if(n){if(t.length>1)return t.every(o=>o instanceof HTMLInputElement)?t.every(o=>o.type==="checkbox")?d({type:"array",items:{type:"string",...G(t)},uniqueItems:!0},e,t):t.every(o=>o.type==="radio")?d({type:"string",...G(t)},e,t):void 0:void 0;if(n instanceof HTMLTextAreaElement)return d({type:"string"},e,t);if(n instanceof HTMLSelectElement){let o=Ve([...n.options]);return d(n.multiple?{type:"array",items:{type:"string",...o},uniqueItems:!0}:{type:"string",...o},e,t)}if(ve.has(n.type)){let o={type:"string"},r=Me(n);return r!==void 0&&(o.pattern=r),d(o,e,t)}if(n.type==="hidden")return n.getAttribute("toolparamdescription")?d({type:"string"},e,t):void 0;if(n.type==="number")return d(pe(n),e,t);if(n.type==="range"){let o=pe(n,!1);return o.minimum??=0,o.maximum??=100,d(o,e,t)}if(n.type==="checkbox")return d({type:"boolean"},e,t);if(n.type==="radio")return d({type:"string",...G([n])},e,t);if(n.type==="date")return d({type:"string",format:"date"},e,t,"Dates MUST be provided in 'YYYY-MM-DD' format.");if(n.type==="month")return d({type:"string",format:"^[0-9]{4}-(0[1-9]|1[0-2])$"},e,t);if(n.type==="week")return d({type:"string",format:"^[0-9]{4}-W(0[1-9]|[1-4][0-9]|5[0-3])$"},e,t);if(n.type==="time")return d({type:"string",format:de(n,"^([01][0-9]|2[0-3]):[0-5][0-9]")},e,t);if(n.type==="datetime-local")return d({type:"string",format:de(n,"^[0-9]{4}-(0[1-9]|1[0-2])-[0-9]{2}T([01][0-9]|2[0-3]):[0-5][0-9]")},e,t);if(n.type==="color")return d({type:"string",format:"^#[0-9a-zA-Z]{6}$"},e,t)}}function Be(e){let t={},n=[];for(let[o,r]of Se(e)){if(!o)continue;let i=Oe(e,r);i&&(Object.defineProperty(t,o,{configurable:!0,enumerable:!0,value:i,writable:!0}),r.some(s=>s.required)&&n.push(o))}return{type:"object",properties:t,required:n}}function Je(e){return{name:Y(e,"toolname")??"",title:Y(e,"tooltitle")??"",description:Y(e,"tooldescription")??"",inputSchema:Be(e),autosubmit:K(e,"toolautosubmit")}}function y(e){if(typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return String(e)}function xe(e){if(typeof e=="boolean")return e;if(typeof e=="number"&&Number.isInteger(e))return e!==0;if(typeof e=="string"){if(e==="1"||e.toLowerCase()==="true")return!0;if(e==="0"||e.toLowerCase()==="false")return!1}}function me(e,t){if(!Array.isArray(e))return!1;let n=new Set(t);for(let o of e){let r=y(o);if(r===void 0||!n.delete(r))return!1}return!0}function Ye(e,t){if(t==="")return e.type!=="number"&&e.type!=="range";let n=e.ownerDocument.createElement("input");return n.type=e.type,n.value=t,n.value!==""}function Ge(e,t,n){let o=t[0];if(!o||!Oe(e,t))return!1;if(t.length>1){if(!t.every(i=>i instanceof HTMLInputElement))return!1;if(t.every(i=>i.type==="checkbox"))return me(n,new Set(t.map(i=>i.value)));if(t.every(i=>i.type==="radio")){let i=y(n);return i!==void 0&&t.some(s=>s.value===i)}return!1}if(o instanceof HTMLSelectElement){let i=new Set([...o.options].map(c=>c.value));if(o.multiple)return me(n,i);let s=y(n);return s!==void 0&&i.has(s)}if(o instanceof HTMLTextAreaElement)return y(n)!==void 0;if(o.type==="checkbox")return xe(n)!==void 0;if(o.type==="radio"){let i=y(n);return i!==void 0&&o.value===i}let r=y(n);return r!==void 0&&Ye(o,r)}function x(e){e.dispatchEvent(new Event("input",{bubbles:!0,composed:!0})),e.dispatchEvent(new Event("change",{bubbles:!0}))}function Ze(e,t){let n=e instanceof HTMLInputElement?HTMLInputElement.prototype:HTMLTextAreaElement.prototype;Object.getOwnPropertyDescriptor(n,"value")?.set?.call(e,t)}function _(e,t){Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"checked")?.set?.call(e,t)}function Ke(e,t){let n=e[0];if(!n)return;if(e.length>1&&e.every(r=>r instanceof HTMLInputElement)){if(e.every(s=>s.type==="checkbox")&&Array.isArray(t)){let s=new Set(t.map(y));for(let c of e){let m=s.has(c.value);c.checked!==m&&(_(c,m),x(c))}return}let r=y(t),i=e.find(s=>s.value===r);i&&!i.checked&&(_(i,!0),x(i));return}if(n instanceof HTMLSelectElement){if(n.multiple&&Array.isArray(t)){let i=new Set(t.map(y)),s=!1;for(let c of n.options){let m=i.has(c.value);c.selected!==m&&(c.selected=m,s=!0)}s&&x(n);return}let r=y(t);r!==void 0&&n.value!==r&&(n.value=r,x(n));return}if(n instanceof HTMLInputElement&&n.type==="checkbox"){let r=xe(t);r!==void 0&&n.checked!==r&&(_(n,r),x(n));return}if(n instanceof HTMLInputElement&&n.type==="radio"){y(t)===n.value&&!n.checked&&(_(n,!0),x(n));return}let o=y(t);o!==void 0&&n.value!==o&&(Ze(n,o),x(n))}function Xe(e,t){if(Array.isArray(t))throw new TypeError("Declarative tool input must be an object");let n=Se(e);for(let[o,r]of Object.entries(t)){let i=n.get(o);if(!i||!Ge(e,i,r))throw new TypeError(`Invalid value for declarative form parameter "${o}"`)}for(let[o,r]of Object.entries(t))Ke(n.get(o)??[],r)}function Qe(e){return[...ee(e)].find(t=>!t.matches(":disabled")&&(t instanceof HTMLButtonElement&&t.type==="submit"||t instanceof HTMLInputElement&&["image","submit"].includes(t.type)))}function et(e){let t=[...ee(e)].filter(n=>Ee(n)&&n.willValidate&&!n.validity.valid).map(n=>`${n.name.trim()||"{unknown}"}: ${n.validationMessage}`).join(". ");return new DOMException(`Form validation failed: ${t}`,"UnknownError")}function he(e){let t=new Event("toolactivated");return Object.defineProperty(t,"toolName",{enumerable:!0,value:e}),t}function tt(e,t,n,o){let{form:r}=e;return e.cancelPending?.(new DOMException("Tool execution cancelled","UnknownError")),new Promise((i,s)=>{let c=!1,m=()=>{Reflect.apply(EventTarget.prototype.removeEventListener,r,["invalid",w,!0]),P.delete(r),e.cancelPending===E&&delete e.cancelPending},h=p=>{c||(c=!0,m(),p())},E=p=>h(()=>s(p)),I=p=>{p.then(g=>h(()=>i(g)),g=>h(()=>s(g)))},w=p=>{p.isTrusted&&queueMicrotask(()=>{We(r)||E(et(r))})};if(P.set(r,{complete(p){queueMicrotask(()=>{let g=Z.get(p);g?I(g):p.defaultPrevented?E(new DOMException("preventDefault() requires respondWith()","UnknownError")):h(()=>i(void 0))})},direct(){h(()=>i(void 0))},respond(p){queueMicrotask(()=>{let g=Z.get(p);g&&I(g)})}}),e.cancelPending=E,Reflect.apply(EventTarget.prototype.addEventListener,r,["invalid",w,!0]),!n){o?.focus(),window.dispatchEvent(he(t));return}try{_e(r,o),window.dispatchEvent(he(t))}catch(p){E(p)}})}function nt(e,t){let n=!0,o=new Map,r=new Map,i=new Map,s=a=>{if(!(a instanceof SubmitEvent)||!a.isTrusted||!(a.target instanceof HTMLFormElement))return;let l=P.get(a.target);l&&(Q.add(a),l.complete(a))},c=a=>{if(!a.isTrusted||!(a.target instanceof HTMLFormElement))return;let l=a.target;queueMicrotask(()=>{a.defaultPrevented||o.get(l)?.cancelPending?.(new DOMException("Tool execution cancelled by form reset","UnknownError"))})};function m(a){i.get(a)?.disconnect(),i.delete(a),a.removeEventListener("reset",c,!0),a.removeEventListener("submit",s,!0)}function h(a){if(i.has(a))return;let l=new MutationObserver(E);i.set(a,l),l.observe(a,{attributes:!0,characterData:!0,childList:!0,subtree:!0}),a.addEventListener("reset",c,!0),a.addEventListener("submit",s,!0)}function E(){h(e);for(let u of i.keys())u instanceof ShadowRoot&&!Reflect.get(Node.prototype,"isConnected",u.host)&&m(u);let a=new Set,l=new Map,H=new Map;for(let u of i.keys())for(let f of u.querySelectorAll("*")){let k=Fe(f);if(k&&h(k),!(f instanceof HTMLFormElement)||!K(f,"toolname")||!K(f,"tooldescription")||!ke(f))continue;let b=f;a.add(b);let M=Je(b),S=JSON.stringify(M),L=r.get(b);if(L===S)continue;let Ie=L!==void 0;r.delete(b);let R=H.get(M.name);if(R&&!Ie){r.set(b,S);continue}if(R){let te=l.get(R);te&&(r.set(R,te.fingerprint),l.delete(R))}H.set(M.name,b),l.set(b,{definition:M,fingerprint:S})}for(let u of r.keys())a.has(u)||r.delete(u);for(let[u,f]of o)l.get(u)?.fingerprint!==f.fingerprint&&(f.cancelPending?.(new DOMException("Tool execution cancelled because its form changed","UnknownError")),f.controller.abort(),o.delete(u));for(let[u,{definition:f,fingerprint:k}]of l){if(o.has(u))continue;let b=new AbortController,M={controller:b,fingerprint:k,form:u};o.set(u,M),t.registerTool({name:f.name,title:f.title,description:f.description,inputSchema:f.inputSchema,execute(S){let L=Qe(u);if(!f.autosubmit&&!L)throw new DOMException("A declarative form without toolautosubmit requires a submit button","UnknownError");return Xe(u,S),tt(M,f.name,f.autosubmit,L)}},{signal:b.signal}).catch(S=>{b.abort(),S?.name!=="AbortError"&&console.error(`[webmcp] declarative form tool "${f.name}" was not registered:`,S)})}}let I=()=>{},w=e.defaultView?.Element.prototype,p=w?Object.getOwnPropertyDescriptor(w,"attachShadow"):void 0;if(w&&p?.configurable){let a=w.attachShadow,l=function(H){let u=a.call(this,H);return n&&u.mode==="open"&&Reflect.get(Node.prototype,"ownerDocument",this)===e&&Reflect.get(Node.prototype,"isConnected",this)&&h(u),u};Object.defineProperty(w,"attachShadow",{...p,value:l}),I=()=>{w.attachShadow===l&&Object.defineProperty(w,"attachShadow",p)}}let g=()=>{},T=e.defaultView?.HTMLFormElement.prototype,V=T?Object.getOwnPropertyDescriptor(T,"submit"):void 0;if(T&&V?.configurable){let a=T.submit,l=function(){a.call(this),n&&P.get(this)?.direct()};Object.defineProperty(T,"submit",{...V,value:l}),g=()=>{T.submit===l&&Object.defineProperty(T,"submit",V)}}return E(),()=>{n=!1,g(),I();for(let a of i.keys())m(a);r.clear();for(let a of o.values())a.cancelPending?.(new DOMException("Tool execution cancelled","UnknownError")),a.controller.abort();o.clear()}}var ot="__isWebMCPPolyfill",$=Symbol("registeredInputSchema"),j=Symbol("registrationSignal"),ge=Symbol("registrationAbort"),U=[],q=null,X=null;function ye(){return typeof globalThis.origin=="string"?globalThis.origin:globalThis.location?.origin??""}function A(e,t,n){let o=Object.getOwnPropertyDescriptor(e,t);try{Object.defineProperty(e,t,n)}catch(r){throw Ce(),r}U.push({target:e,key:t,previous:o})}var v=class extends EventTarget{#e=new Map;#o=null;#t=null;#i=e=>{this.#t?.call(this,e)};#r;#n;constructor(e){super(),this.#n=e,this.#r=e?.defaultView?.DOMException??DOMException,Object.defineProperty(this,ot,{value:!0,enumerable:!1,writable:!1,configurable:!1})}get ontoolchange(){return this.#t}set ontoolchange(e){let t=typeof e=="function"?e:null;if(t===null){this.#t=null,super.removeEventListener("toolchange",this.#i);return}this.#t===null&&super.addEventListener("toolchange",this.#i),this.#t=t}async registerTool(e,t={}){N(this.#n);let n=t?.signal,o=it(e,this.#e);if(n?.throwIfAborted(),J(t?.exposedTo),n?.throwIfAborted(),t?.exposedTo?.length)throw new this.#r("Cross-document tool exposure requires native WebMCP","NotSupportedError");if(this.#e.set(o.name,o),n){let r=()=>{this.#s(o.name,o)&&this.#c()};o[j]=n,o[ge]=r,n.addEventListener("abort",r,{once:!0})}if(await this.#c(),n?.aborted)throw n.reason}async getTools(e={}){if(N(this.#n),J(e?.fromOrigins),e?.fromOrigins?.length)throw new this.#r("Cross-document tool discovery requires native WebMCP","NotSupportedError");let t=[...this.#e.values()].map(n=>{let o=n[$],r=o===void 0?void 0:JSON.parse(o);return{name:n.name,title:n.title??"",description:n.description,...W(r)?{inputSchema:r}:{},origin:ye(),window:globalThis.window,...n.annotations?{annotations:se(n.annotations)}:{}}}).sort((n,o)=>n.name<o.name?-1:n.name>o.name?1:0);return await new Promise(n=>setTimeout(n,0)),t}async executeTool(e,t,n={}){if(N(this.#n),e===null||typeof e!="object")throw new TypeError("RegisteredTool must be an object");for(let o of["name","description","window","origin"])if(!(o in e))throw new TypeError(`RegisteredTool.${o} is required`);if(ue(e.origin),e.window!==globalThis.window||e.origin!==ye())throw O(`Tool not found: ${e.name}`);return this.#a(e.name,t,n)}static getTestingShim(e){return e.#o??=new rt(e),e.#o}static getToolInfos(e){return[...e.#e.values()].map(t=>({name:t.name,description:t.description,...t[$]===void 0?{}:{inputSchema:t[$]}}))}static executeToolForTesting(e,t,n,o){return N(e.#n),e.#a(t,n,o)}static dispose(e){for(let t of e.#e.keys())e.#s(t);e.ontoolchange=null,e.#o?.dispose()}#s(e,t){let n=this.#e.get(e);if(!n||t&&n!==t)return!1;let o=n[j],r=n[ge];return o&&r&&o.removeEventListener("abort",r),this.#e.delete(e)}async#a(e,t,n){n?.signal?.throwIfAborted();let o=this.#e.get(e);if(!o)throw O(`Tool not found: ${e}`);let r=ae(t);if(n?.signal?.throwIfAborted(),o[j]?.aborted)throw O("Tool unregistered");let i;try{let s=o[j];i=await B(B(Promise.resolve(o.execute(r)),s,()=>O("Tool unregistered")),n?.signal)}catch(s){throw n?.signal?.aborted&&s===n.signal.reason||o[j]?.aborted?s:re(s)}return ce(i)}async#c(){await new Promise(e=>setTimeout(e,0)),this.dispatchEvent(new Event("toolchange")),this.#o?.dispatchToolChange()}},C=function(){throw new TypeError("Illegal constructor")};Object.defineProperty(C,"name",{value:"ModelContext"});Object.defineProperty(C,"prototype",{value:v.prototype,writable:!1});Object.setPrototypeOf(C,EventTarget);Object.defineProperty(v.prototype,"constructor",{configurable:!0,writable:!0,value:C});Object.defineProperty(v.prototype,Symbol.toStringTag,{configurable:!0,value:"ModelContext"});for(let e of["registerTool","getTools","executeTool","ontoolchange"]){let t=Object.getOwnPropertyDescriptor(v.prototype,e);t&&Object.defineProperty(v.prototype,e,{...t,enumerable:!0})}var rt=class extends EventTarget{_ontoolchange=null;ontoolchangeListener=e=>{this._ontoolchange?.call(this,e)};#e;constructor(e){super(),this.#e=e}listTools(){return v.getToolInfos(this.#e)}executeTool(e,t,n){return v.executeToolForTesting(this.#e,e,t,n)}get ontoolchange(){return this._ontoolchange}set ontoolchange(e){let t=typeof e=="function"?e:null;if(t===null){this._ontoolchange=null,super.removeEventListener("toolchange",this.ontoolchangeListener);return}this._ontoolchange===null&&super.addEventListener("toolchange",this.ontoolchangeListener),this._ontoolchange=t}dispatchToolChange(){this.dispatchEvent(new Event("toolchange"))}dispose(){this.ontoolchange=null}};function it(e,t){if(!e||typeof e!="object")throw new TypeError("registerTool(tool) requires a tool object");let n=oe(e);if(ie(n),t.has(n.name))throw D(`Tool already registered: ${n.name}`);let o=n.inputSchema===void 0?void 0:le(n.inputSchema);return{name:n.name,...n.title===void 0?{}:{title:n.title},description:n.description,...n.inputSchema===void 0?{}:{inputSchema:n.inputSchema},...n.annotations===void 0?{}:{annotations:n.annotations},execute:r=>Reflect.apply(n.execute,void 0,[r]),...o!==void 0?{[$]:o}:{}}}var z=!1,Pe=new WeakMap,{modelContext:Ae}={modelContext(){if(!(this instanceof Document))throw new TypeError("Illegal invocation");return Pe.get(this)}};Object.defineProperty(Ae,"name",{value:"get modelContext"});function be(e,t){Pe.set(e,t),!Object.hasOwn(Document.prototype,"modelContext")&&A(Document.prototype,"modelContext",{configurable:!0,enumerable:!0,get:Ae})}function st(e,t){A(e,"modelContext",{configurable:!0,enumerable:!0,get(){return z||(z=!0,console.warn("[WebMCPPolyfill] navigator.modelContext is deprecated. The May 27, 2026 WebMCP draft moved the modelContext getter from Navigator to Document \u2014 use document.modelContext instead. See https://github.com/webmachinelearning/webmcp/pull/184.")),t}})}function at(){let e=SubmitEvent.prototype;"agentInvoked"in e||A(e,"agentInvoked",{configurable:!0,enumerable:!0,get(){return we(this)}}),"respondWith"in e||A(e,"respondWith",{configurable:!0,enumerable:!0,writable:!0,value(t){je(this,t)}})}function ct(e){if(globalThis.isSecureContext===!1)return;let t=typeof navigator>"u"?null:navigator,n=typeof document>"u"?null:document;if(!t||!n||typeof window>"u"||n.modelContext)return;let o=t.modelContext;if(U.length>0&&Ce(),o){be(n,o);return}let r=Object.getOwnPropertyDescriptor(window,"ModelContext");if(r&&!r.configurable){if(!Object.is(Reflect.get(window,"ModelContext"),C))throw new TypeError("Cannot install ModelContext over a non-configurable global")}else A(window,"ModelContext",{configurable:!0,enumerable:!1,writable:!0,value:C});let i=new v(n);q=i,be(n,i),z=!1,st(t,i),at(),e?.installTestingShim&&!t.modelContextTesting&&A(t,"modelContextTesting",{configurable:!0,enumerable:!0,writable:!1,value:v.getTestingShim(i)}),X=nt(n,i)}function Ce(){X?.(),X=null,q&&v.dispose(q),q=null;for(let{target:e,key:t,previous:n}of[...U].reverse())n?Object.defineProperty(e,t,n):Reflect.deleteProperty(e,t);U.length=0,z=!1}export{ct as initializeWebMCPPolyfill};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
var h="webmcp:",T=t=>t.startsWith(h)?t.slice(h.length):t,u={warn(t,...e){typeof console<"u"&&typeof console.warn=="function"&&console.warn(`[Persona/WebMCP] ${t}`,...e)}},b=class{constructor(e,n){this.config=e;this.#e=n,this.#o=e.onConfirm??null,this.#r=3e4}#o;#r;#t=!1;#i=null;#l=!1;#e;setConfirmHandler(e){this.#o=e}isOperational(){return this.config.enabled!==!0||!this.#t?!1:this.#n()!==null}async snapshotForDispatch(){if(await this.#s(),this.config.enabled!==!0)return[];let e=this.#n();if(!e)return[];let n;try{n=await e.getTools()}catch(i){return u.warn("getTools() threw: shipping an empty WebMCP snapshot.",i),[]}this.#e.recordToolDisplayTitles(n);let o=typeof location<"u"?location.origin:"";return n.filter(i=>this.#c(i.name)).map(i=>{let l=W(i.annotations);return{name:i.name,description:i.description,parametersSchema:P(i.inputSchema),origin:"webmcp",...o?{pageOrigin:o}:{},...l?{annotations:l}:{},...l?.untrustedContentHint===!0?{untrustedContentHint:!0}:{}}})}async executeToolCall(e,n,o){if(await this.#s(),this.config.enabled!==!0)return s("WebMCP is not enabled on this widget.");let i=this.#n();if(!i){let r=typeof document<"u"&&!!document.modelContext;return s(r?"WebMCP is not operational: document.modelContext is present but does not expose the strict getTools()/executeTool() surface (likely a different or older WebMCP polyfill).":"WebMCP bridge is not operational on this page (document.modelContext not available).")}let l=T(e),c;try{c=await i.getTools()}catch(r){let p=r instanceof Error?r.message:String(r);return s(`Failed to read WebMCP registry: ${p}`)}this.#e.recordToolDisplayTitles(c);let f=c.find(r=>r.name===l);if(!f)return s(`WebMCP tool not registered on this page: ${l}`);if(!this.#c(l))return s(`WebMCP tool not allowed by client allowlist: ${l}`);if(o?.aborted)return s("Aborted by cancel()");let m=this.#e.getToolDisplayTitle(l),C={toolName:l,args:n,description:f.description,...m?{title:m}:{},reason:"gate"};if(!await this.#u(C))return s("User declined the tool call.");if(o?.aborted)return s("Aborted by cancel()");let a=new AbortController,y=!1,M=setTimeout(()=>{y=!0,a.abort()},this.#r),g=()=>a.abort();o&&(o.aborted?a.abort():o.addEventListener("abort",g,{once:!0}));try{let r=await i.executeTool(f,k(n),{signal:a.signal});return w(r)}catch(r){if(y)return s(`WebMCP tool '${l}' timed out after ${this.#r}ms`);if(o?.aborted)return s("Aborted by cancel()");let p=r instanceof Error?r.message:String(r);return s(p)}finally{clearTimeout(M),o&&o.removeEventListener("abort",g)}}#s(){return this.config.enabled!==!0?Promise.resolve():(this.#i||(this.#i=this.#a()),this.#i)}async#a(){try{if(this.#n()){this.#t=!0;return}(await this.#e.loadPolyfill()).initializeWebMCPPolyfill(),this.#t=!0}catch(e){u.warn("Failed to load @mcp-b/webmcp-polyfill: WebMCP consumption disabled.",e),this.#t=!1}}#n(){if(typeof document>"u")return null;let e=document.modelContext;if(!e||typeof e!="object")return null;let n=e;return typeof n.getTools!="function"||typeof n.executeTool!="function"?(this.#l||(this.#l=!0,u.warn("document.modelContext is present but does not expose getTools()/executeTool(): WebMCP consumption is disabled. Another (incompatible or older) WebMCP polyfill likely installed document.modelContext before Persona. Remove it, or use a polyfill implementing the strict standard surface (e.g. @mcp-b/webmcp-polyfill).")),null):e}async#u(e){let n=this.#o??A;try{return await n(e)}catch(o){return u.warn(`Confirm handler threw for WebMCP tool '${e.toolName}'; declining.`,o),!1}}#c(e){let n=this.config.allowlist;return!n||n.length===0?!0:n.some(o=>x(e,o))}},x=(t,e)=>{if(e==="*")return!0;let n=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+n.replace(/\*/g,".*")+"$").test(t)},d={type:"object",properties:{}},W=t=>{if(!t||typeof t!="object")return;let e={...typeof t.readOnlyHint=="boolean"?{readOnlyHint:t.readOnlyHint}:{},...typeof t.untrustedContentHint=="boolean"?{untrustedContentHint:t.untrustedContentHint}:{}};return Object.keys(e).length>0?e:void 0},P=t=>{if(t===void 0||t==="")return{...d};if(typeof t=="object")return t!==null&&!Array.isArray(t)?t:{...d};try{let e=JSON.parse(t);return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{...d}}catch{return{...d}}},w=t=>{if(t==null)return{content:[{type:"text",text:""}]};let e;try{e=JSON.parse(t)}catch{return{content:[{type:"text",text:t}]}}return e!==null&&typeof e=="object"&&Array.isArray(e.content)?e:{content:[{type:"text",text:typeof e=="string"?e:D(e)}]}},s=t=>({isError:!0,content:[{type:"text",text:t}]}),A=async t=>{if(typeof window>"u"||typeof window.confirm!="function")return!1;let e=O(t.args),n=`Allow the AI to call ${t.toolName}`+(e?`
|
|
2
|
+
|
|
3
|
+
Arguments:
|
|
4
|
+
${e}`:"")+(t.description?`
|
|
5
|
+
|
|
6
|
+
${t.description}`:"");return window.confirm(n)},O=t=>{if(t==null)return"";try{let e=JSON.stringify(t,null,2);return e.length>500?e.slice(0,500)+"\u2026":e}catch{return String(t)}},k=t=>{if(t===void 0)return"{}";try{let e=JSON.stringify(t);return e===void 0?"{}":e}catch{return"{}"}},D=t=>{if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}};export{b as WebMcpBridge};
|