UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

192 lines 15.6 kB
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{wr as t}from"./control-ui-foundation-Cydpkyqa.js";import{E as n,Sc as r,T as i,an as a,b as o,bc as s,in as c,k as l,rn as u}from"./control-ui-core-Rwzhj6nO.js";import{$ as d,C as f,K as p,X as m,at as h,b as g,q as _,r as v,st as y,t as b}from"./lit-runtime-CV_MH99K.js";import{Gt as x,Ht as S,Wt as C,Yt as w,Z as T,en as E}from"./control-ui-core-vvcQQV2m.js";import{dn as D,un as O}from"./control-ui-boot-shared-DfZ39Yj9.js";import{cn as k,ln as A,sn as j,un as M}from"./control-ui-boot-chat-_QSl8fbH.js";import{Go as N,Ko as P}from"./control-ui-boot-shared-CXVvK2AW.js";function F(e){return e.digest?e.running?e.activeRunId&&e.digest.runId===e.activeRunId?e.digest:null:e.digest:null}function I(e,t){return(e.health===`done`||e.health===`failed`)&&(t??0)<e.updatedAt}function L(e){return E(`chat.rail.health.${e}`)}function R(e){return E(`chat.pullRequests.${e===`draft`?`draft`:e}`)}function z(e){let t=e.checks;return t?t.state===`passing`?E(`chat.rail.checksPassing`,{count:String(t.passed)}):t.state===`failing`?E(`chat.rail.checksFailing`,{count:String(t.failed)}):E(`chat.rail.checksPending`,{count:String(t.running)}):null}function B(e){return e.exchanges.length>0||e.pendingQuestion!==null||e.failedQuestion!==null||e.draft.length>0}function V(e){return W[e]}var H,U,W,G;function K(){return(K=e((()=>{p(),d(),g(),b(),x(),O(),A(),j(),S(),T(),w(),l(),P(),r(),u(),H=class{constructor(e=c()){this.displayPreference=e,this.autoExpandedRunIds=new Set,this.autoExpandedRunId=null,this.transientExpanded=!1,this.manualOpen=!1}resetTransientState(){this.transientExpanded=!1,this.autoExpandedRunId=null,this.manualOpen=!1}tryAutoOpen(){return this.displayPreference!==`off`&&(this.transientExpanded=!0,!0)}mode(e){let t=F(e),n=t!==null&&(e.running||I(t,e.lastReadAt))||e.hasCompanionActivity||this.manualOpen||this.transientExpanded;if(this.displayPreference===`off`||!n)return this.autoExpandedRunId=null,`hidden`;let r=e.activeRunId??t?.runId??null;return(t?.health===`stuck`||t?.health===`waiting-on-user`)&&r&&!this.autoExpandedRunIds.has(r)&&(this.autoExpandedRunIds.add(r),this.autoExpandedRunId=r),this.displayPreference===`card`||this.transientExpanded||r!==null&&this.autoExpandedRunId===r?`expanded`:`pill`}expand(){this.displayPreference=`card`,this.transientExpanded=!1,this.autoExpandedRunId=null,a(`card`)}collapse(){this.displayPreference=`pill`,this.transientExpanded=!1,this.autoExpandedRunId=null,this.manualOpen=!1,a(`pill`)}hide(){this.displayPreference=`off`,this.resetTransientState(),a(`off`)}openExplicitly(){this.displayPreference=`pill`,this.transientExpanded=!0,this.autoExpandedRunId=null,this.manualOpen=!0,a(`pill`)}},U=[`changed`,`stopped`,`remaining`],W={busy:`chat.rail.askBusy`,"history-unavailable":`chat.rail.askHistoryUnavailable`,missing:`chat.rail.askMissing`,"model-unavailable":`chat.rail.askModelUnavailable`,"rate-limited":`chat.rail.askRateLimited`,unavailable:`chat.rail.askUnavailable`},G=class extends s{constructor(...e){super(...e),this.sessionKey=``,this.digest=null,this.running=!1,this.activeRunId=null,this.pullRequests=[],this.companion={exchanges:[],loading:!1,pendingQuestion:null,failedQuestion:null,hint:null,retryable:!1,draft:``},this.connected=!1,this.command=null,this.consumedCommandGeneration=0,this.embedded=!1,this.now=Date.now(),this.railState=new H,this.clock=null,this.renderedMode=`hidden`,this.reportedMode=null,this.terminalAgeReference=Date.now()}disconnectedCallback(){this.stopClock(),super.disconnectedCallback()}willUpdate(e){e.has(`sessionKey`)&&(this.terminalAgeReference=Date.now(),this.railState.resetTransientState()),e.has(`digest`)&&this.digest&&(this.digest.health===`done`||this.digest.health===`failed`)&&(this.terminalAgeReference=Date.now()),e.has(`command`)&&this.applyPaneCommand()}applyPaneCommand(){let e=this.command;if(!(!e||e.generation<=this.consumedCommandGeneration)){if(this.onCommandConsumed?.(e.generation),e.intent===`open`){this.railState.tryAutoOpen()&&this.onVisibilityChange?.(!0);return}if(this.renderedMode===`expanded`){this.railState.collapse();return}this.railState.openExplicitly(),this.onVisibilityChange?.(!0)}}updated(){this.running&&this.startedAt!=null&&F(this.input())?this.scheduleClock():this.stopClock(),this.reportedMode!==this.renderedMode&&(this.reportedMode=this.renderedMode,this.onModeChange?.(this.renderedMode))}input(){return{running:this.running,activeRunId:this.activeRunId,digest:this.digest,lastReadAt:this.lastReadAt,hasCompanionActivity:B(this.companion)}}scheduleClock(){this.clock===null&&(this.clock=globalThis.setTimeout(()=>{this.clock=null,this.now=Date.now()},1e3))}stopClock(){this.clock!==null&&(globalThis.clearTimeout(this.clock),this.clock=null)}collapse(){this.railState.collapse(),this.requestUpdate()}expand(){this.railState.expand(),this.requestUpdate()}hide(){this.railState.hide(),this.onVisibilityChange?.(!1),this.requestUpdate()}submit(){let e=this.companion.draft.trim();!e||!this.connected||this.companion.pendingQuestion||!this.onSubmit||this.onSubmit(e)}renderStatus(e){let t=e.health===`done`||e.health===`failed`,n=e.health===`stuck`||e.health===`waiting-on-user`;return m` <span class="chat-session-rail__status ${n?`chat-session-rail__status--critical`:``}" data-health=${e.health} > ${t?m`<span class="chat-session-rail__status-icon" aria-hidden="true" >${e.health===`done`?C.check:C.x}</span >`:m`<span class="chat-session-rail__status-dot" aria-hidden="true"></span>`} <span>${L(e.health)}</span> </span> `}renderPullRequests(){let e=this.pullRequests.slice(0,2);return e.length===0?_:m` <div class="chat-session-rail__prs" aria-label=${E(`chat.rail.pullRequests`)}> ${e.map(e=>{let t=z(e);return m` <a class="chat-session-rail__pr" href=${e.url} target="_blank" rel="noopener noreferrer" title=${e.title} > <span>#${e.number}</span> <span>${R(e.state)}</span> ${t?m`<span class="chat-session-rail__pr-checks">${t}</span>`:_} </a> `})} </div> `}renderDigestDetails(e){return e?m` ${e.assessment?m`<p class="chat-session-rail__assessment">${e.assessment}</p>`:_} ${this.renderPullRequests()} `:_}renderExchange(e,t,r){return m` <article class="chat-session-rail__exchange"> <div class="chat-session-rail__question" dir=${N(e)}> ${e} </div> <div class="chat-session-rail__answer" dir=${N(t)}> ${v(D(t))} </div> <time class="chat-session-rail__timestamp" datetime=${new Date(r).toISOString()}> ${E(`chat.rail.asOf`,{time:n(r,{hour:`numeric`,minute:`2-digit`},``)})} </time> </article> `}renderStarters(){let e=!this.connected||this.companion.pendingQuestion!==null;return m` <div class="chat-session-rail__starters"> ${U.map(t=>{let n=E(`chat.rail.starters.${t}`);return m` <button class="chip chat-session-rail__starter" type="button" ?disabled=${e} @click=${()=>this.onSubmit?.(n)} > ${C.spark}<span>${n}</span> </button> `})} </div> `}renderThread(){let e=`${this.companion.exchanges.length}:${this.companion.pendingQuestion??``}:${this.companion.failedQuestion??``}`;return m` <div class="chat-session-rail__thread" aria-live="polite" ${f(t=>{!(t instanceof HTMLElement)||t.dataset.railScrollKey===e||(t.dataset.railScrollKey=e,t.scrollTop=t.scrollHeight)})}> ${this.companion.loading&&this.companion.exchanges.length===0?k(`chat`,E(`chat.thread.loading`)):_} ${!this.companion.loading&&this.companion.exchanges.length===0&&!this.companion.pendingQuestion?M({icon:C.bot,heading:E(`chat.sidePanel.companion`),description:E(`chat.rail.empty`)}):_} ${this.companion.exchanges.map(e=>this.renderExchange(e.question,e.answer,e.ts))} ${this.companion.failedQuestion&&this.companion.hint?m` <article class="chat-session-rail__exchange chat-session-rail__exchange--error"> <div class="chat-session-rail__question">${this.companion.failedQuestion}</div> <div class="chat-session-rail__hint"> ${E(V(this.companion.hint))} </div> ${this.companion.retryable&&this.connected&&this.onSubmit?m` <button class="btn btn--secondary chat-session-rail__retry" type="button" @click=${()=>this.onSubmit?.(this.companion.failedQuestion??``)} > ${E(`chat.rail.askRetry`)} </button> `:_} </article> `:_} ${this.companion.pendingQuestion?m` <article class="chat-session-rail__exchange chat-session-rail__exchange--pending"> <div class="chat-session-rail__question">${this.companion.pendingQuestion}</div> <div class="chat-session-rail__hint">${E(`chat.rail.askPending`)}</div> </article> `:_} </div> `}render(){let e=this.input(),t=this.embedded?`expanded`:this.railState.mode(e);if(this.renderedMode=t,t===`hidden`)return _;let n=F(e);if(t===`pill`)return m` <div class="chat-session-rail chat-session-rail--pill" aria-live="polite"> ${n?this.renderStatus(n):_} <button class="chat-session-rail__expand" type="button" aria-label=${E(`chat.rail.expand`)} @click=${()=>this.expand()} > <span class="chat-session-rail__headline" >${n?.headline??E(`chat.rail.title`)}</span > </button> <button class="btn btn--ghost btn--icon chat-icon-btn chat-session-rail__hide" type="button" aria-label=${E(`chat.rail.close`)} @click=${()=>this.hide()} > ${C.x} </button> <button class="btn btn--ghost btn--icon chat-icon-btn chat-session-rail__toggle" type="button" aria-label=${E(`chat.rail.expand`)} @click=${()=>this.expand()} > ${C.chevronDown} </button> </div> `;let r=this.running&&this.startedAt!=null?o(Math.max(0,this.now-this.startedAt)):null,a=n&&(n.health===`done`||n.health===`failed`)?E(`chat.rail.finished`,{time:i(Math.max(0,this.terminalAgeReference-n.updatedAt))}):null;return m` <section class="chat-session-rail chat-session-rail--expanded ${this.embedded?`chat-session-rail--embedded`:``}" role="region" aria-label=${E(`chat.rail.title`)} tabindex="-1" @keydown=${e=>{!this.embedded&&e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),this.collapse())}} > ${this.embedded?_:m`<header class="rail-header chat-session-rail__header"> <div class="rail-header__copy chat-session-rail__header-copy"> <div class="chat-session-rail__status-row"> ${n?this.renderStatus(n):m`<strong>${E(`chat.rail.title`)}</strong>`} ${r?m`<span class="chat-session-rail__timing">${r}</span>`:a?m`<span class="chat-session-rail__timing">${a}</span>`:_} </div> ${n?m`<strong class="chat-session-rail__headline" >${n.headline}</strong >`:m`<span class="chat-session-rail__subtitle" >${E(`chat.rail.subtitle`)}</span >`} </div> <div class="rail-header__actions chat-session-rail__actions"> <button class="rail-header__action chat-session-rail__hide" type="button" aria-label=${E(`chat.rail.close`)} @click=${()=>this.hide()} > ${C.x} </button> <button class="rail-header__action chat-session-rail__toggle" type="button" aria-label=${E(`chat.rail.collapse`)} @click=${()=>this.collapse()} > ${C.chevronUp} </button> </div> </header>`} ${n?m`<div class="chat-session-rail__digest">${this.renderDigestDetails(n)}</div>`:_} ${this.renderThread()} ${this.companion.exchanges.length===0&&!this.companion.pendingQuestion?this.renderStarters():_} <form class="agent-chat__input chat-session-rail__composer" @submit=${e=>{e.preventDefault(),this.submit()}} > <div class="agent-chat__composer-input-row"> <label class="agent-chat__composer-combobox chat-session-rail__prompt"> <input class="chat-session-rail__input" type="text" maxlength="400" autocomplete="off" aria-label=${E(`chat.rail.askLabel`)} .value=${this.companion.draft} placeholder=${this.companion.pendingQuestion?E(`chat.rail.askPending`):E(`chat.rail.askPlaceholder`)} ?disabled=${!this.connected||this.companion.pendingQuestion!==null} @input=${e=>{this.onDraftChange?.(e.currentTarget.value)}} /> </label> </div> <div class="agent-chat__composer-footer"> <div class="agent-chat__composer-trail"> <div class="agent-chat__composer-actions"> <button class="chat-send-btn" type="submit" aria-label=${E(`chat.rail.askSubmit`)} ?disabled=${!this.connected||this.companion.pendingQuestion!==null||!this.companion.draft.trim()} > ${C.arrowUp} </button> </div> </div> </div> </form> </section> `}},t([y({attribute:!1})],G.prototype,`sessionKey`,void 0),t([y({attribute:!1})],G.prototype,`digest`,void 0),t([y({attribute:!1})],G.prototype,`running`,void 0),t([y({attribute:!1})],G.prototype,`activeRunId`,void 0),t([y({attribute:!1})],G.prototype,`startedAt`,void 0),t([y({attribute:!1})],G.prototype,`lastReadAt`,void 0),t([y({attribute:!1})],G.prototype,`pullRequests`,void 0),t([y({attribute:!1})],G.prototype,`companion`,void 0),t([y({attribute:!1})],G.prototype,`connected`,void 0),t([y({attribute:!1})],G.prototype,`command`,void 0),t([y({attribute:!1})],G.prototype,`consumedCommandGeneration`,void 0),t([y({attribute:!1})],G.prototype,`onCommandConsumed`,void 0),t([y({attribute:!1})],G.prototype,`onSubmit`,void 0),t([y({attribute:!1})],G.prototype,`onDraftChange`,void 0),t([y({attribute:!1})],G.prototype,`onModeChange`,void 0),t([y({attribute:!1})],G.prototype,`onVisibilityChange`,void 0),t([y({type:Boolean})],G.prototype,`embedded`,void 0),t([h()],G.prototype,`now`,void 0),customElements.get(`openclaw-chat-session-rail`)||customElements.define(`openclaw-chat-session-rail`,G)})))()}K();export{G as ChatSessionRailElement,H as ChatSessionRailState}; //# sourceMappingURL=chat-session-rail-BFM_PgRc.js.map