@mihe-dev/js 0.2.6 → 0.2.7
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/mihe.d.ts +1 -1
- package/dist/mihe.iife.min.js +5 -3
- package/dist/mihe.iife.min.js.map +2 -2
- package/dist/mihe.js +1 -1
- package/dist/mihe.min.js +5 -3
- package/dist/mihe.min.js.map +2 -2
- package/dist/widget/panel.js +18 -2
- package/dist/widget/panel.js.map +1 -1
- package/dist/widget/styles.d.ts +1 -1
- package/dist/widget/styles.d.ts.map +1 -1
- package/dist/widget/styles.js +2 -0
- package/dist/widget/styles.js.map +1 -1
- package/package.json +1 -1
package/dist/mihe.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { type CardView, type DescribeProposal } from "./card-view.js";
|
|
|
19
19
|
import { type AssistantChart, type AssistantTable, type AssistantTabs } from "./declarations.js";
|
|
20
20
|
import { AssistantStore, type ActionHandler, type ComponentDeclaration, type ScreenDeclaration } from "./store.js";
|
|
21
21
|
import { type VoiceState } from "./voice.js";
|
|
22
|
-
export declare const SDK_VERSION = "0.2.
|
|
22
|
+
export declare const SDK_VERSION = "0.2.7";
|
|
23
23
|
/**
|
|
24
24
|
* DOM id of the assistant panel, so a custom trigger can point
|
|
25
25
|
* `aria-controls` at it.
|
package/dist/mihe.iife.min.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @mihe-dev/js 0.2.
|
|
1
|
+
/*! @mihe-dev/js 0.2.7 | MIT © Neek Digital Solutions Ltd | https://mihe.dev */
|
|
2
2
|
"use strict";var Mihe=(()=>{var q=Object.defineProperty;var tt=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var nt=Object.prototype.hasOwnProperty;var rt=(n,e,t)=>e in n?q(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var st=(n,e)=>{for(var t in e)q(n,t,{get:e[t],enumerable:!0})},ot=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of it(e))!nt.call(n,r)&&r!==t&&q(n,r,{get:()=>e[r],enumerable:!(i=tt(e,r))||i.enumerable});return n};var at=n=>ot(q({},"__esModule",{value:!0}),n);var o=(n,e,t)=>rt(n,typeof e!="symbol"?e+"":e,t);var Kt={};st(Kt,{ASSISTANT_PANEL_ID:()=>U,ATTACHMENT_TIMEOUT_MS:()=>ke,AssistantClient:()=>E,AssistantStore:()=>R,COMPONENT_ATTRIBUTE:()=>M,DESCRIBE_TIMEOUT_MS:()=>z,ELEMENT_NAME:()=>B,HighlightEngine:()=>L,MAX_ATTACHMENTS:()=>re,MicrophoneCapture:()=>D,Mihe:()=>H,PROTOCOL_VERSION:()=>A,SDK_VERSION:()=>we,SpeakerQueue:()=>P,VOICE_SAMPLE_RATE:()=>y,VoiceSession:()=>O,acceptsFile:()=>Se,appView:()=>j,chartDeclaration:()=>$,chartSignature:()=>ee,createMihe:()=>He,defineMiheAssistant:()=>Ae,executeCommand:()=>Q,fillSummary:()=>ge,formatContextReport:()=>G,formatField:()=>T,formatValue:()=>x,fromPcm16:()=>te,hintedView:()=>C,humanizeKey:()=>S,mountWidget:()=>Ze,parseInline:()=>_,parseMarkdown:()=>he,safeHref:()=>Ce,tableDeclaration:()=>Z,tableSignature:()=>X,tabsDeclaration:()=>Y,tabsSignature:()=>J,toPcm16:()=>ye,voiceUrl:()=>ne});var A=1,y=24e3;var lt=3e4,E=class{constructor(e){o(this,"options",e);o(this,"socket",null);o(this,"state","idle");o(this,"attempt",0);o(this,"reconnectTimer",null);o(this,"heartbeatTimer",null);o(this,"stopped",!1);o(this,"conversationId",null);o(this,"lastScreen",null)}get connectionState(){return this.state}async connect(){this.state==="connecting"||this.state==="open"||(this.stopped=!1,await this.open())}close(){this.stopped=!0,this.clearTimers(),this.socket?.close(),this.socket=null,this.setState("closed")}sendMessage(e,t){this.send({type:"message",data:{text:e,clientMsgId:t}})}updateScreen(e){this.lastScreen=e,this.send({type:"screen_update",data:{screen:e}})}ackCommand(e,t,i,r){this.send({type:"command_result",data:{commandId:e,ok:t,result:i??null,error:r??null}})}confirmAction(e,t,i){this.send({type:"action_confirm",data:{proposalId:e,confirmed:t,editedInput:i??null}})}cancelTurn(e){this.send({type:"cancel",data:{turnId:e}})}requestVoiceToken(){this.send({type:"voice_token_request"})}async open(){this.setState(this.attempt===0?"connecting":"reconnecting");let e;try{e=await this.options.getUserToken()}catch{if(this.stopped)return;this.emit({type:"error",code:"user_token_unavailable",message:"Could not get a session token from the app.",recoverable:!0}),this.scheduleReconnect();return}if(this.stopped)return;let i=(this.options.socketFactory??(r=>new WebSocket(r)))(this.options.url);this.socket=i,i.onopen=()=>{let r={type:"auth",data:{publicKey:this.options.publicKey,userToken:e,sdkVersion:this.options.sdkVersion,protocolVersion:1,conversationId:this.conversationId,...this.options.debug?{debug:!0}:{}}};i.send(JSON.stringify(r))},i.onmessage=r=>{if(typeof r.data!="string")return;let s;try{s=JSON.parse(r.data)}catch{return}this.handle(s)},i.onclose=()=>{if(this.clearTimers(),this.stopped){this.setState("closed");return}this.scheduleReconnect()},i.onerror=()=>{}}handle(e){switch(e.type){case"auth_ok":{this.attempt=0,this.conversationId=e.data.conversationId,this.emit({type:"voice_available",available:e.data.voiceAvailable??!1}),e.data.assistantName&&this.emit({type:"assistant_name",name:e.data.assistantName}),this.emit({type:"launcher_icon",url:e.data.launcherIconUrl??null}),this.emit({type:"widget_settings",settings:e.data.widget??null}),this.setState("open"),this.startHeartbeat(e.data.heartbeatIntervalMs),this.lastScreen&&this.updateScreen(this.lastScreen);break}case"auth_error":{this.emit({type:"error",code:e.data.code,message:e.data.message,recoverable:!1}),this.stopped=!0;break}case"auth_expired":{this.options.getUserToken().then(t=>this.send({type:"auth",data:{publicKey:this.options.publicKey,userToken:t,sdkVersion:this.options.sdkVersion,protocolVersion:1,conversationId:this.conversationId,...this.options.debug?{debug:!0}:{}}})).catch(()=>this.socket?.close());break}case"turn_start":this.emit({type:"turn_start",turnId:e.data.turnId});break;case"delta":this.emit({type:"delta",turnId:e.data.turnId,text:e.data.text});break;case"complete":this.emit({type:"complete",turnId:e.data.turnId,message:e.data.message,sources:e.data.sources??[]});break;case"command":this.emit({type:"command",commandId:e.data.commandId,command:e.data.command});break;case"action_proposal":this.emit({type:"proposal",proposal:e.data});break;case"action_status":this.emit({type:"action_status",proposalId:e.data.proposalId,status:e.data.status,result:e.data.result??void 0,error:e.data.error??void 0});break;case"error":this.emit({type:"error",code:e.data.code,message:e.data.message,recoverable:e.data.recoverable});break;case"voice_token":this.emit({type:"voice_token",token:e.data.token,expiresAt:e.data.expiresAt});break;case"context_report":this.emit({type:"context_report",report:e.data});break;case"pong":break}}send(e){if(!(this.state!=="open"&&e.type!=="auth"))try{this.socket?.send(JSON.stringify(e))}catch{}}scheduleReconnect(){this.setState("reconnecting");let e=this.options.reconnectDelay?.(this.attempt)??ct(this.attempt);this.attempt+=1,this.reconnectTimer=setTimeout(()=>{this.open()},e)}startHeartbeat(e){this.clearHeartbeat(),this.heartbeatTimer=setInterval(()=>{this.send({type:"ping"})},e)}clearHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}clearTimers(){this.clearHeartbeat(),this.reconnectTimer!==null&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}setState(e){this.state!==e&&(this.state=e,this.emit({type:"state",state:e}))}emit(e){this.options.onEvent(e)}};function ct(n){let e=Math.min(1e3*2**n,lt);return e/2+Math.random()*(e/2)}function x(n){if(n==null)return"\u2014";if(typeof n=="string")return n;if(typeof n=="number"||typeof n=="boolean")return String(n);if(Array.isArray(n))return n.map(x).join(", ")||"\u2014";if(typeof n=="object"){let e=Object.entries(n),t=e.find(([r])=>/^(quantity|qty|count)$/i.test(r)),i=e.find(([r,s])=>/(?:name|title|label)$|^(?:product|item)$/i.test(r)&&typeof s=="string");if(t&&i){let r=e.filter(([s])=>s!==t[0]&&s!==i[0]).map(([s,a])=>`${S(s)}: ${x(a)}`);return[`${x(t[1])} \xD7 ${x(i[1])}`,...r].join("; ")}return e.map(([r,s])=>`${S(r)}: ${x(s)}`).join(", ")}return String(n)}function S(n){let e=n.replace(/[_-]+/g," ").replace(/([a-z0-9])([A-Z])/g,"$1 $2").trim();return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}var k=n=>n&&typeof n=="object"?n:{},me=n=>n["x-mihe-hidden"]===!0,Le=(n,e)=>typeof e.title=="string"&&e.title.trim()?e.title:S(n);function T(n,e){let t=k(e),i=t["x-mihe-format"];if(i==="yesno"&&typeof n=="boolean")return n?"Yes":"No";if(i==="money"&&typeof n=="number")return n.toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2});if(i==="date"&&typeof n=="string"&&!Number.isNaN(Date.parse(n)))return new Date(n).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"});if(Array.isArray(n))return n.map(r=>T(r,t.items)).join(", ")||"\u2014";if(n&&typeof n=="object"){let r=t.properties??{},a=[...Object.keys(r).filter(l=>l in n),...Object.keys(n).filter(l=>!(l in r))].filter(l=>!me(k(r[l])));return Object.keys(r).length?a.map(l=>l===a[0]&&typeof n[l]=="string"?String(n[l]):`${Le(l,k(r[l]))} ${T(n[l],r[l])}`).join(" \xB7 "):x(n)}return x(n)}function ge(n,e,t){if(typeof n!="string"||!n.trim())return null;let i=!1,r=n.replace(/\{([A-Za-z0-9_]+)\}/g,(s,a)=>{let l=e[a];return l==null||l===""?(i=!0,""):Array.isArray(l)?String(l.length):T(l,t.properties?.[a])});return i?null:r}function C(n){let e=k(n.inputSchema),t=e.properties??{},i=n.input??{},r=!!e["x-mihe-summary"]||Object.values(t).some(d=>{let h=k(d);return typeof h.title=="string"||me(h)||h["x-mihe-format"]!==void 0}),a=[...Object.keys(t).filter(d=>d in i),...Object.keys(i).filter(d=>!(d in t))].filter(d=>!me(k(t[d]))).map(d=>{let h=i[d],p=r?Le(d,k(t[d])):S(d);return Array.isArray(h)&&h.length>0?{label:p,items:h.map(u=>T(u,k(t[d]).items))}:{label:p,text:T(h,t[d])}}),l=ge(e["x-mihe-summary"],i,e)??void 0;return{source:r?"hints":"plain",...l?{summary:l}:{},lines:a}}var dt=/^(https?:|blob:|data:image\/)/i;function j(n){let e=t=>typeof t=="string"?t:t==null?void 0:String(t);return{source:"app",...e(n.summary)?{summary:e(n.summary)}:{},...e(n.note)?{note:e(n.note)}:{},...e(n.confirmLabel)?{confirmLabel:e(n.confirmLabel)}:{},lines:(Array.isArray(n.lines)?n.lines:[]).map(t=>({...e(t.label)?{label:e(t.label)}:{},...e(t.text)!==void 0?{text:e(t.text)}:{},...e(t.before)!==void 0?{before:e(t.before)}:{},...Array.isArray(t.items)?{items:t.items.map(i=>String(i))}:{},...Array.isArray(t.images)?{images:t.images.filter(i=>i&&typeof i.src=="string"&&dt.test(i.src)).slice(0,12).map(i=>({src:i.src,...e(i.alt)?{alt:e(i.alt)}:{}}))}:{}}))}}var z=4e3;var M="data-mihe-component",ht="mihe-highlight";function pt(n){return n?!!n.closest("button, a[href], [role='button'], [role='link']"):!1}function N(n){return document.querySelector(`[${M}="${CSS.escape(n)}"]`)}var L=class{constructor(){o(this,"overlay",null);o(this,"caption",null);o(this,"target",null);o(this,"tracking",!1);o(this,"observer",null);o(this,"frame",0);o(this,"position",()=>{if(!this.overlay||!this.target)return;if(!this.target.isConnected){this.clear();return}let e=this.target.getBoundingClientRect();Object.assign(this.overlay.style,{top:`${e.top-6}px`,left:`${e.left-6}px`,width:`${e.width+12}px`,height:`${e.height+12}px`})});o(this,"reposition",()=>{this.frame||(this.frame=requestAnimationFrame(()=>{this.frame=0,this.position()}))});o(this,"onKeyDown",e=>{e.key==="Escape"&&this.clear()});o(this,"onPointerDown",e=>{let t=e.target;t instanceof Node&&this.target?.contains(t)&&!pt(this.target)||this.clear()})}highlight(e,t){let i=N(e);return i?(this.target=i,this.ensureOverlay(),this.setCaption(t),this.position(),this.startTracking(),i.scrollIntoView({behavior:"smooth",block:"center"}),!0):!1}focus(e,t){let i=N(e);return i?(this.highlight(e,t),(i.matches("input, textarea, select, button, [tabindex]")?i:i.querySelector("input, textarea, select, button, [tabindex]"))?.focus(),!0):!1}scrollTo(e){let t=N(e);return t?(t.scrollIntoView({behavior:"smooth",block:"center"}),!0):!1}clear(){this.stopTracking(),this.overlay?.remove(),this.overlay=null,this.caption=null,this.target=null}ensureOverlay(){if(this.overlay)return;let e=document.createElement("div");e.id=ht,Object.assign(e.style,{position:"fixed",zIndex:"2147483000",pointerEvents:"none",border:"2px solid #4f7cff",borderRadius:"8px",boxShadow:"0 0 0 9999px rgba(15, 23, 42, 0.45)",transition:"top 120ms ease, left 120ms ease, width 120ms ease, height 120ms ease"});let t=document.createElement("div");Object.assign(t.style,{position:"absolute",left:"0",top:"100%",marginTop:"8px",maxWidth:"260px",padding:"8px 10px",borderRadius:"8px",background:"#0f172a",color:"#f8fafc",font:"500 13px/1.4 system-ui, -apple-system, sans-serif",display:"none"}),e.appendChild(t),document.body.appendChild(e),this.overlay=e,this.caption=t}setCaption(e){this.caption&&(e?(this.caption.textContent=e,this.caption.style.display="block"):(this.caption.textContent="",this.caption.style.display="none"))}startTracking(){this.tracking||(this.tracking=!0,window.addEventListener("scroll",this.position,{passive:!0,capture:!0}),window.addEventListener("resize",this.position,{passive:!0}),window.addEventListener("keydown",this.onKeyDown),window.addEventListener("pointerdown",this.onPointerDown,{capture:!0}),this.observer=new MutationObserver(this.reposition),this.observer.observe(document.body,{childList:!0,subtree:!0}))}stopTracking(){this.tracking&&(this.tracking=!1,window.removeEventListener("scroll",this.position,{capture:!0}),window.removeEventListener("resize",this.position),window.removeEventListener("keydown",this.onKeyDown),window.removeEventListener("pointerdown",this.onPointerDown,{capture:!0}),this.observer?.disconnect(),this.observer=null,this.frame&&(cancelAnimationFrame(this.frame),this.frame=0))}};var Ie=5e3,be=1e4;function ut(n,e){for(let[t,i]of Object.entries(e)){let r=n.find(s=>s.key===t);if(!r)return`"${t}" is not something this table can be searched by.`;if(typeof i!="string")return`The value for "${t}" must be a string.`;if(r.kind==="enum"&&!r.values.includes(i))return`"${i}" is not one of "${t}"'s values.`;if(r.kind==="date"&&!mt(i))return`"${i}" is not a date in YYYY-MM-DD form.`;if(r.kind==="text"&&(i.length>ft||/[\u0000-\u001f\u007f]/.test(i)))return`The search for "${t}" is too long or contains control characters.`}return null}var ft=100;function mt(n){if(!/^\d{4}-\d{2}-\d{2}$/.test(n))return!1;let e=new Date(`${n}T00:00:00Z`);return!Number.isNaN(e.getTime())&&e.toISOString().slice(0,10)===n}function gt(){return typeof window>"u"?null:window.location.pathname}function bt(){return typeof window>"u"?null:window.location.pathname+window.location.search}async function Q(n,e){switch(n.type){case"navigate":{let{route:t}=n.data,i=t.includes("?")&&bt()!==t;return e.navigate(t),await e.screenPublished?.(t,{fresh:i})??!0?{ok:!0,result:{route:t}}:{ok:!0,result:{route:t,note:"Navigation started, but the destination has not reported its context yet. Anything scoped to that screen may not be available for another moment."}}}case"highlight":{let{componentKey:t,message:i}=n.data;return e.highlighter.highlight(t,i??void 0)?{ok:!0}:{ok:!1,error:ve(t)}}case"focus":{let{componentKey:t,message:i}=n.data;return e.highlighter.focus(t,i??void 0)?{ok:!0}:{ok:!1,error:ve(t)}}case"scroll_to":{let{componentKey:t}=n.data;return e.highlighter.scrollTo(t)?{ok:!0}:{ok:!1,error:ve(t)}}case"open_modal":{let{modalKey:t}=n.data;return e.openModal?e.openModal(t)===!1?{ok:!1,error:`There is no \`${t}\` dialog on this screen. It may belong to a different one.`}:{ok:!0}:{ok:!1,error:"This app has not wired up modal opening, so that modal cannot be opened."}}case"run_frontend_action":{let{actionName:t,input:i}=n.data,r=e.store.getAction(t);if(!r)return{ok:!1,error:`No handler is currently mounted for "${t}".`};let s=Date.now(),a=setTimeout(()=>{console.warn(`[mihe] The "${t}" handler has run for ${Ie/1e3}s. The runtime waits ${be/1e3}s unless the action (timeoutSeconds) or the app sets longer, then tells the assistant it failed. If it is waiting for the user, open the UI they need and return at once (say what you opened); they finish it there.`)},Ie),l=()=>{Date.now()-s>be&&console.warn(`[mihe] The "${t}" handler finished after ${Math.round((Date.now()-s)/1e3)}s. If that was past its time limit (${be/1e3}s unless the action sets timeoutSeconds or the app sets longer), the assistant was told it failed whatever the outcome. If it waits on the user, return before they act; if it is slow by nature, give it timeoutSeconds.`)};try{let d=await r.handler(i??{});return l(),{ok:!0,result:d??{done:!0}}}catch(d){return l(),{ok:!1,error:I(d)}}finally{clearTimeout(a)}}case"set_view":{let{controlKey:t,value:i}=n.data,r=e.store.getControl(t);if(!r)return{ok:!1,error:`"${t}" is not on the page right now.`};if(!r.options.some(a=>a.value===i))return{ok:!1,error:`"${i}" is not one of "${t}"'s options.`};try{await r.onChange(i)}catch(a){return{ok:!1,error:I(a)}}return await e.viewPublished?.(t,i)??!0?{ok:!0,result:{showing:i}}:{ok:!1,error:`The app was asked to show "${i}", but "${t}" still reports another tab.`}}case"read_table":{let{tableKey:t,offset:i,limit:r}=n.data,s=e.store.getTable(t);if(!s)return{ok:!1,error:`"${t}" is not on the page right now.`};try{return{ok:!0,result:{rows:s.read(i,r),offset:i,loaded:s.loadedRows,...s.total===void 0?{}:{total:s.total}}}}catch(a){return{ok:!1,error:I(a)}}}case"query_table":{let{tableKey:t,params:i,limit:r,show:s}=n.data,a=e.store.getTable(t);if(!a)return{ok:!1,error:`"${t}" is not on the page right now.`};if(!a.query)return{ok:!1,error:`"${t}" cannot be searched.`};let l=ut(a.query.params,i);if(l)return{ok:!1,error:l};let d;try{d=await a.query.run(i)}catch(p){return{ok:!1,error:I(p)}}let h=!1;if(s&&a.query.show)try{await a.query.show(i),h=await e.screenPublished?.(gt()??"",{fresh:!0})??!0}catch(p){return{ok:!1,error:I(p)}}return{ok:!0,result:{rows:d.rows.slice(0,r),...d.total===void 0?{}:{total:d.total},shown:h}}}case"read_chart":{let{chartKey:t,series:i,limit:r}=n.data,s=e.store.getChart(t);if(!s)return{ok:!1,error:`"${t}" is not on the page right now.`};try{return{ok:!0,result:{series:s.read(i??void 0,r)}}}catch(a){return{ok:!1,error:I(a)}}}case"clear_highlight":return e.highlighter.clear(),{ok:!0};default:return{ok:!1,error:`This app's SDK does not understand the "${n.type}" command. It may need updating.`}}}function ve(n){return!!N(n)?`"${n}" is on the page but not visible.`:`"${n}" is not on the page right now.`}function I(n){return n instanceof Error?n.message:typeof n=="string"?n:"The action failed."}function G(n){let t=[`[mihe] Each answer on ${n.screenId?`\`${n.screenId}\``:"an unregistered page"} re-sends about:`];t.push(` typed: ${Re(n.chat)}`),n.voice&&t.push(` voice: ${Re(n.voice)}`);let i=(n.voice??n.chat).tools.slice(0,5);return i.length>0&&t.push(` largest tools: ${i.map(r=>`${r.name} ${r.tokens}`).join(", ")}`),t.join(`
|
|
3
3
|
`)}function Re(n){return`${(n.instructionTokens+n.toolTokens+n.screenTokens).toLocaleString("en")} tokens \u2014 instructions ${n.instructionTokens}, ${n.tools.length} tools ${n.toolTokens}, this screen ${n.screenTokens}`}function De(n,e){let[t]=n;if(!t)return;let i=n[n.length-1],r=t,s=t,a=0,l,d;return n.forEach((h,p)=>{if(a+=h.y,h.y<r.y&&(r=h),h.y>s.y&&(s=h),!e||p===0)return;let u=n[p-1],m=h.y-u.y;m>0&&(!l||m>l.change)&&(l={from:u.x,to:h.x,change:m}),m<0&&(!d||m<d.change)&&(d={from:u.x,to:h.x,change:m})}),{points:n.length,first:t,last:i,min:r,max:s,total:Math.round(a*100)/100,...l?{largestRise:l}:{},...d?{largestFall:d}:{}}}function Pe(n,e){if(n.length<=e)return n;if(e<=1)return n.slice(0,1);let t=(n.length-1)/(e-1);return Array.from({length:e},(i,r)=>n[Math.round(r*t)])}var Oe=200;function vt(n){if(n==null)return null;if(typeof n=="number"||typeof n=="boolean")return n;let e=n instanceof Date?n.toISOString():typeof n=="string"?n:JSON.stringify(n);return e.length>Oe?`${e.slice(0,Oe)}\u2026`:e}function Y(n){let e=n();return{kind:"tabs",label:e.label,options:e.tabs.map(({value:t,label:i})=>({value:t,label:i})),value:e.value,onChange:t=>n().onChange(t)}}function J(n){return JSON.stringify({label:n.label,tabs:n.tabs.map(({value:e,label:t})=>({value:e,label:t})),value:n.value})}function Ve(n){return Object.entries(n.params).map(([e,t])=>({key:e,kind:t.kind,values:t.kind==="enum"?[...t.values]:[],description:t.description??""}))}function X(n){return JSON.stringify({label:n.label,columns:n.columns.map(({key:e,label:t})=>({key:e,label:t})),rowIdName:n.rowIdName,opens:n.opens?.screenId,total:n.total,loaded:n.rows.length,query:n.query?{params:Ve(n.query),canShow:n.query.show!==void 0}:void 0})}function Z(n){let e=n(),t=i=>{let{rowId:r,columns:s,opens:a}=n(),l={};for(let d of s){let h=d.value?d.value(i):i[d.key];l[d.label]=vt(h)}return{id:r(i),...a?{open:a.params(i)}:{},...l}};return{label:e.label,columns:e.columns.map(({key:i,label:r})=>({key:i,label:r})),rowIdName:e.rowIdName,opens:e.opens?.screenId,total:e.total,loadedRows:e.rows.length,read:(i,r)=>n().rows.slice(i,i+r).map(t),...e.query?{query:{params:Ve(e.query),run:async i=>{let r=n().query;if(!r)throw new Error("This table can no longer be searched.");let s=await r.run(i);return{rows:s.rows.map(t),...s.total===void 0?{}:{total:s.total}}},...e.query.show?{show:i=>n().query?.show?.(i)}:{}}}:{}}}function _e(n,e){let t=n.x.format;return n.data.flatMap(i=>{let r=i[e],s=typeof r=="number"?r:r==null?NaN:Number(r);if(!Number.isFinite(s))return[];let a=i[n.x.key];return[{x:t?t(a):String(a),y:s}]})}function $(n){let e=n(),t=e.x.kind!=="category";return{title:e.title,xLabel:e.x.label,xKind:t?"ordered":"category",series:e.series.map(i=>{let r=De(_e(e,i.key),t);return{name:i.name,...i.unit?{unit:i.unit}:{},...r?{summary:r}:{}}}),read:(i,r)=>{let s=n();return s.series.filter(a=>i===void 0||a.name===i).map(a=>({name:a.name,points:Pe(_e(s,a.key),r)}))}}}function ee(n){let{read:e,...t}=$(()=>n);return JSON.stringify(t)}var R=class{constructor(){o(this,"screen",null);o(this,"components",new Map);o(this,"controls",new Map);o(this,"tables",new Map);o(this,"charts",new Map);o(this,"values",new Map);o(this,"actions",new Map);o(this,"listeners",new Set);o(this,"snapshot",null);o(this,"snapshotDirty",!0);o(this,"subscribe",e=>(this.listeners.add(e),()=>{this.listeners.delete(e)}));o(this,"getScreenContext",()=>this.snapshotDirty?(this.snapshot=this.screen?{screenId:this.screen.screenId,route:this.screen.route,title:this.screen.title,description:this.screen.description??"",keywords:this.screen.keywords??[],visibleData:this.screen.loading?{}:{...this.screen.visibleData??{},...Object.fromEntries(this.values)},components:[...this.components.entries()].map(([e,t])=>({componentKey:e,type:t.type,label:t.label,description:t.description??"",actions:t.actions??[]})),controls:[...this.controls.entries()].map(([e,t])=>({controlKey:e,kind:t.kind,label:t.label,options:t.options.map(({value:i,label:r})=>({value:i,label:r})),...t.value===void 0?{}:{value:t.value}})),tables:[...this.tables.entries()].map(([e,t])=>({tableKey:e,label:t.label,columns:t.columns.map(({key:i,label:r})=>({key:i,label:r})),loadedRows:t.loadedRows,...t.rowIdName?{rowId:t.rowIdName}:{},...t.opens?{opens:t.opens}:{},...t.total===void 0?{}:{totalRows:t.total},...t.query?{query:{params:t.query.params.map(({key:i,kind:r,values:s,description:a})=>({key:i,kind:r,values:s,description:a})),canShow:t.query.show!==void 0}}:{}})),charts:[...this.charts.entries()].map(([e,t])=>({chartKey:e,title:t.title,xLabel:t.xLabel,xKind:t.xKind,series:t.series}))}:null,this.snapshotDirty=!1,this.snapshot):this.snapshot)}setScreen(e){let t=this.screen;this.screen=e,t&&t.screenId!==e.screenId&&(this.components.clear(),this.controls.clear(),this.tables.clear(),this.charts.clear(),this.values.clear()),this.invalidate()}clearScreen(e){this.screen?.screenId===e&&(this.screen=null,this.components.clear(),this.controls.clear(),this.tables.clear(),this.charts.clear(),this.values.clear(),this.invalidate())}registerComponent(e,t){this.components.set(e,t),this.invalidate()}unregisterComponent(e){this.components.delete(e)&&this.invalidate()}registerControl(e,t){this.controls.set(e,t),this.invalidate()}unregisterControl(e){this.controls.delete(e)&&this.invalidate()}getControl(e){return this.controls.get(e)}registerTable(e,t){this.tables.set(e,t),this.invalidate()}unregisterTable(e){this.tables.delete(e)&&this.invalidate()}getTable(e){return this.tables.get(e)}setValues(e,t){this.values.set(e,t),this.invalidate()}clearValues(e){this.values.delete(e)&&this.invalidate()}registerChart(e,t){this.charts.set(e,t),this.invalidate()}unregisterChart(e){this.charts.delete(e)&&this.invalidate()}getChart(e){return this.charts.get(e)}registerAction(e){this.actions.has(e.name)&&console.warn(`[assistant] Two handlers registered for action "${e.name}". The most recent one wins; the earlier one will never run.`),this.actions.set(e.name,e)}unregisterAction(e){this.actions.delete(e)}getAction(e){return this.actions.get(e)}isScreenLoading(){return this.screen?.loading===!0}hasComponent(e){return this.components.has(e)}invalidate(){this.snapshotDirty=!0;for(let e of this.listeners)e()}};var Ne=20,yt=200,xt=`
|
|
4
4
|
class MiheCapture extends AudioWorkletProcessor {
|
|
@@ -43,7 +43,7 @@ class MiheCapture extends AudioWorkletProcessor {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
registerProcessor('mihe-capture', MiheCapture);
|
|
46
|
-
`;function ye(n){let e=new ArrayBuffer(n.length*2),t=new DataView(e);for(let i=0;i<n.length;i+=1){let r=Math.max(-1,Math.min(1,n[i]??0));t.setInt16(i*2,r*32767,!0)}return e}function te(n){let e=new DataView(n),t=new Float32Array(n.byteLength/2);for(let i=0;i<t.length;i+=1)t[i]=e.getInt16(i*2,!0)/32767;return t}function ie(n){let e=te(n);if(e.length===0)return 0;let t=0;for(let r of e)t+=r*r;let i=Math.sqrt(t/e.length);return Math.min(1,Math.sqrt(i)*1.8)}function wt(n,e,t){if(e===t)return n;let i=e/t,r=Math.floor(n.length/i),s=new Float32Array(r);for(let a=0;a<r;a+=1){let l=a*i,d=Math.floor(l),h=Math.min(d+1,n.length-1),p=l-d;s[a]=(n[d]??0)*(1-p)+(n[h]??0)*p}return s}var D=class{constructor(e){o(this,"onFrame",e);o(this,"context",null);o(this,"stream",null);o(this,"node",null);o(this,"source",null);o(this,"open",!1)}get capturing(){return this.open}async start(){if(this.context){await this.context.resume();return}this.stream=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}});let e=new AudioContext({sampleRate:24e3});this.context=e,this.source=e.createMediaStreamSource(this.stream);let t=i=>{this.open&&this.onFrame(ye(wt(i,e.sampleRate,24e3)))};try{let i=URL.createObjectURL(new Blob([xt],{type:"application/javascript"}));await e.audioWorklet.addModule(i),URL.revokeObjectURL(i);let r=new AudioWorkletNode(e,"mihe-capture",{processorOptions:{frameSamples:Math.round(e.sampleRate*Ne/1e3)}});r.port.onmessage=a=>t(a.data),this.source.connect(r);let s=e.createGain();s.gain.value=0,r.connect(s).connect(e.destination),this.node=r}catch{let i=Math.max(256,2**Math.round(Math.log2(e.sampleRate*Ne/1e3))),r=e.createScriptProcessor(i,1,1);r.onaudioprocess=s=>t(new Float32Array(s.inputBuffer.getChannelData(0))),this.source.connect(r),r.connect(e.destination),this.node=r}await e.resume()}unmute(){this.open=!0}mute(){this.open=!1}async stop(){this.open=!1,this.node?.disconnect(),this.source?.disconnect(),this.stream?.getTracks().forEach(e=>e.stop()),await this.context?.close().catch(()=>{}),this.node=null,this.source=null,this.stream=null,this.context=null}},P=class{constructor(e){o(this,"onLevel",e);o(this,"levelTimers",new Set);o(this,"context",null);o(this,"gain",null);o(this,"sources",new Set);o(this,"nextStart",0);o(this,"startedAt",0)}async start(){if(this.context){await this.context.resume();return}let e=new AudioContext({sampleRate:24e3});this.gain=e.createGain(),this.gain.connect(e.destination),this.context=e,await e.resume()}enqueue(e){let t=this.context;if(!t||!this.gain)return;let i=te(e);if(i.length===0)return;let r=t.createBuffer(1,i.length,24e3);r.getChannelData(0).set(i);let s=t.createBufferSource();s.buffer=r,s.connect(this.gain);let a=t.currentTime;if(this.nextStart<a&&(this.nextStart=a+yt/1e3,this.startedAt=this.nextStart),s.start(this.nextStart),this.onLevel){let l=ie(e),d=this.onLevel,h=setTimeout(()=>{this.levelTimers.delete(h),d(l)},Math.max(0,(this.nextStart-a)*1e3));this.levelTimers.add(h)}this.nextStart+=r.duration,this.sources.add(s),s.onended=()=>this.sources.delete(s)}heardMs(){if(!this.context||this.startedAt===0)return 0;let e=this.context.currentTime-this.startedAt;return Math.max(0,Math.round(e*1e3))}get speaking(){return this.sources.size>0}flush(){for(let e of this.sources)try{e.stop()}catch{}this.sources.clear(),this.nextStart=0,this.startedAt=0;for(let e of this.levelTimers)clearTimeout(e);this.levelTimers.clear(),this.onLevel?.(0)}async stop(){this.flush(),this.gain?.disconnect(),await this.context?.close().catch(()=>{}),this.gain=null,this.context=null}};var O=class{constructor(e){o(this,"options",e);o(this,"socket",null);o(this,"state","idle");o(this,"mic");o(this,"speaker");o(this,"held",null);o(this,"stopped",!1);o(this,"utteranceMs",0);o(this,"assistantLine","");o(this,"playbackTimer",null);o(this,"minUtteranceMs",150);this.speaker=new P(t=>e.onLevel?.("assistant",t)),this.mic=new D(t=>this.sendAudio(t))}get currentState(){return this.state}async start(){if(this.socket)return;this.stopped=!1,this.setState("connecting");try{await this.mic.start(),await this.speaker.start()}catch(i){this.emit({type:"error",code:"microphone_unavailable",message:i instanceof Error&&i.name==="NotAllowedError"?"Microphone access was declined, so voice cannot start.":"No microphone is available.",recoverable:!1,fallbackToChat:!0}),this.setState("error");return}let t=(this.options.socketFactory??(i=>new WebSocket(i)))(this.options.url);t.binaryType="arraybuffer",this.socket=t,t.onmessage=i=>{typeof i.data=="string"?this.handleControl(i.data):i.data instanceof ArrayBuffer&&(this.speaker.enqueue(i.data),this.state==="thinking"&&this.setState("speaking"))},t.onclose=()=>{this.stop()},t.onerror=()=>{}}beginUtterance(e){if(!this.options.handsFree&&!(this.state!=="listening"&&this.state!=="speaking")){if(this.utteranceMs=0,e?.hold){this.held=[],this.mic.unmute(),this.setState("recording");return}this.interruptPlayback(),this.mic.unmute(),this.setState("recording")}}confirmUtterance(){let e=this.held;if(e){this.held=null,this.interruptPlayback();for(let t of e)this.sendAudio(t)}}discardUtterance(){this.held&&(this.held=null,this.mic.mute(),this.utteranceMs=0,this.options.onLevel?.("user",0),this.setState(this.speaker.speaking?"speaking":"listening"))}interruptPlayback(){this.speaker.speaking&&(this.sendControl({type:"playback",data:{ms:this.speaker.heardMs()}}),this.speaker.flush())}endUtterance(){if(!this.options.handsFree&&this.state==="recording"){if(this.confirmUtterance(),this.mic.mute(),this.options.onLevel?.("user",0),this.utteranceMs<this.minUtteranceMs){this.emit({type:"error",code:"utterance_too_short",message:"Hold the button while you speak.",recoverable:!0,fallbackToChat:!1}),this.setState("listening");return}this.sendControl({type:"commit"}),this.setState("thinking")}}async stop(){this.stopped||(this.stopped=!0,this.playbackTimer!==null&&(clearInterval(this.playbackTimer),this.playbackTimer=null),this.sendControl({type:"end"}),this.socket?.close(),this.socket=null,await Promise.all([this.mic.stop(),this.speaker.stop()]),this.setState("idle"))}handleControl(e){let t;try{t=JSON.parse(e)}catch{return}switch(t.type){case"ready":this.minUtteranceMs=t.data.minUtteranceMs??this.minUtteranceMs,this.options.handsFree&&this.mic.unmute(),this.setState("listening");break;case"transcript":{let i=t.data.text;t.data.role==="assistant"&&(t.data.final?this.assistantLine="":(this.assistantLine+=i,i=this.assistantLine)),this.emit({type:"transcript",role:t.data.role,text:i,final:t.data.final});break}case"status":t.data.state==="listening"&&this.speaker.speaking&&this.speaker.flush(),t.data.state==="listening"&&(this.assistantLine=""),this.state!=="recording"&&this.setState(t.data.state==="reconnecting"?"connecting":t.data.state);break;case"speech_done":(this.state==="speaking"||this.state==="thinking")&&this.setState("listening");break;case"ending_soon":this.emit({type:"ending_soon",secondsRemaining:t.data.secondsRemaining});break;case"ended":this.emit({type:"ended",reason:t.data.reason,message:t.data.message}),this.stop();break;case"error":this.emit({type:"error",code:t.data.code,message:t.data.message,recoverable:t.data.recoverable,fallbackToChat:t.data.fallbackToChat}),t.data.recoverable||(this.setState("error"),this.stop());break}}sendAudio(e){if(!(!this.options.handsFree&&this.state!=="recording")){if(this.held){this.held.push(e),this.options.onLevel?.("user",ie(e));return}this.options.onLevel?.("user",ie(e)),this.utteranceMs+=e.byteLength*1e3/(2*24e3);try{this.socket?.send(e)}catch{}}}sendControl(e){try{this.socket?.send(JSON.stringify(e))}catch{}}setState(e){this.state!==e&&(this.state=e,this.reportPlaybackWhileSpeaking(),this.options.onEvent({type:"state",state:e}))}reportPlaybackWhileSpeaking(){if(!(!!this.options.handsFree&&this.state==="speaking")){this.playbackTimer!==null&&(clearInterval(this.playbackTimer),this.playbackTimer=null);return}this.playbackTimer===null&&(this.playbackTimer=setInterval(()=>{this.speaker.speaking&&this.sendControl({type:"playback",data:{ms:this.speaker.heardMs()}})},250))}emit(e){this.options.onEvent(e)}};function ne(n,e,t=!1){let i=n.replace(/\/v1\/ws\/?$/,"/v1/voice"),r=i.includes("?")?"&":"?",s=t?"&handsFree=true":"";return`${i}${r}token=${encodeURIComponent(e)}${s}`}var kt=60,$e=2500,we="0.2.
|
|
46
|
+
`;function ye(n){let e=new ArrayBuffer(n.length*2),t=new DataView(e);for(let i=0;i<n.length;i+=1){let r=Math.max(-1,Math.min(1,n[i]??0));t.setInt16(i*2,r*32767,!0)}return e}function te(n){let e=new DataView(n),t=new Float32Array(n.byteLength/2);for(let i=0;i<t.length;i+=1)t[i]=e.getInt16(i*2,!0)/32767;return t}function ie(n){let e=te(n);if(e.length===0)return 0;let t=0;for(let r of e)t+=r*r;let i=Math.sqrt(t/e.length);return Math.min(1,Math.sqrt(i)*1.8)}function wt(n,e,t){if(e===t)return n;let i=e/t,r=Math.floor(n.length/i),s=new Float32Array(r);for(let a=0;a<r;a+=1){let l=a*i,d=Math.floor(l),h=Math.min(d+1,n.length-1),p=l-d;s[a]=(n[d]??0)*(1-p)+(n[h]??0)*p}return s}var D=class{constructor(e){o(this,"onFrame",e);o(this,"context",null);o(this,"stream",null);o(this,"node",null);o(this,"source",null);o(this,"open",!1)}get capturing(){return this.open}async start(){if(this.context){await this.context.resume();return}this.stream=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}});let e=new AudioContext({sampleRate:24e3});this.context=e,this.source=e.createMediaStreamSource(this.stream);let t=i=>{this.open&&this.onFrame(ye(wt(i,e.sampleRate,24e3)))};try{let i=URL.createObjectURL(new Blob([xt],{type:"application/javascript"}));await e.audioWorklet.addModule(i),URL.revokeObjectURL(i);let r=new AudioWorkletNode(e,"mihe-capture",{processorOptions:{frameSamples:Math.round(e.sampleRate*Ne/1e3)}});r.port.onmessage=a=>t(a.data),this.source.connect(r);let s=e.createGain();s.gain.value=0,r.connect(s).connect(e.destination),this.node=r}catch{let i=Math.max(256,2**Math.round(Math.log2(e.sampleRate*Ne/1e3))),r=e.createScriptProcessor(i,1,1);r.onaudioprocess=s=>t(new Float32Array(s.inputBuffer.getChannelData(0))),this.source.connect(r),r.connect(e.destination),this.node=r}await e.resume()}unmute(){this.open=!0}mute(){this.open=!1}async stop(){this.open=!1,this.node?.disconnect(),this.source?.disconnect(),this.stream?.getTracks().forEach(e=>e.stop()),await this.context?.close().catch(()=>{}),this.node=null,this.source=null,this.stream=null,this.context=null}},P=class{constructor(e){o(this,"onLevel",e);o(this,"levelTimers",new Set);o(this,"context",null);o(this,"gain",null);o(this,"sources",new Set);o(this,"nextStart",0);o(this,"startedAt",0)}async start(){if(this.context){await this.context.resume();return}let e=new AudioContext({sampleRate:24e3});this.gain=e.createGain(),this.gain.connect(e.destination),this.context=e,await e.resume()}enqueue(e){let t=this.context;if(!t||!this.gain)return;let i=te(e);if(i.length===0)return;let r=t.createBuffer(1,i.length,24e3);r.getChannelData(0).set(i);let s=t.createBufferSource();s.buffer=r,s.connect(this.gain);let a=t.currentTime;if(this.nextStart<a&&(this.nextStart=a+yt/1e3,this.startedAt=this.nextStart),s.start(this.nextStart),this.onLevel){let l=ie(e),d=this.onLevel,h=setTimeout(()=>{this.levelTimers.delete(h),d(l)},Math.max(0,(this.nextStart-a)*1e3));this.levelTimers.add(h)}this.nextStart+=r.duration,this.sources.add(s),s.onended=()=>this.sources.delete(s)}heardMs(){if(!this.context||this.startedAt===0)return 0;let e=this.context.currentTime-this.startedAt;return Math.max(0,Math.round(e*1e3))}get speaking(){return this.sources.size>0}flush(){for(let e of this.sources)try{e.stop()}catch{}this.sources.clear(),this.nextStart=0,this.startedAt=0;for(let e of this.levelTimers)clearTimeout(e);this.levelTimers.clear(),this.onLevel?.(0)}async stop(){this.flush(),this.gain?.disconnect(),await this.context?.close().catch(()=>{}),this.gain=null,this.context=null}};var O=class{constructor(e){o(this,"options",e);o(this,"socket",null);o(this,"state","idle");o(this,"mic");o(this,"speaker");o(this,"held",null);o(this,"stopped",!1);o(this,"utteranceMs",0);o(this,"assistantLine","");o(this,"playbackTimer",null);o(this,"minUtteranceMs",150);this.speaker=new P(t=>e.onLevel?.("assistant",t)),this.mic=new D(t=>this.sendAudio(t))}get currentState(){return this.state}async start(){if(this.socket)return;this.stopped=!1,this.setState("connecting");try{await this.mic.start(),await this.speaker.start()}catch(i){this.emit({type:"error",code:"microphone_unavailable",message:i instanceof Error&&i.name==="NotAllowedError"?"Microphone access was declined, so voice cannot start.":"No microphone is available.",recoverable:!1,fallbackToChat:!0}),this.setState("error");return}let t=(this.options.socketFactory??(i=>new WebSocket(i)))(this.options.url);t.binaryType="arraybuffer",this.socket=t,t.onmessage=i=>{typeof i.data=="string"?this.handleControl(i.data):i.data instanceof ArrayBuffer&&(this.speaker.enqueue(i.data),this.state==="thinking"&&this.setState("speaking"))},t.onclose=()=>{this.stop()},t.onerror=()=>{}}beginUtterance(e){if(!this.options.handsFree&&!(this.state!=="listening"&&this.state!=="speaking")){if(this.utteranceMs=0,e?.hold){this.held=[],this.mic.unmute(),this.setState("recording");return}this.interruptPlayback(),this.mic.unmute(),this.setState("recording")}}confirmUtterance(){let e=this.held;if(e){this.held=null,this.interruptPlayback();for(let t of e)this.sendAudio(t)}}discardUtterance(){this.held&&(this.held=null,this.mic.mute(),this.utteranceMs=0,this.options.onLevel?.("user",0),this.setState(this.speaker.speaking?"speaking":"listening"))}interruptPlayback(){this.speaker.speaking&&(this.sendControl({type:"playback",data:{ms:this.speaker.heardMs()}}),this.speaker.flush())}endUtterance(){if(!this.options.handsFree&&this.state==="recording"){if(this.confirmUtterance(),this.mic.mute(),this.options.onLevel?.("user",0),this.utteranceMs<this.minUtteranceMs){this.emit({type:"error",code:"utterance_too_short",message:"Hold the button while you speak.",recoverable:!0,fallbackToChat:!1}),this.setState("listening");return}this.sendControl({type:"commit"}),this.setState("thinking")}}async stop(){this.stopped||(this.stopped=!0,this.playbackTimer!==null&&(clearInterval(this.playbackTimer),this.playbackTimer=null),this.sendControl({type:"end"}),this.socket?.close(),this.socket=null,await Promise.all([this.mic.stop(),this.speaker.stop()]),this.setState("idle"))}handleControl(e){let t;try{t=JSON.parse(e)}catch{return}switch(t.type){case"ready":this.minUtteranceMs=t.data.minUtteranceMs??this.minUtteranceMs,this.options.handsFree&&this.mic.unmute(),this.setState("listening");break;case"transcript":{let i=t.data.text;t.data.role==="assistant"&&(t.data.final?this.assistantLine="":(this.assistantLine+=i,i=this.assistantLine)),this.emit({type:"transcript",role:t.data.role,text:i,final:t.data.final});break}case"status":t.data.state==="listening"&&this.speaker.speaking&&this.speaker.flush(),t.data.state==="listening"&&(this.assistantLine=""),this.state!=="recording"&&this.setState(t.data.state==="reconnecting"?"connecting":t.data.state);break;case"speech_done":(this.state==="speaking"||this.state==="thinking")&&this.setState("listening");break;case"ending_soon":this.emit({type:"ending_soon",secondsRemaining:t.data.secondsRemaining});break;case"ended":this.emit({type:"ended",reason:t.data.reason,message:t.data.message}),this.stop();break;case"error":this.emit({type:"error",code:t.data.code,message:t.data.message,recoverable:t.data.recoverable,fallbackToChat:t.data.fallbackToChat}),t.data.recoverable||(this.setState("error"),this.stop());break}}sendAudio(e){if(!(!this.options.handsFree&&this.state!=="recording")){if(this.held){this.held.push(e),this.options.onLevel?.("user",ie(e));return}this.options.onLevel?.("user",ie(e)),this.utteranceMs+=e.byteLength*1e3/(2*24e3);try{this.socket?.send(e)}catch{}}}sendControl(e){try{this.socket?.send(JSON.stringify(e))}catch{}}setState(e){this.state!==e&&(this.state=e,this.reportPlaybackWhileSpeaking(),this.options.onEvent({type:"state",state:e}))}reportPlaybackWhileSpeaking(){if(!(!!this.options.handsFree&&this.state==="speaking")){this.playbackTimer!==null&&(clearInterval(this.playbackTimer),this.playbackTimer=null);return}this.playbackTimer===null&&(this.playbackTimer=setInterval(()=>{this.speaker.speaking&&this.sendControl({type:"playback",data:{ms:this.speaker.heardMs()}})},250))}emit(e){this.options.onEvent(e)}};function ne(n,e,t=!1){let i=n.replace(/\/v1\/ws\/?$/,"/v1/voice"),r=i.includes("?")?"&":"?",s=t?"&handsFree=true":"";return`${i}${r}token=${encodeURIComponent(e)}${s}`}var kt=60,$e=2500,we="0.2.7",U="mihe-panel",re=4,ke=9e4;function St(n){return`About ${Math.max(5,Math.round(n/5)*5)} seconds left of voice. The conversation carries on in text.`}function xe(n){return`${n}_${Date.now()}_${Math.random().toString(36).slice(2,8)}`}function He(n){let e=new H(n);return e.connect(),e}var H=class{constructor(e){o(this,"store",new R);o(this,"highlighter",new L);o(this,"options");o(this,"state");o(this,"listeners",new Set);o(this,"client",null);o(this,"voiceSession",null);o(this,"voiceRequested",!1);o(this,"requestedHandsFree",!1);o(this,"requestedOpenPanel",!0);o(this,"levelListeners",new Set);o(this,"publishedRoute",null);o(this,"publishedScreen",null);o(this,"publishedSettled",!1);o(this,"screenWaiters",new Set);o(this,"publishTimer",null);o(this,"unsubscribeStore",null);o(this,"tabs",new Map);o(this,"tables",new Map);o(this,"charts",new Map);o(this,"actions",new Map);o(this,"lastScreen",null);o(this,"getState",()=>this.state);o(this,"subscribe",e=>(this.listeners.add(e),()=>{this.listeners.delete(e)}));o(this,"send",e=>{let t=e.trim(),i=this.state.attachments.filter(l=>l.status==="ready");if(this.state.attachments.some(l=>l.status==="reading")||!t&&!i.length)return;let r=[t||"(See the attached picture.)",...i.map(l=>`[Attached picture "${l.name}", as the app describes it: ${l.text}]`)].join(`
|
|
47
47
|
|
|
48
48
|
`),s=xe("msg"),a={id:s,role:"user",text:t,...i.length?{attachments:i.map(l=>({name:l.name,...l.previewUrl?{previewUrl:l.previewUrl}:{}}))}:{}};for(let l of this.state.attachments)l.status==="failed"&&l.previewUrl&&URL.revokeObjectURL(l.previewUrl);this.setState({isOpen:!0,messages:[...this.state.messages,a],attachments:[],lastError:null}),this.client?.sendMessage(r,s)});o(this,"attach",e=>{let t=this.options.describeAttachment;if(!t)return;let i=(l,d)=>this.setState({attachments:this.state.attachments.map(h=>h.id===l?{...h,...d}:h)});if(this.state.attachments.length>=re){this.setState({lastError:`Up to ${re} pictures at a time.`});return}if(!Se(this.state.attachAccept??"",e)){this.setState({lastError:`"${e.name}" isn't a kind of file this can read.`});return}let r=xe("att"),s=e.type.startsWith("image/")&&typeof URL.createObjectURL=="function"?URL.createObjectURL(e):void 0;this.setState({attachments:[...this.state.attachments,{id:r,name:e.name||"picture",status:"reading",...s?{previewUrl:s}:{}}],lastError:null});let a;Promise.race([Promise.resolve().then(()=>t(e)),new Promise((l,d)=>{a=setTimeout(()=>d(new Error("It took too long to read.")),ke)})]).then(l=>{let d=typeof l=="string"?l.trim():"";i(r,d?{status:"ready",text:d}:{status:"failed",error:"Nothing could be read from it."}),d&&this.onCall()&&!this.state.attachments.some(h=>h.status==="reading")&&this.send("")}).catch(l=>i(r,{status:"failed",error:l instanceof Error&&l.message?l.message:"It couldn't be read."})).finally(()=>clearTimeout(a))});o(this,"removeAttachment",e=>{let t=this.state.attachments.find(i=>i.id===e);t&&(t.previewUrl&&URL.revokeObjectURL(t.previewUrl),this.setState({attachments:this.state.attachments.filter(i=>i.id!==e)}))});o(this,"respondToProposal",(e,t)=>{this.client?.confirmAction(e,t),t||this.setState({proposals:this.state.proposals.filter(i=>i.proposalId!==e)})});o(this,"open",()=>{this.state.isOpen||this.setState({isOpen:!0})});o(this,"close",()=>{this.state.isOpen&&this.setState({isOpen:!1})});o(this,"toggle",()=>{this.setState({isOpen:!this.state.isOpen})});o(this,"handleEvent",e=>{switch(e.type){case"state":this.setState({connection:e.state}),this.publishTimer!==null&&clearTimeout(this.publishTimer),this.publishTimer=null,this.publish();break;case"turn_start":this.setState({busy:!0,messages:[...this.state.messages,{id:e.turnId,role:"assistant",text:"",streaming:!0}]});break;case"delta":this.setMessages(t=>t.map(i=>i.id===e.turnId?{...i,text:i.text+e.text}:i));break;case"complete":this.setState({busy:!1,messages:this.state.messages.map(t=>t.id===e.turnId?{...t,text:e.message,streaming:!1,sources:e.sources.length?e.sources:void 0}:t)});break;case"command":{let t={store:this.store,highlighter:this.highlighter,navigate:this.options.navigate??(r=>{window.location.assign(r)}),screenPublished:this.awaitScreenPublished,viewPublished:this.awaitViewPublished,openModal:this.options.openModal},i=this.client;Q(e.command,t).then(r=>i?.ackCommand(e.commandId,r.ok,r.result,r.error)).catch(r=>i?.ackCommand(e.commandId,!1,void 0,r instanceof Error?r.message:"The command failed."));break}case"proposal":this.setState({proposals:[...this.state.proposals,e.proposal]}),this.describe(e.proposal);break;case"action_status":{if(e.status==="executing")break;let t=this.state.proposals.find(i=>i.proposalId===e.proposalId);if(t){let i=`status_${e.proposalId}`;if(e.status!=="rejected"&&!this.state.messages.some(r=>r.id===i)){let r=e.status==="executed"?`${t.label} \u2014 done.`:`${t.label} \u2014 ${e.error??"that did not work."}`;this.setMessages(s=>[...s,{id:i,role:"assistant",text:r}])}this.options.onActionComplete?.({actionName:t.actionName,status:e.status,result:e.result})}this.setState({proposals:this.state.proposals.filter(i=>i.proposalId!==e.proposalId),...e.error?{lastError:e.error}:{}});break}case"voice_available":this.setVoice({available:e.available});break;case"assistant_name":this.setState({assistantName:e.name});break;case"launcher_icon":this.setState({launcherIconUrl:e.url});break;case"widget_settings":this.setState({widgetSettings:e.settings});break;case"context_report":console.info(G(e.report));break;case"voice_token":if(!this.voiceRequested)break;this.voiceRequested=!1,this.startVoice(e.token);break;case"error":if(e.code.startsWith("voice_")){this.voiceRequested=!1,this.setState({busy:!1,voice:{...this.state.voice,available:!1}});break}this.setState({busy:!1,lastError:e.message});break}});o(this,"publish",()=>{this.publishTimer=null;let e=this.store.getScreenContext();if(!(!e&&this.publishedRoute===null)&&(this.client?.updateScreen(e),this.publishedRoute=e?.route??null,this.publishedScreen=e,this.publishedSettled=!this.store.isScreenLoading(),!(!e||!this.publishedSettled)))for(let t of[...this.screenWaiters])t(e)});o(this,"awaitScreenPublished",(e,t)=>new Promise(i=>{let r=e.split("?")[0];if(!t?.fresh&&this.publishedRoute===r&&this.publishedSettled)return i(!0);let s=d=>{this.screenWaiters.delete(a),clearTimeout(l),i(d)},a=d=>{d.route===r&&s(!0)},l=setTimeout(()=>s(!1),$e);this.screenWaiters.add(a)}));o(this,"awaitViewPublished",(e,t)=>new Promise(i=>{let r=d=>d?.controls.some(h=>h.controlKey===e&&h.value===t)??!1;if(this.publishedSettled&&r(this.publishedScreen))return i(!0);let s=d=>{this.screenWaiters.delete(a),clearTimeout(l),i(d)},a=d=>{r(d)&&s(!0)},l=setTimeout(()=>s(!1),$e);this.screenWaiters.add(a)}));o(this,"startVoiceRequest",e=>{this.setVoice({notice:null}),this.requestedHandsFree=!!e?.handsFree,this.requestedOpenPanel=e?.openPanel??!0,this.voiceRequested=!0,this.client?.requestVoiceToken()});o(this,"stopVoice",()=>{this.voiceRequested=!1,this.voiceSession?.stop(),this.voiceSession=null,this.setVoice({handsFree:!1,notice:null})});o(this,"handleVoiceEvent",e=>{switch(e.type){case"state":this.setVoice({state:e.state,...e.state==="idle"||e.state==="error"?{caption:""}:{}});break;case"transcript":e.final?this.setState({voice:{...this.state.voice,caption:""},messages:[...this.state.messages,{id:xe("voice"),role:e.role,text:e.text}]}):this.setVoice({caption:e.text});break;case"ending_soon":this.setVoice({notice:St(e.secondsRemaining)});break;case"ended":this.setVoice({caption:"",notice:e.message,handsFree:!1});break;case"error":this.setState({lastError:e.message});break}});this.options={...e},this.state={connection:"idle",messages:[],proposals:[],cardViews:{},busy:!1,lastError:null,isOpen:!1,assistantName:null,launcherIconUrl:null,widgetSettings:null,attachAccept:e.describeAttachment?e.attachmentAccept??"image/*":null,attachments:[],voice:{available:!1,state:"idle",handsFree:!1,caption:"",notice:null,start:this.startVoiceRequest,stop:this.stopVoice,press:t=>this.voiceSession?.beginUtterance(t),release:()=>this.voiceSession?.endUtterance(),confirm:()=>this.voiceSession?.confirmUtterance(),discard:()=>this.voiceSession?.discardUtterance(),onLevel:t=>(this.levelListeners.add(t),()=>{this.levelListeners.delete(t)})}}}get voice(){return this.state.voice}setState(e){this.state={...this.state,...e};for(let t of[...this.listeners])t()}setVoice(e){this.setState({voice:{...this.state.voice,...e}})}setMessages(e){this.setState({messages:e(this.state.messages)})}update(e){let t=this.options;this.options={...t,...e};let i=this.options.describeAttachment?this.options.attachmentAccept??"image/*":null;i!==this.state.attachAccept&&this.setState({attachAccept:i}),(this.options.url!==t.url||this.options.publicKey!==t.publicKey||!!this.options.debug!=!!t.debug)&&this.client&&(this.disconnect(),this.connect())}connect(){if(this.client)return;let e=new E({url:this.options.url,publicKey:this.options.publicKey,getUserToken:()=>this.options.getUserToken(),sdkVersion:we,onEvent:this.handleEvent,debug:this.options.debug??!1});this.client=e,this.unsubscribeStore=this.store.subscribe(()=>{this.publishTimer!==null&&clearTimeout(this.publishTimer),this.publishTimer=setTimeout(this.publish,kt)}),this.publish(),e.connect()}disconnect(){this.publishTimer!==null&&clearTimeout(this.publishTimer),this.publishTimer=null,this.unsubscribeStore?.(),this.unsubscribeStore=null,this.client?.close(),this.client=null,this.voiceSession?.stop(),this.voiceSession=null,this.highlighter.clear()}destroy(){this.disconnect(),this.listeners.clear(),this.levelListeners.clear()}onCall(){return!["idle","connecting","error"].includes(this.state.voice.state)}describe(e){let t=l=>{l!=="pending"&&!this.state.proposals.some(d=>d.proposalId===e.proposalId)||this.setState({cardViews:{...this.state.cardViews,[e.proposalId]:l}})},i=this.options.describeProposal;if(!i){t(C(e));return}t("pending");let r=!1,s=l=>{r||(r=!0,t(l&&Array.isArray(l.lines)?j(l):C(e)))},a=setTimeout(()=>s(null),z);Promise.resolve().then(()=>i(e)).then(l=>{clearTimeout(a),s(l)}).catch(l=>{clearTimeout(a),console.warn("[mihe] describeProposal failed; the card uses the registry's hints.",l),s(null)})}prompt(e){return()=>this.send(e)}setScreen(e){let t=JSON.stringify(e);return(t!==this.lastScreen||this.store.getScreenContext()?.screenId!==e.screenId)&&(this.lastScreen=t,this.store.setScreen(JSON.parse(t))),()=>{this.store.clearScreen(e.screenId),this.store.getScreenContext()===null&&(this.lastScreen=null)}}registerComponent(e,t,i){return e?.setAttribute(M,t),this.store.registerComponent(t,{...i}),()=>{this.store.unregisterComponent(t),e?.getAttribute(M)===t&&e.removeAttribute(M)}}registerAction(e,t){let i=this.actions.get(e);if(i&&this.store.getAction(e)===i.declaration)return i.latest=t,()=>this.undoAction(e,i);let r={latest:t,signature:e,declaration:{name:e,handler:s=>r.latest(s)}};return this.actions.set(e,r),this.store.registerAction(r.declaration),()=>this.undoAction(e,r)}undoAction(e,t){this.actions.get(e)===t&&(this.actions.delete(e),this.store.getAction(e)===t.declaration&&this.store.unregisterAction(e))}registerTabs(e){return this.declare(this.tabs,e.id,e,J(e),t=>Y(t),t=>this.store.getControl(t),(t,i)=>this.store.registerControl(t,i),t=>this.store.unregisterControl(t))}registerTable(e){return this.declare(this.tables,e.id,e,X(e),t=>Z(t),t=>this.store.getTable(t),(t,i)=>this.store.registerTable(t,i),t=>this.store.unregisterTable(t))}registerChart(e){return this.declare(this.charts,e.id,e,ee(e),t=>$(t),t=>this.store.getChart(t),(t,i)=>this.store.registerChart(t,i),t=>this.store.unregisterChart(t))}setValues(e,t){return this.store.setValues(e,JSON.parse(JSON.stringify(t))),()=>this.store.clearValues(e)}declare(e,t,i,r,s,a,l,d){let h=e.get(t);if(h&&a(t)===h.declaration){if(h.latest=i,h.signature!==r){let u=h;h.signature=r,h.declaration=s(()=>u.latest),l(t,h.declaration)}}else{let u={latest:i,signature:r};u.declaration=s(()=>u.latest),e.set(t,u),l(t,u.declaration),h=u}let p=h;return()=>{e.get(t)===p&&(e.delete(t),a(t)===p.declaration&&d(t))}}bindTrigger(e){let t=e instanceof HTMLButtonElement,i=["aria-expanded","aria-controls","aria-haspopup"];t||(e.setAttribute("role","button"),i.push("role"),e.hasAttribute("tabindex")||(e.setAttribute("tabindex","0"),i.push("tabindex"))),e.setAttribute("aria-controls",U),e.setAttribute("aria-haspopup","dialog");let r=()=>e.setAttribute("aria-expanded",String(this.state.isOpen)),s=()=>this.toggle(),a=d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),this.toggle())};r();let l=this.subscribe(r);return e.addEventListener("click",s),t||e.addEventListener("keydown",a),()=>{l(),e.removeEventListener("click",s),e.removeEventListener("keydown",a);for(let d of i)e.removeAttribute(d)}}async startVoice(e){let t=this.requestedHandsFree;this.setVoice({handsFree:t});let i=new O({url:ne(this.options.url,e,t),handsFree:t,onEvent:this.handleVoiceEvent,onLevel:(r,s)=>{for(let a of this.levelListeners)a(r,s)}});this.voiceSession=i,this.requestedOpenPanel&&this.open(),await i.start()}};function Se(n,e){let t=e.name.toLowerCase();return n.split(",").map(i=>i.trim().toLowerCase()).filter(Boolean).some(i=>i.startsWith(".")?t.endsWith(i):i.endsWith("/*")?e.type.toLowerCase().startsWith(i.slice(0,-1)):e.type.toLowerCase()===i)}function c(n,e={},...t){let i=document.createElement(n);e.class&&(i.className=e.class),F(i,e.attrs??{});for(let[r,s]of Object.entries(e.on??{}))i.addEventListener(r,s);return Ue(i,t),i}var Tt="http://www.w3.org/2000/svg";function g(n,e,...t){let i=document.createElementNS(Tt,n);for(let[r,s]of Object.entries(e))i.setAttribute(r,String(s));for(let r of t)i.appendChild(r);return i}function F(n,e){for(let[t,i]of Object.entries(e))i===void 0||i===!1?n.removeAttribute(t):n.setAttribute(t,i===!0?"":String(i))}function Ue(n,e){for(let t of e)t==null||t===!1||n.appendChild(typeof t=="string"?document.createTextNode(t):t)}function b(n,...e){for(;n.firstChild;)n.removeChild(n.firstChild);Ue(n,e)}var Fe="translate(0.000000,1760.000000) scale(0.100000,-0.100000)",Ct="M8165 16868 c-450 -31 -1057 -131 -1495 -248 -76 -20 -156 -42 -180 -50 -14 -5 -50 -15 -80 -24 -146 -41 -273 -82 -360 -117 -25 -9 -74 -27 -110 -39 -36 -12 -74 -25 -85 -30 -11 -4 -40 -15 -65 -25 -25 -10 -54 -21 -65 -26 -11 -4 -85 -35 -165 -67 -218 -90 -530 -238 -715 -340 -38 -21 -106 -58 -150 -82 -44 -24 -108 -61 -143 -82 -34 -21 -65 -38 -68 -38 -2 0 -17 -8 -32 -19 -15 -10 -52 -34 -82 -53 -1161 -733 -2106 -1735 -2771 -2935 -74 -134 -219 -425 -219 -440 0 -4 -10 -24 -23 -43 -13 -19 -34 -60 -46 -90 -13 -30 -35 -80 -48 -110 -49 -112 -56 -127 -91 -220 -16 -41 -32 -84 -37 -95 -45 -114 -195 -563 -238 -715 -26 -88 -58 -212 -67 -255 -5 -22 -16 -69 -25 -105 -19 -78 -66 -317 -89 -455 -140 -836 -144 -1701 -11 -2525 9 -52 20 -122 25 -155 9 -53 17 -97 51 -262 16 -78 80 -337 105 -423 74 -256 219 -700 264 -810 26 -63 55 -135 79 -192 6 -13 24 -54 40 -91 17 -38 31 -70 31 -72 0 -3 105 -221 203 -425 39 -79 80 -154 128 -233 16 -26 29 -50 29 -52 0 -3 37 -65 82 -138 45 -72 88 -143 95 -157 64 -113 285 -440 339 -500 12 -14 43 -56 70 -95 42 -63 164 -220 221 -285 12 -14 36 -43 55 -66 250 -310 644 -706 1038 -1045 68 -59 396 -310 514 -395 88 -63 522 -341 596 -382 19 -10 80 -45 135 -77 120 -69 571 -298 670 -339 39 -16 107 -47 153 -68 46 -21 87 -38 93 -38 5 0 17 -4 27 -10 25 -13 78 -35 157 -63 39 -14 120 -43 180 -65 222 -82 417 -145 565 -183 41 -10 91 -23 110 -29 134 -37 514 -119 645 -139 836 -130 1685 -150 2385 -57 63 8 151 20 195 26 44 6 100 15 125 20 25 5 88 17 140 25 286 49 729 160 1015 256 198 67 349 119 370 129 11 6 72 30 135 54 63 24 142 56 175 71 103 46 118 52 183 79 53 22 224 108 572 287 750 385 1586 1059 2290 1844 219 244 499 612 666 873 32 52 91 144 131 205 91 141 268 456 366 652 87 172 167 341 167 350 0 4 6 21 14 38 56 124 212 529 241 627 9 30 21 64 26 75 4 11 16 45 25 75 9 30 25 82 36 115 54 166 146 535 178 710 82 461 106 640 137 1030 20 252 23 814 5 1015 -6 74 -17 191 -23 260 -12 141 -34 328 -49 410 -5 30 -16 100 -25 155 -9 55 -26 145 -37 200 -11 55 -24 118 -28 140 -4 22 -16 72 -25 110 -9 39 -20 86 -24 105 -203 889 -617 1816 -1181 2640 -141 205 -236 333 -350 470 -52 63 -113 138 -135 165 -203 255 -745 786 -1035 1016 -58 45 -138 109 -179 142 -228 181 -749 524 -1006 662 -49 26 -115 62 -145 78 -71 38 -346 176 -430 215 -138 64 -201 92 -206 92 -3 0 -35 14 -71 30 -35 17 -70 30 -77 30 -6 0 -16 4 -21 8 -9 8 -216 87 -387 148 -38 13 -98 35 -135 49 -38 13 -102 34 -143 45 -41 12 -97 28 -125 36 -180 53 -464 125 -610 154 -165 33 -214 43 -240 47 -16 2 -66 10 -110 18 -328 56 -573 84 -755 88 l-125 2 0 -515 0 -515 190 -21 c105 -12 242 -29 305 -39 63 -10 138 -21 165 -26 123 -18 192 -30 225 -39 19 -5 62 -14 95 -20 233 -44 615 -154 905 -260 47 -17 105 -38 130 -47 25 -8 59 -21 75 -28 17 -7 93 -39 170 -71 418 -173 867 -425 1345 -757 747 -518 1525 -1379 1970 -2182 18 -33 41 -73 50 -90 64 -116 84 -152 123 -231 25 -49 57 -118 72 -154 15 -36 36 -85 47 -110 42 -93 56 -127 78 -180 12 -30 26 -64 31 -75 61 -146 144 -376 194 -540 15 -49 31 -101 36 -115 9 -26 46 -175 74 -295 8 -38 20 -86 25 -105 15 -58 45 -214 80 -425 24 -141 62 -499 79 -745 34 -482 -17 -1111 -134 -1655 -14 -66 -30 -140 -35 -165 -8 -38 -22 -93 -65 -260 -28 -107 -86 -292 -127 -405 -59 -164 -118 -318 -128 -337 -6 -10 -10 -22 -10 -27 0 -6 -18 -49 -40 -96 -22 -47 -40 -88 -40 -90 0 -27 -247 -518 -314 -624 -14 -22 -26 -43 -26 -45 0 -37 -381 -596 -565 -829 -225 -283 -622 -706 -875 -929 -155 -137 -228 -198 -237 -198 -9 0 -127 185 -183 285 -12 22 -28 47 -35 55 -7 8 -32 49 -55 90 -24 41 -76 125 -115 185 -40 61 -123 195 -186 298 -63 103 -126 207 -141 230 -15 23 -31 49 -35 57 -3 8 -16 29 -27 45 -12 17 -26 39 -33 50 -7 11 -33 54 -59 95 -67 106 -620 996 -1072 1725 -58 94 -129 206 -158 251 -29 45 -65 103 -80 130 -15 27 -55 92 -89 144 -88 134 -280 445 -400 645 -56 94 -163 269 -239 389 -75 121 -135 224 -134 228 2 5 35 54 73 109 403 577 447 641 713 1032 134 197 262 399 262 413 0 8 -36 85 -79 172 -44 86 -142 285 -219 442 -77 157 -244 497 -372 755 -128 259 -297 601 -375 760 -78 160 -220 448 -315 640 -95 193 -264 535 -376 760 -400 810 -543 1101 -566 1155 -14 30 -33 74 -43 98 -17 39 -55 61 -55 31 0 -6 -35 -83 -79 -172 -43 -89 -106 -218 -139 -287 -68 -142 -323 -661 -607 -1235 -106 -214 -271 -550 -368 -745 -225 -457 -457 -927 -747 -1515 -363 -735 -420 -852 -420 -862 0 -10 166 -267 241 -373 21 -30 95 -138 164 -240 68 -102 160 -237 204 -300 80 -115 147 -212 296 -430 43 -63 93 -135 112 -159 42 -56 42 -57 -11 -134 -24 -35 -58 -90 -76 -122 -29 -52 -66 -114 -107 -180 -7 -11 -20 -33 -29 -50 -9 -16 -45 -73 -79 -125 -34 -52 -74 -117 -89 -145 -16 -27 -34 -57 -42 -66 -8 -8 -14 -19 -14 -23 0 -4 -10 -22 -23 -39 -12 -18 -28 -41 -34 -52 -7 -11 -33 -54 -59 -95 -26 -41 -58 -95 -72 -120 -13 -25 -35 -58 -47 -75 -21 -29 -238 -378 -619 -995 -96 -157 -210 -339 -252 -405 -104 -164 -269 -429 -343 -550 -33 -55 -92 -149 -131 -210 -38 -60 -78 -126 -90 -145 -11 -19 -25 -42 -30 -50 -5 -8 -44 -71 -86 -140 -42 -69 -104 -168 -138 -220 -34 -53 -66 -104 -73 -115 -6 -11 -76 -123 -155 -249 -79 -126 -145 -234 -147 -240 -2 -6 -21 -36 -41 -66 -76 -112 -170 -260 -170 -267 0 -5 -14 -24 -30 -43 -29 -35 -29 -35 -82 16 -29 28 -91 84 -138 124 -567 490 -1171 1224 -1508 1832 -47 85 -232 451 -274 543 -20 44 -53 115 -72 158 -20 42 -36 80 -36 83 0 3 -6 20 -14 37 -20 47 -40 99 -85 222 -79 217 -90 252 -140 420 -49 167 -85 311 -141 558 -120 534 -163 1390 -99 1962 41 369 37 343 84 595 48 260 75 373 159 683 39 143 224 654 286 792 110 242 174 371 314 630 563 1039 1532 2008 2644 2642 68 38 455 233 532 267 131 58 397 168 465 192 108 39 384 130 445 148 30 8 87 25 125 36 316 96 789 185 1190 225 94 9 176 20 183 24 12 5 16 287 12 1022 0 13 -27 15 -135 7z m660 -4508 c4 -16 11 -32 16 -35 5 -4 9 -12 9 -20 0 -8 19 -53 41 -102 71 -151 106 -226 129 -278 12 -27 39 -86 60 -130 21 -44 52 -111 70 -150 17 -38 44 -97 60 -130 15 -33 35 -76 43 -95 8 -19 31 -69 50 -110 62 -134 89 -194 107 -240 10 -25 46 -103 80 -175 90 -190 106 -224 133 -285 49 -108 70 -156 97 -215 15 -33 37 -82 50 -110 12 -27 40 -87 61 -133 40 -83 40 -83 6 -140 -19 -31 -50 -86 -69 -122 -65 -120 -91 -165 -140 -242 -26 -43 -48 -80 -48 -83 0 -2 -17 -33 -38 -67 -21 -35 -41 -70 -45 -78 -4 -8 -11 -22 -17 -30 -34 -54 -110 -181 -110 -185 0 -3 -11 -23 -25 -45 -14 -22 -46 -80 -72 -128 -25 -48 -54 -98 -63 -112 -41 -58 -150 -263 -150 -280 0 -10 15 -47 33 -82 62 -117 120 -223 128 -234 5 -6 48 -87 95 -180 47 -93 90 -173 94 -179 4 -5 27 -46 50 -90 23 -44 67 -127 98 -185 30 -58 59 -110 63 -116 11 -14 72 -130 111 -209 37 -77 56 -114 103 -200 142 -264 186 -348 323 -615 63 -124 128 -250 145 -280 33 -59 82 -154 250 -480 58 -113 129 -250 157 -305 96 -182 151 -288 268 -515 63 -124 135 -263 160 -310 24 -47 118 -229 207 -405 170 -333 225 -440 277 -534 17 -31 112 -216 211 -411 99 -195 188 -372 199 -393 11 -22 18 -40 16 -42 -10 -11 -431 -215 -443 -215 -2 0 -36 -15 -77 -34 -40 -18 -109 -48 -153 -66 -44 -18 -93 -38 -110 -45 -16 -7 -75 -29 -130 -50 -55 -20 -116 -43 -135 -50 -39 -14 -282 -90 -345 -107 -22 -6 -60 -16 -85 -24 -61 -17 -216 -55 -265 -64 -22 -4 -85 -17 -140 -28 -165 -33 -277 -52 -513 -87 -183 -27 -182 -27 -182 78 0 34 -4 98 -10 142 -5 44 -14 141 -20 215 -24 285 -30 360 -45 530 -9 96 -20 229 -25 295 -5 66 -17 206 -25 310 -9 105 -20 249 -25 320 -5 72 -12 148 -15 170 -3 22 -10 105 -15 185 -5 80 -17 228 -25 330 -9 102 -20 237 -24 300 -5 63 -19 225 -30 360 -11 135 -27 335 -36 445 -30 392 -37 461 -50 510 -8 28 -26 97 -41 155 -14 58 -37 146 -50 195 -41 154 -55 209 -64 245 -9 33 -23 89 -55 205 -7 28 -25 100 -40 160 -24 98 -49 196 -61 233 -8 27 -28 5 -40 -44 -6 -27 -24 -94 -38 -149 -15 -55 -43 -161 -62 -235 -20 -74 -49 -187 -65 -250 -17 -63 -39 -151 -50 -195 -23 -92 -39 -157 -69 -270 -30 -113 -36 -170 -75 -720 -8 -110 -21 -276 -30 -370 -8 -93 -19 -226 -25 -295 -5 -69 -12 -143 -15 -165 -3 -22 -10 -105 -16 -185 -24 -330 -41 -552 -59 -745 -22 -237 -31 -345 -40 -460 -5 -66 -16 -201 -25 -300 -8 -99 -19 -234 -25 -300 -15 -193 -40 -482 -50 -590 -5 -55 -9 -106 -10 -112 0 -18 -71 -17 -184 2 -50 9 -122 20 -161 26 -108 16 -241 39 -345 61 -52 11 -113 24 -135 28 -52 11 -235 56 -300 75 -27 7 -75 20 -106 29 -62 17 -397 127 -444 146 -16 7 -39 16 -50 21 -11 5 -56 22 -100 39 -214 82 -663 292 -724 339 -23 18 -23 18 62 182 46 90 130 252 185 359 55 107 121 236 147 285 26 50 100 194 165 320 64 127 146 286 182 355 36 69 100 193 143 275 43 83 106 204 140 270 34 66 109 210 165 320 108 211 202 391 280 540 26 50 70 133 97 185 28 52 112 217 188 365 76 149 141 275 145 280 4 6 54 100 110 210 57 110 123 238 148 285 25 47 63 119 85 160 22 41 71 133 110 205 39 71 107 202 152 290 45 88 91 177 103 197 12 21 37 66 55 100 19 35 51 95 72 133 238 435 243 447 218 497 -34 66 -100 186 -137 247 -19 31 -43 72 -53 91 -65 116 -87 155 -142 248 -34 57 -61 106 -61 108 0 2 -10 21 -23 42 -13 20 -44 75 -69 122 -25 47 -73 132 -107 188 -33 57 -61 106 -61 108 0 2 -29 52 -65 110 -68 111 -74 132 -51 180 26 52 103 218 126 269 13 28 41 88 62 135 22 47 54 114 70 150 48 104 78 169 124 267 24 51 44 98 44 103 0 6 4 18 10 28 13 22 90 192 90 198 0 2 23 52 51 112 54 112 81 171 205 440 19 41 34 76 34 78 0 3 15 37 34 77 18 40 43 95 56 122 12 28 43 93 67 145 25 52 49 105 54 117 12 32 36 28 44 -7z",Mt="M4399 12732 c-37 -42 -101 -117 -143 -166 -123 -145 -496 -679 -496 -712 0 -2 -18 -34 -41 -71 -100 -164 -271 -530 -369 -793 -17 -47 -36 -96 -42 -110 -35 -86 -134 -426 -172 -595 -50 -218 -49 -218 -81 -445 -85 -598 -74 -1269 30 -1820 8 -47 20 -107 24 -135 11 -60 68 -292 87 -355 8 -25 21 -67 29 -95 23 -79 72 -227 85 -260 7 -16 16 -39 20 -50 34 -90 73 -186 108 -265 11 -25 30 -70 43 -100 45 -106 197 -400 256 -493 14 -22 36 -60 50 -85 97 -175 409 -612 437 -612 6 0 85 66 176 147 91 80 199 176 240 212 41 36 100 89 130 117 30 29 73 67 95 86 123 107 120 82 23 209 -209 275 -459 726 -589 1064 -112 292 -165 474 -219 750 -19 96 -26 136 -50 287 -70 444 -45 1047 65 1543 9 39 20 88 24 110 149 680 553 1448 1043 1980 15 17 28 33 28 36 0 11 -703 699 -714 699 -6 0 -41 -35 -77 -78z M12835 12532 c-154 -152 -313 -307 -354 -344 -84 -76 -85 -63 16 -174 227 -250 460 -601 637 -959 70 -144 93 -192 130 -280 10 -22 21 -49 26 -60 5 -11 16 -42 25 -70 10 -27 21 -59 26 -70 23 -55 77 -234 112 -370 45 -175 56 -227 78 -345 24 -127 27 -151 58 -425 26 -231 28 -544 6 -780 -17 -180 -30 -267 -85 -570 -9 -47 -39 -165 -89 -350 -23 -83 -54 -178 -76 -230 -7 -16 -19 -48 -28 -70 -144 -374 -335 -726 -576 -1060 -56 -77 -100 -145 -99 -151 2 -5 68 -68 148 -140 80 -71 172 -154 205 -185 138 -128 375 -329 388 -329 23 0 437 582 437 614 0 3 16 30 35 60 62 98 305 576 305 601 0 3 14 35 31 72 54 117 135 338 174 478 124 434 155 590 214 1065 67 536 5 1382 -141 1930 -11 41 -24 89 -28 105 -24 91 -128 414 -175 543 -34 95 -127 306 -196 447 -145 295 -273 511 -475 795 -154 217 -416 530 -443 530 -3 0 -132 -125 -286 -278z";function se(n,e,t){let i=g("svg",{viewBox:"0 0 1760 1760",width:n,height:n,"aria-hidden":"true",focusable:"false"},g("path",{fill:e,"fill-rule":"evenodd",transform:Fe,d:Ct}),g("path",{fill:t,"fill-rule":"evenodd",transform:Fe,d:Mt}));return i.style.display="block",i}var Te="#221f1b",oe="#eae7e4",ae="#5ac8cd",Ke=`
|
|
49
49
|
:host {
|
|
@@ -106,6 +106,8 @@ button { font: inherit; color: inherit; margin: 0; }
|
|
|
106
106
|
.talk { margin-left: auto; margin-right: 4px; min-height: 32px; padding: 0 14px; border-radius: 999px; border: 1px solid #cbd5e1; background: #fff; cursor: pointer; font: 600 13px system-ui, sans-serif; }
|
|
107
107
|
.call { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 8px; padding: 12px; border-top: 1px solid #e2e8f0; }
|
|
108
108
|
.call-cards { display: flex; flex-direction: column; gap: 8px; }
|
|
109
|
+
.call-failed { margin: 0; padding: 8px 12px; border-radius: 10px; background: #fef2f2; color: #991b1b; border: 1px solid #fecaca; font-size: 13px; }
|
|
110
|
+
.call-failed[hidden] { display: none; }
|
|
109
111
|
.call-bar { display: flex; align-items: center; gap: 12px; padding: 8px 8px 8px 12px; border-radius: 999px; background: #fff; border: 1px solid rgba(15,23,42,0.1); box-shadow: 0 6px 18px rgba(15,23,42,0.16); min-width: 0; }
|
|
110
112
|
.call-mark { position: relative; display: grid; place-items: center; width: 36px; height: 36px; flex: none; }
|
|
111
113
|
.call-ring { position: absolute; inset: 0; border-radius: 50%; background: rgba(0,114,119,0.14); transition: transform 60ms linear; }
|
|
@@ -258,5 +260,5 @@ button { font: inherit; color: inherit; margin: 0; }
|
|
|
258
260
|
}
|
|
259
261
|
`;function le(n,e,t,i){return n?n.cloneNode(!0):e&&e!==t?c("img",{class:"launcher-image",attrs:{src:e,alt:"",draggable:"false"},on:{error:()=>i(e)}}):se(34,oe,ae)}function K(n,e,t=C(n)){let i=n.risk==="high",r=t==="pending",s=r?null:t,a=s&&s.source!=="plain"?c("details",{class:"card-more"},c("summary",{},"More about this"),c("p",{class:"card-description"},n.description)):c("p",{class:"card-description"},n.description);return c("div",{class:"card",attrs:{role:"group","aria-label":`Confirm: ${n.label}`,"aria-busy":r?"true":void 0}},c("div",{class:"card-header"},c("strong",{},n.label),c("span",{class:i?"risk risk-high":"risk"},i?"Needs care":"Confirm")),r&&c("p",{class:"card-description"},"Checking the details\u2026"),s?.summary&&c("p",{class:"card-summary"},s.summary),s&&s.source==="plain"&&a,s&&s.lines.length>0&&c("dl",{class:"card-input"},...s.lines.map(At)),s?.note&&c("p",{class:"card-note"},s.note),s&&s.source!=="plain"&&a,c("div",{class:"card-actions"},c("button",{class:"button-secondary",attrs:{type:"button"},on:{click:()=>e(n.proposalId,!1)}},"Cancel"),c("button",{class:i?"button-primary button-danger":"button-primary",attrs:{type:"button",disabled:r?"":void 0},on:{click:()=>{r||e(n.proposalId,!0)}}},s?.confirmLabel??"Confirm")))}function At(n){if(n.images?.length)return c("div",{class:"card-media-row"},c("span",{class:"card-images"},...n.images.map(t=>c("img",{attrs:{src:t.src,alt:t.alt??"",loading:"lazy",referrerpolicy:"no-referrer"}}))),c("span",{class:"card-media-text"},n.label&&c("dt",{class:"card-media-label"},n.label),c("dd",{class:n.label?"card-media-value":"card-media-value card-media-strong"},...Be(n))));let e=c("dd",{class:n.label?"card-value":"card-value card-value-wide"},...Be(n));return c("div",{class:"card-row"},n.label&&c("dt",{class:"card-key"},n.label),e)}function Be(n){return[n.before!==void 0&&c("s",{class:"card-before"},n.before),n.before!==void 0&&c("span",{class:"card-arrow",attrs:{"aria-label":"becomes"}}," \u2192 "),n.text!==void 0&&c("span",{class:"input-text"},n.text),!!n.items?.length&&c("ol",{class:"input-list"},...n.items.map(e=>c("li",{},c("span",{class:"input-text"},e))))]}function ce(...n){return g("svg",{viewBox:"0 0 20 20",width:18,height:18,fill:"none",stroke:"currentColor","stroke-width":1.7,"stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true"},...n)}var We=()=>ce(g("path",{d:"M4 4.5h12a1.5 1.5 0 0 1 1.5 1.5v7a1.5 1.5 0 0 1-1.5 1.5H9l-4 3v-3H4A1.5 1.5 0 0 1 2.5 13V6A1.5 1.5 0 0 1 4 4.5Z"})),qe=()=>ce(g("rect",{x:7,y:2.5,width:6,height:10,rx:3}),g("path",{d:"M4.5 9.5a5.5 5.5 0 0 0 11 0M10 15v2.5"})),je=()=>ce(g("path",{d:"M3 10v0M6.5 7v6M10 4v12M13.5 7v6M17 10v0"})),ze=()=>ce(g("path",{d:"M15.5 9.5l-5.6 5.6a3.5 3.5 0 0 1-5-5L10.6 4.4a2.3 2.3 0 0 1 3.3 3.3L8.3 13.3a1.1 1.1 0 0 1-1.6-1.6L11.8 6.6"}));var v=56,Qe=20,Et=8,Lt=150,Ge="mihe:orb-position",Ye="mihe:hold-hint-done";function It(){try{let n=window.localStorage.getItem(Ge);if(!n)return null;let e=JSON.parse(n);if((e.side==="left"||e.side==="right")&&typeof e.y=="number")return e}catch{}return null}function Rt(n){try{window.localStorage.setItem(Ge,JSON.stringify(n))}catch{}}function Dt(){try{return window.localStorage.getItem(Ye)==="1"}catch{return!1}}function Pt(){try{window.localStorage.setItem(Ye,"1")}catch{}}var de=class{constructor(e){o(this,"mihe",e);o(this,"root");o(this,"button");o(this,"ring");o(this,"face");o(this,"stop");o(this,"menu");o(this,"cards");o(this,"bubble");o(this,"options");o(this,"state");o(this,"menuOpen",!1);o(this,"rest",null);o(this,"drag",null);o(this,"showHint",!Dt());o(this,"press",null);o(this,"previousVoiceState","idle");o(this,"faceKey");o(this,"drawnProposals");o(this,"drawnViews");o(this,"failedIcon",null);o(this,"ringFrame",0);o(this,"stopLevel",null);o(this,"reducedMotion",typeof window<"u"&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches===!0);o(this,"cleanups",[]);this.ring=c("span",{class:"ring idle",attrs:{"aria-hidden":"true"}}),this.face=c("span",{class:"face"}),this.button=c("button",{class:"orb",attrs:{type:"button"},on:{pointerdown:r=>this.onPointerDown(r),pointermove:r=>this.onPointerMove(r),pointerup:()=>this.finish(!1),pointercancel:()=>this.finish(!0),keydown:r=>this.onKeyDown(r),keyup:r=>this.onKeyUp(r),contextmenu:r=>r.preventDefault()}},this.ring,this.face),this.stop=c("button",{class:"stop",attrs:{type:"button","aria-label":"End voice"},on:{click:()=>this.mihe.voice.stop()}},c("span",{class:"stop-square",attrs:{"aria-hidden":"true"}})),this.menu=c("div",{class:"popover",attrs:{role:"menu"},on:{keydown:r=>this.onMenuKeyDown(r)}}),this.cards=c("div",{class:"popover cards"}),this.bubble=c("div",{class:"popover orb-bubble",attrs:{role:"status","aria-live":"polite"}}),this.root=c("div",{},this.menu,this.cards,this.bubble,this.button,this.stop);let t=()=>this.render();window.addEventListener("resize",t),this.cleanups.push(()=>window.removeEventListener("resize",t));let i=r=>{if(!this.menuOpen)return;let s=r.composedPath();!s.includes(this.menu)&&!s.includes(this.button)&&this.setMenu(!1)};document.addEventListener("pointerdown",i),this.cleanups.push(()=>document.removeEventListener("pointerdown",i))}update(e,t){this.options?.draggable!==t.draggable&&(this.rest=t.draggable?It():null),this.previousVoiceState==="recording"&&e.voice.state==="thinking"&&(Pt(),this.showHint=!1),this.previousVoiceState=e.voice.state,this.state=e,this.options=t,this.render()}destroy(){this.stopRing(),this.press?.timer&&clearTimeout(this.press.timer);for(let e of this.cleanups)e()}get voiceLive(){let e=this.state.voice.state;return e!=="idle"&&e!=="error"}get handsFree(){return this.voiceLive&&this.state.voice.handsFree}get holdToTalk(){return this.voiceLive&&!this.state.voice.handsFree}menuItems(){let e=this.state.voice.available?this.options.voiceModes:[];return[{key:"chat",label:"Chat"},...e.includes("hands-free")?[{key:"hands-free",label:"Talk"}]:[],...e.includes("hold")?[{key:"hold",label:"Hold to talk"}]:[]]}viewport(){return{width:window.innerWidth,height:window.innerHeight}}clampTop(e){let{height:t}=this.viewport(),i=t-this.options.offset.bottom-v;return Math.min(Math.max(Qe,e),Math.max(Qe,i))}side(){let{width:e}=this.viewport();return this.drag?this.drag.left+v/2<e/2?"left":"right":this.rest?.side??(this.options?.corner==="bottom-left"?"left":"right")}position(){let{width:e,height:t}=this.viewport(),i=this.side(),r=this.options.offset.side,s=this.drag?this.drag.left:i==="left"?r:e-r-v,a=this.drag?this.drag.top:this.clampTop(this.rest?this.rest.y*t:t-this.options.offset.bottom-v);return{side:i,left:s,top:a,above:a+v/2>t/2}}render(){if(!this.state)return;let{voice:e,proposals:t,lastError:i,connection:r}=this.state,{heading:s}=this.options,{side:a,left:l,top:d,above:h}=this.position(),p=this.menuItems(),u=this.voiceLive,m=this.handsFree?`Stop talking to ${s}`:this.holdToTalk?e.state==="recording"?"Release to send":"Hold to talk":p.length===1?`Open ${s}`:`${s}: choose chat or voice`,V=p.length>1&&!u;F(this.button,{"aria-label":m,"aria-haspopup":V?"menu":void 0,"aria-expanded":V?String(this.menuOpen):void 0,"aria-pressed":this.holdToTalk?String(e.state==="recording"):void 0,"aria-busy":String(e.state==="connecting")}),this.button.disabled=r!=="open"&&!u,this.button.style.left=`${l}px`,this.button.style.top=`${d}px`,this.button.classList.toggle("dragging",this.drag!==null);let w=u?["connecting","thinking","recording","speaking"].find(f=>f===e.state)??"listening":"idle";this.ring.className=`ring ${w}`,this.syncRing();let Ee=[this.options.launcherIcon,this.state.launcherIconUrl,this.failedIcon];Ot(Ee,this.faceKey)||(this.faceKey=Ee,b(this.face,le(this.options.launcherIcon,this.state.launcherIconUrl,this.failedIcon,f=>{this.failedIcon=f,this.render()}))),this.stop.hidden=!u,this.stop.style.left=`${l+(a==="right"?-52:v+8)}px`,this.stop.style.top=`${d+(v-44)/2}px`;let{height:et}=this.viewport();for(let f of[this.menu,this.cards,this.bubble])f.style.left=a==="left"?`${this.options.offset.side}px`:"",f.style.right=a==="right"?`${this.options.offset.side}px`:"",f.style.bottom=h?`${et-d+12}px`:"",f.style.top=h?"":`${d+v+12}px`;this.menu.hidden=!this.menuOpen,this.menu.setAttribute("aria-label",s),this.menu.style.flexDirection=h?"column-reverse":"column",this.menu.style.alignItems=a==="right"?"flex-end":"flex-start",this.menuOpen&&this.menu.childElementCount!==p.length&&b(this.menu,...p.map(f=>c("button",{class:"menu-item",attrs:{type:"button",role:"menuitem"},on:{click:()=>this.choose(f.key)}},c("span",{class:"menu-icon",attrs:{"aria-hidden":"true"}},f.key==="chat"?We():f.key==="hold"?qe():je()),f.label))),this.cards.hidden=this.menuOpen||t.length===0,(t!==this.drawnProposals||this.state.cardViews!==this.drawnViews)&&(this.drawnProposals=t,this.drawnViews=this.state.cardViews,b(this.cards,...t.map(f=>K(f,this.mihe.respondToProposal,this.state.cardViews[f.proposalId]))));let W=e.state==="connecting"?{text:"Setting up the microphone\u2026",tone:"quiet"}:i&&(u||e.state==="error")?{text:i,tone:"error"}:e.notice?{text:e.notice,tone:"quiet"}:this.holdToTalk&&this.showHint&&e.state==="listening"?{text:"Hold to talk",tone:"quiet"}:null;this.bubble.hidden=this.menuOpen||t.length>0||W===null,this.bubble.classList.toggle("error",W?.tone==="error"),this.bubble.textContent!==(W?.text??"")&&(this.bubble.textContent=W?.text??"")}syncRing(){let e=this.voiceLive&&!this.reducedMotion;if(e===(this.stopLevel!==null))return;if(!e){this.stopRing();return}let t=0,i=0;this.stopLevel=this.mihe.voice.onLevel((s,a)=>{let l=this.mihe.getState().voice;s==="user"&&(l.state==="recording"||l.handsFree)&&(t=a),s==="assistant"&&(t=a)});let r=()=>{i+=(t-i)*(t>i?.45:.12),t*=.92,this.ring.style.transform=`scale(${1+i*.38})`,this.ringFrame=requestAnimationFrame(r)};this.ringFrame=requestAnimationFrame(r)}stopRing(){this.stopLevel?.(),this.stopLevel=null,cancelAnimationFrame(this.ringFrame),this.ring.style.transform="scale(1)"}setMenu(e){this.menuOpen=e,e||b(this.menu),this.render(),e&&this.menu.querySelector("button")?.focus()}choose(e){this.setMenu(!1),e==="chat"?this.mihe.open():this.mihe.voice.start({handsFree:e==="hands-free",openPanel:!1})}onMenuKeyDown(e){let t=Array.from(this.menu.querySelectorAll("button")),i=this.root.getRootNode().activeElement,r=t.indexOf(i);e.key==="Escape"?(e.preventDefault(),this.setMenu(!1),this.button.focus()):e.key==="ArrowDown"||e.key==="ArrowRight"?(e.preventDefault(),t[(r+1)%t.length]?.focus()):(e.key==="ArrowUp"||e.key==="ArrowLeft")&&(e.preventDefault(),t[(r-1+t.length)%t.length]?.focus())}tap(){if(this.menuOpen){this.setMenu(!1);return}if(this.handsFree){this.mihe.voice.stop();return}this.holdToTalk||(this.menuItems().length===1?this.mihe.open():this.setMenu(!0))}onPointerDown(e){if(e.button!==0)return;this.button.setPointerCapture?.(e.pointerId);let{left:t,top:i}=this.position(),r={x:e.clientX,y:e.clientY,offsetX:e.clientX-t,offsetY:e.clientY-i,dragging:!1,recording:null,timer:null};this.press=r;let s=this.mihe.getState().voice;this.holdToTalk&&(s.state==="listening"||s.state==="speaking")&&(this.options.draggable?(s.press({hold:!0}),r.recording="held",r.timer=setTimeout(()=>{this.press===r&&!r.dragging&&(this.mihe.voice.confirm(),r.recording="live")},Lt)):(s.press(),r.recording="live"))}onPointerMove(e){let t=this.press;if(!t||!this.options.draggable||this.menuOpen||t.recording==="live")return;let i=Math.hypot(e.clientX-t.x,e.clientY-t.y);if(!t.dragging&&i>Et&&(t.dragging=!0,t.recording==="held"&&(t.timer&&clearTimeout(t.timer),this.mihe.voice.discard(),t.recording=null)),t.dragging){let{width:r,height:s}=this.viewport();this.drag={left:Math.min(Math.max(0,e.clientX-t.offsetX),r-v),top:Math.min(Math.max(0,e.clientY-t.offsetY),s-v)},this.render()}}finish(e){let t=this.press;if(this.press=null,!!t){if(t.timer&&clearTimeout(t.timer),t.dragging&&this.drag){let{width:i,height:r}=this.viewport();this.rest={side:this.drag.left+v/2<i/2?"left":"right",y:this.clampTop(this.drag.top)/r},Rt(this.rest),this.drag=null,this.render();return}if(this.drag=null,t.recording){this.mihe.voice.release();return}e||this.tap()}}onKeyDown(e){if(e.repeat)return;let t=this.mihe.getState().voice;if(this.holdToTalk&&e.key===" "){e.preventDefault(),(t.state==="listening"||t.state==="speaking")&&t.press();return}(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this.tap()),e.key==="Escape"&&this.voiceLive&&(e.preventDefault(),t.stop())}onKeyUp(e){this.holdToTalk&&e.key===" "&&(e.preventDefault(),this.mihe.voice.release())}};function Ot(n,e){return Array.isArray(n)&&Array.isArray(e)&&n.length===e.length&&n.every((t,i)=>t===e[i])}var _t=/^\s*[-*•]\s+(.*)$/,Vt=/^\s*(\d{1,3})[.)]\s+(.*)$/,Nt=/^\s{0,3}#{1,6}\s+(.*?)\s*#*\s*$/;function he(n){let e=[],t=[],i=null,r=()=>{t.length&&e.push({kind:"paragraph",lines:t.map(_)}),i&&e.push({kind:"list",ordered:i.ordered,start:i.start,items:i.items.map(_)}),t=[],i=null};for(let s of n.replace(/\r\n?/g,`
|
|
260
262
|
`).split(`
|
|
261
|
-
`)){let a=s.trimEnd();if(a.trim()===""){r();continue}let l=Nt.exec(a);if(l){r(),e.push({kind:"heading",inline:_(l[1]??"")});continue}let d=_t.exec(a),h=d?null:Vt.exec(a);if(d||h){let p=!!h;(t.length||i&&i.ordered!==p)&&r(),i||(i={ordered:p,start:h?Number(h[1]):1,items:[]}),i.items.push((d?d[1]:h[2])??"");continue}if(i&&/^\s+/.test(s)){i.items[i.items.length-1]+=` ${a.trim()}`;continue}i&&r(),t.push(a)}return r(),e}function Ce(n){let e=n.trim();return/^(https?:\/\/|mailto:)/i.test(e)?e:null}var $t=/`([^`\n]+)`|\[([^\]\n]+)\]\(([^)\s]+)\)|\*\*(?=\S)([^*\n]*?\S)\*\*|__(?=\S)([^_\n]*?\S)__|(?<![\w*])\*(?=[^\s*])([^*\n]*?[^\s*])\*(?![\w*])|(?<![\w_])_(?=[^\s_])([^_\n]*?[^\s_])_(?![\w_])/g;function _(n){let e=[],t=r=>{let s=e[e.length-1];r.kind==="text"&&s?.kind==="text"&&!s.bold==!r.bold&&!s.italic==!r.italic?s.text+=r.text:e.push(r)},i=0;for(let r of n.matchAll($t)){let s=r.index??0;s>i&&t({kind:"text",text:n.slice(i,s)});let[a,l,d,h,p,u,m,V]=r;if(l!==void 0)t({kind:"code",text:l});else if(d!==void 0){let w=Ce(h??"");t(w?{kind:"link",text:d,href:w}:{kind:"text",text:d})}else if(p!==void 0||u!==void 0)for(let w of _(p??u??""))t(w.kind==="text"?{...w,bold:!0}:w);else t(m!==void 0||V!==void 0?{kind:"text",text:m??V??"",italic:!0}:{kind:"text",text:a});i=s+a.length}return i<n.length&&t({kind:"text",text:n.slice(i)}),e}function pe(n){return n.map(e=>{if(e.kind==="code")return c("code",{},e.text);if(e.kind==="link")return c("a",{attrs:{href:e.href,target:"_blank",rel:"noreferrer"}},e.text);let t=document.createTextNode(e.text);return e.italic&&(t=c("em",{},t)),e.bold&&(t=c("strong",{},t)),t})}function Je(n){return c("div",{class:"md"},...he(n).map(e=>{if(e.kind==="heading")return c("p",{},c("strong",{},...pe(e.inline)));if(e.kind==="list"){let t=e.items.map(i=>c("li",{},...pe(i)));return e.ordered?c("ol",{attrs:{start:e.start===1?void 0:e.start}},...t):c("ul",{},...t)}return c("p",{},...e.lines.flatMap((t,i)=>i?[c("br"),...pe(t)]:pe(t)))}))}var ue=["hands-free","hold"],fe=class{constructor(e,t){o(this,"mihe",e);o(this,"options",t);o(this,"root");o(this,"heading");o(this,"dot");o(this,"closeButton");o(this,"transcript");o(this,"input");o(this,"sendButton");o(this,"clip");o(this,"fileInput");o(this,"chips");o(this,"drawnAttachments",null);o(this,"talk");o(this,"call");o(this,"body");o(this,"drawn",[]);this.heading=document.createTextNode(""),this.dot=c("span",{class:"status-dot",attrs:{"aria-hidden":"true"}}),this.closeButton=c("button",{class:"icon-button",attrs:{type:"button","aria-label":"Close assistant"},on:{click:()=>this.mihe.close()}},"\u2715"),this.transcript=c("div",{class:"transcript"}),this.input=c("input",{class:"input",attrs:{"aria-label":"Message"},on:{input:()=>this.syncSend(this.mihe.getState()),paste:r=>{if(!this.mihe.getState().attachAccept)return;let s=Array.from(r.clipboardData?.files??[]);if(s.length){r.preventDefault();for(let a of s)this.mihe.attach(a)}}}}),this.fileInput=c("input",{attrs:{type:"file",multiple:!0,hidden:!0},on:{change:()=>{for(let r of Array.from(this.fileInput.files??[]))this.mihe.attach(r);this.fileInput.value=""}}}),this.clip=c("button",{class:"clip",attrs:{type:"button","aria-label":"Attach a picture",title:"Attach a picture"},on:{click:()=>this.fileInput.click()}},ze()),this.chips=c("ul",{class:"chips",attrs:{"aria-label":"Attached pictures"}}),this.sendButton=c("button",{class:"send",attrs:{type:"submit"}},"Send"),this.talk=c("button",{class:"talk",attrs:{type:"button",title:"Talk instead of typing"},on:{click:()=>{let r=this.mihe.getState().widgetSettings?.voiceModes??ue;this.mihe.voice.start(r.includes("hands-free")?{handsFree:!0}:void 0)}}},"Talk"),this.call=new Me(e);let i=c("form",{class:"composer",on:{submit:r=>{r.preventDefault(),this.mihe.send(this.input.value),this.input.value="",this.syncSend(this.mihe.getState())}}},this.clip,this.input,this.sendButton,this.fileInput);this.root=c("section",{class:"panel",attrs:{id:U}},c("header",{class:"header"},c("div",{class:"header-title"},this.dot,this.heading),this.talk,this.closeButton),this.body=c("div",{class:"panel-body"},this.transcript,this.chips,i),this.call.root)}setOptions(e){this.options=e}update(e){let t=this.options.title??e.assistantName??"Assistant";this.heading.data=t,this.root.setAttribute("aria-label",t),this.dot.classList.toggle("open",e.connection==="open"),this.closeButton.hidden=!this.options.showClose,this.input.placeholder=this.options.placeholder??"Ask me anything about this app\u2026",this.input.disabled=e.connection!=="open",this.clip.hidden=!e.attachAccept,this.clip.disabled=e.connection!=="open",e.attachAccept&&(this.fileInput.accept=e.attachAccept),e.attachments!==this.drawnAttachments&&(this.drawnAttachments=e.attachments,this.drawChips(e)),this.syncSend(e);let i=e.widgetSettings?.voiceModes??ue,r=this.options.showVoice&&e.voice.available&&i.length>0,s=this.options.showVoice&&e.voice.state!=="idle"&&e.voice.state!=="error";this.talk.hidden=!r||s,this.talk.disabled=e.connection!=="open",this.body.hidden=s,this.call.update(e,s);let a=[e.messages,e.proposals,e.cardViews,e.voice.state==="connecting",e.voice.notice,e.lastError,e.connection];a.every((l,d)=>l===this.drawn[d])||(this.drawn=a,this.drawTranscript(e))}syncSend(e){let t=e.attachments.some(r=>r.status==="reading"),i=e.attachments.some(r=>r.status==="ready");this.sendButton.disabled=e.busy||e.connection!=="open"||t||!this.input.value.trim()&&!i}drawChips(e){this.chips.hidden=e.attachments.length===0,b(this.chips,...e.attachments.map(t=>c("li",{class:t.status==="failed"?"chip failed":"chip"},t.previewUrl&&c("img",{attrs:{src:t.previewUrl,alt:""}}),c("span",{class:"chip-text"},c("span",{class:"chip-name"},t.name),c("span",{class:"chip-status",attrs:t.status==="failed"?{role:"alert"}:{}},t.status==="reading"?"Reading\u2026":t.status==="ready"?"Ready":t.error??"Couldn't read it")),c("button",{class:"chip-remove",attrs:{type:"button","aria-label":`Remove ${t.name}`},on:{click:()=>this.mihe.removeAttachment(t.id)}},"\u2715"))))}drawTranscript(e){b(this.transcript,e.messages.length===0&&c("p",{class:"empty"},"Ask where something is, what a screen does, or for help getting something done."),...e.messages.map(t=>c("div",{class:t.role==="user"?"bubble-user":"bubble-assistant"},t.attachments&&t.attachments.length>0&&c("div",{class:"sent-pictures"},...t.attachments.map(i=>i.previewUrl?c("img",{attrs:{src:i.previewUrl,alt:i.name,title:i.name}}):c("span",{class:"sent-name"},`\u{1F4CE} ${i.name}`))),t.role==="user"?t.text:Je(t.text),t.streaming&&t.text===""&&c("span",{class:"thinking"},"thinking\u2026"),t.sources&&t.sources.length>0&&c("div",{class:"sources"},...t.sources.map(i=>c("span",{class:"source"},i.url&&/^https?:\/\//i.test(i.url)?c("a",{attrs:{href:i.url,target:"_blank",rel:"noreferrer noopener"}},i.title):i.title))))),...e.proposals.map(t=>K(t,this.mihe.respondToProposal,e.cardViews[t.proposalId])),e.voice.state==="connecting"&&c("div",{class:"voice-notice"},"Setting up the microphone\u2026"),e.voice.notice&&c("div",{class:"voice-notice"},e.voice.notice),e.lastError&&c("div",{class:"error"},e.lastError),e.connection!=="open"&&c("div",{class:"notice"},e.connection==="closed"?"Disconnected.":"Connecting\u2026")),this.transcript.scrollTo?.({top:this.transcript.scrollHeight,behavior:"smooth"})}},Me=class{constructor(e){o(this,"mihe",e);o(this,"root");o(this,"cards");o(this,"ring");o(this,"line");o(this,"hold");o(this,"held","");o(this,"drawnCards",null);o(this,"stopLevel",null);this.cards=c("div",{class:"call-cards"}),this.ring=c("span",{class:"call-ring"}),this.line=c("span",{class:"call-line",attrs:{"aria-live":"polite"}}),this.hold=Ht(e),this.hold.classList.add("call-hold");let t=c("button",{class:"call-end",attrs:{type:"button"},on:{click:()=>this.mihe.voice.stop()}},"End"),i=c("span",{class:"call-mark",attrs:{"aria-hidden":"true"}},this.ring,se(26,"#0f172a","#007277"));this.root=c("div",{class:"call",attrs:{role:"region","aria-label":"Voice call"}},this.cards,c("div",{class:"call-bar"},i,this.line,this.hold,t)),this.root.hidden=!0}update(e,t){this.root.hidden=!t;let i=e.voice;if(!t){this.held="",this.stopLevel?.(),this.stopLevel=null;return}!this.stopLevel&&!matchMedia?.("(prefers-reduced-motion: reduce)").matches&&(this.stopLevel=this.mihe.voice.onLevel((a,l)=>{let d=this.mihe.getState().voice;(a==="assistant"||d.handsFree||d.state==="recording")&&(this.ring.style.transform=`scale(${1+l*.38})`)})),i.caption&&(this.held=i.caption);let r=i.state==="connecting"?"Setting up the microphone\u2026":i.state==="thinking"?"Thinking\u2026":i.state==="recording"?"Listening\u2026":i.handsFree?i.state==="speaking"?"":"Listening, just talk":"Hold to talk",s=(i.caption||this.held||(e.lastError&&i.state!=="connecting"?e.lastError:"")||r).replace(/\s+/g," ").trim();this.line.textContent=s.length<=90?s:`\u2026${s.slice(s.length-89).replace(/^\S*\s/,"")}`,this.line.title=s,this.hold.hidden=i.handsFree||i.state==="connecting",this.hold.textContent=i.state==="recording"?"Release to send":"Hold to talk",e.proposals!==this.drawnCards&&(this.drawnCards=e.proposals,b(this.cards,...e.proposals.map(a=>K(a,this.mihe.respondToProposal,e.cardViews[a.proposalId]))))}};function Ht(n){let e=()=>{let s=n.getState().voice.state,a=s==="connecting";return{connecting:a,live:s!=="idle"&&s!=="error"&&!a}},t=(s,a)=>{let{connecting:l,live:d}=e();if(!l){if(!d){n.voice.start();return}a!==void 0&&s.setPointerCapture?.(a),n.voice.press()}},i=()=>{e().live&&n.voice.release()},r=c("button",{class:"mic",attrs:{type:"button"},on:{pointerdown:s=>t(r,s.pointerId),pointerup:i,pointercancel:i,keydown:s=>{s.repeat||(s.key===" "||s.key==="Enter")&&(s.preventDefault(),t(r))},keyup:s=>{(s.key===" "||s.key==="Enter")&&(s.preventDefault(),i())}}},"\u{1F399}");return r}var B="mihe-assistant";function Ut(n,e){let t=e?.voiceModes??ue;return{form:n.form??e?.form??"orb",draggable:n.draggable??e?.draggable??!1,corner:n.corner??e?.corner??"bottom-right",voiceModes:n.voiceModes?n.voiceModes.filter(i=>t.includes(i)):t}}function Ft(n){let e=r=>n.getAttribute(r)??void 0,t=r=>n.hasAttribute(r)?e(r)!=="false":void 0,i=e("voice-modes");return{layout:e("layout"),title:e("heading"),placeholder:e("placeholder"),showLauncher:t("show-launcher"),defaultOpen:t("default-open"),showClose:t("show-close"),form:e("form"),draggable:t("draggable"),corner:e("corner"),offset:e("offset-bottom")===void 0&&e("offset-side")===void 0?void 0:{bottom:e("offset-bottom")===void 0?void 0:Number(e("offset-bottom")),side:e("offset-side")===void 0?void 0:Number(e("offset-side"))},voiceModes:i===void 0?void 0:i.split(/[\s,]+/).filter(Boolean)}}function Xe(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}function Ae(){if(typeof customElements>"u"||customElements.get(B))return;class n extends HTMLElement{constructor(){super(...arguments);o(this,"assistant",null);o(this,"ownOptions",{});o(this,"unsubscribe",null);o(this,"shadow",null);o(this,"panel",null);o(this,"orb",null);o(this,"launcher",null);o(this,"launcherKey",[]);o(this,"failedIcon",null);o(this,"openedByDefault",!1)}get mihe(){return this.assistant}set mihe(i){i!==this.assistant&&(this.disconnectAssistant(),this.assistant=i,this.isConnected&&this.connectAssistant())}get options(){return this.ownOptions}set options(i){this.ownOptions={...i},this.render()}connectedCallback(){this.shadow||(this.shadow=this.attachShadow({mode:"open"}),this.shadow.appendChild(c("style",{},Ke))),this.connectAssistant()}disconnectedCallback(){this.disconnectAssistant()}attributeChangedCallback(){this.render()}connectAssistant(){if(!this.assistant||this.unsubscribe||!this.shadow)return;let i=this.assistant;this.panel=new fe(i,{showClose:!0,showVoice:!0}),this.shadow.appendChild(this.panel.root),this.unsubscribe=i.subscribe(()=>this.render()),this.resolved().defaultOpen&&!this.openedByDefault&&(this.openedByDefault=!0,i.open()),this.render()}disconnectAssistant(){this.unsubscribe?.(),this.unsubscribe=null,this.orb?.destroy();for(let i of[this.panel?.root,this.orb?.root,this.launcher])i?.remove();this.panel=null,this.orb=null,this.launcher=null,this.launcherKey=[]}resolved(){return{...Xe(Ft(this)),...Xe(this.ownOptions)}}render(){let i=this.assistant;if(!i||!this.shadow||!this.panel)return;let r=i.getState(),s=this.resolved(),a=Ut(s,r.widgetSettings),l=s.title??r.assistantName??"Assistant",d={bottom:s.offset?.bottom??20,side:s.offset?.side??20},h=s.showLauncher??!0,p=this.panel;if(s.layout==="inline"){this.getAttribute("layout")!=="inline"&&this.setAttribute("layout","inline"),p.setOptions({title:s.title,placeholder:s.placeholder,showClose:s.showClose??!1,showVoice:!0}),p.root.classList.remove("floating","left","right"),p.root.removeAttribute("style"),p.root.hidden=!1,p.update(r),this.hideOrb(),this.launcher&&(this.launcher.hidden=!0);return}if(a.form==="orb"){this.launcher&&(this.launcher.hidden=!0),this.orb||(this.orb=new de(i),this.shadow.appendChild(this.orb.root)),this.orb.update(r,{heading:l,draggable:a.draggable,corner:a.corner,voiceModes:a.voiceModes,launcherIcon:s.launcherIcon,offset:d}),this.orb.root.hidden=r.isOpen||!h,this.showPanel(r.isOpen,this.orb.side(),d,{title:s.title,placeholder:s.placeholder,showClose:!0,showVoice:!1});return}this.hideOrb(),this.showPanel(r.isOpen,"right",d,{title:s.title,placeholder:s.placeholder,showClose:!0,showVoice:!0});let u=this.drawLauncher(l,s.launcherIcon,r.launcherIconUrl);u.hidden=r.isOpen||!h,u.style.bottom=`${d.bottom}px`,u.style.right=`${d.side}px`}showPanel(i,r,s,a){let l=this.panel;l.root.hidden=!i,l.root.classList.add("floating"),l.root.style.bottom=`${s.bottom}px`,l.root.style.left=r==="left"?`${s.side}px`:"",l.root.style.right=r==="right"?`${s.side}px`:"",l.root.style.height=`min(560px, calc(100vh - ${s.bottom+20}px))`,l.setOptions(a),l.update(this.assistant.getState())}hideOrb(){this.orb&&(this.orb.root.hidden=!0)}drawLauncher(i,r,s){this.launcher||(this.launcher=c("button",{class:"launcher",attrs:{type:"button","aria-controls":"mihe-panel","aria-expanded":"false"},on:{click:()=>this.assistant?.open()}}),this.shadow.appendChild(this.launcher)),F(this.launcher,{"aria-label":`Open ${i}`});let a=[r,s,this.failedIcon];return a.some((l,d)=>l!==this.launcherKey[d])&&(this.launcherKey=a,b(this.launcher,le(r,s,this.failedIcon,l=>{this.failedIcon=l,this.render()}))),this.launcher}}o(n,"observedAttributes",["layout","heading","placeholder","show-launcher","default-open","show-close","form","draggable","corner","voice-modes","offset-bottom","offset-side"]),customElements.define(B,n)}function Ze(n,e={}){Ae();let{container:t,...i}=e,r=document.createElement(B);return r.options=i,r.mihe=n,(t??document.body).appendChild(r),{element:r,unmount:()=>r.remove()}}return at(Kt);})();
|
|
263
|
+
`)){let a=s.trimEnd();if(a.trim()===""){r();continue}let l=Nt.exec(a);if(l){r(),e.push({kind:"heading",inline:_(l[1]??"")});continue}let d=_t.exec(a),h=d?null:Vt.exec(a);if(d||h){let p=!!h;(t.length||i&&i.ordered!==p)&&r(),i||(i={ordered:p,start:h?Number(h[1]):1,items:[]}),i.items.push((d?d[1]:h[2])??"");continue}if(i&&/^\s+/.test(s)){i.items[i.items.length-1]+=` ${a.trim()}`;continue}i&&r(),t.push(a)}return r(),e}function Ce(n){let e=n.trim();return/^(https?:\/\/|mailto:)/i.test(e)?e:null}var $t=/`([^`\n]+)`|\[([^\]\n]+)\]\(([^)\s]+)\)|\*\*(?=\S)([^*\n]*?\S)\*\*|__(?=\S)([^_\n]*?\S)__|(?<![\w*])\*(?=[^\s*])([^*\n]*?[^\s*])\*(?![\w*])|(?<![\w_])_(?=[^\s_])([^_\n]*?[^\s_])_(?![\w_])/g;function _(n){let e=[],t=r=>{let s=e[e.length-1];r.kind==="text"&&s?.kind==="text"&&!s.bold==!r.bold&&!s.italic==!r.italic?s.text+=r.text:e.push(r)},i=0;for(let r of n.matchAll($t)){let s=r.index??0;s>i&&t({kind:"text",text:n.slice(i,s)});let[a,l,d,h,p,u,m,V]=r;if(l!==void 0)t({kind:"code",text:l});else if(d!==void 0){let w=Ce(h??"");t(w?{kind:"link",text:d,href:w}:{kind:"text",text:d})}else if(p!==void 0||u!==void 0)for(let w of _(p??u??""))t(w.kind==="text"?{...w,bold:!0}:w);else t(m!==void 0||V!==void 0?{kind:"text",text:m??V??"",italic:!0}:{kind:"text",text:a});i=s+a.length}return i<n.length&&t({kind:"text",text:n.slice(i)}),e}function pe(n){return n.map(e=>{if(e.kind==="code")return c("code",{},e.text);if(e.kind==="link")return c("a",{attrs:{href:e.href,target:"_blank",rel:"noreferrer"}},e.text);let t=document.createTextNode(e.text);return e.italic&&(t=c("em",{},t)),e.bold&&(t=c("strong",{},t)),t})}function Je(n){return c("div",{class:"md"},...he(n).map(e=>{if(e.kind==="heading")return c("p",{},c("strong",{},...pe(e.inline)));if(e.kind==="list"){let t=e.items.map(i=>c("li",{},...pe(i)));return e.ordered?c("ol",{attrs:{start:e.start===1?void 0:e.start}},...t):c("ul",{},...t)}return c("p",{},...e.lines.flatMap((t,i)=>i?[c("br"),...pe(t)]:pe(t)))}))}var ue=["hands-free","hold"],fe=class{constructor(e,t){o(this,"mihe",e);o(this,"options",t);o(this,"root");o(this,"heading");o(this,"dot");o(this,"closeButton");o(this,"transcript");o(this,"input");o(this,"sendButton");o(this,"clip");o(this,"fileInput");o(this,"chips");o(this,"drawnAttachments",null);o(this,"talk");o(this,"call");o(this,"body");o(this,"drawn",[]);this.heading=document.createTextNode(""),this.dot=c("span",{class:"status-dot",attrs:{"aria-hidden":"true"}}),this.closeButton=c("button",{class:"icon-button",attrs:{type:"button","aria-label":"Close assistant"},on:{click:()=>this.mihe.close()}},"\u2715"),this.transcript=c("div",{class:"transcript"}),this.input=c("input",{class:"input",attrs:{"aria-label":"Message"},on:{input:()=>this.syncSend(this.mihe.getState()),paste:r=>{if(!this.mihe.getState().attachAccept)return;let s=Array.from(r.clipboardData?.files??[]);if(s.length){r.preventDefault();for(let a of s)this.mihe.attach(a)}}}}),this.fileInput=c("input",{attrs:{type:"file",multiple:!0,hidden:!0},on:{change:()=>{for(let r of Array.from(this.fileInput.files??[]))this.mihe.attach(r);this.fileInput.value=""}}}),this.clip=c("button",{class:"clip",attrs:{type:"button","aria-label":"Attach a picture",title:"Attach a picture"},on:{click:()=>this.fileInput.click()}},ze()),this.chips=c("ul",{class:"chips",attrs:{"aria-label":"Attached pictures"}}),this.sendButton=c("button",{class:"send",attrs:{type:"submit"}},"Send"),this.talk=c("button",{class:"talk",attrs:{type:"button",title:"Talk instead of typing"},on:{click:()=>{let r=this.mihe.getState().widgetSettings?.voiceModes??ue;this.mihe.voice.start(r.includes("hands-free")?{handsFree:!0}:void 0)}}},"Talk"),this.call=new Me(e);let i=c("form",{class:"composer",on:{submit:r=>{r.preventDefault(),this.mihe.send(this.input.value),this.input.value="",this.syncSend(this.mihe.getState())}}},this.clip,this.input,this.sendButton,this.fileInput);this.root=c("section",{class:"panel",attrs:{id:U}},c("header",{class:"header"},c("div",{class:"header-title"},this.dot,this.heading),this.talk,this.closeButton),this.body=c("div",{class:"panel-body"},this.transcript,this.chips,i),this.call.root)}setOptions(e){this.options=e}update(e){let t=this.options.title??e.assistantName??"Assistant";this.heading.data=t,this.root.setAttribute("aria-label",t),this.dot.classList.toggle("open",e.connection==="open"),this.closeButton.hidden=!this.options.showClose,this.input.placeholder=this.options.placeholder??"Ask me anything about this app\u2026",this.input.disabled=e.connection!=="open",this.clip.hidden=!e.attachAccept,this.clip.disabled=e.connection!=="open",e.attachAccept&&(this.fileInput.accept=e.attachAccept),e.attachments!==this.drawnAttachments&&(this.drawnAttachments=e.attachments,this.drawChips(e)),this.syncSend(e);let i=e.widgetSettings?.voiceModes??ue,r=this.options.showVoice&&e.voice.available&&i.length>0,s=this.options.showVoice&&e.voice.state!=="idle"&&e.voice.state!=="error";this.talk.hidden=!r||s,this.talk.disabled=e.connection!=="open",this.body.hidden=s,this.call.update(e,s);let a=[e.messages,e.proposals,e.cardViews,e.voice.state==="connecting",e.voice.notice,e.lastError,e.connection];a.every((l,d)=>l===this.drawn[d])||(this.drawn=a,this.drawTranscript(e))}syncSend(e){let t=e.attachments.some(r=>r.status==="reading"),i=e.attachments.some(r=>r.status==="ready");this.sendButton.disabled=e.busy||e.connection!=="open"||t||!this.input.value.trim()&&!i}drawChips(e){this.chips.hidden=e.attachments.length===0,b(this.chips,...e.attachments.map(t=>c("li",{class:t.status==="failed"?"chip failed":"chip"},t.previewUrl&&c("img",{attrs:{src:t.previewUrl,alt:""}}),c("span",{class:"chip-text"},c("span",{class:"chip-name"},t.name),c("span",{class:"chip-status",attrs:t.status==="failed"?{role:"alert"}:{}},t.status==="reading"?"Reading\u2026":t.status==="ready"?"Ready":t.error??"Couldn't read it")),c("button",{class:"chip-remove",attrs:{type:"button","aria-label":`Remove ${t.name}`},on:{click:()=>this.mihe.removeAttachment(t.id)}},"\u2715"))))}drawTranscript(e){b(this.transcript,e.messages.length===0&&c("p",{class:"empty"},"Ask where something is, what a screen does, or for help getting something done."),...e.messages.map(t=>c("div",{class:t.role==="user"?"bubble-user":"bubble-assistant"},t.attachments&&t.attachments.length>0&&c("div",{class:"sent-pictures"},...t.attachments.map(i=>i.previewUrl?c("img",{attrs:{src:i.previewUrl,alt:i.name,title:i.name}}):c("span",{class:"sent-name"},`\u{1F4CE} ${i.name}`))),t.role==="user"?t.text:Je(t.text),t.streaming&&t.text===""&&c("span",{class:"thinking"},"thinking\u2026"),t.sources&&t.sources.length>0&&c("div",{class:"sources"},...t.sources.map(i=>c("span",{class:"source"},i.url&&/^https?:\/\//i.test(i.url)?c("a",{attrs:{href:i.url,target:"_blank",rel:"noreferrer noopener"}},i.title):i.title))))),...e.proposals.map(t=>K(t,this.mihe.respondToProposal,e.cardViews[t.proposalId])),e.voice.state==="connecting"&&c("div",{class:"voice-notice"},"Setting up the microphone\u2026"),e.voice.notice&&c("div",{class:"voice-notice"},e.voice.notice),e.lastError&&c("div",{class:"error"},e.lastError),e.connection!=="open"&&c("div",{class:"notice"},e.connection==="closed"?"Disconnected.":"Connecting\u2026")),this.transcript.scrollTo?.({top:this.transcript.scrollHeight,behavior:"smooth"})}},Me=class{constructor(e){o(this,"mihe",e);o(this,"root");o(this,"cards");o(this,"ring");o(this,"line");o(this,"hold");o(this,"held","");o(this,"failed",null);o(this,"lastState","idle");o(this,"failedLine");o(this,"drawnCards",null);o(this,"stopLevel",null);this.cards=c("div",{class:"call-cards"}),this.ring=c("span",{class:"call-ring"}),this.line=c("span",{class:"call-line",attrs:{"aria-live":"polite"}}),this.hold=Ht(e),this.hold.classList.add("call-hold");let t=c("button",{class:"call-end",attrs:{type:"button"},on:{click:()=>this.mihe.voice.stop()}},"End"),i=c("span",{class:"call-mark",attrs:{"aria-hidden":"true"}},this.ring,se(26,"#0f172a","#007277"));this.failedLine=c("p",{class:"call-failed",attrs:{role:"alert"}}),this.root=c("div",{class:"call",attrs:{role:"region","aria-label":"Voice call"}},this.cards,this.failedLine,c("div",{class:"call-bar"},i,this.line,this.hold,t)),this.root.hidden=!0}update(e,t){this.root.hidden=!t;let i=e.voice;if(!t){this.held="",this.failed=null,this.failedLine.hidden=!0,this.stopLevel?.(),this.stopLevel=null;return}i.state==="thinking"&&this.lastState!=="thinking"&&(this.failed=null),e.lastError&&e.lastError!==this.failedLine.dataset.seen&&(this.failed=e.lastError,this.failedLine.dataset.seen=e.lastError),this.lastState=i.state,this.failedLine.hidden=!this.failed,this.failedLine.textContent=this.failed??"",!this.stopLevel&&!matchMedia?.("(prefers-reduced-motion: reduce)").matches&&(this.stopLevel=this.mihe.voice.onLevel((a,l)=>{let d=this.mihe.getState().voice;(a==="assistant"||d.handsFree||d.state==="recording")&&(this.ring.style.transform=`scale(${1+l*.38})`)})),i.caption&&(this.held=i.caption);let r=i.state==="connecting"?"Setting up the microphone\u2026":i.state==="thinking"?"Thinking\u2026":i.state==="recording"?"Listening\u2026":i.handsFree?i.state==="speaking"?"":"Listening, just talk":"Hold to talk",s=(i.caption||this.held||r).replace(/\s+/g," ").trim();this.line.textContent=s.length<=90?s:`\u2026${s.slice(s.length-89).replace(/^\S*\s/,"")}`,this.line.title=s,this.hold.hidden=i.handsFree||i.state==="connecting",this.hold.textContent=i.state==="recording"?"Release to send":"Hold to talk",e.proposals!==this.drawnCards&&(this.drawnCards=e.proposals,b(this.cards,...e.proposals.map(a=>K(a,this.mihe.respondToProposal,e.cardViews[a.proposalId]))))}};function Ht(n){let e=()=>{let s=n.getState().voice.state,a=s==="connecting";return{connecting:a,live:s!=="idle"&&s!=="error"&&!a}},t=(s,a)=>{let{connecting:l,live:d}=e();if(!l){if(!d){n.voice.start();return}a!==void 0&&s.setPointerCapture?.(a),n.voice.press()}},i=()=>{e().live&&n.voice.release()},r=c("button",{class:"mic",attrs:{type:"button"},on:{pointerdown:s=>t(r,s.pointerId),pointerup:i,pointercancel:i,keydown:s=>{s.repeat||(s.key===" "||s.key==="Enter")&&(s.preventDefault(),t(r))},keyup:s=>{(s.key===" "||s.key==="Enter")&&(s.preventDefault(),i())}}},"\u{1F399}");return r}var B="mihe-assistant";function Ut(n,e){let t=e?.voiceModes??ue;return{form:n.form??e?.form??"orb",draggable:n.draggable??e?.draggable??!1,corner:n.corner??e?.corner??"bottom-right",voiceModes:n.voiceModes?n.voiceModes.filter(i=>t.includes(i)):t}}function Ft(n){let e=r=>n.getAttribute(r)??void 0,t=r=>n.hasAttribute(r)?e(r)!=="false":void 0,i=e("voice-modes");return{layout:e("layout"),title:e("heading"),placeholder:e("placeholder"),showLauncher:t("show-launcher"),defaultOpen:t("default-open"),showClose:t("show-close"),form:e("form"),draggable:t("draggable"),corner:e("corner"),offset:e("offset-bottom")===void 0&&e("offset-side")===void 0?void 0:{bottom:e("offset-bottom")===void 0?void 0:Number(e("offset-bottom")),side:e("offset-side")===void 0?void 0:Number(e("offset-side"))},voiceModes:i===void 0?void 0:i.split(/[\s,]+/).filter(Boolean)}}function Xe(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}function Ae(){if(typeof customElements>"u"||customElements.get(B))return;class n extends HTMLElement{constructor(){super(...arguments);o(this,"assistant",null);o(this,"ownOptions",{});o(this,"unsubscribe",null);o(this,"shadow",null);o(this,"panel",null);o(this,"orb",null);o(this,"launcher",null);o(this,"launcherKey",[]);o(this,"failedIcon",null);o(this,"openedByDefault",!1)}get mihe(){return this.assistant}set mihe(i){i!==this.assistant&&(this.disconnectAssistant(),this.assistant=i,this.isConnected&&this.connectAssistant())}get options(){return this.ownOptions}set options(i){this.ownOptions={...i},this.render()}connectedCallback(){this.shadow||(this.shadow=this.attachShadow({mode:"open"}),this.shadow.appendChild(c("style",{},Ke))),this.connectAssistant()}disconnectedCallback(){this.disconnectAssistant()}attributeChangedCallback(){this.render()}connectAssistant(){if(!this.assistant||this.unsubscribe||!this.shadow)return;let i=this.assistant;this.panel=new fe(i,{showClose:!0,showVoice:!0}),this.shadow.appendChild(this.panel.root),this.unsubscribe=i.subscribe(()=>this.render()),this.resolved().defaultOpen&&!this.openedByDefault&&(this.openedByDefault=!0,i.open()),this.render()}disconnectAssistant(){this.unsubscribe?.(),this.unsubscribe=null,this.orb?.destroy();for(let i of[this.panel?.root,this.orb?.root,this.launcher])i?.remove();this.panel=null,this.orb=null,this.launcher=null,this.launcherKey=[]}resolved(){return{...Xe(Ft(this)),...Xe(this.ownOptions)}}render(){let i=this.assistant;if(!i||!this.shadow||!this.panel)return;let r=i.getState(),s=this.resolved(),a=Ut(s,r.widgetSettings),l=s.title??r.assistantName??"Assistant",d={bottom:s.offset?.bottom??20,side:s.offset?.side??20},h=s.showLauncher??!0,p=this.panel;if(s.layout==="inline"){this.getAttribute("layout")!=="inline"&&this.setAttribute("layout","inline"),p.setOptions({title:s.title,placeholder:s.placeholder,showClose:s.showClose??!1,showVoice:!0}),p.root.classList.remove("floating","left","right"),p.root.removeAttribute("style"),p.root.hidden=!1,p.update(r),this.hideOrb(),this.launcher&&(this.launcher.hidden=!0);return}if(a.form==="orb"){this.launcher&&(this.launcher.hidden=!0),this.orb||(this.orb=new de(i),this.shadow.appendChild(this.orb.root)),this.orb.update(r,{heading:l,draggable:a.draggable,corner:a.corner,voiceModes:a.voiceModes,launcherIcon:s.launcherIcon,offset:d}),this.orb.root.hidden=r.isOpen||!h,this.showPanel(r.isOpen,this.orb.side(),d,{title:s.title,placeholder:s.placeholder,showClose:!0,showVoice:!1});return}this.hideOrb(),this.showPanel(r.isOpen,"right",d,{title:s.title,placeholder:s.placeholder,showClose:!0,showVoice:!0});let u=this.drawLauncher(l,s.launcherIcon,r.launcherIconUrl);u.hidden=r.isOpen||!h,u.style.bottom=`${d.bottom}px`,u.style.right=`${d.side}px`}showPanel(i,r,s,a){let l=this.panel;l.root.hidden=!i,l.root.classList.add("floating"),l.root.style.bottom=`${s.bottom}px`,l.root.style.left=r==="left"?`${s.side}px`:"",l.root.style.right=r==="right"?`${s.side}px`:"",l.root.style.height=`min(560px, calc(100vh - ${s.bottom+20}px))`,l.setOptions(a),l.update(this.assistant.getState())}hideOrb(){this.orb&&(this.orb.root.hidden=!0)}drawLauncher(i,r,s){this.launcher||(this.launcher=c("button",{class:"launcher",attrs:{type:"button","aria-controls":"mihe-panel","aria-expanded":"false"},on:{click:()=>this.assistant?.open()}}),this.shadow.appendChild(this.launcher)),F(this.launcher,{"aria-label":`Open ${i}`});let a=[r,s,this.failedIcon];return a.some((l,d)=>l!==this.launcherKey[d])&&(this.launcherKey=a,b(this.launcher,le(r,s,this.failedIcon,l=>{this.failedIcon=l,this.render()}))),this.launcher}}o(n,"observedAttributes",["layout","heading","placeholder","show-launcher","default-open","show-close","form","draggable","corner","voice-modes","offset-bottom","offset-side"]),customElements.define(B,n)}function Ze(n,e={}){Ae();let{container:t,...i}=e,r=document.createElement(B);return r.options=i,r.mihe=n,(t??document.body).appendChild(r),{element:r,unmount:()=>r.remove()}}return at(Kt);})();
|
|
262
264
|
//# sourceMappingURL=mihe.iife.min.js.map
|