UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

70 lines 10.7 kB
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{Kn as t,Qi as n,R as r,ea as i,wr as a,z as o}from"./control-ui-foundation-Cydpkyqa.js";import{E as s,Eo as c,Oo as l,Sc as u,bc as ee,cr as te,k as d,lr as f,sr as ne}from"./control-ui-core-Rwzhj6nO.js";import{$ as re,K as p,X as m,at as h,q as g}from"./lit-runtime-CV_MH99K.js";import{_,_n as v,g as ie,jn as ae}from"./control-ui-core-YphAl4aM.js";import{Nt as oe,Pt as se,Yt as ce,en as y}from"./control-ui-core-vvcQQV2m.js";import{B as le,U as b,V as x,z as S}from"./control-ui-boot-shared-BYq7Cchl.js";import{Dr as C,Er as w,Or as T,Tr as E,bt as D,kr as O,wr as k}from"./control-ui-boot-shared-DfZ39Yj9.js";import{$ as A,J as j,L as M,Q as N,V as P}from"./control-ui-boot-chat-_QSl8fbH.js";import{bt as F,yt as I}from"./control-ui-boot-chat-Cgwe4GEM.js";import{Is as L,Ls as R,hs as z,ms as ue}from"./control-ui-boot-shared-CXVvK2AW.js";import{n as B,t as V}from"./stream-auto-follow-controller-DQpG-yCd.js";import{n as H,t as U}from"./settings-workspace-Bseic8Tf.js";function de(e){let t=[];for(let n of Object.keys(e)){if(!/^\d+$/.test(n))continue;let r=e[n];typeof r==`string`?t.push(r):r!=null&&t.push(JSON.stringify(r))}return t.join(` `)}function W(e){if(typeof e!=`string`||!e.trimStart().startsWith(`{`))return{};try{let t=JSON.parse(e);return{subsystem:typeof t.subsystem==`string`?t.subsystem:void 0,module:typeof t.module==`string`?t.module:void 0,plugin:typeof t.plugin==`string`?t.plugin:void 0}}catch{return{}}}function fe(e,t){let n=W(t?.name),r=W(e[0]);return{subsystem:n.subsystem??r.subsystem,module:n.module??r.module,plugin:n.plugin??r.plugin}}function pe(e){try{let n=JSON.parse(e);if(!t(n))return null;let r=t(n._meta)?n._meta:void 0,a=fe(n,r),o=typeof r?.logLevelName==`string`?r.logLevelName:void 0;return{time:typeof n.time==`string`?n.time:typeof r?.date==`string`?r.date:void 0,level:i(o),subsystem:a.subsystem,module:a.module,plugin:a.plugin,message:typeof n.message==`string`?n.message:de(n),raw:e}}catch{return null}}function G(){return(G=e((()=>{})))()}function me(e){if(typeof e!=`string`)return null;let t=n(e);return q.has(t)?t:null}function he(e){let t=pe(e);if(!t)return{raw:e,message:F(e)};let n=t.subsystem??t.module;return{raw:t.raw,time:t.time??null,level:me(t.level),subsystem:n?F(n):null,message:F(t.message)}}var K,q;function J(){return(J=e((()=>{I(),G(),K={trace:!0,debug:!0,info:!0,warn:!0,error:!0,fatal:!0},q=new Set([`trace`,`debug`,`info`,`warn`,`error`,`fatal`])})))()}function ge(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?e:s(t.getTime(),void 0,e)}function _e(e,t){return!t||n([e.message,e.subsystem,e.raw].filter(Boolean).join(` `)).includes(t)}function ve(e){let t=n(e.filterText),r=Y.some(t=>!e.levelFilters[t]),i=e.entries.filter(n=>n.level&&!e.levelFilters[n.level]?!1:_e(n,t)),a=t||r?`filtered`:`visible`,o=y(`gatewayLogs.exportLabels.${a}`),s=e.status.hasLoaded?i.length===0?P(y(`gatewayLogs.empty`)):i.map(e=>m` <div class="log-row"> <div class="log-time mono">${ge(e.time)}</div> <div class="log-level ${e.level??``}">${e.level??``}</div> <div class="log-subsystem mono">${e.subsystem??``}</div> <div class="log-message mono">${e.message??e.raw}</div> </div> `):e.loading?se():g;return m` <div class="settings-section__header"> <h2 class="settings-section__heading">${y(`gatewayLogs.title`)}</h2> <div class="settings-section__actions"> <button class="btn" ?disabled=${e.refreshDisabled} @click=${e.onRefresh}> ${e.loading?y(`common.loading`):y(`common.refresh`)} </button> <button class="btn" ?disabled=${i.length===0} @click=${()=>e.onExport(i.map(e=>e.raw),a)} > ${y(`gatewayLogs.exportButton`,{label:o})} </button> </div> </div> <p class="settings-section__desc">${y(`gatewayLogs.subtitle`)}</p> ${O({status:e.status,onRetry:e.onRefresh,retryDisabled:e.refreshDisabled,className:`logs-refresh-status`})} <div class="settings-group logs-card"> ${j({title:y(`gatewayLogs.filter`),description:e.file?y(`gatewayLogs.file`,{file:e.file}):void 0,control:m` <input class="settings-input" aria-label=${y(`gatewayLogs.filter`)} .value=${e.filterText} @input=${t=>e.onFilterTextChange(t.target.value)} placeholder=${y(`gatewayLogs.searchPlaceholder`)} /> `})} <div class="settings-row"> <div class="chip-row"> ${Y.map(t=>m` <label class="chip log-chip ${t}"> <input type="checkbox" .checked=${e.levelFilters[t]} @change=${n=>e.onLevelToggle(t,n.target.checked)} /> <span>${t}</span> </label> `)} </div> <div class="settings-row__control"> ${A({checked:e.autoFollow,ariaLabel:y(`gatewayLogs.autoFollow`),onChange:t=>e.onToggleAutoFollow(t)})} <span class="settings-row__value">${y(`gatewayLogs.autoFollow`)}</span> </div> </div> ${e.truncated?m` <div class="settings-row"> ${N({kind:`warn`,label:y(`gatewayLogs.truncated`)})} </div> `:g} <div class="log-stream" @scroll=${e.onScroll}>${s}</div> </div> `}var Y;function X(){return(X=e((()=>{p(),oe(),T(),M(),ce(),d(),Y=[`trace`,`debug`,`info`,`warn`,`error`,`fatal`]})))()}var Z,Q;function $(){return($=e((()=>{o(),S(),p(),re(),v(),_(),T(),U(),l(),te(),R(),u(),z(),B(),J(),X(),Z=2e3,Q=class extends ee{constructor(...e){super(...e),this.logsStatus=w(),this.logsFile=null,this.logsEntries=[],this.logsFilterText=``,this.logsLevelFilters={...K},this.logsAutoFollow=!0,this.logsTruncated=!1,this.logsCursor=null,this.logsLimit=500,this.logsMaxBytes=25e4,this.polling=new ue(this,Z,()=>{this.loadLogs({quiet:!0})},!1),this.contentScrollFrame=null,this.logsTaskQuiet=!1,this.logsTask=new le(this,{autoRun:!1,args:()=>this.logsTaskArgs(),task:async([e,t,n,r,i,a],{signal:o})=>{if(!e||!t)return x;try{let e=e=>t.request(`logs.tail`,{cursor:e,limit:this.logsLimit,maxBytes:this.logsMaxBytes},{signal:o}),s=await e(i?void 0:n??void 0),c=!i&&r!==null&&s.file!==void 0&&s.file!==r;return c&&(s=await e()),{ok:!0,payload:s,cursor:n,reset:i||c,quiet:a}}catch(e){return{ok:!1,error:e,quiet:a}}},onComplete:e=>{if(!e.ok){f(e.error)?(this.logsEntries=[],this.logsStatus=C(w(),ne(`logs`))):this.logsStatus=C(this.logsStatus,c(e.error));return}let t=(Array.isArray(e.payload.lines)?e.payload.lines.filter(e=>typeof e==`string`):[]).map(he),n=e.reset||e.payload.reset||e.cursor==null;this.logsEntries=n?t:[...this.logsEntries,...t].slice(-2e3),this.logsCursor=typeof e.payload.cursor==`number`?e.payload.cursor:this.logsCursor,this.logsFile=typeof e.payload.file==`string`?e.payload.file:this.logsFile,this.logsTruncated=!!e.payload.truncated,this.logsStatus=E()}}),this.gateway=new L(this,{getGateway:()=>this.context?.gateway,onIdentityChange:()=>{this.logsStatus=w(),this.logsFile=null,this.logsEntries=[],this.logsTruncated=!1,this.logsCursor=null,this.streamFollow.atBottom=!0},invalidateRequests:()=>{this.logsTaskQuiet=!1,this.logsTask.run([null,null,null,null,!1,!1])},onSnapshot:()=>this.syncPolling(),ensureInitialData:()=>{let e=this.logsStatus.hasLoaded;this.loadLogs({reset:!0,quiet:e}).then(t=>{t&&!e&&this.streamFollow.schedule(!0)})}}),this.streamFollow=new V(this,{selector:`.log-stream`,isEnabled:()=>this.logsAutoFollow,captureCurrent:()=>{let e=this.gateway.gateway,t=this.gateway.epoch;return()=>this.isConnected&&this.gateway.connected&&e!==null&&this.gateway.gateway===e&&this.context.gateway===e&&this.gateway.epoch===t}})}logsTaskArgs(e){return[this.gateway.connected?this.gateway.gateway:null,this.gateway.connected?this.gateway.client:null,e?.reset?null:this.logsCursor,this.logsFile,e?.reset===!0,e?.quiet===!0]}firstUpdated(){this.resetContentScroll(),this.contentScrollFrame=requestAnimationFrame(()=>{this.contentScrollFrame=null,this.resetContentScroll()})}updated(e){let t=this.logsAutoFollow&&e.has(`logsAutoFollow`);(t||this.logsAutoFollow&&this.streamFollow.atBottom&&e.has(`logsEntries`))&&this.streamFollow.schedule(t)}disconnectedCallback(){this.logsTaskQuiet=!1,this.logsTask.run([null,null,null,null,!1,!1]),this.contentScrollFrame!==null&&(cancelAnimationFrame(this.contentScrollFrame),this.contentScrollFrame=null),super.disconnectedCallback()}resetContentScroll(){let e=this.closest(`.content`);e&&(e.scrollTop=0,e.scrollLeft=0)}syncPolling(){if(!this.gateway.connected||!this.gateway.client){this.polling.stop();return}this.polling.start()}async loadLogs(e){let t=e?.quiet===!0,n=this.gateway.gateway;if(!n||!this.gateway.client||!this.gateway.connected||this.context.gateway!==n||this.logsTask.status===b.PENDING&&e?.reset!==!0)return!1;this.logsTaskQuiet=t,this.logsStatus=k(this.logsStatus,{clearError:!t});let r=this.gateway.epoch;return await this.logsTask.run(this.logsTaskArgs(e)),this.gateway.epoch===r&&this.logsTask.status===b.COMPLETE}render(){let e=ve({loading:this.logsTask.status===b.PENDING&&!this.logsTaskQuiet,refreshDisabled:!this.gateway.connected||this.logsTask.status===b.PENDING,status:this.logsStatus,file:this.logsFile,entries:this.logsEntries,filterText:this.logsFilterText,levelFilters:this.logsLevelFilters,autoFollow:this.logsAutoFollow,truncated:this.logsTruncated,onFilterTextChange:e=>this.logsFilterText=e,onLevelToggle:(e,t)=>{this.logsLevelFilters={...this.logsLevelFilters,[e]:t}},onToggleAutoFollow:e=>this.logsAutoFollow=e,onRefresh:()=>void this.loadLogs({reset:!0}).then(e=>{e&&this.streamFollow.schedule(!0)}),onExport:(e,t)=>{let n=new Date().toISOString().slice(0,19).replace(/[:T]/g,`-`);D(`openclaw-logs-${t}-${n}.log`,`${e.join(` `)}\n`)},onScroll:e=>this.streamFollow.handleScroll(e)});return m` <section class="content-header"> <div> <div class="page-title">${ae(`logs`)}</div> </div> </section> ${H(e,{fillHeight:!0})} `}},a([r({context:ie,subscribe:!0})],Q.prototype,`context`,void 0),a([h()],Q.prototype,`logsStatus`,void 0),a([h()],Q.prototype,`logsFile`,void 0),a([h()],Q.prototype,`logsEntries`,void 0),a([h()],Q.prototype,`logsFilterText`,void 0),a([h()],Q.prototype,`logsLevelFilters`,void 0),a([h()],Q.prototype,`logsAutoFollow`,void 0),a([h()],Q.prototype,`logsTruncated`,void 0),customElements.get(`openclaw-logs-page`)||customElements.define(`openclaw-logs-page`,Q)})))()}$(); //# sourceMappingURL=logs-page-C7pdtI3B.js.map