openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
1 lines • 10.6 kB
JavaScript
import{n as e}from"./rolldown-runtime-8BhlS34s.js";import{ao as t}from"./control-ui-foundation-ZY_Flbbd.js";import{hu as n,uu as r}from"./control-ui-core-3P365fbR.js";var i;function a(){return(a=e((()=>{i=class{constructor(e,t,n=()=>1){this.capacity=e,this.overflow=t,this.measure=n,this.values=[],this.head=0,this.size=0,this.closed=!1}push(e){if(this.closed)return!1;let t=this.measure(e);if(this.size+t<=this.capacity)return this.values.push(e),this.size+=t,!0;if(this.overflow.mode!==`drop-oldest`)return this.closed=!0,this.overflow.mode===`fail-closed`&&(this.drain(),this.overflow.onOverflow()),!1;for(this.values.push(e),this.size+=t;this.size>this.capacity&&this.head<this.values.length-1;){let e=this.values[this.head];this.size-=this.measure(e),this.values[this.head]=void 0,this.head+=1}if(this.size>this.capacity){let t=this.overflow.fit?.(e,this.capacity);this.values=t===void 0?[]:[t],this.head=0,this.size=t===void 0?0:this.measure(t)}else this.head*2>=this.values.length&&(this.values=this.values.slice(this.head),this.head=0);return!0}drain(){let e=this.head===0?this.values:this.values.slice(this.head);return this.values=[],this.head=0,this.size=0,e}}})))()}function o(e){for(let n of[`sessionId`,`agentId`,`shell`,`cwd`])if(!t(e[n]))return n;return null}function s(e){return e instanceof Error&&/^gateway request timed out after \d+ms: (?:terminal\.open|sessions\.catalog\.startTerminal)$/u.test(e.message)}function c(e){return e instanceof Error&&(e.message===`terminal open timed out`||s(e))}var l,u,d,f,p,m,h,g;function _(){return(_=e((()=>{a(),l=2e4,u=5e3,d=2,f=5e3,p=35e3,m=class extends Error{constructor(e){super(`terminal open timed out`,{cause:e}),this.name=`TerminalOpenTimeoutError`}},h=class extends Error{constructor(e){super(`terminal session response is missing ${e}`),this.field=e,this.name=`TerminalOpenUnusableSessionError`}},g=class e{static{this.MAX_PENDING_EVENTS=512}constructor(e){this.client=e,this.streams=new Map,this.pending=new Map,this.unsubscribe=null,this.disposed=!1,this.pendingOpenCount=0,this.livenessTimer=null,this.livenessProbeInFlight=!1,this.livenessProbeFailures=0,this.lastLivenessFailureActivityVersion=null,this.lastTerminalActivityAtMs=Date.now(),this.inboundActivityVersion=0}ensureSubscribed(){this.unsubscribe||=this.client.addEventListener(e=>{if(e.event===`terminal.data`){this.noteTerminalActivity();let t=e.payload;if(t?.sessionId&&typeof t.seq==`number`&&typeof t.data==`string`){let e={kind:`data`,seq:t.seq,data:t.data},n=this.streams.get(t.sessionId);n?this.deliverData(t.sessionId,n,e):this.bufferEarly(t.sessionId,e)}return}if(e.event===`terminal.exit`){this.noteTerminalActivity();let t=e.payload;if(t?.sessionId){let e={exitCode:t.exitCode??null,signal:t.signal??null,reason:t.reason,error:t.error},n=this.streams.get(t.sessionId);n&&!n.recovering?this.deliverExit(t.sessionId,n,e):this.bufferEarly(t.sessionId,{kind:`exit`,info:e})}}})}async open(e,t){return this.openRequest(`terminal.open`,e,t)}async start(e,t){return this.openRequest(`sessions.catalog.startTerminal`,e,t)}async openRequest(e,n,r){let i;try{i=await this.requestWhileHoldingStream(()=>this.client.request(e,n,{timeoutMs:p}))}catch(e){throw c(e)?(s(e)&&this.forceReconnect(`terminal open watchdog timeout`),new m(e)):e}let a=o(i);if(a)throw t(i.sessionId)&&this.close(i.sessionId),new h(a);if(this.disposed)return i;let l=this.setStream(i.sessionId,r,{seqMode:`unknown`,expectedSeq:0,recovering:!1});return this.flushPending(i.sessionId,l),this.scheduleLivenessCheck(),i}async attach(e,t){let n=await this.requestWhileHoldingStream(()=>this.client.request(`terminal.attach`,{sessionId:e})),r=o(n)??(typeof n.buffer==`string`?null:`buffer`);if(r)throw new h(r);let i=typeof n.seq==`number`&&Number.isSafeInteger(n.seq)?n.seq:null;if(this.disposed)return n;let a=this.setStream(e,t,{seqMode:i===null?`counter`:`offset`,expectedSeq:i,recovering:!0}),s=a.abort.signal;try{await t.onReplay({data:n.buffer,newlyObservedFrom:n.buffer.length,mode:`initial`,signal:s})}catch(t){throw s.aborted||(this.removeStream(e),this.pending.delete(e),this.maybeUnsubscribe()),t}return s.aborted?n:(a.recovering=!1,this.flushPending(e,a,i??void 0,!0),this.scheduleLivenessCheck(),n)}async list(){return(await this.client.request(`terminal.list`))?.sessions??[]}async requestWhileHoldingStream(e){this.ensureSubscribed(),this.pendingOpenCount+=1;try{let t=await e();return--this.pendingOpenCount,t}catch(e){throw--this.pendingOpenCount,this.maybeUnsubscribe(),e}}deliverData(e,t,n){if(t.recovering){this.bufferEarly(e,n);return}if(!Number.isSafeInteger(n.seq)){this.recoverGap(e,t,n);return}if(t.seqMode===`counter`){t.expectedSeq=n.seq+1,t.sink.onData(n.data);return}if(n.seq-n.data.length===t.expectedSeq){n.data.length>0&&(t.seqMode=`offset`),t.expectedSeq=n.seq,t.sink.onData(n.data);return}if(t.seqMode===`unknown`&&t.expectedSeq===0&&n.seq===0){t.seqMode=`counter`,t.expectedSeq=1,t.sink.onData(n.data);return}this.recoverGap(e,t,n)}recoverGap(e,t,n){if(t.recovering)return;t.recovering=!0;let r=t.abort.signal;this.client.request(`terminal.attach`,{sessionId:e}).then(async i=>{if(r.aborted)return;let a=typeof i.seq==`number`&&Number.isSafeInteger(i.seq)?i.seq:null;if(a===null){t.seqMode=`counter`,t.expectedSeq=null,t.recovering=!1,this.deliverData(e,t,n),this.flushPending(e,t,void 0,!0);return}let o=t.expectedSeq;t.seqMode=`offset`,t.expectedSeq=a;let s=a-i.buffer.length,c=typeof o==`number`?Math.max(0,Math.min(i.buffer.length,o-s)):0;await t.sink.onReplay({data:i.buffer,newlyObservedFrom:c,mode:`recovery`,signal:r}),!r.aborted&&(t.recovering=!1,this.flushPending(e,t,a,!0))}).catch(()=>{if(r.aborted)return;let i=this.pending.get(e)?.drain();if(i?.some(e=>e.kind===`exit`)){this.pending.delete(e),t.recovering=!1,t.sink.onData(n.data);for(let n of i)if(n.kind===`data`)t.sink.onData(n.data);else{this.deliverExit(e,t,n.info);break}return}t.recovering=!1,this.pending.delete(e),this.forceReconnect(`terminal replay failed`)})}flushPending(e,t,n,r=!1){let i=this.pending.get(e);if(!i)return;this.pending.delete(e);let a=i.drain();for(let i of a){if(this.streams.get(e)!==t)break;if(!(r&&i.kind===`exit`&&i.info.reason===`detached`)){if(i.kind===`data`){if(n!==void 0&&i.seq<=n)continue;this.deliverData(e,t,i)}else t.recovering?this.bufferEarly(e,i):this.deliverExit(e,t,i.info)}}}deliverExit(e,t,n){this.removeStream(e),t.sink.onExit(n),this.pending.delete(e),this.maybeUnsubscribe()}setStream(e,t,n){this.removeStream(e);let r={abort:new AbortController,sink:t,...n};return this.streams.set(e,r),this.lastTerminalActivityAtMs=Date.now(),r}removeStream(e){this.streams.get(e)?.abort.abort(),this.streams.delete(e)}bufferEarly(t,n){let r=this.pending.get(t)??new i(e.MAX_PENDING_EVENTS,{mode:`drop-oldest`});this.pending.set(t,r),r.push(n)}noteTerminalActivity(){this.resetLivenessProbeFailures(),this.lastTerminalActivityAtMs=Date.now(),this.inboundActivityVersion+=1}forceReconnect(e){this.resetLivenessProbeFailures(),this.client.forceReconnect(e)}resetLivenessProbeFailures(){this.livenessProbeFailures=0,this.lastLivenessFailureActivityVersion=null}scheduleLivenessCheck(e=l){this.livenessTimer||this.livenessProbeInFlight||this.streams.size===0||(this.livenessTimer=setTimeout(()=>{this.livenessTimer=null,this.checkLiveness()},Math.max(0,e)))}checkLiveness(){if(this.streams.size===0)return;let e=l-(Date.now()-this.lastTerminalActivityAtMs);if(e>0){this.scheduleLivenessCheck(e);return}let t=this.client.inboundActivitySeq??this.inboundActivityVersion;if(this.lastLivenessFailureActivityVersion!==null&&t!==this.lastLivenessFailureActivityVersion){this.resetLivenessProbeFailures(),this.lastTerminalActivityAtMs=Date.now(),this.scheduleLivenessCheck();return}let n=l;this.livenessProbeInFlight=!0,this.client.request(`terminal.list`,void 0,{timeoutMs:u}).then(()=>{this.resetLivenessProbeFailures(),this.lastTerminalActivityAtMs=Date.now()}).catch(()=>{if(this.streams.size===0){this.resetLivenessProbeFailures();return}let e=this.client.inboundActivitySeq??this.inboundActivityVersion;if(e!==t){this.resetLivenessProbeFailures(),this.lastTerminalActivityAtMs=Date.now();return}if(this.livenessProbeFailures+=1,this.lastLivenessFailureActivityVersion=e,this.livenessProbeFailures>=d){this.forceReconnect(`terminal liveness timeout`);return}n=f}).finally(()=>{this.livenessProbeInFlight=!1,this.scheduleLivenessCheck(n)})}async input(e,t){await this.requestAction(`terminal.input`,e,{sessionId:e,data:t})}async resize(e,t,n){await this.requestAction(`terminal.resize`,e,{sessionId:e,cols:t,rows:n})}async requestAction(e,t,n){let r=this.streams.get(t);(await this.client.request(e,n).catch(()=>null))?.ok===!1&&r&&this.streams.get(t)===r&&this.deliverExit(t,r,{exitCode:null,signal:null,reason:`disconnected`,error:`Terminal session is no longer available. Open a new terminal session.`})}async close(e){this.removeStream(e),this.pending.delete(e),await this.client.request(`terminal.close`,{sessionId:e}).catch(()=>void 0),this.pending.delete(e),this.maybeUnsubscribe()}get size(){return this.streams.size}dispose(){this.disposed=!0;for(let e of this.streams.values())e.abort.abort();this.streams.clear(),this.pending.clear(),this.stopLiveness(),this.dropSubscriptions()}maybeUnsubscribe(){this.streams.size===0&&this.pendingOpenCount===0&&(this.pending.clear(),this.stopLiveness(),this.dropSubscriptions())}stopLiveness(){this.resetLivenessProbeFailures(),this.livenessTimer&&=(clearTimeout(this.livenessTimer),null)}dropSubscriptions(){this.unsubscribe?.(),this.unsubscribe=null}}})))()}function v(e){x.delete(e),clearTimeout(e.expiry),e.connection.close(e.result.sessionId),e.connection.dispose()}async function y(e,t,r){if(!r())throw Error(n(`terminal.startCancelled`));let a=new g(e),o=new i(262144,{mode:`drop-oldest`,fit:(e,t)=>e.slice(-t)},e=>e.length),s=null,c=null;try{let i=await a.start(t,{onData:e=>s?s.onData(e):void o.push(e),onReplay:e=>{if(s)return s.onReplay(e);o.drain(),o.push(e.data)},onExit:e=>{c=e,s?.onExit(e)}});if(!r())throw a.close(i.sessionId),Error(n(`terminal.startCancelled`));if(x.size>=8){let e=x.values().next().value;e&&v(e)}let l={client:e,connection:a,result:i,expiry:setTimeout(()=>v(l),6e4),bind:e=>{s=e;for(let t of o.drain())e.onData(t);c&&e.onExit(c)}};return x.add(l),i}catch(e){throw a.dispose(),e}}function b(e,t){let n=[...x].find(n=>n.result.sessionId===e&&n.client===t);return n?(x.delete(n),clearTimeout(n.expiry),n):null}var x;function S(){return(S=e((()=>{a(),_(),r(),x=new Set})))()}export{m as a,i as c,g as i,a as l,y as n,h as o,b as r,_ as s,S as t};