UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

23 lines • 7.49 kB
import{n as e}from"./rolldown-runtime-8BhlS34s.js";import{Br as t,Gi as n,qr as r,zr as i}from"./control-ui-foundation-ZY_Flbbd.js";import{At as a,Gl as o,hu as s,kt as c,lu as l,ou as u,ql as d,uu as f}from"./control-ui-core-3P365fbR.js";import{vi as p,yi as m}from"./control-ui-core-CFW9Qtjn.js";import{$ as h,X as g,Y as _,ct as v,m as y,nt as b,p as x,ut as S}from"./lit-runtime-P5vbNq6b.js";import{Qn as C,Yn as w,Zn as T}from"./control-ui-boot-shared-DoKu-5Ju.js";import{_n as E,fn as D,pn as O,un as k}from"./control-ui-boot-shared-CG9HtEG-.js";import{i as A,r as j,t as M}from"./widget-sandbox-host-BQH21b5-.js";function N(e){let t=I.get(e.client);(!t||t.generation!==e.generation)&&(t={generation:e.generation,requests:new Map},I.set(e.client,t));let n=t.requests.get(e.docId);if(n)return n;let r=e.client.request(`canvas.document.view`,{docId:e.docId},{timeoutMs:M});if(t.requests.size<32){let n=t.requests;n.set(e.docId,r),r.finally(()=>n.delete(e.docId)).catch(()=>{})}return r}var P,F,I,L;function R(){return(R=e((()=>{t(),_(),b(),x(),m(),f(),a(),d(),A(),w(),l(),O(),P=new Set,F=6e5,I=new WeakMap,L=class extends u{constructor(...e){super(...e),this.docId=``,this.sessionKey=``,this.title=``,this.connectionGeneration=0,this.error=``,this.runtimeError=``,this.sandboxOrigin=``,this.scriptsAllowed=!0,this.sandboxGeneration=0,this.handleMessage=e=>{let t=this.sandboxHost,r=this.binding;if(!t||!this.isCurrent(r)||e.source!==t.frame.contentWindow||e.origin!==this.sandboxOrigin)return;t.handleMessage(e);let i=n(e.data);if(i?.type===`openclaw:widget-runtime-error`){if(!this.sessionKey||typeof i.message!=`string`)return;let e={message:i.message.slice(0,500),line:typeof i.line==`number`&&Number.isInteger(i.line)?i.line:void 0,column:typeof i.column==`number`&&Number.isInteger(i.column)?i.column:void 0};this.runtimeError||=e.message;let t=this.messageTimestamp;if(typeof t!=`number`||!Number.isFinite(t)||Date.now()-t>F)return;let n=`error\0${this.sessionKey}\0${r.docId}`;if(P.has(n)||!k(n,Date.now()))return;P.add(n);let a=e.line===void 0?``:`, line ${e.line}${e.column===void 0?``:`, column ${e.column}`}`,o=`Inline widget "${this.title.slice(0,80)}" (${r.docId}) threw a script error after rendering: ${e.message}${a}. Fix the script and show the widget again; if show_widget is unavailable in this turn, reply with the corrected widget code and show it on the next turn.`;r.client.request(`wake`,{mode:`now`,sessionKey:this.sessionKey,text:o}).catch(e=>console.warn(`Widget runtime error wake failed`,e));return}if(i?.type===`openclaw:widget-size`&&typeof i.height==`number`&&Number.isFinite(i.height)&&i.height>0&&(this.contentHeight=Math.min(8e3,Math.max(48,Math.trunc(i.height)))),i?.type===`openclaw:widget-bridge-ready`&&this.postHostState(),i?.type!==`openclaw:widget-prompt-offer`){i?.type===`openclaw:widget-bridge-port-offer`&&e.ports[0]?.close();return}let a=e.ports[0];if(!a||this.promptPort||!t.loaded){a?.close();return}this.promptPort=a,a.addEventListener(`message`,e=>{this.isCurrent(r)&&this.promptPort===a&&e.data?.type===`openclaw:widget-prompt`&&D(t.frame,e.data.prompt,`${this.sessionKey}\0${r.docId}\0${r.generation}`)}),a.start(),a.postMessage({type:`openclaw:widget-prompt-host-ready`})}}get allowScripts(){return this.scriptsAllowed}set allowScripts(e){e!==this.scriptsAllowed&&(this.clearSandbox(),this.sandboxGeneration+=1,this.view&&(this.error=``),this.scriptsAllowed=e)}get documentHtml(){return this.isCurrent(this.binding)?this.view?.html:void 0}connectedCallback(){super.connectedCallback(),window.addEventListener(`message`,this.handleMessage)}disconnectedCallback(){window.removeEventListener(`message`,this.handleMessage),this.clearView(),super.disconnectedCallback()}clearView(){this.runtimeError=``,this.binding=void 0,this.view=void 0,this.clearSandbox()}clearSandbox(){this.sandboxHost?.dispose(),this.sandboxHost=void 0,this.promptPort?.close(),this.promptPort=void 0,this.releaseTheme?.(),this.releaseTheme=void 0,this.contentHeight=void 0}isCurrent(e){return!!(e&&this.isConnected&&this.binding===e&&e.client===this.context?.gateway.snapshot.client&&e.docId===this.docId&&e.sessionKey===this.sessionKey&&e.generation===c())}willUpdate(){let e=this.context?.gateway.snapshot.client;if(!e||!this.docId){this.clearView();return}if(this.binding?.client===e&&this.binding.docId===this.docId&&this.binding.sessionKey===this.sessionKey&&this.binding.generation===this.connectionGeneration)return;this.clearView(),this.error=``;let t={client:e,docId:this.docId,sessionKey:this.sessionKey,generation:this.connectionGeneration};this.binding=t,N(t).then(e=>{this.isCurrent(t)&&(this.view=e)}).catch(e=>{this.isCurrent(t)&&(this.error=o(e))})}updated(){let e=this.querySelector(`iframe`),t=this.view,n=this.binding;this.allowScripts&&e&&t&&this.isCurrent(n)&&!this.sandboxHost&&(this.releaseTheme=C(e,this.sandboxOrigin),this.sandboxHost=new j({frame:e,sandboxOrigin:this.sandboxOrigin,sandboxUrl:e.src,documentKey:`${n.docId}\0${n.generation}`,loadDocument:async()=>t.html,onLoaded:()=>this.postHostState(),onError:e=>this.fail(e),onReadyTimeout:()=>this.fail(Error(s(`board.widget.sandboxUnavailable`)))}))}fail(e){this.clearSandbox(),this.error=o(e)}postHostState(){let e=this.sandboxHost?.frame;e&&(T(e,this.sandboxOrigin),e.contentWindow?.postMessage({type:`openclaw:widget-chat-host`},this.sandboxOrigin))}render(){if(this.error)return h`<div class="board-widget__error" role="alert"> ${this.error} <button class="btn btn--small" @click=${()=>{this.clearView(),this.requestUpdate()}} > ${s(`common.retry`)} </button> </div>`;if(!this.view||!this.context)return h`<div class="skeleton" role="status" aria-label=${s(`common.loading`)} style=${`min-height:${this.preferredHeight??420}px`} ></div>`;let e;try{this.allowScripts&&(e=E(this.view.sandboxUrl,this.view.sandboxPort,this.view.sandboxOrigin,this.context.gateway.connection.gatewayUrl,window.location.origin),this.sandboxOrigin=new URL(e).origin)}catch(e){return h`<div role="alert">${o(e)}</div>`}let t=this.contentHeight??this.preferredHeight;return y(this.sandboxGeneration,h`${this.runtimeError?h`<div class="board-widget__notice" role="status">${s(`board.widget.runtimeError`,{message:this.runtimeError})}</div>`:g}<iframe class="chat-tool-card__preview-frame" title=${this.title} src=${e??g} srcdoc=${this.allowScripts?g:this.view.html} sandbox=${this.allowScripts?`allow-scripts allow-same-origin allow-forms`:``} referrerpolicy="origin" style=${t?`height:${t}px;min-height:${t}px`:g} @error=${()=>this.sandboxHost?.handleFrameError()} ></iframe>`)}},r([i({context:p,subscribe:!0})],L.prototype,`context`,void 0),r([S()],L.prototype,`docId`,void 0),r([S()],L.prototype,`sessionKey`,void 0),r([S({type:Number})],L.prototype,`messageTimestamp`,void 0),r([S()],L.prototype,`title`,void 0),r([S({type:Number})],L.prototype,`preferredHeight`,void 0),r([S({type:Number})],L.prototype,`connectionGeneration`,void 0),r([v()],L.prototype,`view`,void 0),r([v()],L.prototype,`error`,void 0),r([v()],L.prototype,`runtimeError`,void 0),r([v()],L.prototype,`contentHeight`,void 0),r([S({type:Boolean})],L.prototype,`allowScripts`,null),customElements.get(`openclaw-canvas-widget-view`)||customElements.define(`openclaw-canvas-widget-view`,L)})))()}R();export{L as OpenClawCanvasWidgetView};