@makemore/agent-frontend 2.9.0 → 2.11.0
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/chat-widget.cjs.js +330 -231
- package/dist/chat-widget.css +323 -1
- package/dist/chat-widget.esm.js +319 -220
- package/dist/chat-widget.js +285 -186
- package/dist/react.cjs.js +316 -217
- package/dist/react.esm.js +303 -204
- package/package.json +1 -1
- package/src/components/ChatWidget.js +18 -15
- package/src/components/ContentBlocks.js +203 -0
- package/src/components/Message.js +23 -0
- package/src/hooks/useChat.js +20 -0
- package/src/utils/config.js +3 -0
package/dist/chat-widget.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
<div class="cw-header" style=${{backgroundColor:
|
|
3
|
-
${w&&
|
|
1
|
+
var vt=Object.defineProperty;var kt=(e,t,s)=>t in e?vt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var Pe=(e,t,s)=>(kt(e,typeof t!="symbol"?t+"":t,s),s);import{render as yt}from"preact";import{html as Wt}from"htm/preact";import{html as G}from"htm/preact";import{useState as Y,useEffect as he,useCallback as ie,useMemo as Re}from"preact/hooks";import{html as te}from"htm/preact";function bt(e){return e.replace(/_([a-z])/g,(t,s)=>s.toUpperCase())}function Me(e){return e.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}function ge(e){return Array.isArray(e)?e.map(ge):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([t,s])=>[bt(t),ge(s)])):e}function fe(e){return Array.isArray(e)?e.map(fe):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([t,s])=>[Me(t),fe(s)])):e}function $e(){return"msg-"+Date.now()+"-"+Math.random().toString(36).substr(2,9)}function B(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}function Le(e){if(!e)return"";try{let t=new Date(e),n=new Date-t,o=Math.floor(n/6e4),r=Math.floor(n/36e5),y=Math.floor(n/864e5);return o<1?"Just now":o<60?`${o}m ago`:r<24?`${r}h ago`:y<7?`${y}d ago`:t.toLocaleDateString()}catch{return""}}function Ke(e,t=null){if(t)return t(e);let s=B(e);return s=s.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),s=s.replace(/__(.+?)__/g,"<strong>$1</strong>"),s=s.replace(/\*(.+?)\*/g,"<em>$1</em>"),s=s.replace(/_(.+?)_/g,"<em>$1</em>"),s=s.replace(/`(.+?)`/g,"<code>$1</code>"),s=s.replace(/\[(.+?)\]\((.+?)\)/g,'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'),s=s.replace(/\n/g,"<br>"),s}function Ne(e=""){let t=s=>e?`${s}_${e}`:s;return{get(s){try{return localStorage.getItem(t(s))}catch{return null}},set(s,n){try{let o=t(s);n===null?localStorage.removeItem(o):localStorage.setItem(o,n)}catch{}}}}function Be(e="csrftoken"){let t=document.cookie.split(";");for(let n of t){let[o,r]=n.trim().split("=");if(o===e)return decodeURIComponent(r)}let s=document.querySelector('meta[name="csrf-token"]');return s?s.getAttribute("content"):null}function ye(e){if(e===0)return"0 B";let t=1024,s=["B","KB","MB","GB"],n=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/Math.pow(t,n)).toFixed(1))+" "+s[n]}function we(e){return e?e.startsWith("image/")?"\u{1F5BC}\uFE0F":e.startsWith("video/")?"\u{1F3AC}":e.startsWith("audio/")?"\u{1F3B5}":e.includes("pdf")?"\u{1F4D5}":e.includes("spreadsheet")||e.includes("excel")?"\u{1F4CA}":e.includes("document")||e.includes("word")?"\u{1F4DD}":e.includes("presentation")||e.includes("powerpoint")?"\u{1F4FD}\uFE0F":e.includes("zip")||e.includes("compressed")?"\u{1F5DC}\uFE0F":(e.includes("text/"),"\u{1F4C4}"):"\u{1F4C4}"}function Ct(e){if(!e||typeof e!="string")return 0;let t=e.replace("#","");if(t.length!==6&&t.length!==3)return 0;let s=t.length===3?t.split("").map(i=>i+i).join(""):t,n=parseInt(s.substr(0,2),16)/255,o=parseInt(s.substr(2,2),16)/255,r=parseInt(s.substr(4,2),16)/255,y=i=>i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4);return .2126*y(n)+.7152*y(o)+.0722*y(r)}function He(e){return Ct(e)>.179?"#000000":"#ffffff"}function We({config:e,debugMode:t,isExpanded:s,isSpeaking:n,messagesCount:o,isLoading:r,currentAgent:y,onClose:i,onToggleExpand:$,onToggleDebug:g,onToggleTTS:u,onClear:b,onToggleSidebar:c}){let{title:C,primaryColor:l,embedded:f,showConversationSidebar:w,showClearButton:v,showDebugButton:_,enableDebugMode:m,showTTSButton:H,showExpandButton:U,enableTTS:A,elevenLabsApiKey:O,ttsProxyUrl:F}=e,L=O||F;return te`
|
|
2
|
+
<div class="cw-header" style=${{backgroundColor:l}}>
|
|
3
|
+
${w&&te`
|
|
4
4
|
<button
|
|
5
5
|
class="cw-header-btn cw-hamburger"
|
|
6
6
|
onClick=${c}
|
|
@@ -15,50 +15,50 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
15
15
|
`}
|
|
16
16
|
|
|
17
17
|
<div class="cw-title-container">
|
|
18
|
-
<span class="cw-title">${
|
|
19
|
-
${
|
|
18
|
+
<span class="cw-title">${B(C)}</span>
|
|
19
|
+
${y&&te`
|
|
20
20
|
<span class="cw-current-agent" title="Currently active agent">
|
|
21
21
|
<span class="cw-agent-indicator">🤖</span>
|
|
22
|
-
<span class="cw-agent-name">${
|
|
22
|
+
<span class="cw-agent-name">${B(y.name||y.key)}</span>
|
|
23
23
|
</span>
|
|
24
24
|
`}
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
27
|
<div class="cw-header-actions">
|
|
28
|
-
${v&&
|
|
28
|
+
${v&&te`
|
|
29
29
|
<button
|
|
30
30
|
class="cw-header-btn"
|
|
31
|
-
onClick=${
|
|
31
|
+
onClick=${b}
|
|
32
32
|
title="Clear"
|
|
33
|
-
disabled=${r||
|
|
33
|
+
disabled=${r||o===0}
|
|
34
34
|
>🗑️</button>
|
|
35
35
|
`}
|
|
36
36
|
|
|
37
|
-
${
|
|
37
|
+
${_&&m&&te`
|
|
38
38
|
<button
|
|
39
39
|
class="cw-header-btn ${t?"cw-btn-active":""}"
|
|
40
|
-
onClick=${
|
|
40
|
+
onClick=${g}
|
|
41
41
|
title="Debug"
|
|
42
42
|
>🐛</button>
|
|
43
43
|
`}
|
|
44
44
|
|
|
45
|
-
${
|
|
45
|
+
${H&&L&&te`
|
|
46
46
|
<button
|
|
47
|
-
class="cw-header-btn ${
|
|
47
|
+
class="cw-header-btn ${A?"cw-btn-active":""}"
|
|
48
48
|
onClick=${u}
|
|
49
49
|
title="TTS"
|
|
50
|
-
>${
|
|
50
|
+
>${A?"\u{1F50A}":"\u{1F507}"}</button>
|
|
51
51
|
`}
|
|
52
52
|
|
|
53
|
-
${U&&!
|
|
53
|
+
${U&&!f&&te`
|
|
54
54
|
<button
|
|
55
55
|
class="cw-header-btn"
|
|
56
|
-
onClick=${
|
|
56
|
+
onClick=${$}
|
|
57
57
|
title=${s?"Minimize":"Expand"}
|
|
58
58
|
>${s?"\u2296":"\u2295"}</button>
|
|
59
59
|
`}
|
|
60
60
|
|
|
61
|
-
${!
|
|
61
|
+
${!f&&te`
|
|
62
62
|
<button
|
|
63
63
|
class="cw-header-btn"
|
|
64
64
|
onClick=${i}
|
|
@@ -67,20 +67,107 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
67
67
|
`}
|
|
68
68
|
</div>
|
|
69
69
|
</div>
|
|
70
|
-
`}import{html as
|
|
70
|
+
`}import{html as ne}from"htm/preact";import{useRef as qe,useEffect as Ye}from"preact/hooks";import{html as K}from"htm/preact";import{useState as ke,useRef as Ot,useEffect as Ft}from"preact/hooks";import{html as x}from"htm/preact";import{useState as Ve}from"preact/hooks";function Ue({block:e,onAction:t,markdownParser:s}){return x`
|
|
71
|
+
<div class="cw-block-card">
|
|
72
|
+
${e.image&&x`<img class="cw-block-card-image" src=${e.image} alt=${e.title||""} />`}
|
|
73
|
+
<div class="cw-block-card-body">
|
|
74
|
+
${e.badge&&x`<span class="cw-block-card-badge">${e.badge}</span>`}
|
|
75
|
+
${e.title&&x`<div class="cw-block-card-title">${e.title}</div>`}
|
|
76
|
+
${e.subtitle&&x`<div class="cw-block-card-subtitle">${e.subtitle}</div>`}
|
|
77
|
+
${e.metadata&&e.metadata.length>0&&x`
|
|
78
|
+
<div class="cw-block-card-meta">
|
|
79
|
+
${e.metadata.map(n=>x`
|
|
80
|
+
<span class="cw-block-meta-pair">
|
|
81
|
+
<span class="cw-block-meta-label">${n.label}:</span> ${n.value}
|
|
82
|
+
</span>
|
|
83
|
+
`)}
|
|
84
|
+
</div>
|
|
85
|
+
`}
|
|
86
|
+
${e.actions&&e.actions.length>0&&x`
|
|
87
|
+
<div class="cw-block-card-actions">
|
|
88
|
+
${e.actions.map(n=>x`<${je} action=${n} onAction=${t} />`)}
|
|
89
|
+
</div>
|
|
90
|
+
`}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
`}function St({block:e,onAction:t,markdownParser:s}){let n=e.layout||"vertical";return x`
|
|
94
|
+
<div class="cw-block-card-list cw-block-card-list-${n}">
|
|
95
|
+
${(e.items||[]).map(o=>x`
|
|
96
|
+
<${Ue} block=${{type:"card",...o}} onAction=${t} markdownParser=${s} />
|
|
97
|
+
`)}
|
|
98
|
+
</div>
|
|
99
|
+
`}function je({action:e,onAction:t}){let s=e.style||"primary",n=()=>{t&&t(e)};return e.type==="link"?x`<a class="cw-block-btn cw-block-btn-${s}" href=${e.url} target="_blank" rel="noopener">${e.label}</a>`:x`<button class="cw-block-btn cw-block-btn-${s}" onClick=${n}>${e.label}</button>`}function Tt({block:e,onAction:t}){return x`
|
|
100
|
+
<div class="cw-block-action-buttons">
|
|
101
|
+
${(e.buttons||[]).map(s=>x`<${je} action=${s} onAction=${t} />`)}
|
|
102
|
+
</div>
|
|
103
|
+
`}function _t({block:e}){let t=e.style||"info";return x`
|
|
104
|
+
<div class="cw-block-callout cw-block-callout-${t}">
|
|
105
|
+
<span class="cw-block-callout-icon">${{info:"\u2139\uFE0F",success:"\u2705",warning:"\u26A0\uFE0F"}[t]||"\u2139\uFE0F"}</span>
|
|
106
|
+
<div class="cw-block-callout-content">
|
|
107
|
+
${e.title&&x`<strong>${e.title}</strong>`}
|
|
108
|
+
${e.body&&x`<span>${e.body}</span>`}
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
`}function Mt({block:e}){return x`
|
|
112
|
+
<figure class="cw-block-image">
|
|
113
|
+
<img src=${e.url} alt=${e.alt||""} />
|
|
114
|
+
${e.caption&&x`<figcaption>${e.caption}</figcaption>`}
|
|
115
|
+
</figure>
|
|
116
|
+
`}function Et(){return x`<hr class="cw-block-divider" />`}function It({block:e}){return x`
|
|
117
|
+
<div class="cw-block-table-wrapper">
|
|
118
|
+
<table class="cw-block-table">
|
|
119
|
+
${e.headers&&e.headers.length>0&&x`
|
|
120
|
+
<thead><tr>${e.headers.map(t=>x`<th>${t}</th>`)}</tr></thead>
|
|
121
|
+
`}
|
|
122
|
+
<tbody>
|
|
123
|
+
${(e.rows||[]).map(t=>x`
|
|
124
|
+
<tr>${t.map(s=>x`<td>${s}</td>`)}</tr>
|
|
125
|
+
`)}
|
|
126
|
+
</tbody>
|
|
127
|
+
</table>
|
|
128
|
+
</div>
|
|
129
|
+
`}function xt({block:e}){let[t,s]=Ve(!1),n=()=>{navigator.clipboard.writeText(e.code).then(()=>{s(!0),setTimeout(()=>s(!1),1500)})};return x`
|
|
130
|
+
<div class="cw-block-code">
|
|
131
|
+
${e.filename&&x`<div class="cw-block-code-filename">${e.filename}</div>`}
|
|
132
|
+
<pre><code>${B(e.code)}</code></pre>
|
|
133
|
+
${e.copyable!==!1&&x`
|
|
134
|
+
<button class="cw-block-code-copy" onClick=${n}>${t?"\u2713":"\u2398"}</button>
|
|
135
|
+
`}
|
|
136
|
+
</div>
|
|
137
|
+
`}function At({block:e}){let[t,s]=Ve(e.defaultOpen||!1);return x`
|
|
138
|
+
<details class="cw-block-collapsible" open=${t} onClick=${n=>{n.preventDefault(),s(!t)}}>
|
|
139
|
+
<summary>${e.title}</summary>
|
|
140
|
+
<div class="cw-block-collapsible-body">${e.body}</div>
|
|
141
|
+
</details>
|
|
142
|
+
`}function Rt({block:e}){let t={loading:"\u23F3",success:"\u2705",error:"\u274C",warning:"\u26A0\uFE0F",info:"\u2139\uFE0F"};return x`
|
|
143
|
+
<div class="cw-block-status cw-block-status-${e.state||"info"}">
|
|
144
|
+
<span class="cw-block-status-icon">${t[e.state]||"\u2139\uFE0F"}</span>
|
|
145
|
+
<div>
|
|
146
|
+
<strong>${e.title}</strong>
|
|
147
|
+
${e.body&&x`<div>${e.body}</div>`}
|
|
148
|
+
${e.progress!=null&&x`
|
|
149
|
+
<div class="cw-block-progress"><div class="cw-block-progress-bar" style=${{width:`${e.progress*100}%`}}></div></div>
|
|
150
|
+
`}
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
`}var Dt={card:Ue,cardList:St,actionButtons:Tt,callout:_t,image:Mt,divider:Et,table:It,code:xt,collapsible:At,status:Rt};function Je({blocks:e,onAction:t,markdownParser:s}){return!e||e.length===0?null:x`
|
|
154
|
+
<div class="cw-content-blocks">
|
|
155
|
+
${e.map((n,o)=>{let r=Dt[n.type];return r?x`<${r} key=${o} block=${n} onAction=${t} markdownParser=${s} />`:null})}
|
|
156
|
+
</div>
|
|
157
|
+
`}function ve({msg:e,show:t,onToggle:s}){return t?K`
|
|
71
158
|
<div class="cw-debug-payload">
|
|
72
159
|
<button class="cw-debug-payload-close" onClick=${s}>×</button>
|
|
73
160
|
<pre class="cw-debug-payload-content">${JSON.stringify(e,null,2)}</pre>
|
|
74
161
|
</div>
|
|
75
|
-
`:
|
|
162
|
+
`:K`
|
|
76
163
|
<button
|
|
77
164
|
class="cw-debug-payload-btn"
|
|
78
165
|
onClick=${s}
|
|
79
166
|
title="Show message payload"
|
|
80
167
|
>{ }</button>
|
|
81
|
-
`}function
|
|
168
|
+
`}function ze({onEdit:e,onRetry:t,isLoading:s,position:n,showEdit:o=!0}){return s?null:K`
|
|
82
169
|
<div class="cw-message-actions cw-message-actions-${n||"left"}">
|
|
83
|
-
${
|
|
170
|
+
${o&&K`
|
|
84
171
|
<button
|
|
85
172
|
class="cw-message-action-btn"
|
|
86
173
|
onClick=${e}
|
|
@@ -104,14 +191,14 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
104
191
|
</svg>
|
|
105
192
|
</button>
|
|
106
193
|
</div>
|
|
107
|
-
`}function
|
|
194
|
+
`}function Pt({initialContent:e,onSave:t,onCancel:s}){let[n,o]=ke(e),r=Ot(null);return Ft(()=>{r.current&&(r.current.focus(),r.current.setSelectionRange(n.length,n.length),r.current.style.height="auto",r.current.style.height=r.current.scrollHeight+"px")},[]),K`
|
|
108
195
|
<div class="cw-inline-edit">
|
|
109
196
|
<textarea
|
|
110
197
|
ref=${r}
|
|
111
198
|
class="cw-inline-edit-input"
|
|
112
199
|
value=${n}
|
|
113
|
-
onInput=${
|
|
114
|
-
onKeyDown=${
|
|
200
|
+
onInput=${$=>{o($.target.value),$.target.style.height="auto",$.target.style.height=$.target.scrollHeight+"px"}}
|
|
201
|
+
onKeyDown=${$=>{$.key==="Enter"&&!$.shiftKey?($.preventDefault(),n.trim()&&t(n.trim())):$.key==="Escape"&&s()}}
|
|
115
202
|
rows="1"
|
|
116
203
|
/>
|
|
117
204
|
<div class="cw-inline-edit-actions">
|
|
@@ -128,111 +215,120 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
128
215
|
>Save & Send</button>
|
|
129
216
|
</div>
|
|
130
217
|
</div>
|
|
131
|
-
`}function
|
|
132
|
-
<div class="cw-agent-context ${
|
|
133
|
-
<span class="cw-agent-context-icon">${
|
|
218
|
+
`}function Ge({msg:e,debugMode:t,markdownParser:s,onEdit:n,onRetry:o,isLoading:r,messageIndex:y}){let[i,$]=ke(!1),[g,u]=ke(!1),[b,c]=ke(!1),C=e.role==="user",l=e.role==="system",f=e.type==="tool_call",w=e.type==="tool_result",v=e.type==="error",_=e.type==="sub_agent_start",m=e.type==="sub_agent_end",H=e.type==="agent_context";if(l&&!t)return null;if(_||m||H)return K`
|
|
219
|
+
<div class="cw-agent-context ${_?"cw-agent-delegating":""} ${m?"cw-agent-returned":""}" style="position: relative;">
|
|
220
|
+
<span class="cw-agent-context-icon">${_?"\u{1F517}":m?"\u2713":"\u{1F916}"}</span>
|
|
134
221
|
<span class="cw-agent-context-text">${e.content}</span>
|
|
135
|
-
${e.metadata?.agentName&&
|
|
222
|
+
${e.metadata?.agentName&&K`
|
|
136
223
|
<span class="cw-agent-context-name">${e.metadata.agentName}</span>
|
|
137
224
|
`}
|
|
138
|
-
${t&&
|
|
225
|
+
${t&&K`<${ve} msg=${e} show=${g} onToggle=${()=>u(!g)} />`}
|
|
226
|
+
</div>
|
|
227
|
+
`;if(e.type==="content_blocks"&&e.metadata?.blocks){let k=T=>{T.type==="message"&&e._onSendMessage&&e._onSendMessage(T.message),T.type==="callback"&&e._onCallback&&e._onCallback(T.callbackId)};return K`
|
|
228
|
+
<div class="cw-message-row" style="position: relative;">
|
|
229
|
+
<${Je}
|
|
230
|
+
blocks=${e.metadata.blocks}
|
|
231
|
+
onAction=${k}
|
|
232
|
+
markdownParser=${s}
|
|
233
|
+
/>
|
|
234
|
+
${t&&K`<${ve} msg=${e} show=${g} onToggle=${()=>u(!g)} />`}
|
|
139
235
|
</div>
|
|
140
|
-
|
|
236
|
+
`}if(f||w){let k=e.metadata?.arguments||e.metadata?.result,T=d=>{if(typeof d=="string")try{return JSON.stringify(JSON.parse(d),null,2)}catch{return d}return JSON.stringify(d,null,2)};return K`
|
|
141
237
|
<div class="cw-tool-message ${w?"cw-tool-result":"cw-tool-call"}" style="position: relative;">
|
|
142
|
-
<span class="cw-tool-label" onClick=${()=>
|
|
238
|
+
<span class="cw-tool-label" onClick=${()=>k&&$(!i)}>
|
|
143
239
|
${e.content}
|
|
144
|
-
${
|
|
240
|
+
${k&&K`<span class="cw-tool-expand">${i?"\u25BC":"\u25B6"}</span>`}
|
|
145
241
|
</span>
|
|
146
|
-
${i&&
|
|
147
|
-
<pre class="cw-tool-details">${
|
|
242
|
+
${i&&k&&K`
|
|
243
|
+
<pre class="cw-tool-details">${B(T(f?e.metadata.arguments:e.metadata.result))}</pre>
|
|
148
244
|
`}
|
|
149
|
-
${t&&
|
|
245
|
+
${t&&K`<${ve} msg=${e} show=${g} onToggle=${()=>u(!g)} />`}
|
|
150
246
|
</div>
|
|
151
|
-
`}let U=["cw-message",
|
|
247
|
+
`}let U=["cw-message",C&&"cw-message-user",v&&"cw-message-error"].filter(Boolean).join(" "),A=`cw-message-row ${C?"cw-message-row-user":""}`,O=e.role==="assistant"?Ke(e.content,s):B(e.content),F=e.files&&e.files.length>0,L=()=>F?K`
|
|
152
248
|
<div class="cw-message-attachments">
|
|
153
|
-
${e.files.map(
|
|
154
|
-
<a class="cw-attachment-thumbnail" href=${
|
|
155
|
-
<img src=${
|
|
249
|
+
${e.files.map(k=>k.type&&k.type.startsWith("image/")?K`
|
|
250
|
+
<a class="cw-attachment-thumbnail" href=${k.url} target="_blank" title=${k.name}>
|
|
251
|
+
<img src=${k.url} alt=${k.name} />
|
|
156
252
|
</a>
|
|
157
|
-
`:
|
|
158
|
-
<a class="cw-attachment-file" href=${
|
|
159
|
-
<span class="cw-attachment-icon">${
|
|
253
|
+
`:K`
|
|
254
|
+
<a class="cw-attachment-file" href=${k.url} target="_blank" title=${k.name}>
|
|
255
|
+
<span class="cw-attachment-icon">${we(k.type)}</span>
|
|
160
256
|
<span class="cw-attachment-info">
|
|
161
|
-
<span class="cw-attachment-name">${
|
|
162
|
-
<span class="cw-attachment-size">${
|
|
257
|
+
<span class="cw-attachment-name">${k.name}</span>
|
|
258
|
+
<span class="cw-attachment-size">${ye(k.size)}</span>
|
|
163
259
|
</span>
|
|
164
260
|
</a>
|
|
165
261
|
`)}
|
|
166
262
|
</div>
|
|
167
|
-
`:null,
|
|
168
|
-
<div class=${
|
|
169
|
-
${
|
|
170
|
-
<${
|
|
263
|
+
`:null,j=k=>{c(!1),n&&n(y,k)},W=()=>{o&&o(y)};if(C&&b)return K`
|
|
264
|
+
<div class=${A} style="position: relative;">
|
|
265
|
+
${L()}
|
|
266
|
+
<${Pt}
|
|
171
267
|
initialContent=${e.content}
|
|
172
|
-
onSave=${
|
|
268
|
+
onSave=${j}
|
|
173
269
|
onCancel=${()=>c(!1)}
|
|
174
270
|
/>
|
|
175
271
|
</div>
|
|
176
|
-
`;let h=
|
|
177
|
-
<div class="${
|
|
178
|
-
${
|
|
179
|
-
${h&&
|
|
272
|
+
`;let h=C&&n&&o,p=e.role==="assistant"&&o&&!r;return K`
|
|
273
|
+
<div class="${A} ${h||p?"cw-message-row-with-actions":""}">
|
|
274
|
+
${L()}
|
|
275
|
+
${h&&K`
|
|
180
276
|
<div class="cw-user-actions-wrapper">
|
|
181
|
-
<${
|
|
277
|
+
<${ze}
|
|
182
278
|
onEdit=${()=>c(!0)}
|
|
183
279
|
onRetry=${W}
|
|
184
280
|
isLoading=${r}
|
|
185
281
|
position="left"
|
|
186
282
|
showEdit=${!0}
|
|
187
283
|
/>
|
|
188
|
-
<div class=${U} dangerouslySetInnerHTML=${{__html:
|
|
284
|
+
<div class=${U} dangerouslySetInnerHTML=${{__html:O}} />
|
|
189
285
|
</div>
|
|
190
286
|
`}
|
|
191
|
-
${!h&&
|
|
192
|
-
<div class=${U} dangerouslySetInnerHTML=${{__html:
|
|
287
|
+
${!h&&K`
|
|
288
|
+
<div class=${U} dangerouslySetInnerHTML=${{__html:O}} />
|
|
193
289
|
`}
|
|
194
|
-
${p&&
|
|
195
|
-
<${
|
|
290
|
+
${p&&K`
|
|
291
|
+
<${ze}
|
|
196
292
|
onRetry=${W}
|
|
197
293
|
isLoading=${r}
|
|
198
294
|
position="right"
|
|
199
295
|
showEdit=${!1}
|
|
200
296
|
/>
|
|
201
297
|
`}
|
|
202
|
-
${t&&
|
|
298
|
+
${t&&K`<${ve} msg=${e} show=${g} onToggle=${()=>u(!g)} />`}
|
|
203
299
|
</div>
|
|
204
|
-
`}function
|
|
205
|
-
<div class="cw-messages" ref=${
|
|
206
|
-
${
|
|
300
|
+
`}function Xe({messages:e,isLoading:t,hasMoreMessages:s,loadingMoreMessages:n,onLoadMore:o,onEditMessage:r,onRetryMessage:y,debugMode:i,markdownParser:$,emptyStateTitle:g,emptyStateMessage:u}){let b=qe(null),c=qe(!0),C=f=>{let w=f.target,v=w.scrollHeight-w.scrollTop-w.clientHeight<100;if(c.current=v,w.scrollTop<50&&s&&!n){let _=w.scrollHeight;o().then(()=>{let m=w.scrollHeight;w.scrollTop=m-_+w.scrollTop})}};Ye(()=>{let f=b.current;f&&c.current&&requestAnimationFrame(()=>{f.scrollTop=f.scrollHeight})},[e,t]),Ye(()=>{let f=b.current;f&&e.length<=2&&(c.current=!0,requestAnimationFrame(()=>{f.scrollTop=f.scrollHeight}))},[e.length]);let l=e.length===0;return ne`
|
|
301
|
+
<div class="cw-messages" ref=${b} onScroll=${C}>
|
|
302
|
+
${l&&ne`
|
|
207
303
|
<div class="cw-empty-state">
|
|
208
304
|
<svg class="cw-empty-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
209
305
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
|
210
306
|
</svg>
|
|
211
|
-
<h3>${
|
|
212
|
-
<p>${
|
|
307
|
+
<h3>${B(g)}</h3>
|
|
308
|
+
<p>${B(u)}</p>
|
|
213
309
|
</div>
|
|
214
310
|
`}
|
|
215
311
|
|
|
216
|
-
${!
|
|
217
|
-
<div class="cw-load-more" onClick=${
|
|
218
|
-
${n?
|
|
312
|
+
${!l&&s&&ne`
|
|
313
|
+
<div class="cw-load-more" onClick=${o}>
|
|
314
|
+
${n?ne`<span class="cw-spinner"></span><span>Loading...</span>`:ne`<span>↑ Scroll up or click to load older messages</span>`}
|
|
219
315
|
</div>
|
|
220
316
|
`}
|
|
221
317
|
|
|
222
|
-
${e.map((
|
|
223
|
-
<${
|
|
224
|
-
key=${
|
|
225
|
-
msg=${
|
|
318
|
+
${e.map((f,w)=>ne`
|
|
319
|
+
<${Ge}
|
|
320
|
+
key=${f.id}
|
|
321
|
+
msg=${f}
|
|
226
322
|
messageIndex=${w}
|
|
227
323
|
debugMode=${i}
|
|
228
|
-
markdownParser=${
|
|
324
|
+
markdownParser=${$}
|
|
229
325
|
onEdit=${r}
|
|
230
|
-
onRetry=${
|
|
326
|
+
onRetry=${y}
|
|
231
327
|
isLoading=${t}
|
|
232
328
|
/>
|
|
233
329
|
`)}
|
|
234
330
|
|
|
235
|
-
${t&&
|
|
331
|
+
${t&&ne`
|
|
236
332
|
<div class="cw-message-row">
|
|
237
333
|
<div class="cw-typing">
|
|
238
334
|
<span class="cw-spinner"></span>
|
|
@@ -241,23 +337,23 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
241
337
|
</div>
|
|
242
338
|
`}
|
|
243
339
|
</div>
|
|
244
|
-
`}import{html as
|
|
340
|
+
`}import{html as Z}from"htm/preact";import{useState as ce,useRef as be,useEffect as Ee}from"preact/hooks";var Ie=typeof window<"u"?window.SpeechRecognition||window.webkitSpeechRecognition:null;function Ze({onSend:e,onCancel:t,isLoading:s,placeholder:n,primaryColor:o,enableVoice:r=!0,enableFiles:y=!0}){let[i,$]=ce(""),[g,u]=ce([]),[b,c]=ce(!1),[C,l]=ce(!1),[f]=ce(()=>!!Ie),w=be(null),v=be(null),_=be(null),m=be(!1);Ee(()=>{!s&&w.current&&w.current.focus()},[s]),Ee(()=>{w.current&&(w.current.style.height="auto",w.current.style.height=Math.min(w.current.scrollHeight,150)+"px")},[i]),Ee(()=>()=>{m.current=!1,_.current&&_.current.abort()},[]);let H=d=>{d.preventDefault(),(i.trim()||g.length>0)&&!s&&(e(i,g),$(""),u([]),w.current&&(w.current.style.height="auto"),v.current&&(v.current.value=""))},U=d=>{let R=Array.from(d.target.files||[]);R.length>0&&u(D=>[...D,...R])},A=d=>{u(R=>R.filter((D,a)=>a!==d))},O=d=>{d.preventDefault(),v.current&&!s&&v.current.click()},F=d=>{d.key==="Enter"&&!d.shiftKey&&(d.preventDefault(),H(d))},L=d=>{s&&t&&(d.preventDefault(),t())},j=()=>{if(!Ie||s)return;m.current=!0;let d=new Ie;d.continuous=!0,d.interimResults=!0,d.lang=navigator.language||"en-US";let R=i,D="";d.onstart=()=>{l(!0)},d.onresult=a=>{D="";for(let M=a.resultIndex;M<a.results.length;M++){let N=a.results[M][0].transcript;a.results[M].isFinal?R+=(R?" ":"")+N:D+=N}$(R+(D?" "+D:""))},d.onerror=a=>{if(a.error==="no-speech"||a.error==="aborted"){console.log("[ChatWidget] Speech recognition:",a.error,"- continuing...");return}console.warn("[ChatWidget] Speech recognition error:",a.error),m.current=!1,l(!1),$(R||i)},d.onend=()=>{if(m.current){console.log("[ChatWidget] Recognition paused, restarting...");try{d.start();return}catch(a){console.warn("[ChatWidget] Could not restart recognition:",a)}}l(!1),R&&$(R),_.current=null},_.current=d,d.start()},W=()=>{m.current=!1,_.current&&_.current.stop()},h=d=>{d.preventDefault(),C?W():j()},I=Z`
|
|
245
341
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor">
|
|
246
342
|
<rect x="2" y="2" width="10" height="10" rx="1" />
|
|
247
343
|
</svg>
|
|
248
|
-
`,p=
|
|
344
|
+
`,p=Z`
|
|
249
345
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
250
346
|
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path>
|
|
251
347
|
<path d="M19 10v2a7 7 0 0 1-14 0v-2"></path>
|
|
252
348
|
<line x1="12" y1="19" x2="12" y2="23"></line>
|
|
253
349
|
<line x1="8" y1="23" x2="16" y2="23"></line>
|
|
254
350
|
</svg>
|
|
255
|
-
`,
|
|
351
|
+
`,S=Z`
|
|
256
352
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
257
353
|
<path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"></path>
|
|
258
354
|
</svg>
|
|
259
|
-
`,
|
|
260
|
-
<form class="cw-input-form" onSubmit=${
|
|
355
|
+
`,k=r&&f,T=y;return Z`
|
|
356
|
+
<form class="cw-input-form" onSubmit=${H}>
|
|
261
357
|
<input
|
|
262
358
|
type="file"
|
|
263
359
|
ref=${v}
|
|
@@ -265,17 +361,17 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
265
361
|
multiple
|
|
266
362
|
onChange=${U}
|
|
267
363
|
/>
|
|
268
|
-
${
|
|
364
|
+
${g.length>0&&Z`
|
|
269
365
|
<div class="cw-file-chips">
|
|
270
|
-
${
|
|
271
|
-
<div class="cw-file-chip" key=${
|
|
272
|
-
<span class="cw-file-chip-icon">${
|
|
366
|
+
${g.map((d,R)=>Z`
|
|
367
|
+
<div class="cw-file-chip" key=${R}>
|
|
368
|
+
<span class="cw-file-chip-icon">${we(d.type)}</span>
|
|
273
369
|
<span class="cw-file-chip-name" title=${d.name}>${d.name.length>20?d.name.substring(0,17)+"...":d.name}</span>
|
|
274
|
-
<span class="cw-file-chip-size">(${
|
|
370
|
+
<span class="cw-file-chip-size">(${ye(d.size)})</span>
|
|
275
371
|
<button
|
|
276
372
|
type="button"
|
|
277
373
|
class="cw-file-chip-remove"
|
|
278
|
-
onClick=${()=>
|
|
374
|
+
onClick=${()=>A(R)}
|
|
279
375
|
title="Remove file"
|
|
280
376
|
>×</button>
|
|
281
377
|
</div>
|
|
@@ -285,52 +381,52 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
285
381
|
<textarea
|
|
286
382
|
ref=${w}
|
|
287
383
|
class="cw-input"
|
|
288
|
-
placeholder=${
|
|
384
|
+
placeholder=${B(n)}
|
|
289
385
|
value=${i}
|
|
290
|
-
onInput=${d
|
|
291
|
-
onKeyDown=${
|
|
386
|
+
onInput=${d=>$(d.target.value)}
|
|
387
|
+
onKeyDown=${F}
|
|
292
388
|
disabled=${s}
|
|
293
389
|
rows="1"
|
|
294
390
|
/>
|
|
295
|
-
${
|
|
391
|
+
${T&&Z`
|
|
296
392
|
<button
|
|
297
393
|
type="button"
|
|
298
394
|
class="cw-attach-btn"
|
|
299
|
-
onClick=${
|
|
395
|
+
onClick=${O}
|
|
300
396
|
disabled=${s}
|
|
301
397
|
title="Attach files"
|
|
302
398
|
>
|
|
303
|
-
${
|
|
399
|
+
${S}
|
|
304
400
|
</button>
|
|
305
401
|
`}
|
|
306
|
-
${
|
|
402
|
+
${k&&Z`
|
|
307
403
|
<button
|
|
308
404
|
type="button"
|
|
309
|
-
class=${`cw-voice-btn ${
|
|
405
|
+
class=${`cw-voice-btn ${C?"cw-voice-btn-recording":""}`}
|
|
310
406
|
onClick=${h}
|
|
311
407
|
disabled=${s}
|
|
312
|
-
title=${
|
|
408
|
+
title=${C?"Stop recording":"Voice input"}
|
|
313
409
|
>
|
|
314
410
|
${p}
|
|
315
411
|
</button>
|
|
316
412
|
`}
|
|
317
413
|
<button
|
|
318
414
|
type=${s?"button":"submit"}
|
|
319
|
-
class=${`cw-send-btn ${s?"cw-send-btn-loading":""} ${s&&
|
|
320
|
-
style=${{backgroundColor:s&&
|
|
321
|
-
onClick=${
|
|
415
|
+
class=${`cw-send-btn ${s?"cw-send-btn-loading":""} ${s&&b?"cw-send-btn-stop":""}`}
|
|
416
|
+
style=${{backgroundColor:s&&b?"#dc2626":o}}
|
|
417
|
+
onClick=${L}
|
|
322
418
|
onMouseEnter=${()=>c(!0)}
|
|
323
419
|
onMouseLeave=${()=>c(!1)}
|
|
324
420
|
title=${s?"Stop":"Send"}
|
|
325
421
|
>
|
|
326
|
-
${s?
|
|
422
|
+
${s?b?I:Z`<span class="cw-spinner"></span>`:"\u27A4"}
|
|
327
423
|
</button>
|
|
328
424
|
</form>
|
|
329
|
-
`}import{html as
|
|
425
|
+
`}import{html as Ce}from"htm/preact";function Qe({isOpen:e,conversations:t,conversationsLoading:s,currentConversationId:n,onClose:o,onNewConversation:r,onSwitchConversation:y}){return Ce`
|
|
330
426
|
<div class="cw-sidebar ${e?"cw-sidebar-open":""}">
|
|
331
427
|
<div class="cw-sidebar-header">
|
|
332
428
|
<span>Conversations</span>
|
|
333
|
-
<button class="cw-sidebar-close" onClick=${
|
|
429
|
+
<button class="cw-sidebar-close" onClick=${o}>✕</button>
|
|
334
430
|
</div>
|
|
335
431
|
|
|
336
432
|
<button class="cw-new-conversation" onClick=${r}>
|
|
@@ -338,24 +434,24 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
338
434
|
</button>
|
|
339
435
|
|
|
340
436
|
<div class="cw-conversation-list">
|
|
341
|
-
${s&&
|
|
437
|
+
${s&&Ce`
|
|
342
438
|
<div class="cw-sidebar-loading">
|
|
343
439
|
<span class="cw-spinner"></span>
|
|
344
440
|
</div>
|
|
345
441
|
`}
|
|
346
442
|
|
|
347
|
-
${!s&&t.length===0&&
|
|
443
|
+
${!s&&t.length===0&&Ce`
|
|
348
444
|
<div class="cw-sidebar-empty">No conversations yet</div>
|
|
349
445
|
`}
|
|
350
446
|
|
|
351
|
-
${t.map(i=>
|
|
447
|
+
${t.map(i=>Ce`
|
|
352
448
|
<div
|
|
353
449
|
key=${i.id}
|
|
354
450
|
class="cw-conversation-item ${i.id===n?"cw-conversation-active":""}"
|
|
355
|
-
onClick=${()
|
|
451
|
+
onClick=${()=>y(i.id)}
|
|
356
452
|
>
|
|
357
|
-
<div class="cw-conversation-title">${
|
|
358
|
-
<div class="cw-conversation-date">${
|
|
453
|
+
<div class="cw-conversation-title">${B(i.title||"Untitled")}</div>
|
|
454
|
+
<div class="cw-conversation-date">${Le(i.updatedAt||i.createdAt)}</div>
|
|
359
455
|
</div>
|
|
360
456
|
`)}
|
|
361
457
|
</div>
|
|
@@ -363,25 +459,25 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
363
459
|
|
|
364
460
|
<div
|
|
365
461
|
class="cw-sidebar-overlay ${e?"cw-sidebar-overlay-visible":""}"
|
|
366
|
-
onClick=${
|
|
462
|
+
onClick=${o}
|
|
367
463
|
/>
|
|
368
|
-
`}import{html as
|
|
464
|
+
`}import{html as re}from"htm/preact";import{useState as Lt}from"preact/hooks";function et({availableModels:e,selectedModel:t,onSelectModel:s,thinkingEnabled:n,onToggleThinking:o,disabled:r}){let[y,i]=Lt(!1);if(!e||e.length===0)return null;let $=e.find(l=>l.id===t),g=$?.name||"Select Model",u=$?.supports_thinking||!1,b=()=>{r||i(!y)},c=l=>{s(l),i(!1)},C=l=>{l.stopPropagation(),o&&u&&o(!n)};return re`
|
|
369
465
|
<div class="cw-model-selector">
|
|
370
466
|
<button
|
|
371
467
|
class="cw-model-btn"
|
|
372
|
-
onClick=${
|
|
468
|
+
onClick=${b}
|
|
373
469
|
disabled=${r}
|
|
374
470
|
title="Select Model"
|
|
375
471
|
>
|
|
376
472
|
<span class="cw-model-icon">🤖</span>
|
|
377
|
-
<span class="cw-model-name">${
|
|
378
|
-
<span class="cw-model-chevron">${
|
|
473
|
+
<span class="cw-model-name">${B(g)}</span>
|
|
474
|
+
<span class="cw-model-chevron">${y?"\u25B2":"\u25BC"}</span>
|
|
379
475
|
</button>
|
|
380
476
|
|
|
381
|
-
${u&&
|
|
477
|
+
${u&&o&&re`
|
|
382
478
|
<button
|
|
383
479
|
class="cw-thinking-toggle ${n?"cw-thinking-enabled":""}"
|
|
384
|
-
onClick=${
|
|
480
|
+
onClick=${C}
|
|
385
481
|
disabled=${r}
|
|
386
482
|
title=${n?"Thinking enabled - click to disable":"Enable extended thinking"}
|
|
387
483
|
>
|
|
@@ -389,48 +485,48 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
389
485
|
</button>
|
|
390
486
|
`}
|
|
391
487
|
|
|
392
|
-
${
|
|
488
|
+
${y&&re`
|
|
393
489
|
<div class="cw-model-dropdown">
|
|
394
|
-
${e.map(
|
|
490
|
+
${e.map(l=>re`
|
|
395
491
|
<button
|
|
396
|
-
key=${
|
|
397
|
-
class="cw-model-option ${
|
|
398
|
-
onClick=${()=>c(
|
|
492
|
+
key=${l.id}
|
|
493
|
+
class="cw-model-option ${l.id===t?"cw-model-option-selected":""}"
|
|
494
|
+
onClick=${()=>c(l.id)}
|
|
399
495
|
>
|
|
400
496
|
<span class="cw-model-option-name">
|
|
401
|
-
${
|
|
402
|
-
${
|
|
497
|
+
${B(l.name)}
|
|
498
|
+
${l.supports_thinking&&re`<span class="cw-thinking-badge" title="Supports extended thinking">🧠</span>`}
|
|
403
499
|
</span>
|
|
404
|
-
<span class="cw-model-option-provider">${
|
|
405
|
-
${
|
|
406
|
-
<span class="cw-model-option-desc">${
|
|
500
|
+
<span class="cw-model-option-provider">${B(l.provider)}</span>
|
|
501
|
+
${l.description&&re`
|
|
502
|
+
<span class="cw-model-option-desc">${B(l.description)}</span>
|
|
407
503
|
`}
|
|
408
504
|
</button>
|
|
409
505
|
`)}
|
|
410
506
|
</div>
|
|
411
507
|
`}
|
|
412
508
|
</div>
|
|
413
|
-
`}import{html as
|
|
414
|
-
<div class="cw-task-item ${
|
|
509
|
+
`}import{html as Q}from"htm/preact";import{useState as tt,useCallback as de}from"preact/hooks";var Kt={not_started:"\u25CB",in_progress:"\u25D0",complete:"\u25CF",cancelled:"\u2298"},Nt={not_started:"Not Started",in_progress:"In Progress",complete:"Complete",cancelled:"Cancelled"};function Bt({task:e,onUpdate:t,onRemove:s,depth:n=0}){let[o,r]=tt(!1),[y,i]=tt(e.name),$=de(()=>{let c={not_started:"in_progress",in_progress:"complete",complete:"not_started",cancelled:"not_started"};t(e.id,{state:c[e.state]||"not_started"})},[e,t]),g=de(()=>{y.trim()&&y!==e.name&&t(e.id,{name:y.trim()}),r(!1)},[e,y,t]),u=de(c=>{c.key==="Enter"&&g(),c.key==="Escape"&&(i(e.name),r(!1))},[g,e.name]),b=`cw-task-state-${e.state.replace("_","-")}`;return Q`
|
|
510
|
+
<div class="cw-task-item ${b}" style=${{paddingLeft:`${n*16+8}px`}}>
|
|
415
511
|
<button
|
|
416
512
|
class="cw-task-state-btn"
|
|
417
|
-
onClick=${
|
|
418
|
-
title=${
|
|
513
|
+
onClick=${$}
|
|
514
|
+
title=${Nt[e.state]}
|
|
419
515
|
>
|
|
420
|
-
${
|
|
516
|
+
${Kt[e.state]}
|
|
421
517
|
</button>
|
|
422
518
|
|
|
423
|
-
${
|
|
519
|
+
${o?Q`
|
|
424
520
|
<input
|
|
425
521
|
type="text"
|
|
426
522
|
class="cw-task-edit-input"
|
|
427
|
-
value=${
|
|
523
|
+
value=${y}
|
|
428
524
|
onInput=${c=>i(c.target.value)}
|
|
429
|
-
onBlur=${
|
|
525
|
+
onBlur=${g}
|
|
430
526
|
onKeyDown=${u}
|
|
431
527
|
autoFocus
|
|
432
528
|
/>
|
|
433
|
-
`:
|
|
529
|
+
`:Q`
|
|
434
530
|
<span
|
|
435
531
|
class="cw-task-name"
|
|
436
532
|
onClick=${()=>r(!0)}
|
|
@@ -448,16 +544,16 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
448
544
|
×
|
|
449
545
|
</button>
|
|
450
546
|
</div>
|
|
451
|
-
`}function
|
|
452
|
-
<${
|
|
453
|
-
key=${
|
|
454
|
-
task=${
|
|
547
|
+
`}function st({tasks:e,progress:t,isLoading:s,error:n,onUpdate:o,onRemove:r,onClear:y,onRefresh:i}){let $=de(b=>{let c=new Map,C=[];return b.forEach(l=>{c.set(l.id,{...l,children:[]})}),b.forEach(l=>{let f=c.get(l.id);l.parent_id&&c.has(l.parent_id)?c.get(l.parent_id).children.push(f):C.push(f)}),C},[]),g=de((b,c=0)=>Q`
|
|
548
|
+
<${Bt}
|
|
549
|
+
key=${b.id}
|
|
550
|
+
task=${b}
|
|
455
551
|
depth=${c}
|
|
456
|
-
onUpdate=${
|
|
552
|
+
onUpdate=${o}
|
|
457
553
|
onRemove=${r}
|
|
458
554
|
/>
|
|
459
|
-
${
|
|
460
|
-
`,[
|
|
555
|
+
${b.children?.map(C=>g(C,c+1))}
|
|
556
|
+
`,[o,r]),u=$(e);return s&&e.length===0?Q`<div class="cw-tasks-loading">Loading tasks...</div>`:Q`
|
|
461
557
|
<div class="cw-tasks-container">
|
|
462
558
|
<div class="cw-tasks-header">
|
|
463
559
|
<div class="cw-tasks-progress">
|
|
@@ -473,24 +569,24 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
473
569
|
</div>
|
|
474
570
|
<div class="cw-tasks-actions">
|
|
475
571
|
<button class="cw-tasks-action-btn" onClick=${i} title="Refresh">↻</button>
|
|
476
|
-
${e.length>0&&
|
|
477
|
-
<button class="cw-tasks-action-btn" onClick=${
|
|
572
|
+
${e.length>0&&Q`
|
|
573
|
+
<button class="cw-tasks-action-btn" onClick=${y} title="Clear all">🗑</button>
|
|
478
574
|
`}
|
|
479
575
|
</div>
|
|
480
576
|
</div>
|
|
481
577
|
|
|
482
|
-
${n&&
|
|
578
|
+
${n&&Q`<div class="cw-tasks-error">${n}</div>`}
|
|
483
579
|
|
|
484
580
|
<div class="cw-tasks-list">
|
|
485
|
-
${u.length===0?
|
|
581
|
+
${u.length===0?Q`
|
|
486
582
|
<div class="cw-tasks-empty">
|
|
487
583
|
<p>No tasks yet</p>
|
|
488
584
|
<p class="cw-tasks-empty-hint">Tasks will appear here when the agent creates them</p>
|
|
489
585
|
</div>
|
|
490
|
-
`:u.map(
|
|
586
|
+
`:u.map(b=>g(b))}
|
|
491
587
|
</div>
|
|
492
588
|
</div>
|
|
493
|
-
`}import{html as
|
|
589
|
+
`}import{html as z}from"htm/preact";function nt({systems:e,agents:t,selectedSystem:s,selectedAgent:n,selectedSystemVersion:o,selectedAgentVersion:r,onSelectSystem:y,onSelectAgent:i,onSelectSystemVersion:$,onSelectAgentVersion:g,disabled:u}){let b=e.find(m=>m.slug===s),c=t.find(m=>m.slug===n),C=b?.versions||[],l=c?.versions||[];if(e.length===0&&t.length===0)return null;let f=e.length>1,w=t.length>1,v=C.length>1,_=l.length>1;return z`
|
|
494
590
|
<div class="cw-dev-toolbar">
|
|
495
591
|
<div class="cw-dev-toolbar-label">
|
|
496
592
|
<span class="cw-dev-toolbar-icon">🛠️</span>
|
|
@@ -501,89 +597,89 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
501
597
|
<!-- System -->
|
|
502
598
|
<div class="cw-dev-select-group">
|
|
503
599
|
<label class="cw-dev-label">System</label>
|
|
504
|
-
${
|
|
600
|
+
${f?z`
|
|
505
601
|
<select
|
|
506
602
|
class="cw-dev-select"
|
|
507
603
|
value=${s||""}
|
|
508
|
-
onChange=${m
|
|
604
|
+
onChange=${m=>y(m.target.value)}
|
|
509
605
|
disabled=${u}
|
|
510
606
|
>
|
|
511
|
-
${e.map(m=>
|
|
607
|
+
${e.map(m=>z`
|
|
512
608
|
<option key=${m.slug} value=${m.slug}>
|
|
513
609
|
${m.name}
|
|
514
610
|
</option>
|
|
515
611
|
`)}
|
|
516
612
|
</select>
|
|
517
|
-
`:
|
|
518
|
-
<span class="cw-dev-badge">${
|
|
613
|
+
`:z`
|
|
614
|
+
<span class="cw-dev-badge">${b?.name||"\u2014"}</span>
|
|
519
615
|
`}
|
|
520
616
|
</div>
|
|
521
617
|
|
|
522
618
|
<!-- System Version -->
|
|
523
619
|
<div class="cw-dev-select-group">
|
|
524
620
|
<label class="cw-dev-label">Sys Ver</label>
|
|
525
|
-
${v?
|
|
621
|
+
${v?z`
|
|
526
622
|
<select
|
|
527
623
|
class="cw-dev-select"
|
|
528
|
-
value=${
|
|
529
|
-
onChange=${m
|
|
624
|
+
value=${o||""}
|
|
625
|
+
onChange=${m=>$(m.target.value||null)}
|
|
530
626
|
disabled=${u}
|
|
531
627
|
>
|
|
532
|
-
${
|
|
628
|
+
${C.map(m=>z`
|
|
533
629
|
<option key=${m.version} value=${m.version}>
|
|
534
630
|
${m.version}${m.is_active?" \u2713":""}${m.is_draft?" (draft)":""}
|
|
535
631
|
</option>
|
|
536
632
|
`)}
|
|
537
633
|
</select>
|
|
538
|
-
`:
|
|
539
|
-
<span class="cw-dev-badge">${
|
|
634
|
+
`:z`
|
|
635
|
+
<span class="cw-dev-badge">${C.length===1?C[0].version:"none"}</span>
|
|
540
636
|
`}
|
|
541
637
|
</div>
|
|
542
638
|
|
|
543
639
|
<!-- Agent -->
|
|
544
640
|
<div class="cw-dev-select-group">
|
|
545
641
|
<label class="cw-dev-label">Agent</label>
|
|
546
|
-
${w?
|
|
642
|
+
${w?z`
|
|
547
643
|
<select
|
|
548
644
|
class="cw-dev-select"
|
|
549
645
|
value=${n||""}
|
|
550
646
|
onChange=${m=>i(m.target.value)}
|
|
551
647
|
disabled=${u}
|
|
552
648
|
>
|
|
553
|
-
${t.map(m=>
|
|
649
|
+
${t.map(m=>z`
|
|
554
650
|
<option key=${m.slug} value=${m.slug}>
|
|
555
|
-
${m.name}${
|
|
651
|
+
${m.name}${b?.entry_agent?.slug===m.slug?" \u2605":""}
|
|
556
652
|
</option>
|
|
557
653
|
`)}
|
|
558
654
|
</select>
|
|
559
|
-
`:
|
|
560
|
-
<span class="cw-dev-badge">${c?.name||t[0]?.name||"\u2014"}${
|
|
655
|
+
`:z`
|
|
656
|
+
<span class="cw-dev-badge">${c?.name||t[0]?.name||"\u2014"}${b?.entry_agent?.slug===(c?.slug||t[0]?.slug)?" \u2605":""}</span>
|
|
561
657
|
`}
|
|
562
658
|
</div>
|
|
563
659
|
|
|
564
660
|
<!-- Agent Version -->
|
|
565
661
|
<div class="cw-dev-select-group">
|
|
566
662
|
<label class="cw-dev-label">Agent Ver</label>
|
|
567
|
-
${
|
|
663
|
+
${_?z`
|
|
568
664
|
<select
|
|
569
665
|
class="cw-dev-select"
|
|
570
666
|
value=${r||""}
|
|
571
|
-
onChange=${m=>
|
|
667
|
+
onChange=${m=>g(m.target.value||null)}
|
|
572
668
|
disabled=${u}
|
|
573
669
|
>
|
|
574
|
-
${
|
|
670
|
+
${l.map(m=>z`
|
|
575
671
|
<option key=${m.version} value=${m.version}>
|
|
576
672
|
${m.version}${m.is_active?" \u2713":""}${m.is_draft?" (draft)":""}
|
|
577
673
|
</option>
|
|
578
674
|
`)}
|
|
579
675
|
</select>
|
|
580
|
-
`:
|
|
581
|
-
<span class="cw-dev-badge">${
|
|
676
|
+
`:z`
|
|
677
|
+
<span class="cw-dev-badge">${l.length===1?l[0].version:c?.active_version||"\u2014"}</span>
|
|
582
678
|
`}
|
|
583
679
|
</div>
|
|
584
680
|
</div>
|
|
585
681
|
</div>
|
|
586
|
-
`}import{useState as ne,useCallback as te,useRef as Qe,useEffect as et}from"preact/hooks";function tt(e,t,s){let[n,l]=ne([]),[r,$]=ne(!1),[i,f]=ne(null),[y,u]=ne(()=>s?.get(e.conversationIdKey)||null),[k,c]=ne(!1),[S,a]=ne(!1),[g,w]=ne(0),v=Qe(null),T=Qe(null);et(()=>{y&&s?.set(e.conversationIdKey,y)},[y,e.conversationIdKey,s]);let m=te(async(h,M,p)=>{v.current&&v.current.close();let C=e.apiPaths.runEvents.replace("{runId}",h),b=`${e.backendUrl}${C}`;M&&(b+=`?anonymous_token=${encodeURIComponent(M)}`);let E=new EventSource(b);v.current=E;let d="";E.addEventListener("assistant.message",F=>{try{let o=JSON.parse(F.data);e.onEvent&&e.onEvent("assistant.message",o.payload);let I=o.payload.content;I&&(d+=I,l(K=>{let j=K[K.length-1];return j?.role==="assistant"&&j.id.startsWith("assistant-stream-")?[...K.slice(0,-1),{...j,content:d}]:[...K,{id:"assistant-stream-"+Date.now(),role:"assistant",content:d,timestamp:new Date,type:"message"}]}))}catch(o){console.error("[ChatWidget] Parse error:",o)}}),E.addEventListener("tool.call",F=>{try{let o=JSON.parse(F.data);e.onEvent&&e.onEvent("tool.call",o.payload),l(I=>[...I,{id:"tool-call-"+Date.now(),role:"assistant",content:`\u{1F527} ${o.payload.name}`,timestamp:new Date,type:"tool_call",metadata:{toolName:o.payload.name,arguments:o.payload.arguments,toolCallId:o.payload.id}}])}catch(o){console.error("[ChatWidget] Parse error:",o)}}),E.addEventListener("tool.result",F=>{try{let o=JSON.parse(F.data);e.onEvent&&e.onEvent("tool.result",o.payload);let I=o.payload.result,K=I?.error;l(j=>[...j,{id:"tool-result-"+Date.now(),role:"system",content:K?`\u274C ${I.error}`:"\u2713 Done",timestamp:new Date,type:"tool_result",metadata:{toolName:o.payload.name,result:I,toolCallId:o.payload.tool_call_id}}])}catch(o){console.error("[ChatWidget] Parse error:",o)}}),E.addEventListener("custom",F=>{try{let o=JSON.parse(F.data);e.onEvent&&e.onEvent("custom",o.payload),o.payload?.type==="ui_control"&&e.onUIControl&&e.onUIControl(o.payload),o.payload?.type==="agent_context"&&l(I=>[...I,{id:"agent-context-"+Date.now(),role:"system",content:`\u{1F517} ${o.payload.agent_name||"Sub-agent"} is now handling this request`,timestamp:new Date,type:"agent_context",metadata:{agentKey:o.payload.agent_key,agentName:o.payload.agent_name,action:o.payload.action}}])}catch(o){console.error("[ChatWidget] Parse error:",o)}}),E.addEventListener("sub_agent.start",F=>{try{let o=JSON.parse(F.data);e.onEvent&&e.onEvent("sub_agent.start",o.payload),l(I=>[...I,{id:"sub-agent-start-"+Date.now(),role:"system",content:`\u{1F517} Delegating to ${o.payload.agent_name||o.payload.sub_agent_key||"sub-agent"}...`,timestamp:new Date,type:"sub_agent_start",metadata:{subAgentKey:o.payload.sub_agent_key,agentName:o.payload.agent_name,invocationMode:o.payload.invocation_mode}}])}catch(o){console.error("[ChatWidget] Parse error:",o)}}),E.addEventListener("sub_agent.end",F=>{try{let o=JSON.parse(F.data);e.onEvent&&e.onEvent("sub_agent.end",o.payload),l(I=>[...I,{id:"sub-agent-end-"+Date.now(),role:"system",content:`\u2713 ${o.payload.agent_name||"Sub-agent"} completed`,timestamp:new Date,type:"sub_agent_end",metadata:{subAgentKey:o.payload.sub_agent_key,agentName:o.payload.agent_name}}])}catch(o){console.error("[ChatWidget] Parse error:",o)}});let A=F=>{try{let o=JSON.parse(F.data);if(e.onEvent&&e.onEvent(o.type,o.payload),o.type==="run.failed"){let I=o.payload.error||"Agent run failed";f(I),l(K=>[...K,{id:"error-"+Date.now(),role:"system",content:`\u274C Error: ${I}`,timestamp:new Date,type:"error"}])}}catch(o){console.error("[ChatWidget] Parse error:",o)}$(!1),E.close(),v.current=null,d&&p&&p(d)};E.addEventListener("run.succeeded",A),E.addEventListener("run.failed",A),E.addEventListener("run.cancelled",A),E.addEventListener("run.timed_out",A),E.onerror=()=>{$(!1),E.close(),v.current=null}},[e]),N=te(async(h,M={},p={})=>{if(!h.trim()||r)return;let C=[],b={};typeof M=="function"?b={onAssistantMessage:M}:Array.isArray(M)?(C=M,b=p):b=M||{};let{model:E,thinking:d,onAssistantMessage:A,supersedeFromMessageIndex:F}=b;$(!0),f(null);let o={id:fe(),role:"user",content:h.trim(),timestamp:new Date,type:"message",files:C.length>0?C.map(I=>({name:I.name,size:I.size,type:I.type})):void 0};l(I=>[...I,o]);try{let I=await t.getOrCreateSession(),K;if(C.length>0){let V=e.apiCaseStyle!=="camel",Oe=he=>V?Te(he):he,Q=new FormData;Q.append(Oe("agentKey"),e.agentKey),y&&Q.append(Oe("conversationId"),y),Q.append("messages",JSON.stringify([{role:"user",content:h.trim()}])),Q.append("metadata",JSON.stringify(V?{...e.metadata,journey_type:e.defaultJourneyType}:{...e.metadata,journeyType:e.defaultJourneyType})),E&&Q.append("model",E),d&&Q.append("thinking","true"),C.forEach(he=>{Q.append("files",he)}),K=t.getFetchOptions({method:"POST",body:Q},I)}else{let V=t.transformRequest({agentKey:e.agentKey,conversationId:y,messages:[{role:"user",content:h.trim()}],metadata:{...e.metadata,journeyType:e.defaultJourneyType},...E&&{model:E},...d&&{thinking:!0},...F!==void 0&&{supersedeFromMessageIndex:F}});K=t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(V)},I)}let j=await fetch(`${e.backendUrl}${e.apiPaths.runs}`,K),_=I;if(j.status===401){t.clearSession();let V=await t.getOrCreateSession(!0);V&&(_=V,C.length>0?K=t.getFetchOptions({method:"POST",body:K.body},V):K=t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:K.body},V),j=await fetch(`${e.backendUrl}${e.apiPaths.runs}`,K))}if(!j.ok){let V=await j.json().catch(()=>({}));throw new Error(V.error||V.detail||`HTTP ${j.status}`)}let z=await j.json(),Y=t.transformResponse(z);T.current=Y.id,!y&&Y.conversationId&&u(Y.conversationId),await m(Y.id,_,A)}catch(I){f(I.message||"Failed to send message"),$(!1)}finally{T.current=null}},[e,t,y,r,m]),U=te(async()=>{let h=T.current;if(!(!h||!r))try{let M=e.apiPaths.cancelRun?e.apiPaths.cancelRun.replace("{runId}",h):`${e.apiPaths.runs}${h}/cancel/`;(await fetch(`${e.backendUrl}${M}`,t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"}}))).ok&&(v.current&&(v.current.close(),v.current=null),$(!1),T.current=null,l(C=>[...C,{id:"cancelled-"+Date.now(),role:"system",content:"\u23F9 Run cancelled",timestamp:new Date,type:"cancelled"}]))}catch(M){console.error("[ChatWidget] Failed to cancel run:",M)}},[e,t,r]),x=te(()=>{l([]),u(null),f(null),c(!1),w(0),s?.set(e.conversationIdKey,null)},[e.conversationIdKey,s]),R=h=>{let M={id:fe(),role:h.role,timestamp:h.timestamp?new Date(h.timestamp):new Date};if(h.role==="tool")return{...M,role:"system",content:"\u2713 Done",type:"tool_result",metadata:{result:h.content,toolCallId:h.toolCallId}};if(h.role==="assistant"&&h.toolCalls&&h.toolCalls.length>0)return h.toolCalls.map(C=>({id:fe(),role:"assistant",content:`\u{1F527} ${C.function?.name||C.name||"tool"}`,timestamp:M.timestamp,type:"tool_call",metadata:{toolName:C.function?.name||C.name,arguments:C.function?.arguments||C.arguments,toolCallId:C.id}}));let p=typeof h.content=="string"?h.content:JSON.stringify(h.content);return h.role==="assistant"&&!p?.trim()?null:{...M,content:p,type:"message"}},D=te(async h=>{console.log("[ChatWidget] loadConversation called with:",h),$(!0),l([]),u(h);try{let M=await t.getOrCreateSession(),C=`${e.backendUrl}${e.apiPaths.conversations}${h}/?limit=10&offset=0`;console.log("[ChatWidget] Fetching conversation from:",C);let b=await fetch(C,t.getFetchOptions({method:"GET"},M));if(console.log("[ChatWidget] Response status:",b.status),b.ok){let E=await b.json();console.log("[ChatWidget] Raw conversation:",E);let d=t.transformResponse(E);if(console.log("[ChatWidget] Transformed conversation:",d),d.messages){let A=d.messages.flatMap(R).filter(Boolean);console.log("[ChatWidget] Mapped messages:",A),l(A)}c(d.hasMore||!1),w(d.messages?.length||0)}else b.status===404?(console.log("[ChatWidget] Conversation not found, clearing"),u(null),s?.set(e.conversationIdKey,null)):console.error("[ChatWidget] Unexpected response status:",b.status)}catch(M){console.error("[ChatWidget] Failed to load conversation:",M)}finally{$(!1)}},[e,t,s]),P=te(async()=>{if(!(!y||S||!k)){a(!0);try{let h=await t.getOrCreateSession(),p=`${e.backendUrl}${e.apiPaths.conversations}${y}/?limit=10&offset=${g}`,C=await fetch(p,t.getFetchOptions({method:"GET"},h));if(C.ok){let b=await C.json(),E=t.transformResponse(b);if(E.messages?.length>0){let d=E.messages.flatMap(R).filter(Boolean);l(A=>[...d,...A]),w(A=>A+E.messages.length),c(E.hasMore||!1)}else c(!1)}}catch(h){console.error("[ChatWidget] Failed to load more messages:",h)}finally{a(!1)}}},[e,t,y,g,S,k]),B=te(async(h,M,p={})=>{if(r)return;let C=n[h];if(!C||C.role!=="user")return;let b=n.slice(0,h);l(b),await N(M,{...p,supersedeFromMessageIndex:h})},[n,r,N]),W=te(async(h,M={})=>{if(r)return;let p=n[h];if(!p)return;let C=h,b=p;if(p.role==="assistant"){for(let d=h-1;d>=0;d--)if(n[d].role==="user"){C=d,b=n[d];break}if(b.role!=="user")return}else if(p.role!=="user")return;let E=n.slice(0,C);l(E),await N(b.content,{...M,supersedeFromMessageIndex:C})},[n,r,N]);return et(()=>()=>{v.current&&v.current.close()},[]),{messages:n,isLoading:r,error:i,conversationId:y,hasMoreMessages:k,loadingMoreMessages:S,sendMessage:N,cancelRun:U,clearMessages:x,loadConversation:D,loadMoreMessages:P,setConversationId:u,editMessage:B,retryMessage:W}}import{useState as de,useEffect as _t,useCallback as be}from"preact/hooks";var st="cw_thinking_enabled";function nt(e,t,s){let[n,l]=de([]),[r,$]=de(null),[i,f]=de(null),[y,u]=de(!1),[k,c]=de(!1);_t(()=>{(async()=>{if(e.showModelSelector){u(!0);try{let T=await fetch(`${e.backendUrl}${e.apiPaths.models}`,t.getFetchOptions({method:"GET"}));if(T.ok){let m=await T.json(),N=m.models||[];l(N),f(m.default);let U=s?.get(e.modelKey);U&&N.some(R=>R.id===U)?$(U):$(m.default),s?.get(st)==="true"&&c(!0)}}catch(T){console.warn("[ChatWidget] Failed to load models:",T)}finally{u(!1)}}})()},[e.backendUrl,e.apiPaths.models,e.showModelSelector,e.modelKey,t,s]);let S=be(v=>{$(v),s?.set(e.modelKey,v)},[e.modelKey,s]),a=be(v=>{c(v),s?.set(st,v?"true":"false")},[s]),g=be(()=>n.find(v=>v.id===r)||null,[n,r]),w=be(()=>g()?.supports_thinking||!1,[g]);return{availableModels:n,selectedModel:r,defaultModel:i,isLoading:y,selectModel:S,getSelectedModelInfo:g,thinkingEnabled:k,toggleThinking:a,supportsThinking:w}}import{useState as Ie,useCallback as re}from"preact/hooks";function at(e,t){let[s,n]=Ie(null),[l,r]=Ie(!1),[$,i]=Ie(null),f=e.apiPaths?.tasks||"/api/agent/tasks/",y=re(async()=>{r(!0),i(null);try{let g=`${e.backendUrl}${f}`,w=await fetch(g,t.getFetchOptions({method:"GET"}));if(w.ok){let v=await w.json();n(v)}else{let v=await w.json().catch(()=>({}));i(v.error||"Failed to load tasks")}}catch(g){console.error("[useTasks] Failed to load task list:",g),i("Failed to load tasks")}finally{r(!1)}},[e.backendUrl,f,t]),u=re(async g=>{if(!s)return null;try{let w=`${e.backendUrl}${f}${s.id}/add_task/`,v=await fetch(w,t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)}));if(v.ok){let T=await v.json();return await y(),T}else{let T=await v.json().catch(()=>({}));return i(T.error||"Failed to add task"),null}}catch(w){return console.error("[useTasks] Failed to add task:",w),i("Failed to add task"),null}},[e.backendUrl,f,s,t,y]),k=re(async(g,w)=>{if(!s)return null;try{let v=`${e.backendUrl}${f}${s.id}/update_task/${g}/`,T=await fetch(v,t.getFetchOptions({method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(w)}));if(T.ok){let m=await T.json();return await y(),m}else{let m=await T.json().catch(()=>({}));return i(m.error||"Failed to update task"),null}}catch(v){return console.error("[useTasks] Failed to update task:",v),i("Failed to update task"),null}},[e.backendUrl,f,s,t,y]),c=re(async g=>{if(!s)return!1;try{let w=`${e.backendUrl}${f}${s.id}/remove_task/${g}/`,v=await fetch(w,t.getFetchOptions({method:"DELETE"}));if(v.ok)return await y(),!0;{let T=await v.json().catch(()=>({}));return i(T.error||"Failed to remove task"),!1}}catch(w){return console.error("[useTasks] Failed to remove task:",w),i("Failed to remove task"),!1}},[e.backendUrl,f,s,t,y]),S=re(async()=>{if(!s)return!1;try{let g=`${e.backendUrl}${f}${s.id}/clear/`,w=await fetch(g,t.getFetchOptions({method:"POST"}));if(w.ok)return await y(),!0;{let v=await w.json().catch(()=>({}));return i(v.error||"Failed to clear tasks"),!1}}catch(g){return console.error("[useTasks] Failed to clear tasks:",g),i("Failed to clear tasks"),!1}},[e.backendUrl,f,s,t,y]),a=re(()=>i(null),[]);return{taskList:s,tasks:s?.tasks||[],progress:s?.progress||{total:0,completed:0,percent_complete:0},isLoading:l,error:$,loadTaskList:y,addTask:u,updateTask:k,removeTask:c,clearTasks:S,clearError:a}}import{useState as ae,useEffect as ot,useCallback as ue}from"preact/hooks";var rt="cw_selected_system",xe="cw_selected_agent",lt="cw_selected_system_version",Se="cw_selected_agent_version";function it(e,t,s){let[n,l]=ae([]),[r,$]=ae([]),[i,f]=ae(null),[y,u]=ae(null),[k,c]=ae(null),[S,a]=ae(null),[g,w]=ae(!1),v=ue(()=>{if(y)return y;if(i){let x=n.find(R=>R.slug===i);if(x?.entry_agent)return x.entry_agent.slug}return e.agentKey},[y,i,n,e.agentKey]);ot(()=>{if(!e.showDevTools)return;(async()=>{w(!0);try{let R=await fetch(`${e.backendUrl}${e.apiPaths.systems}`,t.getFetchOptions({method:"GET"}));if(R.ok){let D=await R.json(),P=D.results||D;l(P);let B=s?.get(rt);B&&P.some(W=>W.slug===B)?f(B):P.length===1&&f(P[0].slug)}}catch(R){console.warn("[ChatWidget] Failed to load systems:",R)}finally{w(!1)}})()},[e.backendUrl,e.apiPaths.systems,e.showDevTools,t,s]),ot(()=>{if(!e.showDevTools)return;(async()=>{try{let R=i?`?system=${encodeURIComponent(i)}`:"",D=await fetch(`${e.backendUrl}${e.apiPaths.agents}${R}`,t.getFetchOptions({method:"GET"}));if(D.ok){let P=await D.json(),B=P.results||P;$(B);let W=s?.get(xe);if(W&&B.some(M=>M.slug===W))u(W);else if(i){let M=n.find(p=>p.slug===i);M?.entry_agent&&u(M.entry_agent.slug)}let h=s?.get(Se);h&&a(h)}}catch(R){console.warn("[ChatWidget] Failed to load agents:",R)}})()},[e.backendUrl,e.apiPaths.agents,e.showDevTools,i,t,s,n]);let T=ue(x=>{f(x),s?.set(rt,x),u(null),a(null),s?.set(xe,null),s?.set(Se,null);let D=n.find(P=>P.slug===x)?.active_version||null;c(D),s?.set(lt,D)},[s,n]),m=ue(x=>{u(x),s?.set(xe,x);let D=r.find(P=>P.slug===x)?.active_version||null;a(D),s?.set(Se,D)},[s,r]),N=ue(x=>{c(x),s?.set(lt,x)},[s]),U=ue(x=>{a(x),s?.set(Se,x)},[s]);return{systems:n,agents:r,selectedSystem:i,selectedAgent:y,selectedSystemVersion:k,selectedAgentVersion:S,isLoading:g,selectSystem:T,selectAgent:m,selectSystemVersion:N,selectAgentVersion:U,getEffectiveAgentKey:v}}function ct(e,t,s){let n=u=>!u||typeof u!="object"||e.apiCaseStyle==="camel"?u:ge(u),l=u=>!u||typeof u!="object"||e.apiCaseStyle==="snake"?u:me(u),r=()=>e.authStrategy?e.authStrategy:e.authToken?"token":e.apiPaths.anonymousSession||e.anonymousSessionEndpoint?"anonymous":"none",$=(u=null)=>{let k=r(),c={},S=u||e.authToken||t().authToken;if(k==="token"&&S){let a=e.authHeader||"Authorization",g=e.authTokenPrefix!==void 0?e.authTokenPrefix:"Token";c[a]=g?`${g} ${S}`:S}else if(k==="jwt"&&S){let a=e.authHeader||"Authorization",g=e.authTokenPrefix!==void 0?e.authTokenPrefix:"Bearer";c[a]=g?`${g} ${S}`:S}else if(k==="anonymous"&&S){let a=e.authHeader||e.anonymousTokenHeader||"X-Anonymous-Token";c[a]=S}if(k==="session"){let a=Ne(e.csrfCookieName);a&&(c["X-CSRFToken"]=a)}return c};return{getAuthStrategy:r,getAuthHeaders:$,getFetchOptions:(u={},k=null)=>{let c=r(),S={...u},a=$(k);return console.log("[ChatWidget] getFetchOptions - strategy:",c,"overrideToken:",k,"authHeaders:",a),S.headers={...S.headers,...a},c==="session"&&(S.credentials="include"),S},getOrCreateSession:async(u=!1)=>{let k=r(),c=t(),S=e.anonymousTokenKey||e.sessionTokenKey;if(k!=="anonymous")return e.authToken||c.authToken;if(!u){if(c.authToken)return c.authToken;let a=c.storage?.get(S);if(a)return s(g=>({...g,authToken:a})),a}try{let a=e.anonymousSessionEndpoint||e.apiPaths.anonymousSession,g=await fetch(`${e.backendUrl}${a}`,{method:"POST",headers:{"Content-Type":"application/json"}});if(g.ok){let w=await g.json();return s(v=>({...v,authToken:w.token})),c.storage?.set(S,w.token),w.token}}catch(a){console.warn("[ChatWidget] Failed to create session:",a)}return null},clearSession:()=>{let u=e.anonymousTokenKey||e.sessionTokenKey,k=t();s(c=>({...c,authToken:null})),k.storage?.set(u,null)},transformRequest:n,transformResponse:l}}function dt({config:e,onStateChange:t,markdownParser:s,apiRef:n}){console.log("[ChatWidget] Config:",{showConversationSidebar:e.showConversationSidebar,apiPaths:e.apiPaths});let[l,r]=q(e.embedded||e.forceOpen===!0),[$,i]=q(!1),[f,y]=q(!1),[u,k]=q(!1),[c,S]=q([]),[a,g]=q("chat"),[w,v]=q(!1),[T,m]=q(e.enableTTS),[N,U]=q(!1),[x,R]=q(null);pe(()=>{e.forceOpen!==void 0&&r(e.forceOpen)},[e.forceOpen]);let D=Ae(()=>Le(e.containerId),[e.containerId]),[P,B]=q(e.authToken||null),W=Ae(()=>ct(e,()=>({authToken:P,storage:D}),Y=>{let V=Y({authToken:P,storage:D});V.authToken!==P&&B(V.authToken)}),[e,P,D]),h=it(e,W,D),M=Ae(()=>{if(!e.showDevTools)return e;let _=h.getEffectiveAgentKey();return _&&_!==e.agentKey?{...e,agentKey:_}:e},[e,h.getEffectiveAgentKey]),p=tt(M,W,D),C=nt(e,W,D),b=at(e,W);pe(()=>{for(let _=p.messages.length-1;_>=0;_--){let z=p.messages[_];if(z.type==="sub_agent_start"){R({key:z.metadata?.subAgentKey,name:z.metadata?.agentName});return}if(z.type==="sub_agent_end"){R(null);return}}},[p.messages]),pe(()=>{let _=D.get(e.conversationIdKey);console.log("[ChatWidget] Initial load - storedConvId:",_,"key:",e.conversationIdKey),console.log("[ChatWidget] apiPaths.conversations:",e.apiPaths.conversations),_&&(console.log("[ChatWidget] Loading conversation:",_),p.loadConversation(_))},[]),pe(()=>{t&&t({isOpen:l,isExpanded:$,debugMode:f,messages:p.messages,conversationId:p.conversationId,isLoading:p.isLoading,error:p.error})},[l,$,f,p.messages,p.conversationId,p.isLoading,p.error]);let E=le(async()=>{if(e.showConversationSidebar){v(!0);try{let _=M.agentKey,z=`${e.backendUrl}${e.apiPaths.conversations}?agent_key=${encodeURIComponent(_)}`,Y=await fetch(z,W.getFetchOptions({method:"GET"}));if(Y.ok){let V=await Y.json();S(V.results||V)}}catch(_){console.error("[ChatWidget] Failed to load conversations:",_),S([])}finally{v(!1)}}},[e,M,W]),d=le(()=>{let _=!u;k(_),_&&E()},[u,E]),A=le(_=>{_!==p.conversationId&&p.loadConversation(_),k(!1)},[p]),F=le(()=>{p.clearMessages(),k(!1)},[p]),o=le(_=>{p.sendMessage(_,{model:C.selectedModel,thinking:C.thinkingEnabled&&C.supportsThinking(),onAssistantMessage:z=>{}})},[p,T,C.selectedModel,C.thinkingEnabled,C.supportsThinking]),I=le(_=>{g(_),_==="tasks"&&b.loadTaskList()},[b]);if(pe(()=>{n&&(n.current={open:()=>r(!0),close:()=>r(!1),send:_=>o(_),clearMessages:()=>p.clearMessages(),toggleTTS:()=>m(_=>!_),stopSpeech:()=>U(!1),setAuth:_=>{_.token!==void 0&&B(_.token)},clearAuth:()=>B(null)})},[p,n,o]),!e.embedded&&!l)return G`
|
|
682
|
+
`}import{useState as ae,useCallback as se,useRef as at,useEffect as ot}from"preact/hooks";function rt(e,t,s){let[n,o]=ae([]),[r,y]=ae(!1),[i,$]=ae(null),[g,u]=ae(()=>s?.get(e.conversationIdKey)||null),[b,c]=ae(!1),[C,l]=ae(!1),[f,w]=ae(0),v=at(null),_=at(null);ot(()=>{g&&s?.set(e.conversationIdKey,g)},[g,e.conversationIdKey,s]);let m=se(async(h,I,p)=>{v.current&&v.current.close();let S=e.apiPaths.runEvents.replace("{runId}",h),k=`${e.backendUrl}${S}`;I&&(k+=`?anonymous_token=${encodeURIComponent(I)}`);let T=new EventSource(k);v.current=T;let d="";T.addEventListener("assistant.message",D=>{try{let a=JSON.parse(D.data);e.onEvent&&e.onEvent("assistant.message",a.payload);let M=a.payload.content;M&&(d+=M,o(N=>{let J=N[N.length-1];return J?.role==="assistant"&&J.id.startsWith("assistant-stream-")?[...N.slice(0,-1),{...J,content:d}]:[...N,{id:"assistant-stream-"+Date.now(),role:"assistant",content:d,timestamp:new Date,type:"message"}]}))}catch(a){console.error("[ChatWidget] Parse error:",a)}}),T.addEventListener("tool.call",D=>{try{let a=JSON.parse(D.data);e.onEvent&&e.onEvent("tool.call",a.payload),o(M=>[...M,{id:"tool-call-"+Date.now(),role:"assistant",content:`\u{1F527} ${a.payload.name}`,timestamp:new Date,type:"tool_call",metadata:{toolName:a.payload.name,arguments:a.payload.arguments,toolCallId:a.payload.id}}])}catch(a){console.error("[ChatWidget] Parse error:",a)}}),T.addEventListener("tool.result",D=>{try{let a=JSON.parse(D.data);e.onEvent&&e.onEvent("tool.result",a.payload);let M=a.payload.result,N=M?.error;o(J=>[...J,{id:"tool-result-"+Date.now(),role:"system",content:N?`\u274C ${M.error}`:"\u2713 Done",timestamp:new Date,type:"tool_result",metadata:{toolName:a.payload.name,result:M,toolCallId:a.payload.tool_call_id}}])}catch(a){console.error("[ChatWidget] Parse error:",a)}}),T.addEventListener("custom",D=>{try{let a=JSON.parse(D.data);e.onEvent&&e.onEvent("custom",a.payload),a.payload?.type==="ui_control"&&e.onUIControl&&e.onUIControl(a.payload),a.payload?.type==="agent_context"&&o(M=>[...M,{id:"agent-context-"+Date.now(),role:"system",content:`\u{1F517} ${a.payload.agent_name||"Sub-agent"} is now handling this request`,timestamp:new Date,type:"agent_context",metadata:{agentKey:a.payload.agent_key,agentName:a.payload.agent_name,action:a.payload.action}}])}catch(a){console.error("[ChatWidget] Parse error:",a)}}),T.addEventListener("sub_agent.start",D=>{try{let a=JSON.parse(D.data);e.onEvent&&e.onEvent("sub_agent.start",a.payload),o(M=>[...M,{id:"sub-agent-start-"+Date.now(),role:"system",content:`\u{1F517} Delegating to ${a.payload.agent_name||a.payload.sub_agent_key||"sub-agent"}...`,timestamp:new Date,type:"sub_agent_start",metadata:{subAgentKey:a.payload.sub_agent_key,agentName:a.payload.agent_name,invocationMode:a.payload.invocation_mode}}])}catch(a){console.error("[ChatWidget] Parse error:",a)}}),T.addEventListener("sub_agent.end",D=>{try{let a=JSON.parse(D.data);e.onEvent&&e.onEvent("sub_agent.end",a.payload),o(M=>[...M,{id:"sub-agent-end-"+Date.now(),role:"system",content:`\u2713 ${a.payload.agent_name||"Sub-agent"} completed`,timestamp:new Date,type:"sub_agent_end",metadata:{subAgentKey:a.payload.sub_agent_key,agentName:a.payload.agent_name}}])}catch(a){console.error("[ChatWidget] Parse error:",a)}}),T.addEventListener("content.blocks",D=>{try{let a=JSON.parse(D.data);e.onEvent&&e.onEvent("content.blocks",a.payload),o(M=>[...M,{id:"content-blocks-"+Date.now(),role:"assistant",content:"",timestamp:new Date,type:"content_blocks",metadata:{toolName:a.payload.tool_name,toolCallId:a.payload.tool_call_id,blocks:a.payload.blocks}}])}catch(a){console.error("[ChatWidget] Parse error:",a)}});let R=D=>{try{let a=JSON.parse(D.data);if(e.onEvent&&e.onEvent(a.type,a.payload),a.type==="run.failed"){let M=a.payload.error||"Agent run failed";$(M),o(N=>[...N,{id:"error-"+Date.now(),role:"system",content:`\u274C Error: ${M}`,timestamp:new Date,type:"error"}])}}catch(a){console.error("[ChatWidget] Parse error:",a)}y(!1),T.close(),v.current=null,d&&p&&p(d)};T.addEventListener("run.succeeded",R),T.addEventListener("run.failed",R),T.addEventListener("run.cancelled",R),T.addEventListener("run.timed_out",R),T.onerror=()=>{y(!1),T.close(),v.current=null}},[e]),H=se(async(h,I={},p={})=>{if(!h.trim()||r)return;let S=[],k={};typeof I=="function"?k={onAssistantMessage:I}:Array.isArray(I)?(S=I,k=p):k=I||{};let{model:T,thinking:d,onAssistantMessage:R,supersedeFromMessageIndex:D}=k;y(!0),$(null);let a={id:$e(),role:"user",content:h.trim(),timestamp:new Date,type:"message",files:S.length>0?S.map(M=>({name:M.name,size:M.size,type:M.type})):void 0};o(M=>[...M,a]);try{let M=await t.getOrCreateSession(),N;if(S.length>0){let V=e.apiCaseStyle!=="camel",Fe=me=>V?Me(me):me,ee=new FormData;ee.append(Fe("agentKey"),e.agentKey),g&&ee.append(Fe("conversationId"),g),ee.append("messages",JSON.stringify([{role:"user",content:h.trim()}])),ee.append("metadata",JSON.stringify(V?{...e.metadata,journey_type:e.defaultJourneyType}:{...e.metadata,journeyType:e.defaultJourneyType})),T&&ee.append("model",T),d&&ee.append("thinking","true"),S.forEach(me=>{ee.append("files",me)}),N=t.getFetchOptions({method:"POST",body:ee},M)}else{let V=t.transformRequest({agentKey:e.agentKey,conversationId:g,messages:[{role:"user",content:h.trim()}],metadata:{...e.metadata,journeyType:e.defaultJourneyType},...T&&{model:T},...d&&{thinking:!0},...D!==void 0&&{supersedeFromMessageIndex:D}});N=t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(V)},M)}let J=await fetch(`${e.backendUrl}${e.apiPaths.runs}`,N),E=M;if(J.status===401){t.clearSession();let V=await t.getOrCreateSession(!0);V&&(E=V,S.length>0?N=t.getFetchOptions({method:"POST",body:N.body},V):N=t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:N.body},V),J=await fetch(`${e.backendUrl}${e.apiPaths.runs}`,N))}if(!J.ok){let V=await J.json().catch(()=>({}));throw new Error(V.error||V.detail||`HTTP ${J.status}`)}let q=await J.json(),X=t.transformResponse(q);_.current=X.id,!g&&X.conversationId&&u(X.conversationId),await m(X.id,E,R)}catch(M){$(M.message||"Failed to send message"),y(!1)}finally{_.current=null}},[e,t,g,r,m]),U=se(async()=>{let h=_.current;if(!(!h||!r))try{let I=e.apiPaths.cancelRun?e.apiPaths.cancelRun.replace("{runId}",h):`${e.apiPaths.runs}${h}/cancel/`;(await fetch(`${e.backendUrl}${I}`,t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"}}))).ok&&(v.current&&(v.current.close(),v.current=null),y(!1),_.current=null,o(S=>[...S,{id:"cancelled-"+Date.now(),role:"system",content:"\u23F9 Run cancelled",timestamp:new Date,type:"cancelled"}]))}catch(I){console.error("[ChatWidget] Failed to cancel run:",I)}},[e,t,r]),A=se(()=>{o([]),u(null),$(null),c(!1),w(0),s?.set(e.conversationIdKey,null)},[e.conversationIdKey,s]),O=h=>{let I={id:$e(),role:h.role,timestamp:h.timestamp?new Date(h.timestamp):new Date};if(h.role==="tool")return{...I,role:"system",content:"\u2713 Done",type:"tool_result",metadata:{result:h.content,toolCallId:h.toolCallId}};if(h.role==="assistant"&&h.toolCalls&&h.toolCalls.length>0)return h.toolCalls.map(S=>({id:$e(),role:"assistant",content:`\u{1F527} ${S.function?.name||S.name||"tool"}`,timestamp:I.timestamp,type:"tool_call",metadata:{toolName:S.function?.name||S.name,arguments:S.function?.arguments||S.arguments,toolCallId:S.id}}));let p=typeof h.content=="string"?h.content:JSON.stringify(h.content);return h.role==="assistant"&&!p?.trim()?null:{...I,content:p,type:"message"}},F=se(async h=>{console.log("[ChatWidget] loadConversation called with:",h),y(!0),o([]),u(h);try{let I=await t.getOrCreateSession(),S=`${e.backendUrl}${e.apiPaths.conversations}${h}/?limit=10&offset=0`;console.log("[ChatWidget] Fetching conversation from:",S);let k=await fetch(S,t.getFetchOptions({method:"GET"},I));if(console.log("[ChatWidget] Response status:",k.status),k.ok){let T=await k.json();console.log("[ChatWidget] Raw conversation:",T);let d=t.transformResponse(T);if(console.log("[ChatWidget] Transformed conversation:",d),d.messages){let R=d.messages.flatMap(O).filter(Boolean);console.log("[ChatWidget] Mapped messages:",R),o(R)}c(d.hasMore||!1),w(d.messages?.length||0)}else k.status===404?(console.log("[ChatWidget] Conversation not found, clearing"),u(null),s?.set(e.conversationIdKey,null)):console.error("[ChatWidget] Unexpected response status:",k.status)}catch(I){console.error("[ChatWidget] Failed to load conversation:",I)}finally{y(!1)}},[e,t,s]),L=se(async()=>{if(!(!g||C||!b)){l(!0);try{let h=await t.getOrCreateSession(),p=`${e.backendUrl}${e.apiPaths.conversations}${g}/?limit=10&offset=${f}`,S=await fetch(p,t.getFetchOptions({method:"GET"},h));if(S.ok){let k=await S.json(),T=t.transformResponse(k);if(T.messages?.length>0){let d=T.messages.flatMap(O).filter(Boolean);o(R=>[...d,...R]),w(R=>R+T.messages.length),c(T.hasMore||!1)}else c(!1)}}catch(h){console.error("[ChatWidget] Failed to load more messages:",h)}finally{l(!1)}}},[e,t,g,f,C,b]),j=se(async(h,I,p={})=>{if(r)return;let S=n[h];if(!S||S.role!=="user")return;let k=n.slice(0,h);o(k),await H(I,{...p,supersedeFromMessageIndex:h})},[n,r,H]),W=se(async(h,I={})=>{if(r)return;let p=n[h];if(!p)return;let S=h,k=p;if(p.role==="assistant"){for(let d=h-1;d>=0;d--)if(n[d].role==="user"){S=d,k=n[d];break}if(k.role!=="user")return}else if(p.role!=="user")return;let T=n.slice(0,S);o(T),await H(k.content,{...I,supersedeFromMessageIndex:S})},[n,r,H]);return ot(()=>()=>{v.current&&v.current.close()},[]),{messages:n,isLoading:r,error:i,conversationId:g,hasMoreMessages:b,loadingMoreMessages:C,sendMessage:H,cancelRun:U,clearMessages:A,loadConversation:F,loadMoreMessages:L,setConversationId:u,editMessage:j,retryMessage:W}}import{useState as ue,useEffect as Ht,useCallback as Se}from"preact/hooks";var lt="cw_thinking_enabled";function it(e,t,s){let[n,o]=ue([]),[r,y]=ue(null),[i,$]=ue(null),[g,u]=ue(!1),[b,c]=ue(!1);Ht(()=>{(async()=>{if(e.showModelSelector){u(!0);try{let _=await fetch(`${e.backendUrl}${e.apiPaths.models}`,t.getFetchOptions({method:"GET"}));if(_.ok){let m=await _.json(),H=m.models||[];o(H),$(m.default);let U=s?.get(e.modelKey);U&&H.some(O=>O.id===U)?y(U):y(m.default),s?.get(lt)==="true"&&c(!0)}}catch(_){console.warn("[ChatWidget] Failed to load models:",_)}finally{u(!1)}}})()},[e.backendUrl,e.apiPaths.models,e.showModelSelector,e.modelKey,t,s]);let C=Se(v=>{y(v),s?.set(e.modelKey,v)},[e.modelKey,s]),l=Se(v=>{c(v),s?.set(lt,v?"true":"false")},[s]),f=Se(()=>n.find(v=>v.id===r)||null,[n,r]),w=Se(()=>f()?.supports_thinking||!1,[f]);return{availableModels:n,selectedModel:r,defaultModel:i,isLoading:g,selectModel:C,getSelectedModelInfo:f,thinkingEnabled:b,toggleThinking:l,supportsThinking:w}}import{useState as xe,useCallback as le}from"preact/hooks";function ct(e,t){let[s,n]=xe(null),[o,r]=xe(!1),[y,i]=xe(null),$=e.apiPaths?.tasks||"/api/agent/tasks/",g=le(async()=>{r(!0),i(null);try{let f=`${e.backendUrl}${$}`,w=await fetch(f,t.getFetchOptions({method:"GET"}));if(w.ok){let v=await w.json();n(v)}else{let v=await w.json().catch(()=>({}));i(v.error||"Failed to load tasks")}}catch(f){console.error("[useTasks] Failed to load task list:",f),i("Failed to load tasks")}finally{r(!1)}},[e.backendUrl,$,t]),u=le(async f=>{if(!s)return null;try{let w=`${e.backendUrl}${$}${s.id}/add_task/`,v=await fetch(w,t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(f)}));if(v.ok){let _=await v.json();return await g(),_}else{let _=await v.json().catch(()=>({}));return i(_.error||"Failed to add task"),null}}catch(w){return console.error("[useTasks] Failed to add task:",w),i("Failed to add task"),null}},[e.backendUrl,$,s,t,g]),b=le(async(f,w)=>{if(!s)return null;try{let v=`${e.backendUrl}${$}${s.id}/update_task/${f}/`,_=await fetch(v,t.getFetchOptions({method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(w)}));if(_.ok){let m=await _.json();return await g(),m}else{let m=await _.json().catch(()=>({}));return i(m.error||"Failed to update task"),null}}catch(v){return console.error("[useTasks] Failed to update task:",v),i("Failed to update task"),null}},[e.backendUrl,$,s,t,g]),c=le(async f=>{if(!s)return!1;try{let w=`${e.backendUrl}${$}${s.id}/remove_task/${f}/`,v=await fetch(w,t.getFetchOptions({method:"DELETE"}));if(v.ok)return await g(),!0;{let _=await v.json().catch(()=>({}));return i(_.error||"Failed to remove task"),!1}}catch(w){return console.error("[useTasks] Failed to remove task:",w),i("Failed to remove task"),!1}},[e.backendUrl,$,s,t,g]),C=le(async()=>{if(!s)return!1;try{let f=`${e.backendUrl}${$}${s.id}/clear/`,w=await fetch(f,t.getFetchOptions({method:"POST"}));if(w.ok)return await g(),!0;{let v=await w.json().catch(()=>({}));return i(v.error||"Failed to clear tasks"),!1}}catch(f){return console.error("[useTasks] Failed to clear tasks:",f),i("Failed to clear tasks"),!1}},[e.backendUrl,$,s,t,g]),l=le(()=>i(null),[]);return{taskList:s,tasks:s?.tasks||[],progress:s?.progress||{total:0,completed:0,percent_complete:0},isLoading:o,error:y,loadTaskList:g,addTask:u,updateTask:b,removeTask:c,clearTasks:C,clearError:l}}import{useState as oe,useEffect as dt,useCallback as pe}from"preact/hooks";var ut="cw_selected_system",Ae="cw_selected_agent",pt="cw_selected_system_version",Te="cw_selected_agent_version";function ht(e,t,s){let[n,o]=oe([]),[r,y]=oe([]),[i,$]=oe(null),[g,u]=oe(null),[b,c]=oe(null),[C,l]=oe(null),[f,w]=oe(!1),v=pe(()=>{if(g)return g;if(i){let A=n.find(O=>O.slug===i);if(A?.entry_agent)return A.entry_agent.slug}return e.agentKey},[g,i,n,e.agentKey]);dt(()=>{if(!e.showDevTools)return;(async()=>{w(!0);try{let O=await fetch(`${e.backendUrl}${e.apiPaths.systems}`,t.getFetchOptions({method:"GET"}));if(O.ok){let F=await O.json(),L=F.results||F;o(L);let j=s?.get(ut);j&&L.some(W=>W.slug===j)?$(j):L.length===1&&$(L[0].slug)}}catch(O){console.warn("[ChatWidget] Failed to load systems:",O)}finally{w(!1)}})()},[e.backendUrl,e.apiPaths.systems,e.showDevTools,t,s]),dt(()=>{if(!e.showDevTools)return;(async()=>{try{let O=i?`?system=${encodeURIComponent(i)}`:"",F=await fetch(`${e.backendUrl}${e.apiPaths.agents}${O}`,t.getFetchOptions({method:"GET"}));if(F.ok){let L=await F.json(),j=L.results||L;y(j);let W=s?.get(Ae);if(W&&j.some(I=>I.slug===W))u(W);else if(i){let I=n.find(p=>p.slug===i);I?.entry_agent&&u(I.entry_agent.slug)}let h=s?.get(Te);h&&l(h)}}catch(O){console.warn("[ChatWidget] Failed to load agents:",O)}})()},[e.backendUrl,e.apiPaths.agents,e.showDevTools,i,t,s,n]);let _=pe(A=>{$(A),s?.set(ut,A),u(null),l(null),s?.set(Ae,null),s?.set(Te,null);let F=n.find(L=>L.slug===A)?.active_version||null;c(F),s?.set(pt,F)},[s,n]),m=pe(A=>{u(A),s?.set(Ae,A);let F=r.find(L=>L.slug===A)?.active_version||null;l(F),s?.set(Te,F)},[s,r]),H=pe(A=>{c(A),s?.set(pt,A)},[s]),U=pe(A=>{l(A),s?.set(Te,A)},[s]);return{systems:n,agents:r,selectedSystem:i,selectedAgent:g,selectedSystemVersion:b,selectedAgentVersion:C,isLoading:f,selectSystem:_,selectAgent:m,selectSystemVersion:H,selectAgentVersion:U,getEffectiveAgentKey:v}}function mt(e,t,s){let n=u=>!u||typeof u!="object"||e.apiCaseStyle==="camel"?u:fe(u),o=u=>!u||typeof u!="object"||e.apiCaseStyle==="snake"?u:ge(u),r=()=>e.authStrategy?e.authStrategy:e.authToken?"token":e.apiPaths.anonymousSession||e.anonymousSessionEndpoint?"anonymous":"none",y=(u=null)=>{let b=r(),c={},C=u||e.authToken||t().authToken;if(b==="token"&&C){let l=e.authHeader||"Authorization",f=e.authTokenPrefix!==void 0?e.authTokenPrefix:"Token";c[l]=f?`${f} ${C}`:C}else if(b==="jwt"&&C){let l=e.authHeader||"Authorization",f=e.authTokenPrefix!==void 0?e.authTokenPrefix:"Bearer";c[l]=f?`${f} ${C}`:C}else if(b==="anonymous"&&C){let l=e.authHeader||e.anonymousTokenHeader||"X-Anonymous-Token";c[l]=C}if(b==="session"){let l=Be(e.csrfCookieName);l&&(c["X-CSRFToken"]=l)}return c};return{getAuthStrategy:r,getAuthHeaders:y,getFetchOptions:(u={},b=null)=>{let c=r(),C={...u},l=y(b);return console.log("[ChatWidget] getFetchOptions - strategy:",c,"overrideToken:",b,"authHeaders:",l),C.headers={...C.headers,...l},c==="session"&&(C.credentials="include"),C},getOrCreateSession:async(u=!1)=>{let b=r(),c=t(),C=e.anonymousTokenKey||e.sessionTokenKey;if(b!=="anonymous")return e.authToken||c.authToken;if(!u){if(c.authToken)return c.authToken;let l=c.storage?.get(C);if(l)return s(f=>({...f,authToken:l})),l}try{let l=e.anonymousSessionEndpoint||e.apiPaths.anonymousSession,f=await fetch(`${e.backendUrl}${l}`,{method:"POST",headers:{"Content-Type":"application/json"}});if(f.ok){let w=await f.json();return s(v=>({...v,authToken:w.token})),c.storage?.set(C,w.token),w.token}}catch(l){console.warn("[ChatWidget] Failed to create session:",l)}return null},clearSession:()=>{let u=e.anonymousTokenKey||e.sessionTokenKey,b=t();s(c=>({...c,authToken:null})),b.storage?.set(u,null)},transformRequest:n,transformResponse:o}}function gt({config:e,onStateChange:t,markdownParser:s,apiRef:n}){console.log("[ChatWidget] Config:",{showConversationSidebar:e.showConversationSidebar,apiPaths:e.apiPaths});let[o,r]=Y(e.embedded||e.forceOpen===!0),[y,i]=Y(!1),[$,g]=Y(!1),[u,b]=Y(!1),[c,C]=Y([]),[l,f]=Y("chat"),[w,v]=Y(!1),[_,m]=Y(e.enableTTS),[H,U]=Y(!1),[A,O]=Y(null);he(()=>{e.forceOpen!==void 0&&r(e.forceOpen)},[e.forceOpen]);let F=Re(()=>Ne(e.containerId),[e.containerId]),[L,j]=Y(e.authToken||null),W=Re(()=>mt(e,()=>({authToken:L,storage:F}),X=>{let V=X({authToken:L,storage:F});V.authToken!==L&&j(V.authToken)}),[e,L,F]),h=ht(e,W,F),I=Re(()=>{if(!e.showDevTools)return e;let E=h.getEffectiveAgentKey();return E&&E!==e.agentKey?{...e,agentKey:E}:e},[e,h.getEffectiveAgentKey]),p=rt(I,W,F),S=it(e,W,F),k=ct(e,W);he(()=>{for(let E=p.messages.length-1;E>=0;E--){let q=p.messages[E];if(q.type==="sub_agent_start"){O({key:q.metadata?.subAgentKey,name:q.metadata?.agentName});return}if(q.type==="sub_agent_end"){O(null);return}}},[p.messages]),he(()=>{let E=F.get(e.conversationIdKey);console.log("[ChatWidget] Initial load - storedConvId:",E,"key:",e.conversationIdKey),console.log("[ChatWidget] apiPaths.conversations:",e.apiPaths.conversations),E&&(console.log("[ChatWidget] Loading conversation:",E),p.loadConversation(E))},[]),he(()=>{t&&t({isOpen:o,isExpanded:y,debugMode:$,messages:p.messages,conversationId:p.conversationId,isLoading:p.isLoading,error:p.error})},[o,y,$,p.messages,p.conversationId,p.isLoading,p.error]);let T=ie(async()=>{if(e.showConversationSidebar){v(!0);try{let E=I.agentKey,q=`${e.backendUrl}${e.apiPaths.conversations}?agent_key=${encodeURIComponent(E)}`,X=await fetch(q,W.getFetchOptions({method:"GET"}));if(X.ok){let V=await X.json();C(V.results||V)}}catch(E){console.error("[ChatWidget] Failed to load conversations:",E),C([])}finally{v(!1)}}},[e,I,W]),d=ie(()=>{let E=!u;b(E),E&&T()},[u,T]),R=ie(E=>{E!==p.conversationId&&p.loadConversation(E),b(!1)},[p]),D=ie(()=>{p.clearMessages(),b(!1)},[p]),a=ie(E=>{p.sendMessage(E,{model:S.selectedModel,thinking:S.thinkingEnabled&&S.supportsThinking(),onAssistantMessage:q=>{}})},[p,_,S.selectedModel,S.thinkingEnabled,S.supportsThinking]),M=ie(E=>{f(E),E==="tasks"&&k.loadTaskList()},[k]);if(he(()=>{n&&(n.current={open:()=>r(!0),close:()=>r(!1),send:E=>a(E),clearMessages:()=>p.clearMessages(),toggleTTS:()=>m(E=>!E),stopSpeech:()=>U(!1),setAuth:E=>{E.token!==void 0&&j(E.token)},clearAuth:()=>j(null)})},[p,n,a]),!e.embedded&&!o)return G`
|
|
587
683
|
<button
|
|
588
684
|
class="cw-fab"
|
|
589
685
|
style=${{backgroundColor:e.primaryColor}}
|
|
@@ -593,38 +689,40 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
593
689
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
|
594
690
|
</svg>
|
|
595
691
|
</button>
|
|
596
|
-
`;let
|
|
597
|
-
<div class=${
|
|
692
|
+
`;let N=["cw-widget",y&&"cw-widget-expanded",e.embedded&&"cw-widget-embedded"].filter(Boolean).join(" "),J=e.headerTextColor||He(e.primaryColor);return G`
|
|
693
|
+
<div class=${N} style=${{"--cw-primary":e.primaryColor,"--cw-header-text":J}}>
|
|
598
694
|
${e.showConversationSidebar&&G`
|
|
599
|
-
<${
|
|
695
|
+
<${Qe}
|
|
600
696
|
isOpen=${u}
|
|
601
697
|
conversations=${c}
|
|
602
698
|
conversationsLoading=${w}
|
|
603
699
|
currentConversationId=${p.conversationId}
|
|
604
|
-
onClose=${()=>
|
|
605
|
-
onNewConversation=${
|
|
606
|
-
onSwitchConversation=${
|
|
700
|
+
onClose=${()=>b(!1)}
|
|
701
|
+
onNewConversation=${D}
|
|
702
|
+
onSwitchConversation=${R}
|
|
607
703
|
/>
|
|
608
704
|
`}
|
|
609
705
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
706
|
+
${e.showHeader!==!1&&G`
|
|
707
|
+
<${We}
|
|
708
|
+
config=${e}
|
|
709
|
+
debugMode=${$}
|
|
710
|
+
isExpanded=${y}
|
|
711
|
+
isSpeaking=${H}
|
|
712
|
+
messagesCount=${p.messages.length}
|
|
713
|
+
isLoading=${p.isLoading}
|
|
714
|
+
currentAgent=${A}
|
|
715
|
+
onClose=${()=>r(!1)}
|
|
716
|
+
onToggleExpand=${()=>i(!y)}
|
|
717
|
+
onToggleDebug=${()=>g(!$)}
|
|
718
|
+
onToggleTTS=${()=>m(!_)}
|
|
719
|
+
onClear=${p.clearMessages}
|
|
720
|
+
onToggleSidebar=${d}
|
|
721
|
+
/>
|
|
722
|
+
`}
|
|
625
723
|
|
|
626
724
|
${e.showDevTools&&G`
|
|
627
|
-
<${
|
|
725
|
+
<${nt}
|
|
628
726
|
systems=${h.systems}
|
|
629
727
|
agents=${h.agents}
|
|
630
728
|
selectedSystem=${h.selectedSystem}
|
|
@@ -642,24 +740,24 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
642
740
|
${e.showTasksTab!==!1&&G`
|
|
643
741
|
<div class="cw-tabs">
|
|
644
742
|
<button
|
|
645
|
-
class=${`cw-tab ${
|
|
646
|
-
onClick=${()=>
|
|
743
|
+
class=${`cw-tab ${l==="chat"?"cw-tab-active":""}`}
|
|
744
|
+
onClick=${()=>M("chat")}
|
|
647
745
|
>
|
|
648
746
|
Chat
|
|
649
747
|
</button>
|
|
650
748
|
<button
|
|
651
|
-
class=${`cw-tab ${
|
|
652
|
-
onClick=${()=>
|
|
749
|
+
class=${`cw-tab ${l==="tasks"?"cw-tab-active":""}`}
|
|
750
|
+
onClick=${()=>M("tasks")}
|
|
653
751
|
>
|
|
654
|
-
Tasks ${
|
|
752
|
+
Tasks ${k.progress.total>0?G`<span class="cw-tab-badge">${k.progress.completed}/${k.progress.total}</span>`:""}
|
|
655
753
|
</button>
|
|
656
754
|
</div>
|
|
657
755
|
`}
|
|
658
756
|
|
|
659
|
-
${
|
|
757
|
+
${$&&G`<div class="cw-status-bar"><span>🐛 Debug</span></div>`}
|
|
660
758
|
|
|
661
|
-
${
|
|
662
|
-
<${
|
|
759
|
+
${l==="chat"?G`
|
|
760
|
+
<${Xe}
|
|
663
761
|
messages=${p.messages}
|
|
664
762
|
isLoading=${p.isLoading}
|
|
665
763
|
hasMoreMessages=${p.hasMoreMessages}
|
|
@@ -667,7 +765,7 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
667
765
|
onLoadMore=${p.loadMoreMessages}
|
|
668
766
|
onEditMessage=${p.editMessage}
|
|
669
767
|
onRetryMessage=${p.retryMessage}
|
|
670
|
-
debugMode=${
|
|
768
|
+
debugMode=${$}
|
|
671
769
|
markdownParser=${s}
|
|
672
770
|
emptyStateTitle=${e.emptyStateTitle}
|
|
673
771
|
emptyStateMessage=${e.emptyStateMessage}
|
|
@@ -675,41 +773,42 @@ var gt=Object.defineProperty;var ft=(e,t,s)=>t in e?gt(e,t,{enumerable:!0,config
|
|
|
675
773
|
|
|
676
774
|
${p.error&&G`<div class="cw-error-bar">${p.error}</div>`}
|
|
677
775
|
|
|
678
|
-
${e.showModelSelector&&
|
|
679
|
-
<${
|
|
680
|
-
availableModels=${
|
|
681
|
-
selectedModel=${
|
|
682
|
-
onSelectModel=${
|
|
683
|
-
thinkingEnabled=${
|
|
684
|
-
onToggleThinking=${
|
|
776
|
+
${e.showModelSelector&&S.availableModels.length>0&&G`
|
|
777
|
+
<${et}
|
|
778
|
+
availableModels=${S.availableModels}
|
|
779
|
+
selectedModel=${S.selectedModel}
|
|
780
|
+
onSelectModel=${S.selectModel}
|
|
781
|
+
thinkingEnabled=${S.thinkingEnabled}
|
|
782
|
+
onToggleThinking=${S.toggleThinking}
|
|
685
783
|
disabled=${p.isLoading}
|
|
686
784
|
/>
|
|
687
785
|
`}
|
|
688
786
|
|
|
689
|
-
<${
|
|
690
|
-
onSend=${
|
|
787
|
+
<${Ze}
|
|
788
|
+
onSend=${a}
|
|
691
789
|
onCancel=${p.cancelRun}
|
|
692
790
|
isLoading=${p.isLoading}
|
|
693
791
|
placeholder=${e.placeholder}
|
|
694
792
|
primaryColor=${e.primaryColor}
|
|
695
793
|
enableVoice=${e.enableVoice}
|
|
794
|
+
enableFiles=${e.showFileAttachment!==!1}
|
|
696
795
|
/>
|
|
697
796
|
`:G`
|
|
698
|
-
<${
|
|
699
|
-
tasks=${
|
|
700
|
-
progress=${
|
|
701
|
-
isLoading=${
|
|
702
|
-
error=${
|
|
703
|
-
onUpdate=${
|
|
704
|
-
onRemove=${
|
|
705
|
-
onClear=${
|
|
706
|
-
onRefresh=${
|
|
797
|
+
<${st}
|
|
798
|
+
tasks=${k.tasks}
|
|
799
|
+
progress=${k.progress}
|
|
800
|
+
isLoading=${k.isLoading}
|
|
801
|
+
error=${k.error}
|
|
802
|
+
onUpdate=${k.updateTask}
|
|
803
|
+
onRemove=${k.removeTask}
|
|
804
|
+
onClear=${k.clearTasks}
|
|
805
|
+
onRefresh=${k.loadTaskList}
|
|
707
806
|
/>
|
|
708
807
|
`}
|
|
709
808
|
</div>
|
|
710
|
-
`}var
|
|
809
|
+
`}var ft={backendUrl:"http://localhost:8000",agentKey:"default-agent",title:"Chat Assistant",subtitle:"How can we help you today?",primaryColor:"#0066cc",headerTextColor:null,position:"bottom-right",defaultJourneyType:"general",enableDebugMode:!0,enableAutoRun:!0,journeyTypes:{},customerPrompts:{},placeholder:"Type your message...",emptyStateTitle:"Start a Conversation",emptyStateMessage:"Send a message to get started.",authStrategy:null,authToken:null,authHeader:null,authTokenPrefix:null,anonymousSessionEndpoint:null,anonymousTokenKey:"chat_widget_anonymous_token",onAuthError:null,anonymousTokenHeader:"X-Anonymous-Token",conversationIdKey:"chat_widget_conversation_id",sessionTokenKey:"chat_widget_session_token",apiPaths:{anonymousSession:"/api/accounts/anonymous-session/",conversations:"/api/agent-runtime/conversations/",runs:"/api/agent-runtime/runs/",runEvents:"/api/agent-runtime/runs/{runId}/events/",simulateCustomer:"/api/agent-runtime/simulate-customer/",ttsVoices:"/api/tts/voices/",ttsSetVoice:"/api/tts/set-voice/",models:"/api/agent-runtime/models/",systems:"/api/agent-runtime/systems/",agents:"/api/agent-runtime/agents/"},apiCaseStyle:"auto",theme:"light",showHeader:!0,showFileAttachment:!0,showTasksTab:!0,showConversationSidebar:!0,showClearButton:!0,showDebugButton:!0,showTTSButton:!0,showVoiceSettings:!0,showExpandButton:!0,showModelSelector:!1,showDevTools:!1,enableVoice:!0,modelKey:"chat_widget_selected_model",autoRunDelay:1e3,autoRunMode:"automatic",enableTTS:!1,ttsProxyUrl:null,elevenLabsApiKey:null,ttsVoices:{assistant:null,user:null},ttsModel:"eleven_turbo_v2_5",ttsSettings:{stability:.5,similarity_boost:.75,style:0,use_speaker_boost:!0},availableVoices:[],onEvent:null,containerId:null,embedded:!1,metadata:{}};function $t(e){let t={...ft.apiPaths,...e.apiPaths||{}};return{...ft,...e,apiPaths:t}}var _e=new Map,Vt=0,P=null,De=class{constructor(t={}){Pe(this,"_handleStateChange",t=>{this._state=t});this.instanceId=`cw-${++Vt}`,this.config=$t(t),this.container=null,this._state={},this._apiRef={current:null},_e.set(this.instanceId,this)}init(){if(this.config.containerId){if(this.container=document.getElementById(this.config.containerId),!this.container)return console.error(`[ChatWidget] Container not found: ${this.config.containerId}`),this;this.container.classList.add("cw-container-embedded")}else this.container=document.createElement("div"),this.container.id=this.instanceId,this.container.className=`cw-container cw-position-${this.config.position}`,document.body.appendChild(this.container);return this._applyTheme(),this._render(),console.log(`[ChatWidget] Instance ${this.instanceId} initialized`),this}_applyTheme(){this.container&&(this.container.classList.remove("cw-dark","cw-auto"),this.config.theme==="dark"?this.container.classList.add("cw-dark"):this.config.theme==="auto"&&this.container.classList.add("cw-auto"))}_render(t={}){this.container&&yt(Wt`<${gt}
|
|
711
810
|
config=${{...this.config,...t}}
|
|
712
811
|
onStateChange=${this._handleStateChange}
|
|
713
|
-
markdownParser=${
|
|
812
|
+
markdownParser=${Oe._enhancedMarkdownParser}
|
|
714
813
|
apiRef=${this._apiRef}
|
|
715
|
-
/>`,this.container)}destroy(){this.container&&(
|
|
814
|
+
/>`,this.container)}destroy(){this.container&&(yt(null,this.container),this.config.containerId?this.container.classList.remove("cw-container-embedded"):this.container.remove(),this.container=null),_e.delete(this.instanceId),console.log(`[ChatWidget] Instance ${this.instanceId} destroyed`)}open(){this._apiRef.current?this._apiRef.current.open():this._render({forceOpen:!0})}close(){this._apiRef.current?this._apiRef.current.close():this._render({forceOpen:!1})}send(t){this._apiRef.current&&this._apiRef.current.send(t)}clearMessages(){this._apiRef.current&&this._apiRef.current.clearMessages()}toggleTTS(){this._apiRef.current&&this._apiRef.current.toggleTTS()}stopSpeech(){this._apiRef.current&&this._apiRef.current.stopSpeech()}setAuth(t){this._apiRef.current&&this._apiRef.current.setAuth(t)}clearAuth(){this._apiRef.current&&this._apiRef.current.clearAuth()}getState(){return{...this._state}}getConfig(){return{...this.config}}updateMetadata(t){this.config.metadata={...this.config.metadata,...t},this._render(),console.log(`[ChatWidget] Instance ${this.instanceId} metadata updated:`,t)}updateConfig(t){this.config={...this.config,...t},"theme"in t&&this._applyTheme(),this._render(),console.log(`[ChatWidget] Instance ${this.instanceId} config updated`)}};function wt(e={}){return new De(e).init()}function Ut(e={}){return P&&P.destroy(),P=wt(e),P}function jt(){P&&(P.destroy(),P=null)}function Jt(){P&&P.open()}function zt(){P&&P.close()}function Gt(e){P&&P.send(e)}function qt(){P&&P.clearMessages()}function Yt(){P&&P.toggleTTS()}function Xt(){P&&P.stopSpeech()}function Zt(e){P&&P.setAuth(e)}function Qt(){P&&P.clearAuth()}function es(){return P?P.getState():null}function ts(){return P?P.getConfig():null}var Oe={createInstance:wt,getInstance:e=>_e.get(e),getAllInstances:()=>Array.from(_e.values()),init:Ut,destroy:jt,open:Jt,close:zt,send:Gt,clearMessages:qt,toggleTTS:Yt,stopSpeech:Xt,setAuth:Zt,clearAuth:Qt,getState:es,getConfig:ts,_enhancedMarkdownParser:null};var kn=Oe;typeof window<"u"&&(window.ChatWidget=Oe);export{Oe as ChatWidget,kn as default};
|