UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

37 lines • 11.5 kB
import{n as e}from"./rolldown-runtime-8BhlS34s.js";import{Au as t,Ft as n,Gs as r,Ic as i,Js as a,Lc as o,Nu as s,Pt as c,Pu as ee,qs as l,xu as u,yu as d,zu as f}from"./control-ui-core-CBJ5efDh.js";import{Ai as p,Sr as m,ki as h,wr as g}from"./control-ui-core-DtLivg_r.js";import{G as _,J as v,W as y,Z as b,at as x,c as te,l as S,rt as C}from"./lit-runtime-IOnANfcZ.js";import{Bi as w,Jt as T,Kt as E,Mt as D,Ur as O,Wr as k,Xt as A,Yt as j,Zr as M,jt as N,qt as P,xa as F}from"./ui-CmSP4d14.js";import{B as I,R as L,V as ne}from"./control-ui-boot-chat-XPUNenUd.js";import{l as R,u as z}from"./control-ui-boot-chat-BD9CwLj7.js";import{ht as B,vt as V,yt as H}from"./control-ui-boot-chat-CmENwCKi.js";import{a as U,i as W,n as G,t as K}from"./widget-sandbox-host-COBvR0Ux.js";import{r as q}from"./sandbox-host-Dm6XHU23.js";function J(e){let t=Z.get(e.client);(!t||t.generation!==e.generation)&&(t={generation:e.generation,requests:new Map},Z.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:G});if(t.requests.size<32){let n=t.requests;n.set(e.docId,r),r.finally(()=>n.delete(e.docId)).catch(()=>{})}return r}var Y,X,Z,Q;function $(){return($=e((()=>{k(),A(),E(),y(),b(),te(),p(),g(),ee(),n(),u(),r(),D(),U(),L(),s(),o(),z(),H(),Y=new Set,X=6e5,Z=new WeakMap,Q=class extends t{constructor(){super(),this.docId=``,this.sessionKey=``,this.title=``,this.connectionGeneration=0,this.error=``,this.runtimeError=``,this.resourceError=!1,this.sandboxOrigin=``,this.scrollNonce=``,this.scriptsAllowed=!0,this.sandboxGeneration=0,this.retryDelayMs=1e3,this.pending=!1,this.handleMessage=e=>{let t=this.sandboxHost,n=this.viewOwner;if(!t||!this.sameOwner(n)||e.source!==t.frame.contentWindow||e.origin!==this.sandboxOrigin)return;t.handleMessage(e);let r=F(e.data);if(r?.type===`openclaw:widget-scroll`&&this.scrollNonce&&r.nonce===this.scrollNonce&&typeof r.deltaY==`number`&&Number.isFinite(r.deltaY)){R(new WheelEvent(`wheel`,{deltaY:r.deltaY,cancelable:!0}),this.closest(`.chat-thread`));return}if(r?.type===`openclaw:widget-runtime-error`){if(!this.sessionKey||typeof r.message!=`string`)return;if(!this.isCurrent(this.validated)||!navigator.onLine||/failed to fetch|load failed|networkerror|network request failed|importing a module script failed|failed to load module script/i.test(r.message)){this.resourceError=!0;return}let e={message:w(r.message,500).toWellFormed(),line:typeof r.line==`number`&&Number.isInteger(r.line)?r.line:void 0,column:typeof r.column==`number`&&Number.isInteger(r.column)?r.column:void 0};this.runtimeError||=e.message;let t=this.messageTimestamp;if(typeof t!=`number`||!Number.isFinite(t)||Date.now()-t>X)return;let i=`error\0${this.sessionKey}\0${n.docId}`;if(Y.has(i)||!B(i,Date.now()))return;Y.add(i);let a=e.line===void 0?``:`, line ${e.line}${e.column===void 0?``:`, column ${e.column}`}`,o=`Inline widget "${w(this.title,80)}" (${n.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.`;n.client.request(`wake`,{mode:`now`,sessionKey:this.sessionKey,text:o}).catch(e=>console.warn(`Widget runtime error wake failed`,e));return}if(r?.type===`openclaw:widget-size`&&typeof r.height==`number`&&Number.isFinite(r.height)&&r.height>0&&(this.contentHeight=Math.min(8e3,Math.max(48,Math.trunc(r.height)))),r?.type===`openclaw:widget-bridge-ready`&&this.postHostState(),r?.type!==`openclaw:widget-prompt-offer`){r?.type===`openclaw:widget-bridge-port-offer`&&e.ports[0]?.close();return}let i=e.ports[0];if(!i||this.promptPort||!t.loaded){i?.close();return}this.promptPort=i,i.addEventListener(`message`,e=>{this.isCurrent(this.validated)&&this.sandboxHost===t&&this.promptPort===i&&e.data?.type===`openclaw:widget-prompt`&&V(t.frame,e.data.prompt,`${this.sessionKey}\0${this.docId}\0${this.validated.generation}`)}),i.start(),i.postMessage({type:`openclaw:widget-prompt-host-ready`})},new i(this).watchStore(()=>this.context?.gateway)}clearRetry(){window.clearTimeout(this.slowTimer),this.slowTimer=void 0,window.clearTimeout(this.retryTimer),this.retryTimer=void 0}scheduleRetry(e,t=0){this.retryTimer===void 0&&(this.pending=!0,this.retryTimer=window.setTimeout(()=>{this.retryTimer=void 0,this.isCurrent(e)&&(this.binding=void 0,this.requestUpdate())},P(Math.max(this.retryDelayMs,t))),this.retryDelayMs=Math.min(this.retryDelayMs*2,3e4))}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.sameOwner(this.viewOwner)?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.clearRetry(),this.validated=void 0,this.viewOwner=void 0,this.sandboxGeneration+=1,this.runtimeError=``,this.resourceError=!1,this.binding=void 0,this.view=void 0,this.clearSandbox()}clearSandbox(){this.scrollNonce=``,this.sandboxHost?.dispose(),this.sandboxHost=void 0,this.promptPort?.close(),this.promptPort=void 0,this.releaseTheme?.(),this.releaseTheme=void 0,this.contentHeight=void 0}sameOwner(e){let t=this.context?.gateway,n=t?.snapshot;return!(!e||!t||!n||e.client!==n.client||e.docId!==this.docId||e.sessionKey!==this.sessionKey||e.connectionRevision!==t.connectionRevision||e.gatewayUrl!==t.connection.gatewayUrl||n.lastErrorAuthReason||n.phase===`stopped`||n.phase===`connected`&&(e.profileId&&n.selfUser?.id&&e.profileId!==n.selfUser.id||e.recoveryScope!==n.hello?.auth?.recoveryScope||!m(n.hello?.auth??null)))}isCurrent(e){return this.sameOwner(e)&&this.isConnected&&this.binding===e&&a(this.context.gateway.snapshot)&&e.generation===c()}willUpdate(){let e=this.context?.gateway,t=e?.snapshot.client;if((this.binding&&!this.sameOwner(this.binding)||this.viewOwner&&!this.sameOwner(this.viewOwner))&&this.clearView(),!e||!t||!this.docId){this.clearView();return}if(!a(e.snapshot)){this.binding=void 0,this.clearRetry(),this.validated=void 0,this.sandboxHost?.setActive(!1),this.pending=!0;return}if(!m(e.snapshot.hello?.auth??null)){this.error=f(`board.widget.sandboxUnavailable`);return}let n=e.snapshot.selfUser?.id;n&&(this.binding&&!this.binding.profileId&&(this.binding.profileId=n),this.viewOwner&&!this.viewOwner.profileId&&(this.viewOwner.profileId=n));let r=c();if(this.binding?.generation===r)return;this.clearRetry(),this.validated=void 0,this.error=``;let i={client:t,docId:this.docId,sessionKey:this.sessionKey,generation:r,connectionRevision:e.connectionRevision,gatewayUrl:e.connection.gatewayUrl,profileId:e.snapshot.selfUser?.id??this.viewOwner?.profileId??null,recoveryScope:e.snapshot.hello?.auth?.recoveryScope};this.binding=i,this.pending=!!this.view,this.slowTimer=window.setTimeout(()=>{this.isCurrent(i)&&(this.pending=!0)},K),J(i).then(e=>{if(!this.isCurrent(i))return;this.clearRetry();let t=this.view;t&&(t.html!==e.html||t.sandboxUrl!==e.sandboxUrl||t.sandboxPort!==e.sandboxPort||t.sandboxOrigin!==e.sandboxOrigin)&&(this.clearSandbox(),this.runtimeError=``,this.resourceError=!1,this.sandboxGeneration+=1),this.view=e,this.viewOwner=i,this.validated=i,this.pending=!1,this.retryDelayMs=1e3,this.sandboxHost?.setActive(!0)}).catch(t=>{if(this.isCurrent(i)){if(this.clearRetry(),l(t,e.snapshot)||t instanceof j||t instanceof T&&t.gatewayCode===`UNAVAILABLE`&&t.retryable){this.scheduleRetry(i,t instanceof T?t.retryAfterMs:void 0);return}this.view=void 0,this.clearSandbox(),this.pending=!1,this.error=d(t)}})}updated(){let e=this.querySelector(`iframe`),t=this.view,n=this.binding;this.allowScripts&&e&&t&&this.isCurrent(n)&&!this.sandboxHost&&(this.releaseTheme=ne(e,this.sandboxOrigin),this.scrollNonce=N(),this.sandboxHost=new W({frame:e,sandboxOrigin:this.sandboxOrigin,sandboxUrl:e.src,documentKey:`${n.docId}\0${n.generation}`,loadDocument:async()=>t.html,onLoaded:()=>{this.pending=!1,this.postHostState()},onRendered:()=>this.postHostState(),onError:e=>{this.clearSandbox(),this.error=d(e)},onReadyTimeout:()=>{this.pending=!0},onPending:()=>{this.pending=!0}}))}postHostState(){let e=this.sandboxHost?.frame;e&&(I(e,this.sandboxOrigin),e.contentWindow?.postMessage({type:`openclaw:widget-chat-host`},this.sandboxOrigin),e.contentWindow?.postMessage({type:`openclaw:widget-board-host`,nonce:this.scrollNonce},this.sandboxOrigin))}render(){if(this.error)return v`<div class="board-widget__error" role="alert"> ${this.error} <button class="btn btn--small" @click=${()=>{this.clearView(),this.requestUpdate()}} > ${f(`common.retry`)} </button> </div>`;if(!this.view||!this.context)return this.pending?v`<div class="board-widget__notice" role="status" style=${`min-height:${this.preferredHeight??420}px`} > ${f(`board.widget.waitingForConnection`)} </div>`:v`<div class="skeleton" role="status" aria-label=${f(`common.loading`)} style=${`min-height:${this.preferredHeight??420}px`} ></div>`;let e;try{this.allowScripts&&(e=q(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 v`<div role="alert">${d(e)}</div>`}let t=this.contentHeight??this.preferredHeight;return S(this.sandboxGeneration,v`${this.pending?v`<div class="board-widget__notice" role="status">${f(`board.widget.waitingForConnection`)}</div>`:_}${this.resourceError?v`<div class="board-widget__notice" role="status"> ${f(`board.widget.resourceUnavailable`)} <button class="btn btn--small" @click=${()=>{this.clearView(),this.requestUpdate()}} > ${f(`common.retry`)} </button> </div>`:_}${this.runtimeError?v`<div class="board-widget__notice" role="status">${f(`board.widget.runtimeError`,{message:this.runtimeError})}</div>`:_}<iframe class="chat-tool-card__preview-frame" title=${this.title} src=${e??_} srcdoc=${this.allowScripts?_:this.view.html} sandbox=${this.allowScripts?`allow-scripts allow-same-origin allow-forms`:``} referrerpolicy="origin" style=${t?`height:${t}px;min-height:${t}px`:_} @error=${()=>this.sandboxHost?.handleFrameError()} ></iframe>`)}},M([O({context:h,subscribe:!0})],Q.prototype,`context`,void 0),M([x()],Q.prototype,`docId`,void 0),M([x()],Q.prototype,`sessionKey`,void 0),M([x({type:Number})],Q.prototype,`messageTimestamp`,void 0),M([x()],Q.prototype,`title`,void 0),M([x({type:Number})],Q.prototype,`preferredHeight`,void 0),M([x({type:Number})],Q.prototype,`connectionGeneration`,void 0),M([C()],Q.prototype,`view`,void 0),M([C()],Q.prototype,`error`,void 0),M([C()],Q.prototype,`runtimeError`,void 0),M([C()],Q.prototype,`resourceError`,void 0),M([C()],Q.prototype,`contentHeight`,void 0),M([C()],Q.prototype,`pending`,void 0),M([x({type:Boolean})],Q.prototype,`allowScripts`,null),customElements.get(`openclaw-canvas-widget-view`)||customElements.define(`openclaw-canvas-widget-view`,Q)})))()}$();export{Q as OpenClawCanvasWidgetView};