stableclaw 2026.5.2 → 2026.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.buildstamp +1 -1
- package/dist/control-ui/apple-touch-icon.png +0 -0
- package/dist/control-ui/assets/agents-DIJiVfPj.js +813 -0
- package/dist/control-ui/assets/anthropic-BnQLajET.js +37 -0
- package/dist/control-ui/assets/azure-openai-responses-D6oH5P8v.js +2 -0
- package/dist/control-ui/assets/channel-config-extras-Cu8rP5sC.js +2 -0
- package/dist/control-ui/assets/channels-DMte0OdA.js +349 -0
- package/dist/control-ui/assets/cron-hM6tj-cg.js +928 -0
- package/dist/control-ui/assets/de-BzA7Smom.js +2 -0
- package/dist/control-ui/assets/debug-ChdgbieB.js +94 -0
- package/dist/control-ui/assets/directive-C6NBp6xJ.js +2 -0
- package/dist/control-ui/assets/es--sAce87o.js +2 -0
- package/dist/control-ui/assets/event-stream-B8X6sYaV.js +2 -0
- package/dist/control-ui/assets/format-nUIQxx1z.js +2 -0
- package/dist/control-ui/assets/github-copilot-headers-cUjskhp6.js +2 -0
- package/dist/control-ui/assets/google-DDYMjR2f.js +2 -0
- package/dist/control-ui/assets/google-gemini-cli-BBZpF1Bz.js +3 -0
- package/dist/control-ui/assets/google-shared-Brxly9jR.js +12 -0
- package/dist/control-ui/assets/google-vertex-moPkJqQt.js +2 -0
- package/dist/control-ui/assets/hash-BN8UQrrC.js +2 -0
- package/dist/control-ui/assets/index-DOMg2RvO.css +1 -0
- package/dist/control-ui/assets/index-hSu8pNmQ.js +4841 -0
- package/dist/control-ui/assets/instances-BO-5LU4G.js +57 -0
- package/dist/control-ui/assets/lit-zdTgzAJI.js +3 -0
- package/dist/control-ui/assets/logs-CaFT90eM.js +74 -0
- package/dist/control-ui/assets/mistral-yMnz8nsP.js +8 -0
- package/dist/control-ui/assets/nodes-6XxETMb5.js +430 -0
- package/dist/control-ui/assets/openai-CQsomflW.js +17 -0
- package/dist/control-ui/assets/openai-codex-responses-DXqDuiSK.js +8 -0
- package/dist/control-ui/assets/openai-completions-Bme8q7yw.js +6 -0
- package/dist/control-ui/assets/openai-responses-DpESo9k8.js +2 -0
- package/dist/control-ui/assets/openai-responses-shared-CjacPL_h.js +11 -0
- package/dist/control-ui/assets/preload-helper-xBbMyY7u.js +1 -0
- package/dist/control-ui/assets/preview-Ca6p7-4-.js +2 -0
- package/dist/control-ui/assets/pt-BR-DkjnRLn3.js +2 -0
- package/dist/control-ui/assets/sessions-USutdtjY.js +236 -0
- package/dist/control-ui/assets/skills-DLY8KTEh.js +216 -0
- package/dist/control-ui/assets/skills-shared-DUfo2UBp.js +11 -0
- package/dist/control-ui/assets/transform-messages-Lu1Q3cQf.js +2 -0
- package/dist/control-ui/assets/zh-CN-Di7IMlSu.js +2 -0
- package/dist/control-ui/assets/zh-TW-yENTnmx1.js +2 -0
- package/dist/control-ui/favicon-32.png +0 -0
- package/dist/control-ui/favicon.ico +0 -0
- package/dist/control-ui/favicon.svg +66 -0
- package/dist/control-ui/index.html +75 -0
- package/package.json +1 -1
|
@@ -0,0 +1,813 @@
|
|
|
1
|
+
import{i as e,n as t}from"./lit-zdTgzAJI.js";import{t as n}from"./preload-helper-xBbMyY7u.js";import{l as r}from"./format-nUIQxx1z.js";import{A as i,C as a,D as o,E as s,M as c,S as l,T as u,_ as d,a as f,b as p,f as m,g as h,h as g,j as _,k as v,m as y,n as b,p as x,r as S,t as C,v as w,w as T,x as E,y as D}from"./index-hSu8pNmQ.js";import{r as O}from"./channel-config-extras-Cu8rP5sC.js";import{i as k,n as A,r as j,t as M}from"./skills-shared-DUfo2UBp.js";function N(n){let{agent:r,configForm:i,agentFilesList:o,configLoading:s,configSaving:c,configDirty:u,onConfigReload:d,onConfigSave:f,onModelChange:m,onModelFallbacksChange:h,onSelectPanel:g}=n,_=p(i,r.id),v=r.model,b=(o&&o.agentId===r.id?o.workspace:null)||_.entry?.workspace||_.defaults?.workspace||r.workspace||`default`,x=_.entry?.model?l(_.entry?.model):_.defaults?.model?l(_.defaults?.model):l(v),S=l(_.defaults?.model??v),C=a(_.entry?.model),T=a(_.defaults?.model)||(S===`-`?null:w(S))||(i?null:a(v)),O=C??T??null,k=E(_.entry?.model)??E(_.defaults?.model)??(i?null:E(v))??[],A=Array.isArray(_.entry?.skills)?_.entry?.skills:null,j=A?.length??null,M=!!(n.defaultId&&r.id===n.defaultId),N=!i||s||c,P=e=>{let t=k.filter((t,n)=>n!==e);h(r.id,t)};return e`
|
|
2
|
+
<section class="card">
|
|
3
|
+
<div class="card-title">Overview</div>
|
|
4
|
+
<div class="card-sub">Workspace paths and identity metadata.</div>
|
|
5
|
+
|
|
6
|
+
<div class="agents-overview-grid" style="margin-top: 16px;">
|
|
7
|
+
<div class="agent-kv">
|
|
8
|
+
<div class="label">Workspace</div>
|
|
9
|
+
<div>
|
|
10
|
+
<button
|
|
11
|
+
type="button"
|
|
12
|
+
class="workspace-link mono"
|
|
13
|
+
@click=${()=>g(`files`)}
|
|
14
|
+
title="Open Files tab"
|
|
15
|
+
>
|
|
16
|
+
${b}
|
|
17
|
+
</button>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="agent-kv">
|
|
21
|
+
<div class="label">Primary Model</div>
|
|
22
|
+
<div class="mono">${x}</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="agent-kv">
|
|
25
|
+
<div class="label">Skills Filter</div>
|
|
26
|
+
<div>${A?`${j} selected`:`all skills`}</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
${u?e`
|
|
31
|
+
<div class="callout warn" style="margin-top: 16px">
|
|
32
|
+
You have unsaved config changes.
|
|
33
|
+
</div>
|
|
34
|
+
`:t}
|
|
35
|
+
|
|
36
|
+
<div class="agent-model-select" style="margin-top: 20px;">
|
|
37
|
+
<div class="label">Model Selection</div>
|
|
38
|
+
<div class="agent-model-fields">
|
|
39
|
+
<label class="field">
|
|
40
|
+
<span>Primary model${M?` (default)`:``}</span>
|
|
41
|
+
<select
|
|
42
|
+
.value=${M?O??``:C??``}
|
|
43
|
+
?disabled=${N}
|
|
44
|
+
@change=${e=>m(r.id,e.target.value||null)}
|
|
45
|
+
>
|
|
46
|
+
${M?e` <option value="">Not set</option> `:e`
|
|
47
|
+
<option value="">
|
|
48
|
+
${T?`Inherit default (${T})`:`Inherit default`}
|
|
49
|
+
</option>
|
|
50
|
+
`}
|
|
51
|
+
${y(i,O??void 0,n.modelCatalog)}
|
|
52
|
+
</select>
|
|
53
|
+
</label>
|
|
54
|
+
<div class="field">
|
|
55
|
+
<span>Fallbacks</span>
|
|
56
|
+
<div
|
|
57
|
+
class="agent-chip-input"
|
|
58
|
+
@click=${e=>{let t=e.currentTarget.querySelector(`input`);t&&t.focus()}}
|
|
59
|
+
>
|
|
60
|
+
${k.map((t,n)=>e`
|
|
61
|
+
<span class="chip">
|
|
62
|
+
${t}
|
|
63
|
+
<button
|
|
64
|
+
type="button"
|
|
65
|
+
class="chip-remove"
|
|
66
|
+
?disabled=${N}
|
|
67
|
+
@click=${()=>P(n)}
|
|
68
|
+
>
|
|
69
|
+
×
|
|
70
|
+
</button>
|
|
71
|
+
</span>
|
|
72
|
+
`)}
|
|
73
|
+
<input
|
|
74
|
+
?disabled=${N}
|
|
75
|
+
placeholder=${k.length===0?`provider/model`:``}
|
|
76
|
+
@keydown=${e=>{let t=e.target;if(e.key===`Enter`||e.key===`,`){e.preventDefault();let n=D(t.value);n.length>0&&(h(r.id,[...k,...n]),t.value=``)}}}
|
|
77
|
+
@blur=${e=>{let t=e.target,n=D(t.value);n.length>0&&(h(r.id,[...k,...n]),t.value=``)}}
|
|
78
|
+
/>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="agent-model-actions">
|
|
83
|
+
<button
|
|
84
|
+
type="button"
|
|
85
|
+
class="btn btn--sm"
|
|
86
|
+
?disabled=${s}
|
|
87
|
+
@click=${d}
|
|
88
|
+
>
|
|
89
|
+
Reload Config
|
|
90
|
+
</button>
|
|
91
|
+
<button
|
|
92
|
+
type="button"
|
|
93
|
+
class="btn btn--sm primary"
|
|
94
|
+
?disabled=${c||!u}
|
|
95
|
+
@click=${f}
|
|
96
|
+
>
|
|
97
|
+
${c?`Saving…`:`Save`}
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</section>
|
|
102
|
+
`}var P=Object.defineProperty,ee=(e,t,n)=>t in e?P(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,F=(e,t,n)=>ee(e,typeof t==`symbol`?t:t+``,n),I={classPrefix:`cm-`,theme:`github`,linkTarget:`_blank`,sanitize:!1,plugins:[],customRenderers:{}};function L(e){return{...I,...e,plugins:e?.plugins??[],customRenderers:e?.customRenderers??{}}}function te(e,t){return typeof t==`function`?t(e):e}function R(e,t){let n=L(t),r=n.classPrefix,i=e;for(let e of n.plugins)e.transformBlock&&(i=i.map(e.transformBlock));let a=`<div class="${r}preview">${i.map(e=>{for(let t of n.plugins)if(t.renderBlock){let r=t.renderBlock(e,()=>B(e,n));if(r!==null)return r}let t=n.customRenderers[e.type];return t?t(e):B(e,n)}).join(`
|
|
103
|
+
`)}</div>`;return a=te(a,n.sanitize),a}async function z(e,t){let n=L(t);for(let e of n.plugins)e.init&&await e.init();let r=R(e,t);for(let e of n.plugins)e.postProcess&&(r=await e.postProcess(r));return r}function B(e,t){let n=t.classPrefix;switch(e.type){case`paragraph`:return`<p class="${n}paragraph">${Y(e.content,t)}</p>`;case`heading`:return V(e,t);case`bulletList`:return H(e,t);case`numberedList`:return U(e,t);case`checkList`:return W(e,t);case`codeBlock`:return G(e,t);case`blockquote`:return`<blockquote class="${n}blockquote">${Y(e.content,t)}</blockquote>`;case`table`:return K(e,t);case`image`:return q(e,t);case`divider`:return`<hr class="${n}divider" />`;case`callout`:return J(e,t);default:return`<div class="${n}unknown">${Y(e.content,t)}</div>`}}function V(e,t){let n=t.classPrefix,r=e.props.level,i=`h${r}`;return`<${i} class="${n}heading ${n}h${r}">${Y(e.content,t)}</${i}>`}function H(e,t){return`<ul class="${t.classPrefix}bullet-list">
|
|
104
|
+
${e.children.map(e=>`<li>${Y(e.content,t)}</li>`).join(`
|
|
105
|
+
`)}
|
|
106
|
+
</ul>`}function U(e,t){return`<ol class="${t.classPrefix}numbered-list">
|
|
107
|
+
${e.children.map(e=>`<li>${Y(e.content,t)}</li>`).join(`
|
|
108
|
+
`)}
|
|
109
|
+
</ol>`}function W(e,t){let n=t.classPrefix,r=e.props.checked;return`
|
|
110
|
+
<div class="${n}checklist-item">
|
|
111
|
+
<input type="checkbox" ${r?`checked disabled`:`disabled`} />
|
|
112
|
+
<span class="${r?`${n}checked`:``}">${Y(e.content,t)}</span>
|
|
113
|
+
</div>`.trim()}function G(e,t){let n=t.classPrefix,r=e.content.map(e=>e.text).join(``),i=e.props.language||``,a=Z(r),o=i?` language-${i}`:``;return`<pre class="${n}code-block"${i?` data-language="${i}"`:``}><code class="${n}code${o}">${a}</code></pre>`}function K(e,t){let n=t.classPrefix,{headers:r,rows:i,alignments:a}=e.props,o=e=>{let t=a?.[e];return t?` style="text-align: ${t}"`:``};return`<table class="${n}table">
|
|
114
|
+
${r.length>0?`<thead><tr>${r.map((e,t)=>`<th${o(t)}>${Z(e)}</th>`).join(``)}</tr></thead>`:``}
|
|
115
|
+
<tbody>
|
|
116
|
+
${i.map(e=>`<tr>${e.map((e,t)=>`<td${o(t)}>${Z(e)}</td>`).join(``)}</tr>`).join(`
|
|
117
|
+
`)}
|
|
118
|
+
</tbody>
|
|
119
|
+
</table>`}function q(e,t){let n=t.classPrefix,{url:r,alt:i,title:a,width:o,height:s}=e.props,c=i?` alt="${Z(i)}"`:` alt=""`,l=a?` title="${Z(a)}"`:``,u=o?` width="${o}"`:``,d=s?` height="${s}"`:``;return`<figure class="${n}image">${`<img src="${Z(r)}"${c}${l}${u}${d} />`}${i?`<figcaption>${Z(i)}</figcaption>`:``}</figure>`}function J(e,t){let n=t.classPrefix,r=e.props.type;return`
|
|
120
|
+
<div class="${n}callout ${n}callout-${r}" role="alert">
|
|
121
|
+
<strong class="${n}callout-title">${r}</strong>
|
|
122
|
+
<div class="${n}callout-content">${Y(e.content,t)}</div>
|
|
123
|
+
</div>`.trim()}function Y(e,t){return e.map(e=>X(e,t)).join(``)}function X(e,t){let n=Z(e.text),r=e.styles;if(r.code&&(n=`<code>${n}</code>`),r.highlight&&(n=`<mark>${n}</mark>`),r.strikethrough&&(n=`<del>${n}</del>`),r.underline&&(n=`<u>${n}</u>`),r.italic&&(n=`<em>${n}</em>`),r.bold&&(n=`<strong>${n}</strong>`),r.link){let e=t.linkTarget===`_blank`?` target="_blank" rel="noopener noreferrer"`:``,i=r.link.title?` title="${Z(r.link.title)}"`:``;n=`<a href="${Z(r.link.url)}"${i}${e}>${n}</a>`}return n}function Z(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`)}function ne(e){return[...[1,2,3,4,5,6].map(t=>({tag:`h${t}`,classes:[`${e}heading`,`${e}h${t}`]})),{tag:`p`,classes:[`${e}paragraph`]},{tag:`ul`,classes:[`${e}bullet-list`]},{tag:`ol`,classes:[`${e}numbered-list`]},{tag:`pre`,classes:[`${e}code-block`]},{tag:`blockquote`,classes:[`${e}blockquote`]},{tag:`hr`,classes:[`${e}divider`]},{tag:`table`,classes:[`${e}table`]},{tag:`figure`,classes:[`${e}image`]}]}function Q(e,t){let n=t.join(` `),r=/\bclass\s*=\s*"([^"]*)"/i,i=e.match(r);return i?e.replace(r,`class="${n} ${i[1]}"`):e.endsWith(`/>`)?e.slice(0,-2)+` class="${n}" />`:e.slice(0,-1)+` class="${n}">`}function re(e,t){return e.replace(/(?<!<figure[^>]*>\s*)(<img\s[^>]*\/?>)(?!\s*<\/figure>)/gi,`<figure class="${t}image">$1</figure>`)}function ie(e,t){let n=t?.classPrefix??`cm-`,r=t?.wrapperClass??`${n}preview`,i=ne(n),a=e;for(let{tag:e,classes:t}of i){let n=RegExp(`<${e}(\\s[^>]*)?>|<${e}\\s*\\/?>`,`gi`);a=a.replace(n,e=>Q(e,t))}return a=re(a,n),a=`<div class="${r}">${a}</div>`,typeof t?.sanitize==`function`&&(a=t.sanitize(a)),a}async function ae(e){try{return(await n(()=>import(`./preview-Ca6p7-4-.js`),[],import.meta.url)).parse(e)}catch{throw Error(`@create-markdown/core is required to parse markdown in <markdown-preview>. Install it, or provide pre-parsed blocks via the blocks attribute / setBlocks().`)}}F(class extends HTMLElement{constructor(){super(),F(this,`_shadow`,null),F(this,`plugins`,[]),F(this,`defaultTheme`,`github`),F(this,`styleElement`),F(this,`contentElement`);let e=this.constructor._shadowMode;e!==`none`&&(this._shadow=this.attachShadow({mode:e})),this.styleElement=document.createElement(`style`),this.renderRoot.appendChild(this.styleElement),this.contentElement=document.createElement(`div`),this.contentElement.className=`markdown-preview-content`,this.renderRoot.appendChild(this.contentElement),this.updateStyles()}static get observedAttributes(){return[`theme`,`link-target`,`async`]}get renderRoot(){return this._shadow??this}connectedCallback(){this.render()}attributeChangedCallback(e,t,n){this.render()}setPlugins(e){this.plugins=e,this.render()}setDefaultTheme(e){this.defaultTheme=e,this.render()}getMarkdown(){let e=this.getAttribute(`blocks`);if(e)try{return JSON.parse(e).map(e=>e.content.map(e=>e.text).join(``)).join(`
|
|
124
|
+
|
|
125
|
+
`)}catch{return``}return this.textContent||``}setMarkdown(e){this.textContent=e,this.render()}setBlocks(e){this.setAttribute(`blocks`,JSON.stringify(e)),this.render()}getOptions(){return{theme:this.getAttribute(`theme`)||this.defaultTheme,linkTarget:this.getAttribute(`link-target`)||`_blank`,plugins:this.plugins}}async getBlocks(){let e=this.getAttribute(`blocks`);if(e)try{return JSON.parse(e)}catch{return console.warn(`Invalid blocks JSON in markdown-preview element`),[]}return ae(this.textContent||``)}async render(){let e=await this.getBlocks(),t=this.getOptions(),n=this.hasAttribute(`async`)||this.plugins.length>0;try{let r;r=n?await z(e,t):R(e,t),this.contentElement.innerHTML=r}catch(e){console.error(`Error rendering markdown preview:`,e),this.contentElement.innerHTML=`<div class="error">Error rendering content</div>`}}updateStyles(){let e=this.plugins.filter(e=>e.getCSS).map(e=>e.getCSS()).join(`
|
|
126
|
+
|
|
127
|
+
`),t=this._shadow?`:host { display: block; }`:`markdown-preview { display: block; }`;this.styleElement.textContent=`
|
|
128
|
+
${t}
|
|
129
|
+
|
|
130
|
+
.markdown-preview-content {
|
|
131
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
|
132
|
+
font-size: 16px;
|
|
133
|
+
line-height: 1.6;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.error {
|
|
137
|
+
color: #cf222e;
|
|
138
|
+
padding: 1rem;
|
|
139
|
+
background: #ffebe9;
|
|
140
|
+
border-radius: 6px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
${e}
|
|
144
|
+
`.trim()}},`_shadowMode`,`open`);function $(t,n,r){return e`
|
|
145
|
+
<section class="card">
|
|
146
|
+
<div class="card-title">Agent Context</div>
|
|
147
|
+
<div class="card-sub">${n}</div>
|
|
148
|
+
<div class="agents-overview-grid" style="margin-top: 16px;">
|
|
149
|
+
<div class="agent-kv">
|
|
150
|
+
<div class="label">Workspace</div>
|
|
151
|
+
<div>
|
|
152
|
+
<button
|
|
153
|
+
type="button"
|
|
154
|
+
class="workspace-link mono"
|
|
155
|
+
@click=${()=>r(`files`)}
|
|
156
|
+
title="Open Files tab"
|
|
157
|
+
>
|
|
158
|
+
${t.workspace}
|
|
159
|
+
</button>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="agent-kv">
|
|
163
|
+
<div class="label">Primary Model</div>
|
|
164
|
+
<div class="mono">${t.model}</div>
|
|
165
|
+
</div>
|
|
166
|
+
<div class="agent-kv">
|
|
167
|
+
<div class="label">Identity Name</div>
|
|
168
|
+
<div>${t.identityName}</div>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="agent-kv">
|
|
171
|
+
<div class="label">Identity Avatar</div>
|
|
172
|
+
<div>${t.identityAvatar}</div>
|
|
173
|
+
</div>
|
|
174
|
+
<div class="agent-kv">
|
|
175
|
+
<div class="label">Skills Filter</div>
|
|
176
|
+
<div>${t.skillsLabel}</div>
|
|
177
|
+
</div>
|
|
178
|
+
<div class="agent-kv">
|
|
179
|
+
<div class="label">Default</div>
|
|
180
|
+
<div>${t.isDefault?`yes`:`no`}</div>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</section>
|
|
184
|
+
`}function oe(e,t){let n=e.channelMeta?.find(e=>e.id===t);return n?.label?n.label:e.channelLabels?.[t]??t}function se(e){if(!e)return[];let t=new Set;for(let n of e.channelOrder??[])t.add(n);for(let n of e.channelMeta??[])t.add(n.id);for(let n of Object.keys(e.channelAccounts??{}))t.add(n);let n=[],r=e.channelOrder?.length?e.channelOrder:Array.from(t);for(let e of r)t.has(e)&&(n.push(e),t.delete(e));for(let e of t)n.push(e);return n.map(t=>({id:t,label:oe(e,t),accounts:e.channelAccounts?.[t]??[]}))}var ce=[`groupPolicy`,`streamMode`,`dmPolicy`];function le(e){let t=0,n=0,r=0;for(let i of e){let e=i.probe&&typeof i.probe==`object`&&`ok`in i.probe?!!i.probe.ok:!1;(i.connected===!0||i.running===!0||e)&&(t+=1),i.configured&&(n+=1),i.enabled&&(r+=1)}return{total:e.length,connected:t,configured:n,enabled:r}}function ue(n){let i=se(n.snapshot),a=n.lastSuccess?r(n.lastSuccess):`never`;return e`
|
|
185
|
+
<section class="grid grid-cols-2">
|
|
186
|
+
${$(n.context,`Workspace, identity, and model configuration.`,n.onSelectPanel)}
|
|
187
|
+
<section class="card">
|
|
188
|
+
<div class="row" style="justify-content: space-between;">
|
|
189
|
+
<div>
|
|
190
|
+
<div class="card-title">Channels</div>
|
|
191
|
+
<div class="card-sub">Gateway-wide channel status snapshot.</div>
|
|
192
|
+
</div>
|
|
193
|
+
<button class="btn btn--sm" ?disabled=${n.loading} @click=${n.onRefresh}>
|
|
194
|
+
${n.loading?`Refreshing…`:`Refresh`}
|
|
195
|
+
</button>
|
|
196
|
+
</div>
|
|
197
|
+
<div class="muted" style="margin-top: 8px;">Last refresh: ${a}</div>
|
|
198
|
+
${n.error?e`<div class="callout danger" style="margin-top: 12px;">${n.error}</div>`:t}
|
|
199
|
+
${n.snapshot?t:e`
|
|
200
|
+
<div class="callout info" style="margin-top: 12px">
|
|
201
|
+
Load channels to see live status.
|
|
202
|
+
</div>
|
|
203
|
+
`}
|
|
204
|
+
${i.length===0?e` <div class="muted" style="margin-top: 16px">No channels found.</div> `:e`
|
|
205
|
+
<div class="list" style="margin-top: 16px;">
|
|
206
|
+
${i.map(r=>{let i=le(r.accounts),a=i.total?`${i.connected}/${i.total} connected`:`no accounts`,o=i.configured?`${i.configured} configured`:`not configured`,s=i.total?`${i.enabled} enabled`:`disabled`,c=O({configForm:n.configForm,channelId:r.id,fields:ce});return e`
|
|
207
|
+
<div class="list-item">
|
|
208
|
+
<div class="list-main">
|
|
209
|
+
<div class="list-title">${r.label}</div>
|
|
210
|
+
<div class="list-sub mono">${r.id}</div>
|
|
211
|
+
</div>
|
|
212
|
+
<div class="list-meta">
|
|
213
|
+
<div>${a}</div>
|
|
214
|
+
<div>${o}</div>
|
|
215
|
+
<div>${s}</div>
|
|
216
|
+
${i.configured===0?e`
|
|
217
|
+
<div>
|
|
218
|
+
<a
|
|
219
|
+
href="https://github.com/ctz168/stableclaw/channels"
|
|
220
|
+
target="_blank"
|
|
221
|
+
rel="noopener"
|
|
222
|
+
style="color: var(--accent); font-size: 12px"
|
|
223
|
+
>Setup guide</a
|
|
224
|
+
>
|
|
225
|
+
</div>
|
|
226
|
+
`:t}
|
|
227
|
+
${c.length>0?c.map(t=>e`<div>${t.label}: ${t.value}</div>`):t}
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
`})}
|
|
231
|
+
</div>
|
|
232
|
+
`}
|
|
233
|
+
</section>
|
|
234
|
+
</section>
|
|
235
|
+
`}function de(n){let r=n.jobs.filter(e=>e.agentId===n.agentId);return e`
|
|
236
|
+
<section class="grid grid-cols-2">
|
|
237
|
+
${$(n.context,`Workspace and scheduling targets.`,n.onSelectPanel)}
|
|
238
|
+
<section class="card">
|
|
239
|
+
<div class="row" style="justify-content: space-between;">
|
|
240
|
+
<div>
|
|
241
|
+
<div class="card-title">Scheduler</div>
|
|
242
|
+
<div class="card-sub">Gateway cron status.</div>
|
|
243
|
+
</div>
|
|
244
|
+
<button class="btn btn--sm" ?disabled=${n.loading} @click=${n.onRefresh}>
|
|
245
|
+
${n.loading?`Refreshing…`:`Refresh`}
|
|
246
|
+
</button>
|
|
247
|
+
</div>
|
|
248
|
+
<div class="stat-grid" style="margin-top: 16px;">
|
|
249
|
+
<div class="stat">
|
|
250
|
+
<div class="stat-label">Enabled</div>
|
|
251
|
+
<div class="stat-value">
|
|
252
|
+
${n.status?n.status.enabled?`Yes`:`No`:`n/a`}
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
<div class="stat">
|
|
256
|
+
<div class="stat-label">Jobs</div>
|
|
257
|
+
<div class="stat-value">${n.status?.jobs??`n/a`}</div>
|
|
258
|
+
</div>
|
|
259
|
+
<div class="stat">
|
|
260
|
+
<div class="stat-label">Next wake</div>
|
|
261
|
+
<div class="stat-value">${f(n.status?.nextWakeAtMs??null)}</div>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
${n.error?e`<div class="callout danger" style="margin-top: 12px;">${n.error}</div>`:t}
|
|
265
|
+
</section>
|
|
266
|
+
</section>
|
|
267
|
+
<section class="card">
|
|
268
|
+
<div class="card-title">Agent Cron Jobs</div>
|
|
269
|
+
<div class="card-sub">Scheduled jobs targeting this agent.</div>
|
|
270
|
+
${r.length===0?e` <div class="muted" style="margin-top: 16px">No jobs assigned.</div> `:e`
|
|
271
|
+
<div class="list" style="margin-top: 16px;">
|
|
272
|
+
${r.map(r=>e`
|
|
273
|
+
<div class="list-item">
|
|
274
|
+
<div class="list-main">
|
|
275
|
+
<div class="list-title">${r.name}</div>
|
|
276
|
+
${r.description?e`<div class="list-sub">${r.description}</div>`:t}
|
|
277
|
+
<div class="chip-row" style="margin-top: 6px;">
|
|
278
|
+
<span class="chip">${b(r)}</span>
|
|
279
|
+
<span class="chip ${r.enabled?`chip-ok`:`chip-warn`}">
|
|
280
|
+
${r.enabled?`enabled`:`disabled`}
|
|
281
|
+
</span>
|
|
282
|
+
<span class="chip">${r.sessionTarget}</span>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
<div class="list-meta">
|
|
286
|
+
<div class="mono">${S(r)}</div>
|
|
287
|
+
<div class="muted">${C(r)}</div>
|
|
288
|
+
<button
|
|
289
|
+
class="btn btn--sm"
|
|
290
|
+
style="margin-top: 6px;"
|
|
291
|
+
?disabled=${!r.enabled}
|
|
292
|
+
@click=${()=>n.onRunNow(r.id)}
|
|
293
|
+
>
|
|
294
|
+
Run Now
|
|
295
|
+
</button>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
`)}
|
|
299
|
+
</div>
|
|
300
|
+
`}
|
|
301
|
+
</section>
|
|
302
|
+
`}function fe(n){let r=n.agentFilesList?.agentId===n.agentId?n.agentFilesList:null,a=r?.files??[],o=n.agentFileActive??null,s=o?a.find(e=>e.name===o)??null:null,l=o?n.agentFileContents[o]??``:``,u=o?n.agentFileDrafts[o]??l:``,d=o?u!==l:!1;return e`
|
|
303
|
+
<section class="card">
|
|
304
|
+
<div class="row" style="justify-content: space-between;">
|
|
305
|
+
<div>
|
|
306
|
+
<div class="card-title">Core Files</div>
|
|
307
|
+
<div class="card-sub">Bootstrap persona, identity, and tool guidance.</div>
|
|
308
|
+
</div>
|
|
309
|
+
<button
|
|
310
|
+
class="btn btn--sm"
|
|
311
|
+
?disabled=${n.agentFilesLoading}
|
|
312
|
+
@click=${()=>n.onLoadFiles(n.agentId)}
|
|
313
|
+
>
|
|
314
|
+
${n.agentFilesLoading?`Loading…`:`Refresh`}
|
|
315
|
+
</button>
|
|
316
|
+
</div>
|
|
317
|
+
${r?e`<div class="muted mono" style="margin-top: 8px;">
|
|
318
|
+
Workspace: <span>${r.workspace}</span>
|
|
319
|
+
</div>`:t}
|
|
320
|
+
${n.agentFilesError?e`<div class="callout danger" style="margin-top: 12px;">
|
|
321
|
+
${n.agentFilesError}
|
|
322
|
+
</div>`:t}
|
|
323
|
+
${r?a.length===0?e` <div class="muted" style="margin-top: 16px">No files found.</div> `:e`
|
|
324
|
+
<div class="agent-tabs" style="margin-top: 14px;">
|
|
325
|
+
${a.map(r=>{let i=o===r.name,a=r.name.replace(/\.md$/i,``);return e`
|
|
326
|
+
<button
|
|
327
|
+
class="agent-tab ${i?`active`:``} ${r.missing?`agent-tab--missing`:``}"
|
|
328
|
+
@click=${()=>n.onSelectFile(r.name)}
|
|
329
|
+
>
|
|
330
|
+
${a}${r.missing?e` <span class="agent-tab-badge">missing</span> `:t}
|
|
331
|
+
</button>
|
|
332
|
+
`})}
|
|
333
|
+
</div>
|
|
334
|
+
${s?e`
|
|
335
|
+
<div class="agent-file-header" style="margin-top: 14px;">
|
|
336
|
+
<div>
|
|
337
|
+
<div class="agent-file-sub mono">${s.path}</div>
|
|
338
|
+
</div>
|
|
339
|
+
<div class="agent-file-actions">
|
|
340
|
+
<button
|
|
341
|
+
class="btn btn--sm"
|
|
342
|
+
title="Preview rendered markdown"
|
|
343
|
+
@click=${e=>{let t=e.currentTarget.closest(`.card`)?.querySelector(`dialog`);t&&t.showModal()}}
|
|
344
|
+
>
|
|
345
|
+
${_.eye} Preview
|
|
346
|
+
</button>
|
|
347
|
+
<button
|
|
348
|
+
class="btn btn--sm"
|
|
349
|
+
?disabled=${!d}
|
|
350
|
+
@click=${()=>n.onFileReset(s.name)}
|
|
351
|
+
>
|
|
352
|
+
Reset
|
|
353
|
+
</button>
|
|
354
|
+
<button
|
|
355
|
+
class="btn btn--sm primary"
|
|
356
|
+
?disabled=${n.agentFileSaving||!d}
|
|
357
|
+
@click=${()=>n.onFileSave(s.name)}
|
|
358
|
+
>
|
|
359
|
+
${n.agentFileSaving?`Saving…`:`Save`}
|
|
360
|
+
</button>
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
${s.missing?e`
|
|
364
|
+
<div class="callout info" style="margin-top: 10px">
|
|
365
|
+
This file is missing. Saving will create it in the agent workspace.
|
|
366
|
+
</div>
|
|
367
|
+
`:t}
|
|
368
|
+
<label class="field agent-file-field" style="margin-top: 12px;">
|
|
369
|
+
<span>Content</span>
|
|
370
|
+
<textarea
|
|
371
|
+
class="agent-file-textarea"
|
|
372
|
+
.value=${u}
|
|
373
|
+
@input=${e=>n.onFileDraftChange(s.name,e.target.value)}
|
|
374
|
+
></textarea>
|
|
375
|
+
</label>
|
|
376
|
+
<dialog
|
|
377
|
+
class="md-preview-dialog"
|
|
378
|
+
@click=${e=>{let t=e.currentTarget;e.target===t&&t.close()}}
|
|
379
|
+
@close=${e=>{e.currentTarget.querySelector(`.md-preview-dialog__panel`)?.classList.remove(`fullscreen`)}}
|
|
380
|
+
>
|
|
381
|
+
<div class="md-preview-dialog__panel">
|
|
382
|
+
<div class="md-preview-dialog__header">
|
|
383
|
+
<div class="md-preview-dialog__title mono">${s.name}</div>
|
|
384
|
+
<div class="md-preview-dialog__actions">
|
|
385
|
+
<button
|
|
386
|
+
class="btn btn--sm md-preview-expand-btn"
|
|
387
|
+
title="Toggle fullscreen"
|
|
388
|
+
@click=${e=>{let t=e.currentTarget,n=t.closest(`.md-preview-dialog__panel`);if(!n)return;let r=n.classList.toggle(`fullscreen`);t.classList.toggle(`is-fullscreen`,r)}}
|
|
389
|
+
>
|
|
390
|
+
<span class="when-normal">${_.maximize} Expand</span
|
|
391
|
+
><span class="when-fullscreen">${_.minimize} Collapse</span>
|
|
392
|
+
</button>
|
|
393
|
+
<button
|
|
394
|
+
class="btn btn--sm"
|
|
395
|
+
title="Edit file"
|
|
396
|
+
@click=${e=>{e.currentTarget.closest(`dialog`)?.close(),document.querySelector(`.agent-file-textarea`)?.focus()}}
|
|
397
|
+
>
|
|
398
|
+
${_.edit} Editor
|
|
399
|
+
</button>
|
|
400
|
+
<button
|
|
401
|
+
class="btn btn--sm"
|
|
402
|
+
@click=${e=>{e.currentTarget.closest(`dialog`)?.close()}}
|
|
403
|
+
>
|
|
404
|
+
${_.x} Close
|
|
405
|
+
</button>
|
|
406
|
+
</div>
|
|
407
|
+
</div>
|
|
408
|
+
<div class="md-preview-dialog__body">
|
|
409
|
+
${c(ie(v.parse(u,{gfm:!0,breaks:!0}),{sanitize:e=>i.sanitize(e)}))}
|
|
410
|
+
</div>
|
|
411
|
+
</div>
|
|
412
|
+
</dialog>
|
|
413
|
+
`:e` <div class="muted" style="margin-top: 16px">Select a file to edit.</div> `}
|
|
414
|
+
`:e`
|
|
415
|
+
<div class="callout info" style="margin-top: 12px">
|
|
416
|
+
Load the agent workspace files to edit core instructions.
|
|
417
|
+
</div>
|
|
418
|
+
`}
|
|
419
|
+
</section>
|
|
420
|
+
`}function pe(n,r){let i=r.source??n.source,a=r.pluginId??n.pluginId,o=[];return i===`plugin`&&a?o.push(`plugin:${a}`):i===`core`&&o.push(`core`),r.optional&&o.push(`optional`),o.length===0?t:e`
|
|
421
|
+
<div style="display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px;">
|
|
422
|
+
${o.map(t=>e`<span class="agent-pill">${t}</span>`)}
|
|
423
|
+
</div>
|
|
424
|
+
`}function me(e){return e.source===`plugin`?e.pluginId?`Connected: ${e.pluginId}`:`Connected`:e.source===`channel`?e.channelId?`Channel: ${e.channelId}`:`Channel`:`Built-in`}function he(n){let r=p(n.configForm,n.agentId),i=r.entry?.tools??{},a=r.globalTools??{},c=i.profile??a.profile??`full`,l=u(n.toolsCatalogResult),d=s(n.toolsCatalogResult),f=i.profile?`agent override`:a.profile?`global default`:`default`,m=Array.isArray(i.allow)&&i.allow.length>0,_=Array.isArray(a.allow)&&a.allow.length>0,v=!!n.configForm&&!n.configLoading&&!n.configSaving&&!m&&!(n.toolsCatalogLoading&&!n.toolsCatalogResult&&!n.toolsCatalogError),y=m?[]:Array.isArray(i.alsoAllow)?i.alsoAllow:[],b=m?[]:Array.isArray(i.deny)?i.deny:[],x=m?{allow:i.allow??[],deny:i.deny??[]}:T(c)??void 0,S=d.flatMap(e=>e.tools.map(e=>e.id)),C=e=>{let t=g(e,x),n=h(e,y),r=h(e,b);return{allowed:(t||n)&&!r,baseAllowed:t,denied:r}},w=S.filter(e=>C(e).allowed).length,E=(e,t)=>{let r=new Set(y.map(e=>o(e)).filter(e=>e.length>0)),i=new Set(b.map(e=>o(e)).filter(e=>e.length>0)),a=C(e).baseAllowed,s=o(e);t?(i.delete(s),a||r.add(s)):(r.delete(s),i.add(s)),n.onOverridesChange(n.agentId,[...r],[...i])},D=e=>{let t=new Set(y.map(e=>o(e)).filter(e=>e.length>0)),r=new Set(b.map(e=>o(e)).filter(e=>e.length>0));for(let n of S){let i=C(n).baseAllowed,a=o(n);e?(r.delete(a),i||t.add(a)):(t.delete(a),r.add(a))}n.onOverridesChange(n.agentId,[...t],[...r])};return e`
|
|
425
|
+
<section class="card">
|
|
426
|
+
<div class="row" style="justify-content: space-between; flex-wrap: wrap;">
|
|
427
|
+
<div style="min-width: 0;">
|
|
428
|
+
<div class="card-title">Tool Access</div>
|
|
429
|
+
<div class="card-sub">
|
|
430
|
+
Profile + per-tool overrides for this agent.
|
|
431
|
+
<span class="mono">${w}/${S.length}</span> enabled.
|
|
432
|
+
</div>
|
|
433
|
+
</div>
|
|
434
|
+
<div class="row" style="gap: 8px; flex-wrap: wrap;">
|
|
435
|
+
<button class="btn btn--sm" ?disabled=${!v} @click=${()=>D(!0)}>
|
|
436
|
+
Enable All
|
|
437
|
+
</button>
|
|
438
|
+
<button class="btn btn--sm" ?disabled=${!v} @click=${()=>D(!1)}>
|
|
439
|
+
Disable All
|
|
440
|
+
</button>
|
|
441
|
+
<button
|
|
442
|
+
class="btn btn--sm"
|
|
443
|
+
?disabled=${n.configLoading}
|
|
444
|
+
@click=${n.onConfigReload}
|
|
445
|
+
>
|
|
446
|
+
Reload Config
|
|
447
|
+
</button>
|
|
448
|
+
<button
|
|
449
|
+
class="btn btn--sm primary"
|
|
450
|
+
?disabled=${n.configSaving||!n.configDirty}
|
|
451
|
+
@click=${n.onConfigSave}
|
|
452
|
+
>
|
|
453
|
+
${n.configSaving?`Saving…`:`Save`}
|
|
454
|
+
</button>
|
|
455
|
+
</div>
|
|
456
|
+
</div>
|
|
457
|
+
|
|
458
|
+
${n.configForm?t:e`
|
|
459
|
+
<div class="callout info" style="margin-top: 12px">
|
|
460
|
+
Load the gateway config to adjust tool profiles.
|
|
461
|
+
</div>
|
|
462
|
+
`}
|
|
463
|
+
${m?e`
|
|
464
|
+
<div class="callout info" style="margin-top: 12px">
|
|
465
|
+
This agent is using an explicit allowlist in config. Tool overrides are managed in the
|
|
466
|
+
Config tab.
|
|
467
|
+
</div>
|
|
468
|
+
`:t}
|
|
469
|
+
${_?e`
|
|
470
|
+
<div class="callout info" style="margin-top: 12px">
|
|
471
|
+
Global tools.allow is set. Agent overrides cannot enable tools that are globally
|
|
472
|
+
blocked.
|
|
473
|
+
</div>
|
|
474
|
+
`:t}
|
|
475
|
+
${n.toolsCatalogLoading&&!n.toolsCatalogResult&&!n.toolsCatalogError?e`
|
|
476
|
+
<div class="callout info" style="margin-top: 12px">Loading runtime tool catalog…</div>
|
|
477
|
+
`:t}
|
|
478
|
+
${n.toolsCatalogError?e`
|
|
479
|
+
<div class="callout info" style="margin-top: 12px">
|
|
480
|
+
Could not load runtime tool catalog. Showing built-in fallback list instead.
|
|
481
|
+
</div>
|
|
482
|
+
`:t}
|
|
483
|
+
|
|
484
|
+
<div class="agent-tools-meta" style="margin-top: 16px;">
|
|
485
|
+
<div class="agent-kv">
|
|
486
|
+
<div class="label">Profile</div>
|
|
487
|
+
<div class="mono">${c}</div>
|
|
488
|
+
</div>
|
|
489
|
+
<div class="agent-kv">
|
|
490
|
+
<div class="label">Source</div>
|
|
491
|
+
<div>${f}</div>
|
|
492
|
+
</div>
|
|
493
|
+
${n.configDirty?e`
|
|
494
|
+
<div class="agent-kv">
|
|
495
|
+
<div class="label">Status</div>
|
|
496
|
+
<div class="mono">unsaved</div>
|
|
497
|
+
</div>
|
|
498
|
+
`:t}
|
|
499
|
+
</div>
|
|
500
|
+
|
|
501
|
+
<div style="margin-top: 18px;">
|
|
502
|
+
<div class="label">Available Right Now</div>
|
|
503
|
+
<div class="card-sub">
|
|
504
|
+
What this agent can use in the current chat session.
|
|
505
|
+
<span class="mono">${n.runtimeSessionKey||`no session`}</span>
|
|
506
|
+
</div>
|
|
507
|
+
${n.runtimeSessionMatchesSelectedAgent?n.toolsEffectiveLoading&&!n.toolsEffectiveResult&&!n.toolsEffectiveError?e`
|
|
508
|
+
<div class="callout info" style="margin-top: 12px">Loading available tools…</div>
|
|
509
|
+
`:n.toolsEffectiveError?e`
|
|
510
|
+
<div class="callout info" style="margin-top: 12px">
|
|
511
|
+
Could not load available tools for this session.
|
|
512
|
+
</div>
|
|
513
|
+
`:(n.toolsEffectiveResult?.groups?.length??0)===0?e`
|
|
514
|
+
<div class="callout info" style="margin-top: 12px">
|
|
515
|
+
No tools are available for this session right now.
|
|
516
|
+
</div>
|
|
517
|
+
`:e`
|
|
518
|
+
<div class="agent-tools-grid" style="margin-top: 16px;">
|
|
519
|
+
${n.toolsEffectiveResult?.groups.map(t=>e`
|
|
520
|
+
<div class="agent-tools-section">
|
|
521
|
+
<div class="agent-tools-header">${t.label}</div>
|
|
522
|
+
<div class="agent-tools-list">
|
|
523
|
+
${t.tools.map(t=>e`
|
|
524
|
+
<div class="agent-tool-row">
|
|
525
|
+
<div>
|
|
526
|
+
<div class="agent-tool-title">${t.label}</div>
|
|
527
|
+
<div class="agent-tool-sub">${t.description}</div>
|
|
528
|
+
<div
|
|
529
|
+
style="display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px;"
|
|
530
|
+
>
|
|
531
|
+
<span class="agent-pill"
|
|
532
|
+
>${me(t)}</span
|
|
533
|
+
>
|
|
534
|
+
</div>
|
|
535
|
+
</div>
|
|
536
|
+
</div>
|
|
537
|
+
`)}
|
|
538
|
+
</div>
|
|
539
|
+
</div>
|
|
540
|
+
`)}
|
|
541
|
+
</div>
|
|
542
|
+
`:e`
|
|
543
|
+
<div class="callout info" style="margin-top: 12px">
|
|
544
|
+
Switch chat to this agent to view its live runtime tools.
|
|
545
|
+
</div>
|
|
546
|
+
`}
|
|
547
|
+
</div>
|
|
548
|
+
|
|
549
|
+
<div class="agent-tools-presets" style="margin-top: 16px;">
|
|
550
|
+
<div class="label">Quick Presets</div>
|
|
551
|
+
<div class="agent-tools-buttons">
|
|
552
|
+
${l.map(t=>e`
|
|
553
|
+
<button
|
|
554
|
+
class="btn btn--sm ${c===t.id?`active`:``}"
|
|
555
|
+
?disabled=${!v}
|
|
556
|
+
@click=${()=>n.onProfileChange(n.agentId,t.id,!0)}
|
|
557
|
+
>
|
|
558
|
+
${t.label}
|
|
559
|
+
</button>
|
|
560
|
+
`)}
|
|
561
|
+
<button
|
|
562
|
+
class="btn btn--sm"
|
|
563
|
+
?disabled=${!v}
|
|
564
|
+
@click=${()=>n.onProfileChange(n.agentId,null,!1)}
|
|
565
|
+
>
|
|
566
|
+
Inherit
|
|
567
|
+
</button>
|
|
568
|
+
</div>
|
|
569
|
+
</div>
|
|
570
|
+
|
|
571
|
+
<div class="agent-tools-grid" style="margin-top: 20px;">
|
|
572
|
+
${d.map(n=>e`
|
|
573
|
+
<div class="agent-tools-section">
|
|
574
|
+
<div class="agent-tools-header">
|
|
575
|
+
${n.label}
|
|
576
|
+
${n.source===`plugin`&&n.pluginId?e`<span class="agent-pill" style="margin-left: 8px;"
|
|
577
|
+
>plugin:${n.pluginId}</span
|
|
578
|
+
>`:t}
|
|
579
|
+
</div>
|
|
580
|
+
<div class="agent-tools-list">
|
|
581
|
+
${n.tools.map(t=>{let{allowed:r}=C(t.id);return e`
|
|
582
|
+
<div class="agent-tool-row">
|
|
583
|
+
<div>
|
|
584
|
+
<div class="agent-tool-title mono">${t.label}</div>
|
|
585
|
+
<div class="agent-tool-sub">${t.description}</div>
|
|
586
|
+
${pe(n,t)}
|
|
587
|
+
</div>
|
|
588
|
+
<label class="cfg-toggle">
|
|
589
|
+
<input
|
|
590
|
+
type="checkbox"
|
|
591
|
+
.checked=${r}
|
|
592
|
+
?disabled=${!v}
|
|
593
|
+
@change=${e=>E(t.id,e.target.checked)}
|
|
594
|
+
/>
|
|
595
|
+
<span class="cfg-toggle__track"></span>
|
|
596
|
+
</label>
|
|
597
|
+
</div>
|
|
598
|
+
`})}
|
|
599
|
+
</div>
|
|
600
|
+
</div>
|
|
601
|
+
`)}
|
|
602
|
+
</div>
|
|
603
|
+
</section>
|
|
604
|
+
`}function ge(n){let r=!!n.configForm&&!n.configLoading&&!n.configSaving,i=p(n.configForm,n.agentId),a=Array.isArray(i.entry?.skills)?i.entry?.skills:void 0,o=new Set((a??[]).map(e=>e.trim()).filter(Boolean)),s=a!==void 0,c=!!(n.report&&n.activeAgentId===n.agentId),l=c?n.report?.skills??[]:[],u=n.filter.trim().toLowerCase(),d=u?l.filter(e=>[e.name,e.description,e.source].join(` `).toLowerCase().includes(u)):l,f=k(d),m=s?l.filter(e=>o.has(e.name)).length:l.length,h=l.length;return e`
|
|
605
|
+
<section class="card">
|
|
606
|
+
<div class="row" style="justify-content: space-between; flex-wrap: wrap;">
|
|
607
|
+
<div style="min-width: 0;">
|
|
608
|
+
<div class="card-title">Skills</div>
|
|
609
|
+
<div class="card-sub">
|
|
610
|
+
Per-agent skill allowlist and workspace skills.
|
|
611
|
+
${h>0?e`<span class="mono">${m}/${h}</span>`:t}
|
|
612
|
+
</div>
|
|
613
|
+
</div>
|
|
614
|
+
<div class="row" style="gap: 8px; flex-wrap: wrap;">
|
|
615
|
+
<div
|
|
616
|
+
class="row"
|
|
617
|
+
style="gap: 4px; border: 1px solid var(--border); border-radius: var(--radius-md); padding: 2px;"
|
|
618
|
+
>
|
|
619
|
+
<button
|
|
620
|
+
class="btn btn--sm"
|
|
621
|
+
?disabled=${!r}
|
|
622
|
+
@click=${()=>n.onClear(n.agentId)}
|
|
623
|
+
>
|
|
624
|
+
Enable All
|
|
625
|
+
</button>
|
|
626
|
+
<button
|
|
627
|
+
class="btn btn--sm"
|
|
628
|
+
?disabled=${!r}
|
|
629
|
+
@click=${()=>n.onDisableAll(n.agentId)}
|
|
630
|
+
>
|
|
631
|
+
Disable All
|
|
632
|
+
</button>
|
|
633
|
+
<button
|
|
634
|
+
class="btn btn--sm"
|
|
635
|
+
?disabled=${!r||!s}
|
|
636
|
+
@click=${()=>n.onClear(n.agentId)}
|
|
637
|
+
title="Remove per-agent allowlist and use all skills"
|
|
638
|
+
>
|
|
639
|
+
Reset
|
|
640
|
+
</button>
|
|
641
|
+
</div>
|
|
642
|
+
<button
|
|
643
|
+
class="btn btn--sm"
|
|
644
|
+
?disabled=${n.configLoading}
|
|
645
|
+
@click=${n.onConfigReload}
|
|
646
|
+
>
|
|
647
|
+
Reload Config
|
|
648
|
+
</button>
|
|
649
|
+
<button class="btn btn--sm" ?disabled=${n.loading} @click=${n.onRefresh}>
|
|
650
|
+
${n.loading?`Loading…`:`Refresh`}
|
|
651
|
+
</button>
|
|
652
|
+
<button
|
|
653
|
+
class="btn btn--sm primary"
|
|
654
|
+
?disabled=${n.configSaving||!n.configDirty}
|
|
655
|
+
@click=${n.onConfigSave}
|
|
656
|
+
>
|
|
657
|
+
${n.configSaving?`Saving…`:`Save`}
|
|
658
|
+
</button>
|
|
659
|
+
</div>
|
|
660
|
+
</div>
|
|
661
|
+
|
|
662
|
+
${n.configForm?t:e`
|
|
663
|
+
<div class="callout info" style="margin-top: 12px">
|
|
664
|
+
Load the gateway config to set per-agent skills.
|
|
665
|
+
</div>
|
|
666
|
+
`}
|
|
667
|
+
${s?e`
|
|
668
|
+
<div class="callout info" style="margin-top: 12px">
|
|
669
|
+
This agent uses a custom skill allowlist.
|
|
670
|
+
</div>
|
|
671
|
+
`:e`
|
|
672
|
+
<div class="callout info" style="margin-top: 12px">
|
|
673
|
+
All skills are enabled. Disabling any skill will create a per-agent allowlist.
|
|
674
|
+
</div>
|
|
675
|
+
`}
|
|
676
|
+
${!c&&!n.loading?e`
|
|
677
|
+
<div class="callout info" style="margin-top: 12px">
|
|
678
|
+
Load skills for this agent to view workspace-specific entries.
|
|
679
|
+
</div>
|
|
680
|
+
`:t}
|
|
681
|
+
${n.error?e`<div class="callout danger" style="margin-top: 12px;">${n.error}</div>`:t}
|
|
682
|
+
|
|
683
|
+
<div class="filters" style="margin-top: 14px;">
|
|
684
|
+
<label class="field" style="flex: 1;">
|
|
685
|
+
<span>Filter</span>
|
|
686
|
+
<input
|
|
687
|
+
.value=${n.filter}
|
|
688
|
+
@input=${e=>n.onFilterChange(e.target.value)}
|
|
689
|
+
placeholder="Search skills"
|
|
690
|
+
autocomplete="off"
|
|
691
|
+
name="agent-skills-filter"
|
|
692
|
+
/>
|
|
693
|
+
</label>
|
|
694
|
+
<div class="muted">${d.length} shown</div>
|
|
695
|
+
</div>
|
|
696
|
+
|
|
697
|
+
${d.length===0?e` <div class="muted" style="margin-top: 16px">No skills found.</div> `:e`
|
|
698
|
+
<div class="agent-skills-groups" style="margin-top: 16px;">
|
|
699
|
+
${f.map(e=>_e(e,{agentId:n.agentId,allowSet:o,usingAllowlist:s,editable:r,onToggle:n.onToggle}))}
|
|
700
|
+
</div>
|
|
701
|
+
`}
|
|
702
|
+
</section>
|
|
703
|
+
`}function _e(t,n){return e`
|
|
704
|
+
<details class="agent-skills-group" ?open=${!(t.id===`workspace`||t.id===`built-in`)}>
|
|
705
|
+
<summary class="agent-skills-header">
|
|
706
|
+
<span>${t.label}</span>
|
|
707
|
+
<span class="muted">${t.skills.length}</span>
|
|
708
|
+
</summary>
|
|
709
|
+
<div class="list skills-grid">
|
|
710
|
+
${t.skills.map(e=>ve(e,{agentId:n.agentId,allowSet:n.allowSet,usingAllowlist:n.usingAllowlist,editable:n.editable,onToggle:n.onToggle}))}
|
|
711
|
+
</div>
|
|
712
|
+
</details>
|
|
713
|
+
`}function ve(n,r){let i=r.usingAllowlist?r.allowSet.has(n.name):!0,a=M(n),o=A(n);return e`
|
|
714
|
+
<div class="list-item agent-skill-row">
|
|
715
|
+
<div class="list-main">
|
|
716
|
+
<div class="list-title">${n.emoji?`${n.emoji} `:``}${n.name}</div>
|
|
717
|
+
<div class="list-sub">${n.description}</div>
|
|
718
|
+
${j({skill:n})}
|
|
719
|
+
${a.length>0?e`<div class="muted" style="margin-top: 6px;">Missing: ${a.join(`, `)}</div>`:t}
|
|
720
|
+
${o.length>0?e`<div class="muted" style="margin-top: 6px;">Reason: ${o.join(`, `)}</div>`:t}
|
|
721
|
+
</div>
|
|
722
|
+
<div class="list-meta">
|
|
723
|
+
<label class="cfg-toggle">
|
|
724
|
+
<input
|
|
725
|
+
type="checkbox"
|
|
726
|
+
.checked=${i}
|
|
727
|
+
?disabled=${!r.editable}
|
|
728
|
+
@change=${e=>r.onToggle(r.agentId,n.name,e.target.checked)}
|
|
729
|
+
/>
|
|
730
|
+
<span class="cfg-toggle__track"></span>
|
|
731
|
+
</label>
|
|
732
|
+
</div>
|
|
733
|
+
</div>
|
|
734
|
+
`}function ye(n){let r=n.agentsList?.agents??[],i=n.agentsList?.defaultId??null,a=n.selectedAgentId??i??r[0]?.id??null,o=a?r.find(e=>e.id===a)??null:null,s=a&&n.agentSkills.agentId===a?n.agentSkills.report?.skills?.length??null:null,c=n.channels.snapshot?Object.keys(n.channels.snapshot.channelAccounts??{}).length:null,l=a?n.cron.jobs.filter(e=>e.agentId===a).length:null,u={files:n.agentFiles.list?.files?.length??null,skills:s,channels:c,cron:l||null};return e`
|
|
735
|
+
<div class="agents-layout">
|
|
736
|
+
<section class="agents-toolbar">
|
|
737
|
+
<div class="agents-toolbar-row">
|
|
738
|
+
<div class="agents-control-select">
|
|
739
|
+
<select
|
|
740
|
+
class="agents-select"
|
|
741
|
+
.value=${a??``}
|
|
742
|
+
?disabled=${n.loading||r.length===0}
|
|
743
|
+
@change=${e=>n.onSelectAgent(e.target.value)}
|
|
744
|
+
>
|
|
745
|
+
${r.length===0?e` <option value="">No agents</option> `:r.map(t=>e`
|
|
746
|
+
<option value=${t.id} ?selected=${t.id===a}>
|
|
747
|
+
${d(t)}${m(t.id,i)?` (${m(t.id,i)})`:``}
|
|
748
|
+
</option>
|
|
749
|
+
`)}
|
|
750
|
+
</select>
|
|
751
|
+
</div>
|
|
752
|
+
<div class="agents-toolbar-actions">
|
|
753
|
+
${o?e`
|
|
754
|
+
<button
|
|
755
|
+
type="button"
|
|
756
|
+
class="btn btn--sm btn--ghost"
|
|
757
|
+
@click=${()=>void navigator.clipboard.writeText(o.id)}
|
|
758
|
+
title="Copy agent ID to clipboard"
|
|
759
|
+
>
|
|
760
|
+
Copy ID
|
|
761
|
+
</button>
|
|
762
|
+
<button
|
|
763
|
+
type="button"
|
|
764
|
+
class="btn btn--sm btn--ghost"
|
|
765
|
+
?disabled=${!!(i&&o.id===i)}
|
|
766
|
+
@click=${()=>n.onSetDefault(o.id)}
|
|
767
|
+
title=${i&&o.id===i?`Already the default agent`:`Set as the default agent`}
|
|
768
|
+
>
|
|
769
|
+
${i&&o.id===i?`Default`:`Set Default`}
|
|
770
|
+
</button>
|
|
771
|
+
`:t}
|
|
772
|
+
<button
|
|
773
|
+
class="btn btn--sm agents-refresh-btn"
|
|
774
|
+
?disabled=${n.loading}
|
|
775
|
+
@click=${n.onRefresh}
|
|
776
|
+
>
|
|
777
|
+
${n.loading?`Loading…`:`Refresh`}
|
|
778
|
+
</button>
|
|
779
|
+
</div>
|
|
780
|
+
</div>
|
|
781
|
+
${n.error?e`<div class="callout danger" style="margin-top: 8px;">${n.error}</div>`:t}
|
|
782
|
+
</section>
|
|
783
|
+
<section class="agents-main">
|
|
784
|
+
${o?e`
|
|
785
|
+
${be(n.activePanel,e=>n.onSelectPanel(e),u)}
|
|
786
|
+
${n.activePanel===`overview`?N({agent:o,basePath:n.basePath,defaultId:i,configForm:n.config.form,agentFilesList:n.agentFiles.list,agentIdentity:n.agentIdentityById[o.id]??null,agentIdentityError:n.agentIdentityError,agentIdentityLoading:n.agentIdentityLoading,configLoading:n.config.loading,configSaving:n.config.saving,configDirty:n.config.dirty,modelCatalog:n.modelCatalog,onConfigReload:n.onConfigReload,onConfigSave:n.onConfigSave,onModelChange:n.onModelChange,onModelFallbacksChange:n.onModelFallbacksChange,onSelectPanel:n.onSelectPanel}):t}
|
|
787
|
+
${n.activePanel===`files`?fe({agentId:o.id,agentFilesList:n.agentFiles.list,agentFilesLoading:n.agentFiles.loading,agentFilesError:n.agentFiles.error,agentFileActive:n.agentFiles.active,agentFileContents:n.agentFiles.contents,agentFileDrafts:n.agentFiles.drafts,agentFileSaving:n.agentFiles.saving,onLoadFiles:n.onLoadFiles,onSelectFile:n.onSelectFile,onFileDraftChange:n.onFileDraftChange,onFileReset:n.onFileReset,onFileSave:n.onFileSave}):t}
|
|
788
|
+
${n.activePanel===`tools`?he({agentId:o.id,configForm:n.config.form,configLoading:n.config.loading,configSaving:n.config.saving,configDirty:n.config.dirty,toolsCatalogLoading:n.toolsCatalog.loading,toolsCatalogError:n.toolsCatalog.error,toolsCatalogResult:n.toolsCatalog.result,toolsEffectiveLoading:n.toolsEffective.loading,toolsEffectiveError:n.toolsEffective.error,toolsEffectiveResult:n.toolsEffective.result,runtimeSessionKey:n.runtimeSessionKey,runtimeSessionMatchesSelectedAgent:n.runtimeSessionMatchesSelectedAgent,onProfileChange:n.onToolsProfileChange,onOverridesChange:n.onToolsOverridesChange,onConfigReload:n.onConfigReload,onConfigSave:n.onConfigSave}):t}
|
|
789
|
+
${n.activePanel===`skills`?ge({agentId:o.id,report:n.agentSkills.report,loading:n.agentSkills.loading,error:n.agentSkills.error,activeAgentId:n.agentSkills.agentId,configForm:n.config.form,configLoading:n.config.loading,configSaving:n.config.saving,configDirty:n.config.dirty,filter:n.agentSkills.filter,onFilterChange:n.onSkillsFilterChange,onRefresh:n.onSkillsRefresh,onToggle:n.onAgentSkillToggle,onClear:n.onAgentSkillsClear,onDisableAll:n.onAgentSkillsDisableAll,onConfigReload:n.onConfigReload,onConfigSave:n.onConfigSave}):t}
|
|
790
|
+
${n.activePanel===`channels`?ue({context:x(o,n.config.form,n.agentFiles.list,i,n.agentIdentityById[o.id]??null),configForm:n.config.form,snapshot:n.channels.snapshot,loading:n.channels.loading,error:n.channels.error,lastSuccess:n.channels.lastSuccess,onRefresh:n.onChannelsRefresh,onSelectPanel:n.onSelectPanel}):t}
|
|
791
|
+
${n.activePanel===`cron`?de({context:x(o,n.config.form,n.agentFiles.list,i,n.agentIdentityById[o.id]??null),agentId:o.id,jobs:n.cron.jobs,status:n.cron.status,loading:n.cron.loading,error:n.cron.error,onRefresh:n.onCronRefresh,onRunNow:n.onCronRunNow,onSelectPanel:n.onSelectPanel}):t}
|
|
792
|
+
`:e`
|
|
793
|
+
<div class="card">
|
|
794
|
+
<div class="card-title">Select an agent</div>
|
|
795
|
+
<div class="card-sub">Pick an agent to inspect its workspace and tools.</div>
|
|
796
|
+
</div>
|
|
797
|
+
`}
|
|
798
|
+
</section>
|
|
799
|
+
</div>
|
|
800
|
+
`}function be(n,r,i){return e`
|
|
801
|
+
<div class="agent-tabs">
|
|
802
|
+
${[{id:`overview`,label:`Overview`},{id:`files`,label:`Files`},{id:`tools`,label:`Tools`},{id:`skills`,label:`Skills`},{id:`channels`,label:`Channels`},{id:`cron`,label:`Cron Jobs`}].map(a=>e`
|
|
803
|
+
<button
|
|
804
|
+
class="agent-tab ${n===a.id?`active`:``}"
|
|
805
|
+
type="button"
|
|
806
|
+
@click=${()=>r(a.id)}
|
|
807
|
+
>
|
|
808
|
+
${a.label}${i[a.id]==null?t:e`<span class="agent-tab-count">${i[a.id]}</span>`}
|
|
809
|
+
</button>
|
|
810
|
+
`)}
|
|
811
|
+
</div>
|
|
812
|
+
`}export{ye as renderAgents};
|
|
813
|
+
//# sourceMappingURL=agents-DIJiVfPj.js.map
|