@makemore/agent-frontend 2.8.1 → 2.8.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/chat-widget.cjs.js +218 -202
- package/dist/chat-widget.css +55 -3
- package/dist/chat-widget.esm.js +207 -191
- package/dist/chat-widget.js +188 -172
- package/dist/react.cjs.js +220 -204
- package/dist/react.esm.js +206 -190
- package/package.json +1 -1
- package/src/components/ChatWidget.js +13 -3
- package/src/components/ModelSelector.js +34 -10
- package/src/hooks/useChat.js +17 -2
- package/src/hooks/useModels.js +28 -4
- package/src/utils/config.js +1 -0
- package/src/utils/helpers.js +35 -0
package/dist/react.esm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
var
|
|
2
|
-
<div class="cw-header" style=${{backgroundColor:
|
|
3
|
-
${
|
|
1
|
+
var rt=Object.defineProperty;var it=(e,t,n)=>t in e?rt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Ve=(e,t,n)=>(it(e,typeof t!="symbol"?t+"":t,n),n);import{html as J}from"htm/preact";import{useState as j,useEffect as pe,useCallback as se,useMemo as st}from"preact/compat";import{html as X}from"htm/preact";function Ge(e){return e.replace(/_([a-z])/g,(t,n)=>n.toUpperCase())}function $e(e){return e.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}function ae(e){return Array.isArray(e)?e.map(ae):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([t,n])=>[Ge(t),ae(n)])):e}function oe(e){return Array.isArray(e)?e.map(oe):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([t,n])=>[$e(t),oe(n)])):e}function re(){return"msg-"+Date.now()+"-"+Math.random().toString(36).substr(2,9)}function D(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}function Ce(e){if(!e)return"";try{let t=new Date(e),o=new Date-t,i=Math.floor(o/6e4),l=Math.floor(o/36e5),h=Math.floor(o/864e5);return i<1?"Just now":i<60?`${i}m ago`:l<24?`${l}h ago`:h<7?`${h}d ago`:t.toLocaleDateString()}catch{return""}}function Se(e,t=null){if(t)return t(e);let n=D(e);return n=n.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),n=n.replace(/__(.+?)__/g,"<strong>$1</strong>"),n=n.replace(/\*(.+?)\*/g,"<em>$1</em>"),n=n.replace(/_(.+?)_/g,"<em>$1</em>"),n=n.replace(/`(.+?)`/g,"<code>$1</code>"),n=n.replace(/\[(.+?)\]\((.+?)\)/g,'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'),n=n.replace(/\n/g,"<br>"),n}function Te(e=""){let t=n=>e?`${n}_${e}`:n;return{get(n){try{return localStorage.getItem(t(n))}catch{return null}},set(n,o){try{let i=t(n);o===null?localStorage.removeItem(i):localStorage.setItem(i,o)}catch{}}}}function _e(e="csrftoken"){let t=document.cookie.split(";");for(let o of t){let[i,l]=o.trim().split("=");if(i===e)return decodeURIComponent(l)}let n=document.querySelector('meta[name="csrf-token"]');return n?n.getAttribute("content"):null}function ie(e){if(e===0)return"0 B";let t=1024,n=["B","KB","MB","GB"],o=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/Math.pow(t,o)).toFixed(1))+" "+n[o]}function le(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 lt(e){if(!e||typeof e!="string")return 0;let t=e.replace("#","");if(t.length!==6&&t.length!==3)return 0;let n=t.length===3?t.split("").map(u=>u+u).join(""):t,o=parseInt(n.substr(0,2),16)/255,i=parseInt(n.substr(2,2),16)/255,l=parseInt(n.substr(4,2),16)/255,h=u=>u<=.03928?u/12.92:Math.pow((u+.055)/1.055,2.4);return .2126*h(o)+.7152*h(i)+.0722*h(l)}function qe(e){return lt(e)>.179?"#000000":"#ffffff"}function Me({config:e,debugMode:t,isExpanded:n,isSpeaking:o,messagesCount:i,isLoading:l,currentAgent:h,onClose:u,onToggleExpand:m,onToggleDebug:y,onToggleTTS:f,onClear:k,onToggleSidebar:d}){let{title:v,primaryColor:c,embedded:p,showConversationSidebar:g,showClearButton:$,showDebugButton:S,enableDebugMode:E,showTTSButton:P,showExpandButton:L,enableTTS:H,elevenLabsApiKey:W,ttsProxyUrl:K}=e,N=W||K;return X`
|
|
2
|
+
<div class="cw-header" style=${{backgroundColor:c}}>
|
|
3
|
+
${g&&X`
|
|
4
4
|
<button
|
|
5
5
|
class="cw-header-btn cw-hamburger"
|
|
6
|
-
onClick=${
|
|
6
|
+
onClick=${d}
|
|
7
7
|
title="Conversations"
|
|
8
8
|
>
|
|
9
9
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
|
|
@@ -15,42 +15,42 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(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">${D(v)}</span>
|
|
19
|
+
${h&&X`
|
|
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">${D(h.name||h.key)}</span>
|
|
23
23
|
</span>
|
|
24
24
|
`}
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
27
|
<div class="cw-header-actions">
|
|
28
|
-
${
|
|
28
|
+
${$&&X`
|
|
29
29
|
<button
|
|
30
30
|
class="cw-header-btn"
|
|
31
31
|
onClick=${k}
|
|
32
32
|
title="Clear"
|
|
33
|
-
disabled=${
|
|
33
|
+
disabled=${l||i===0}
|
|
34
34
|
>🗑️</button>
|
|
35
35
|
`}
|
|
36
36
|
|
|
37
|
-
${
|
|
37
|
+
${S&&E&&X`
|
|
38
38
|
<button
|
|
39
39
|
class="cw-header-btn ${t?"cw-btn-active":""}"
|
|
40
|
-
onClick=${
|
|
40
|
+
onClick=${y}
|
|
41
41
|
title="Debug"
|
|
42
42
|
>🐛</button>
|
|
43
43
|
`}
|
|
44
44
|
|
|
45
|
-
${
|
|
45
|
+
${P&&N&&X`
|
|
46
46
|
<button
|
|
47
|
-
class="cw-header-btn ${
|
|
48
|
-
onClick=${
|
|
47
|
+
class="cw-header-btn ${H?"cw-btn-active":""}"
|
|
48
|
+
onClick=${f}
|
|
49
49
|
title="TTS"
|
|
50
|
-
>${
|
|
50
|
+
>${H?"\u{1F50A}":"\u{1F507}"}</button>
|
|
51
51
|
`}
|
|
52
52
|
|
|
53
|
-
${
|
|
53
|
+
${L&&!p&&X`
|
|
54
54
|
<button
|
|
55
55
|
class="cw-header-btn"
|
|
56
56
|
onClick=${m}
|
|
@@ -58,29 +58,29 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
58
58
|
>${n?"\u2296":"\u2295"}</button>
|
|
59
59
|
`}
|
|
60
60
|
|
|
61
|
-
${!
|
|
61
|
+
${!p&&X`
|
|
62
62
|
<button
|
|
63
63
|
class="cw-header-btn"
|
|
64
|
-
onClick=${
|
|
64
|
+
onClick=${u}
|
|
65
65
|
title="Close"
|
|
66
66
|
>✕</button>
|
|
67
67
|
`}
|
|
68
68
|
</div>
|
|
69
69
|
</div>
|
|
70
|
-
`}import{html as Q}from"htm/preact";import{useRef as
|
|
70
|
+
`}import{html as Q}from"htm/preact";import{useRef as Ye,useEffect as Ze}from"preact/compat";import{html as O}from"htm/preact";import{useState as ye,useRef as ct,useEffect as dt}from"preact/compat";function xe({msg:e,show:t,onToggle:n}){return t?O`
|
|
71
71
|
<div class="cw-debug-payload">
|
|
72
72
|
<button class="cw-debug-payload-close" onClick=${n}>×</button>
|
|
73
73
|
<pre class="cw-debug-payload-content">${JSON.stringify(e,null,2)}</pre>
|
|
74
74
|
</div>
|
|
75
|
-
`:
|
|
75
|
+
`:O`
|
|
76
76
|
<button
|
|
77
77
|
class="cw-debug-payload-btn"
|
|
78
78
|
onClick=${n}
|
|
79
79
|
title="Show message payload"
|
|
80
80
|
>{ }</button>
|
|
81
|
-
`}function
|
|
81
|
+
`}function Xe({onEdit:e,onRetry:t,isLoading:n,position:o,showEdit:i=!0}){return n?null:O`
|
|
82
82
|
<div class="cw-message-actions cw-message-actions-${o||"left"}">
|
|
83
|
-
${i&&
|
|
83
|
+
${i&&O`
|
|
84
84
|
<button
|
|
85
85
|
class="cw-message-action-btn"
|
|
86
86
|
onClick=${e}
|
|
@@ -104,10 +104,10 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
104
104
|
</svg>
|
|
105
105
|
</button>
|
|
106
106
|
</div>
|
|
107
|
-
`}function
|
|
107
|
+
`}function ut({initialContent:e,onSave:t,onCancel:n}){let[o,i]=ye(e),l=ct(null);return dt(()=>{l.current&&(l.current.focus(),l.current.setSelectionRange(o.length,o.length),l.current.style.height="auto",l.current.style.height=l.current.scrollHeight+"px")},[]),O`
|
|
108
108
|
<div class="cw-inline-edit">
|
|
109
109
|
<textarea
|
|
110
|
-
ref=${
|
|
110
|
+
ref=${l}
|
|
111
111
|
class="cw-inline-edit-input"
|
|
112
112
|
value=${o}
|
|
113
113
|
onInput=${m=>{i(m.target.value),m.target.style.height="auto",m.target.style.height=m.target.scrollHeight+"px"}}
|
|
@@ -128,106 +128,106 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
128
128
|
>Save & Send</button>
|
|
129
129
|
</div>
|
|
130
130
|
</div>
|
|
131
|
-
`}function
|
|
132
|
-
<div class="cw-agent-context ${
|
|
133
|
-
<span class="cw-agent-context-icon">${
|
|
131
|
+
`}function Ie({msg:e,debugMode:t,markdownParser:n,onEdit:o,onRetry:i,isLoading:l,messageIndex:h}){let[u,m]=ye(!1),[y,f]=ye(!1),[k,d]=ye(!1),v=e.role==="user",c=e.role==="system",p=e.type==="tool_call",g=e.type==="tool_result",$=e.type==="error",S=e.type==="sub_agent_start",E=e.type==="sub_agent_end",P=e.type==="agent_context";if(c&&!t)return null;if(S||E||P)return O`
|
|
132
|
+
<div class="cw-agent-context ${S?"cw-agent-delegating":""} ${E?"cw-agent-returned":""}" style="position: relative;">
|
|
133
|
+
<span class="cw-agent-context-icon">${S?"\u{1F517}":E?"\u2713":"\u{1F916}"}</span>
|
|
134
134
|
<span class="cw-agent-context-text">${e.content}</span>
|
|
135
|
-
${e.metadata?.agentName&&
|
|
135
|
+
${e.metadata?.agentName&&O`
|
|
136
136
|
<span class="cw-agent-context-name">${e.metadata.agentName}</span>
|
|
137
137
|
`}
|
|
138
|
-
${t&&
|
|
138
|
+
${t&&O`<${xe} msg=${e} show=${y} onToggle=${()=>f(!y)} />`}
|
|
139
139
|
</div>
|
|
140
|
-
`;if(
|
|
141
|
-
<div class="cw-tool-message ${
|
|
142
|
-
<span class="cw-tool-label" onClick=${()=>b&&m(
|
|
140
|
+
`;if(p||g){let b=e.metadata?.arguments||e.metadata?.result,M=r=>{if(typeof r=="string")try{return JSON.stringify(JSON.parse(r),null,2)}catch{return r}return JSON.stringify(r,null,2)};return O`
|
|
141
|
+
<div class="cw-tool-message ${g?"cw-tool-result":"cw-tool-call"}" style="position: relative;">
|
|
142
|
+
<span class="cw-tool-label" onClick=${()=>b&&m(!u)}>
|
|
143
143
|
${e.content}
|
|
144
|
-
${b&&
|
|
144
|
+
${b&&O`<span class="cw-tool-expand">${u?"\u25BC":"\u25B6"}</span>`}
|
|
145
145
|
</span>
|
|
146
|
-
${
|
|
147
|
-
<pre class="cw-tool-details">${
|
|
146
|
+
${u&&b&&O`
|
|
147
|
+
<pre class="cw-tool-details">${D(M(p?e.metadata.arguments:e.metadata.result))}</pre>
|
|
148
148
|
`}
|
|
149
|
-
${t&&
|
|
149
|
+
${t&&O`<${xe} msg=${e} show=${y} onToggle=${()=>f(!y)} />`}
|
|
150
150
|
</div>
|
|
151
|
-
`}let
|
|
151
|
+
`}let L=["cw-message",v&&"cw-message-user",$&&"cw-message-error"].filter(Boolean).join(" "),H=`cw-message-row ${v?"cw-message-row-user":""}`,W=e.role==="assistant"?Se(e.content,n):D(e.content),K=e.files&&e.files.length>0,N=()=>K?O`
|
|
152
152
|
<div class="cw-message-attachments">
|
|
153
|
-
${e.files.map(b=>b.type&&b.type.startsWith("image/")?
|
|
153
|
+
${e.files.map(b=>b.type&&b.type.startsWith("image/")?O`
|
|
154
154
|
<a class="cw-attachment-thumbnail" href=${b.url} target="_blank" title=${b.name}>
|
|
155
155
|
<img src=${b.url} alt=${b.name} />
|
|
156
156
|
</a>
|
|
157
|
-
`:
|
|
157
|
+
`:O`
|
|
158
158
|
<a class="cw-attachment-file" href=${b.url} target="_blank" title=${b.name}>
|
|
159
|
-
<span class="cw-attachment-icon">${
|
|
159
|
+
<span class="cw-attachment-icon">${le(b.type)}</span>
|
|
160
160
|
<span class="cw-attachment-info">
|
|
161
161
|
<span class="cw-attachment-name">${b.name}</span>
|
|
162
|
-
<span class="cw-attachment-size">${
|
|
162
|
+
<span class="cw-attachment-size">${ie(b.size)}</span>
|
|
163
163
|
</span>
|
|
164
164
|
</a>
|
|
165
165
|
`)}
|
|
166
166
|
</div>
|
|
167
|
-
`:null,z=b=>{
|
|
168
|
-
<div class=${
|
|
169
|
-
${
|
|
170
|
-
<${
|
|
167
|
+
`:null,z=b=>{d(!1),o&&o(h,b)},U=()=>{i&&i(h)};if(v&&k)return O`
|
|
168
|
+
<div class=${H} style="position: relative;">
|
|
169
|
+
${N()}
|
|
170
|
+
<${ut}
|
|
171
171
|
initialContent=${e.content}
|
|
172
172
|
onSave=${z}
|
|
173
|
-
onCancel=${()=>
|
|
173
|
+
onCancel=${()=>d(!1)}
|
|
174
174
|
/>
|
|
175
175
|
</div>
|
|
176
|
-
`;let s=
|
|
177
|
-
<div class="${
|
|
178
|
-
${
|
|
179
|
-
${s&&
|
|
176
|
+
`;let s=v&&o&&i,T=e.role==="assistant"&&i&&!l;return O`
|
|
177
|
+
<div class="${H} ${s||T?"cw-message-row-with-actions":""}">
|
|
178
|
+
${N()}
|
|
179
|
+
${s&&O`
|
|
180
180
|
<div class="cw-user-actions-wrapper">
|
|
181
|
-
<${
|
|
182
|
-
onEdit=${()=>
|
|
183
|
-
onRetry=${
|
|
184
|
-
isLoading=${
|
|
181
|
+
<${Xe}
|
|
182
|
+
onEdit=${()=>d(!0)}
|
|
183
|
+
onRetry=${U}
|
|
184
|
+
isLoading=${l}
|
|
185
185
|
position="left"
|
|
186
186
|
showEdit=${!0}
|
|
187
187
|
/>
|
|
188
|
-
<div class=${
|
|
188
|
+
<div class=${L} dangerouslySetInnerHTML=${{__html:W}} />
|
|
189
189
|
</div>
|
|
190
190
|
`}
|
|
191
|
-
${!s&&
|
|
192
|
-
<div class=${
|
|
191
|
+
${!s&&O`
|
|
192
|
+
<div class=${L} dangerouslySetInnerHTML=${{__html:W}} />
|
|
193
193
|
`}
|
|
194
|
-
${
|
|
195
|
-
<${
|
|
196
|
-
onRetry=${
|
|
197
|
-
isLoading=${
|
|
194
|
+
${T&&O`
|
|
195
|
+
<${Xe}
|
|
196
|
+
onRetry=${U}
|
|
197
|
+
isLoading=${l}
|
|
198
198
|
position="right"
|
|
199
199
|
showEdit=${!1}
|
|
200
200
|
/>
|
|
201
201
|
`}
|
|
202
|
-
${t&&
|
|
202
|
+
${t&&O`<${xe} msg=${e} show=${y} onToggle=${()=>f(!y)} />`}
|
|
203
203
|
</div>
|
|
204
|
-
`}function
|
|
205
|
-
<div class="cw-messages" ref=${k} onScroll=${
|
|
206
|
-
${
|
|
204
|
+
`}function Ee({messages:e,isLoading:t,hasMoreMessages:n,loadingMoreMessages:o,onLoadMore:i,onEditMessage:l,onRetryMessage:h,debugMode:u,markdownParser:m,emptyStateTitle:y,emptyStateMessage:f}){let k=Ye(null),d=Ye(!0),v=p=>{let g=p.target,$=g.scrollHeight-g.scrollTop-g.clientHeight<100;if(d.current=$,g.scrollTop<50&&n&&!o){let S=g.scrollHeight;i().then(()=>{let E=g.scrollHeight;g.scrollTop=E-S+g.scrollTop})}};Ze(()=>{let p=k.current;p&&d.current&&requestAnimationFrame(()=>{p.scrollTop=p.scrollHeight})},[e,t]),Ze(()=>{let p=k.current;p&&e.length<=2&&(d.current=!0,requestAnimationFrame(()=>{p.scrollTop=p.scrollHeight}))},[e.length]);let c=e.length===0;return Q`
|
|
205
|
+
<div class="cw-messages" ref=${k} onScroll=${v}>
|
|
206
|
+
${c&&Q`
|
|
207
207
|
<div class="cw-empty-state">
|
|
208
208
|
<svg class="cw-empty-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
209
209
|
<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
210
|
</svg>
|
|
211
|
-
<h3>${
|
|
212
|
-
<p>${
|
|
211
|
+
<h3>${D(y)}</h3>
|
|
212
|
+
<p>${D(f)}</p>
|
|
213
213
|
</div>
|
|
214
214
|
`}
|
|
215
215
|
|
|
216
|
-
${!
|
|
216
|
+
${!c&&n&&Q`
|
|
217
217
|
<div class="cw-load-more" onClick=${i}>
|
|
218
218
|
${o?Q`<span class="cw-spinner"></span><span>Loading...</span>`:Q`<span>↑ Scroll up or click to load older messages</span>`}
|
|
219
219
|
</div>
|
|
220
220
|
`}
|
|
221
221
|
|
|
222
|
-
${e.map((
|
|
223
|
-
<${
|
|
224
|
-
key=${
|
|
225
|
-
msg=${
|
|
226
|
-
messageIndex=${
|
|
227
|
-
debugMode=${
|
|
222
|
+
${e.map((p,g)=>Q`
|
|
223
|
+
<${Ie}
|
|
224
|
+
key=${p.id}
|
|
225
|
+
msg=${p}
|
|
226
|
+
messageIndex=${g}
|
|
227
|
+
debugMode=${u}
|
|
228
228
|
markdownParser=${m}
|
|
229
|
-
onEdit=${
|
|
230
|
-
onRetry=${
|
|
229
|
+
onEdit=${l}
|
|
230
|
+
onRetry=${h}
|
|
231
231
|
isLoading=${t}
|
|
232
232
|
/>
|
|
233
233
|
`)}
|
|
@@ -241,41 +241,41 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
241
241
|
</div>
|
|
242
242
|
`}
|
|
243
243
|
</div>
|
|
244
|
-
`}import{html as V}from"htm/preact";import{useState as
|
|
244
|
+
`}import{html as V}from"htm/preact";import{useState as ce,useRef as we,useEffect as Re}from"preact/compat";var Ae=typeof window<"u"?window.SpeechRecognition||window.webkitSpeechRecognition:null;function Fe({onSend:e,onCancel:t,isLoading:n,placeholder:o,primaryColor:i,enableVoice:l=!0,enableFiles:h=!0}){let[u,m]=ce(""),[y,f]=ce([]),[k,d]=ce(!1),[v,c]=ce(!1),[p]=ce(()=>!!Ae),g=we(null),$=we(null),S=we(null),E=we(!1);Re(()=>{!n&&g.current&&g.current.focus()},[n]),Re(()=>{g.current&&(g.current.style.height="auto",g.current.style.height=Math.min(g.current.scrollHeight,150)+"px")},[u]),Re(()=>()=>{E.current=!1,S.current&&S.current.abort()},[]);let P=r=>{r.preventDefault(),(u.trim()||y.length>0)&&!n&&(e(u,y),m(""),f([]),g.current&&(g.current.style.height="auto"),$.current&&($.current.value=""))},L=r=>{let I=Array.from(r.target.files||[]);I.length>0&&f(R=>[...R,...I])},H=r=>{f(I=>I.filter((R,a)=>a!==r))},W=r=>{r.preventDefault(),$.current&&!n&&$.current.click()},K=r=>{r.key==="Enter"&&!r.shiftKey&&(r.preventDefault(),P(r))},N=r=>{n&&t&&(r.preventDefault(),t())},z=()=>{if(!Ae||n)return;E.current=!0;let r=new Ae;r.continuous=!0,r.interimResults=!0,r.lang=navigator.language||"en-US";let I=u,R="";r.onstart=()=>{c(!0)},r.onresult=a=>{R="";for(let x=a.resultIndex;x<a.results.length;x++){let w=a.results[x][0].transcript;a.results[x].isFinal?I+=(I?" ":"")+w:R+=w}m(I+(R?" "+R:""))},r.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),E.current=!1,c(!1),m(I||u)},r.onend=()=>{if(E.current){console.log("[ChatWidget] Recognition paused, restarting...");try{r.start();return}catch(a){console.warn("[ChatWidget] Could not restart recognition:",a)}}c(!1),I&&m(I),S.current=null},S.current=r,r.start()},U=()=>{E.current=!1,S.current&&S.current.stop()},s=r=>{r.preventDefault(),v?U():z()},C=V`
|
|
245
245
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor">
|
|
246
246
|
<rect x="2" y="2" width="10" height="10" rx="1" />
|
|
247
247
|
</svg>
|
|
248
|
-
`,
|
|
248
|
+
`,T=V`
|
|
249
249
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
250
250
|
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path>
|
|
251
251
|
<path d="M19 10v2a7 7 0 0 1-14 0v-2"></path>
|
|
252
252
|
<line x1="12" y1="19" x2="12" y2="23"></line>
|
|
253
253
|
<line x1="8" y1="23" x2="16" y2="23"></line>
|
|
254
254
|
</svg>
|
|
255
|
-
`,
|
|
255
|
+
`,_=V`
|
|
256
256
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
257
257
|
<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
258
|
</svg>
|
|
259
|
-
`,b=
|
|
260
|
-
<form class="cw-input-form" onSubmit=${
|
|
259
|
+
`,b=l&&p,M=h;return V`
|
|
260
|
+
<form class="cw-input-form" onSubmit=${P}>
|
|
261
261
|
<input
|
|
262
262
|
type="file"
|
|
263
|
-
ref=${
|
|
263
|
+
ref=${$}
|
|
264
264
|
style="display: none"
|
|
265
265
|
multiple
|
|
266
|
-
onChange=${
|
|
266
|
+
onChange=${L}
|
|
267
267
|
/>
|
|
268
|
-
${
|
|
268
|
+
${y.length>0&&V`
|
|
269
269
|
<div class="cw-file-chips">
|
|
270
|
-
${
|
|
271
|
-
<div class="cw-file-chip" key=${
|
|
272
|
-
<span class="cw-file-chip-icon">${
|
|
270
|
+
${y.map((r,I)=>V`
|
|
271
|
+
<div class="cw-file-chip" key=${I}>
|
|
272
|
+
<span class="cw-file-chip-icon">${le(r.type)}</span>
|
|
273
273
|
<span class="cw-file-chip-name" title=${r.name}>${r.name.length>20?r.name.substring(0,17)+"...":r.name}</span>
|
|
274
|
-
<span class="cw-file-chip-size">(${
|
|
274
|
+
<span class="cw-file-chip-size">(${ie(r.size)})</span>
|
|
275
275
|
<button
|
|
276
276
|
type="button"
|
|
277
277
|
class="cw-file-chip-remove"
|
|
278
|
-
onClick=${()=>
|
|
278
|
+
onClick=${()=>H(I)}
|
|
279
279
|
title="Remove file"
|
|
280
280
|
>×</button>
|
|
281
281
|
</div>
|
|
@@ -283,79 +283,79 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
283
283
|
</div>
|
|
284
284
|
`}
|
|
285
285
|
<textarea
|
|
286
|
-
ref=${
|
|
286
|
+
ref=${g}
|
|
287
287
|
class="cw-input"
|
|
288
|
-
placeholder=${
|
|
289
|
-
value=${
|
|
288
|
+
placeholder=${D(o)}
|
|
289
|
+
value=${u}
|
|
290
290
|
onInput=${r=>m(r.target.value)}
|
|
291
|
-
onKeyDown=${
|
|
291
|
+
onKeyDown=${K}
|
|
292
292
|
disabled=${n}
|
|
293
293
|
rows="1"
|
|
294
294
|
/>
|
|
295
|
-
${
|
|
295
|
+
${M&&V`
|
|
296
296
|
<button
|
|
297
297
|
type="button"
|
|
298
298
|
class="cw-attach-btn"
|
|
299
|
-
onClick=${
|
|
299
|
+
onClick=${W}
|
|
300
300
|
disabled=${n}
|
|
301
301
|
title="Attach files"
|
|
302
302
|
>
|
|
303
|
-
${
|
|
303
|
+
${_}
|
|
304
304
|
</button>
|
|
305
305
|
`}
|
|
306
306
|
${b&&V`
|
|
307
307
|
<button
|
|
308
308
|
type="button"
|
|
309
|
-
class=${`cw-voice-btn ${
|
|
309
|
+
class=${`cw-voice-btn ${v?"cw-voice-btn-recording":""}`}
|
|
310
310
|
onClick=${s}
|
|
311
311
|
disabled=${n}
|
|
312
|
-
title=${
|
|
312
|
+
title=${v?"Stop recording":"Voice input"}
|
|
313
313
|
>
|
|
314
|
-
${
|
|
314
|
+
${T}
|
|
315
315
|
</button>
|
|
316
316
|
`}
|
|
317
317
|
<button
|
|
318
318
|
type=${n?"button":"submit"}
|
|
319
319
|
class=${`cw-send-btn ${n?"cw-send-btn-loading":""} ${n&&k?"cw-send-btn-stop":""}`}
|
|
320
320
|
style=${{backgroundColor:n&&k?"#dc2626":i}}
|
|
321
|
-
onClick=${
|
|
322
|
-
onMouseEnter=${()=>
|
|
323
|
-
onMouseLeave=${()=>
|
|
321
|
+
onClick=${N}
|
|
322
|
+
onMouseEnter=${()=>d(!0)}
|
|
323
|
+
onMouseLeave=${()=>d(!1)}
|
|
324
324
|
title=${n?"Stop":"Send"}
|
|
325
325
|
>
|
|
326
|
-
${n?k?
|
|
326
|
+
${n?k?C:V`<span class="cw-spinner"></span>`:"\u27A4"}
|
|
327
327
|
</button>
|
|
328
328
|
</form>
|
|
329
|
-
`}import{html as
|
|
329
|
+
`}import{html as ke}from"htm/preact";function Oe({isOpen:e,conversations:t,conversationsLoading:n,currentConversationId:o,onClose:i,onNewConversation:l,onSwitchConversation:h}){return ke`
|
|
330
330
|
<div class="cw-sidebar ${e?"cw-sidebar-open":""}">
|
|
331
331
|
<div class="cw-sidebar-header">
|
|
332
332
|
<span>Conversations</span>
|
|
333
333
|
<button class="cw-sidebar-close" onClick=${i}>✕</button>
|
|
334
334
|
</div>
|
|
335
335
|
|
|
336
|
-
<button class="cw-new-conversation" onClick=${
|
|
336
|
+
<button class="cw-new-conversation" onClick=${l}>
|
|
337
337
|
<span>+ New Conversation</span>
|
|
338
338
|
</button>
|
|
339
339
|
|
|
340
340
|
<div class="cw-conversation-list">
|
|
341
|
-
${n
|
|
341
|
+
${n&&ke`
|
|
342
342
|
<div class="cw-sidebar-loading">
|
|
343
343
|
<span class="cw-spinner"></span>
|
|
344
344
|
</div>
|
|
345
345
|
`}
|
|
346
346
|
|
|
347
|
-
${!n&&t.length===0
|
|
347
|
+
${!n&&t.length===0&&ke`
|
|
348
348
|
<div class="cw-sidebar-empty">No conversations yet</div>
|
|
349
349
|
`}
|
|
350
350
|
|
|
351
|
-
${t.map(
|
|
351
|
+
${t.map(u=>ke`
|
|
352
352
|
<div
|
|
353
|
-
key=${
|
|
354
|
-
class="cw-conversation-item ${
|
|
355
|
-
onClick=${()=>
|
|
353
|
+
key=${u.id}
|
|
354
|
+
class="cw-conversation-item ${u.id===o?"cw-conversation-active":""}"
|
|
355
|
+
onClick=${()=>h(u.id)}
|
|
356
356
|
>
|
|
357
|
-
<div class="cw-conversation-title">${
|
|
358
|
-
<div class="cw-conversation-date">${
|
|
357
|
+
<div class="cw-conversation-title">${D(u.title||"Untitled")}</div>
|
|
358
|
+
<div class="cw-conversation-date">${Ce(u.updatedAt||u.createdAt)}</div>
|
|
359
359
|
</div>
|
|
360
360
|
`)}
|
|
361
361
|
</div>
|
|
@@ -365,61 +365,75 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
365
365
|
class="cw-sidebar-overlay ${e?"cw-sidebar-overlay-visible":""}"
|
|
366
366
|
onClick=${i}
|
|
367
367
|
/>
|
|
368
|
-
`}import{html as
|
|
368
|
+
`}import{html as te}from"htm/preact";import{useState as pt}from"preact/compat";function De({availableModels:e,selectedModel:t,onSelectModel:n,thinkingEnabled:o,onToggleThinking:i,disabled:l}){let[h,u]=pt(!1);if(!e||e.length===0)return null;let m=e.find(c=>c.id===t),y=m?.name||"Select Model",f=m?.supports_thinking||!1,k=()=>{l||u(!h)},d=c=>{n(c),u(!1)},v=c=>{c.stopPropagation(),i&&f&&i(!o)};return te`
|
|
369
369
|
<div class="cw-model-selector">
|
|
370
|
-
<button
|
|
371
|
-
class="cw-model-btn"
|
|
372
|
-
onClick=${
|
|
373
|
-
disabled=${
|
|
370
|
+
<button
|
|
371
|
+
class="cw-model-btn"
|
|
372
|
+
onClick=${k}
|
|
373
|
+
disabled=${l}
|
|
374
374
|
title="Select Model"
|
|
375
375
|
>
|
|
376
376
|
<span class="cw-model-icon">🤖</span>
|
|
377
|
-
<span class="cw-model-name">${
|
|
378
|
-
<span class="cw-model-chevron">${
|
|
377
|
+
<span class="cw-model-name">${D(y)}</span>
|
|
378
|
+
<span class="cw-model-chevron">${h?"\u25B2":"\u25BC"}</span>
|
|
379
379
|
</button>
|
|
380
|
-
|
|
381
|
-
${i&&
|
|
380
|
+
|
|
381
|
+
${f&&i&&te`
|
|
382
|
+
<button
|
|
383
|
+
class="cw-thinking-toggle ${o?"cw-thinking-enabled":""}"
|
|
384
|
+
onClick=${v}
|
|
385
|
+
disabled=${l}
|
|
386
|
+
title=${o?"Thinking enabled - click to disable":"Enable extended thinking"}
|
|
387
|
+
>
|
|
388
|
+
<span class="cw-thinking-icon">🧠</span>
|
|
389
|
+
</button>
|
|
390
|
+
`}
|
|
391
|
+
|
|
392
|
+
${h&&te`
|
|
382
393
|
<div class="cw-model-dropdown">
|
|
383
|
-
${e.map(
|
|
384
|
-
<button
|
|
385
|
-
key=${
|
|
386
|
-
class="cw-model-option ${
|
|
387
|
-
onClick=${()=>
|
|
394
|
+
${e.map(c=>te`
|
|
395
|
+
<button
|
|
396
|
+
key=${c.id}
|
|
397
|
+
class="cw-model-option ${c.id===t?"cw-model-option-selected":""}"
|
|
398
|
+
onClick=${()=>d(c.id)}
|
|
388
399
|
>
|
|
389
|
-
<span class="cw-model-option-name"
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
400
|
+
<span class="cw-model-option-name">
|
|
401
|
+
${D(c.name)}
|
|
402
|
+
${c.supports_thinking&&te`<span class="cw-thinking-badge" title="Supports extended thinking">🧠</span>`}
|
|
403
|
+
</span>
|
|
404
|
+
<span class="cw-model-option-provider">${D(c.provider)}</span>
|
|
405
|
+
${c.description&&te`
|
|
406
|
+
<span class="cw-model-option-desc">${D(c.description)}</span>
|
|
393
407
|
`}
|
|
394
408
|
</button>
|
|
395
409
|
`)}
|
|
396
410
|
</div>
|
|
397
411
|
`}
|
|
398
412
|
</div>
|
|
399
|
-
`}import{html as G}from"htm/preact";import{useState as
|
|
413
|
+
`}import{html as G}from"htm/preact";import{useState as Qe,useCallback as de}from"preact/compat";var ht={not_started:"\u25CB",in_progress:"\u25D0",complete:"\u25CF",cancelled:"\u2298"},mt={not_started:"Not Started",in_progress:"In Progress",complete:"Complete",cancelled:"Cancelled"};function ft({task:e,onUpdate:t,onRemove:n,depth:o=0}){let[i,l]=Qe(!1),[h,u]=Qe(e.name),m=de(()=>{let d={not_started:"in_progress",in_progress:"complete",complete:"not_started",cancelled:"not_started"};t(e.id,{state:d[e.state]||"not_started"})},[e,t]),y=de(()=>{h.trim()&&h!==e.name&&t(e.id,{name:h.trim()}),l(!1)},[e,h,t]),f=de(d=>{d.key==="Enter"&&y(),d.key==="Escape"&&(u(e.name),l(!1))},[y,e.name]),k=`cw-task-state-${e.state.replace("_","-")}`;return G`
|
|
400
414
|
<div class="cw-task-item ${k}" style=${{paddingLeft:`${o*16+8}px`}}>
|
|
401
415
|
<button
|
|
402
416
|
class="cw-task-state-btn"
|
|
403
417
|
onClick=${m}
|
|
404
|
-
title=${
|
|
418
|
+
title=${mt[e.state]}
|
|
405
419
|
>
|
|
406
|
-
${
|
|
420
|
+
${ht[e.state]}
|
|
407
421
|
</button>
|
|
408
422
|
|
|
409
423
|
${i?G`
|
|
410
424
|
<input
|
|
411
425
|
type="text"
|
|
412
426
|
class="cw-task-edit-input"
|
|
413
|
-
value=${
|
|
414
|
-
onInput=${
|
|
415
|
-
onBlur=${
|
|
416
|
-
onKeyDown=${
|
|
427
|
+
value=${h}
|
|
428
|
+
onInput=${d=>u(d.target.value)}
|
|
429
|
+
onBlur=${y}
|
|
430
|
+
onKeyDown=${f}
|
|
417
431
|
autoFocus
|
|
418
432
|
/>
|
|
419
433
|
`:G`
|
|
420
434
|
<span
|
|
421
435
|
class="cw-task-name"
|
|
422
|
-
onClick=${()=>
|
|
436
|
+
onClick=${()=>l(!0)}
|
|
423
437
|
title="Click to edit"
|
|
424
438
|
>
|
|
425
439
|
${e.name}
|
|
@@ -434,16 +448,16 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
434
448
|
×
|
|
435
449
|
</button>
|
|
436
450
|
</div>
|
|
437
|
-
`}function
|
|
438
|
-
<${
|
|
451
|
+
`}function Pe({tasks:e,progress:t,isLoading:n,error:o,onUpdate:i,onRemove:l,onClear:h,onRefresh:u}){let m=de(k=>{let d=new Map,v=[];return k.forEach(c=>{d.set(c.id,{...c,children:[]})}),k.forEach(c=>{let p=d.get(c.id);c.parent_id&&d.has(c.parent_id)?d.get(c.parent_id).children.push(p):v.push(p)}),v},[]),y=de((k,d=0)=>G`
|
|
452
|
+
<${ft}
|
|
439
453
|
key=${k.id}
|
|
440
454
|
task=${k}
|
|
441
|
-
depth=${
|
|
455
|
+
depth=${d}
|
|
442
456
|
onUpdate=${i}
|
|
443
|
-
onRemove=${
|
|
457
|
+
onRemove=${l}
|
|
444
458
|
/>
|
|
445
|
-
${k.children?.map(y
|
|
446
|
-
`,[i,
|
|
459
|
+
${k.children?.map(v=>y(v,d+1))}
|
|
460
|
+
`,[i,l]),f=m(e);return n&&e.length===0?G`<div class="cw-tasks-loading">Loading tasks...</div>`:G`
|
|
447
461
|
<div class="cw-tasks-container">
|
|
448
462
|
<div class="cw-tasks-header">
|
|
449
463
|
<div class="cw-tasks-progress">
|
|
@@ -458,9 +472,9 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
458
472
|
</div>
|
|
459
473
|
</div>
|
|
460
474
|
<div class="cw-tasks-actions">
|
|
461
|
-
<button class="cw-tasks-action-btn" onClick=${
|
|
475
|
+
<button class="cw-tasks-action-btn" onClick=${u} title="Refresh">↻</button>
|
|
462
476
|
${e.length>0&&G`
|
|
463
|
-
<button class="cw-tasks-action-btn" onClick=${
|
|
477
|
+
<button class="cw-tasks-action-btn" onClick=${h} title="Clear all">🗑</button>
|
|
464
478
|
`}
|
|
465
479
|
</div>
|
|
466
480
|
</div>
|
|
@@ -468,50 +482,50 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
468
482
|
${o&&G`<div class="cw-tasks-error">${o}</div>`}
|
|
469
483
|
|
|
470
484
|
<div class="cw-tasks-list">
|
|
471
|
-
${
|
|
485
|
+
${f.length===0?G`
|
|
472
486
|
<div class="cw-tasks-empty">
|
|
473
487
|
<p>No tasks yet</p>
|
|
474
488
|
<p class="cw-tasks-empty-hint">Tasks will appear here when the agent creates them</p>
|
|
475
489
|
</div>
|
|
476
|
-
`:
|
|
490
|
+
`:f.map(k=>y(k))}
|
|
477
491
|
</div>
|
|
478
492
|
</div>
|
|
479
|
-
`}import{useState as Y,useCallback as X,useRef as Ze,useEffect as Qe}from"preact/compat";function De(e,t,n){let[o,i]=Y([]),[c,w]=Y(!1),[$,m]=Y(null),[f,l]=Y(()=>n?.get(e.conversationIdKey)||null),[k,p]=Y(!1),[y,g]=Y(!1),[u,h]=Y(0),v=Ze(null),T=Ze(null);Qe(()=>{f&&n?.set(e.conversationIdKey,f)},[f,e.conversationIdKey,n]);let A=X(async(s,M,C)=>{v.current&&v.current.close();let S=e.apiPaths.runEvents.replace("{runId}",s),b=`${e.backendUrl}${S}`;M&&(b+=`?anonymous_token=${encodeURIComponent(M)}`);let _=new EventSource(b);v.current=_;let r="";_.addEventListener("assistant.message",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("assistant.message",a.payload);let d=a.payload.content;d&&(r+=d,i(I=>{let K=I[I.length-1];return K?.role==="assistant"&&K.id.startsWith("assistant-stream-")?[...I.slice(0,-1),{...K,content:r}]:[...I,{id:"assistant-stream-"+Date.now(),role:"assistant",content:r,timestamp:new Date,type:"message"}]}))}catch(a){console.error("[ChatWidget] Parse error:",a)}}),_.addEventListener("tool.call",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("tool.call",a.payload),i(d=>[...d,{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)}}),_.addEventListener("tool.result",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("tool.result",a.payload);let d=a.payload.result,I=d?.error;i(K=>[...K,{id:"tool-result-"+Date.now(),role:"system",content:I?`\u274C ${d.error}`:"\u2713 Done",timestamp:new Date,type:"tool_result",metadata:{toolName:a.payload.name,result:d,toolCallId:a.payload.tool_call_id}}])}catch(a){console.error("[ChatWidget] Parse error:",a)}}),_.addEventListener("custom",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("custom",a.payload),a.payload?.type==="ui_control"&&e.onUIControl&&e.onUIControl(a.payload),a.payload?.type==="agent_context"&&i(d=>[...d,{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)}}),_.addEventListener("sub_agent.start",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("sub_agent.start",a.payload),i(d=>[...d,{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)}}),_.addEventListener("sub_agent.end",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("sub_agent.end",a.payload),i(d=>[...d,{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)}});let x=R=>{try{let a=JSON.parse(R.data);if(e.onEvent&&e.onEvent(a.type,a.payload),a.type==="run.failed"){let d=a.payload.error||"Agent run failed";m(d),i(I=>[...I,{id:"error-"+Date.now(),role:"system",content:`\u274C Error: ${d}`,timestamp:new Date,type:"error"}])}}catch(a){console.error("[ChatWidget] Parse error:",a)}w(!1),_.close(),v.current=null,r&&C&&C(r)};_.addEventListener("run.succeeded",x),_.addEventListener("run.failed",x),_.addEventListener("run.cancelled",x),_.addEventListener("run.timed_out",x),_.onerror=()=>{w(!1),_.close(),v.current=null}},[e]),D=X(async(s,M={},C={})=>{if(!s.trim()||c)return;let S=[],b={};typeof M=="function"?b={onAssistantMessage:M}:Array.isArray(M)?(S=M,b=C):b=M||{};let{model:_,onAssistantMessage:r,supersedeFromMessageIndex:x}=b;w(!0),m(null);let R={id:ae(),role:"user",content:s.trim(),timestamp:new Date,type:"message",files:S.length>0?S.map(a=>({name:a.name,size:a.size,type:a.type})):void 0};i(a=>[...a,R]);try{let a=await t.getOrCreateSession(),d;if(S.length>0){let W=e.apiCaseStyle!=="camel",je=he=>W?me(he):he,Z=new FormData;Z.append(je("agentKey"),e.agentKey),f&&Z.append(je("conversationId"),f),Z.append("messages",JSON.stringify([{role:"user",content:s.trim()}])),Z.append("metadata",JSON.stringify(W?{...e.metadata,journey_type:e.defaultJourneyType}:{...e.metadata,journeyType:e.defaultJourneyType})),_&&Z.append("model",_),S.forEach(he=>{Z.append("files",he)}),d=t.getFetchOptions({method:"POST",body:Z},a)}else{let W=t.transformRequest({agentKey:e.agentKey,conversationId:f,messages:[{role:"user",content:s.trim()}],metadata:{...e.metadata,journeyType:e.defaultJourneyType},..._&&{model:_},...x!==void 0&&{supersedeFromMessageIndex:x}});d=t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(W)},a)}let I=await fetch(`${e.backendUrl}${e.apiPaths.runs}`,d),K=a;if(I.status===401){t.clearSession();let W=await t.getOrCreateSession(!0);W&&(K=W,S.length>0?d=t.getFetchOptions({method:"POST",body:d.body},W):d=t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:d.body},W),I=await fetch(`${e.backendUrl}${e.apiPaths.runs}`,d))}if(!I.ok){let W=await I.json().catch(()=>({}));throw new Error(W.error||W.detail||`HTTP ${I.status}`)}let ue=await I.json(),pe=t.transformResponse(ue);T.current=pe.id,!f&&pe.conversationId&&l(pe.conversationId),await A(pe.id,K,r)}catch(a){m(a.message||"Failed to send message"),w(!1)}finally{T.current=null}},[e,t,f,c,A]),j=X(async()=>{let s=T.current;if(!(!s||!c))try{let M=e.apiPaths.cancelRun?e.apiPaths.cancelRun.replace("{runId}",s):`${e.apiPaths.runs}${s}/cancel/`;(await fetch(`${e.backendUrl}${M}`,t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"}}))).ok&&(v.current&&(v.current.close(),v.current=null),w(!1),T.current=null,i(S=>[...S,{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,c]),B=X(()=>{i([]),l(null),m(null),p(!1),h(0),n?.set(e.conversationIdKey,null)},[e.conversationIdKey,n]),N=s=>{let M={id:ae(),role:s.role,timestamp:s.timestamp?new Date(s.timestamp):new Date};if(s.role==="tool")return{...M,role:"system",content:"\u2713 Done",type:"tool_result",metadata:{result:s.content,toolCallId:s.toolCallId}};if(s.role==="assistant"&&s.toolCalls&&s.toolCalls.length>0)return s.toolCalls.map(S=>({id:ae(),role:"assistant",content:`\u{1F527} ${S.function?.name||S.name||"tool"}`,timestamp:M.timestamp,type:"tool_call",metadata:{toolName:S.function?.name||S.name,arguments:S.function?.arguments||S.arguments,toolCallId:S.id}}));let C=typeof s.content=="string"?s.content:JSON.stringify(s.content);return s.role==="assistant"&&!C?.trim()?null:{...M,content:C,type:"message"}},P=X(async s=>{w(!0),i([]),l(s);try{let M=await t.getOrCreateSession(),S=`${e.backendUrl}${e.apiPaths.conversations}${s}/?limit=10&offset=0`,b=await fetch(S,t.getFetchOptions({method:"GET"},M));if(b.ok){let _=await b.json(),r=t.transformResponse(_);r.messages&&i(r.messages.flatMap(N).filter(Boolean)),p(r.hasMore||!1),h(r.messages?.length||0)}else b.status===404&&(l(null),n?.set(e.conversationIdKey,null))}catch(M){console.error("[ChatWidget] Failed to load conversation:",M)}finally{w(!1)}},[e,t,n]),L=X(async()=>{if(!(!f||y||!k)){g(!0);try{let s=await t.getOrCreateSession(),C=`${e.backendUrl}${e.apiPaths.conversations}${f}/?limit=10&offset=${u}`,S=await fetch(C,t.getFetchOptions({method:"GET"},s));if(S.ok){let b=await S.json(),_=t.transformResponse(b);if(_.messages?.length>0){let r=_.messages.flatMap(N).filter(Boolean);i(x=>[...r,...x]),h(x=>x+_.messages.length),p(_.hasMore||!1)}else p(!1)}}catch(s){console.error("[ChatWidget] Failed to load more messages:",s)}finally{g(!1)}}},[e,t,f,u,y,k]),z=X(async(s,M,C={})=>{if(c)return;let S=o[s];if(!S||S.role!=="user")return;let b=o.slice(0,s);i(b),await D(M,{...C,supersedeFromMessageIndex:s})},[o,c,D]),H=X(async(s,M={})=>{if(c)return;let C=o[s];if(!C)return;let S=s,b=C;if(C.role==="assistant"){for(let r=s-1;r>=0;r--)if(o[r].role==="user"){S=r,b=o[r];break}if(b.role!=="user")return}else if(C.role!=="user")return;let _=o.slice(0,S);i(_),await D(b.content,{...M,supersedeFromMessageIndex:S})},[o,c,D]);return Qe(()=>()=>{v.current&&v.current.close()},[]),{messages:o,isLoading:c,error:$,conversationId:f,hasMoreMessages:k,loadingMoreMessages:y,sendMessage:D,cancelRun:j,clearMessages:B,loadConversation:P,loadMoreMessages:L,setConversationId:l,editMessage:z,retryMessage:H}}import{useState as we,useEffect as pt,useCallback as Ye}from"preact/compat";function Pe(e,t,n){let[o,i]=we([]),[c,w]=we(null),[$,m]=we(null),[f,l]=we(!1);pt(()=>{(async()=>{if(e.showModelSelector){l(!0);try{let g=await fetch(`${e.backendUrl}${e.apiPaths.models}`,t.getFetchOptions({method:"GET"}));if(g.ok){let u=await g.json(),h=u.models||[];i(h),m(u.default);let v=n?.get(e.modelKey);v&&h.some(T=>T.id===v)?w(v):w(u.default)}}catch(g){console.warn("[ChatWidget] Failed to load models:",g)}finally{l(!1)}}})()},[e.backendUrl,e.apiPaths.models,e.showModelSelector,e.modelKey,t,n]);let k=Ye(y=>{w(y),n?.set(e.modelKey,y)},[e.modelKey,n]),p=Ye(()=>o.find(y=>y.id===c)||null,[o,c]);return{availableModels:o,selectedModel:c,defaultModel:$,isLoading:f,selectModel:k,getSelectedModelInfo:p}}import{useState as Le,useCallback as ee}from"preact/compat";function Ke(e,t){let[n,o]=Le(null),[i,c]=Le(!1),[w,$]=Le(null),m=e.apiPaths?.tasks||"/api/agent/tasks/",f=ee(async()=>{c(!0),$(null);try{let u=`${e.backendUrl}${m}`,h=await fetch(u,t.getFetchOptions({method:"GET"}));if(h.ok){let v=await h.json();o(v)}else{let v=await h.json().catch(()=>({}));$(v.error||"Failed to load tasks")}}catch(u){console.error("[useTasks] Failed to load task list:",u),$("Failed to load tasks")}finally{c(!1)}},[e.backendUrl,m,t]),l=ee(async u=>{if(!n)return null;try{let h=`${e.backendUrl}${m}${n.id}/add_task/`,v=await fetch(h,t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}));if(v.ok){let T=await v.json();return await f(),T}else{let T=await v.json().catch(()=>({}));return $(T.error||"Failed to add task"),null}}catch(h){return console.error("[useTasks] Failed to add task:",h),$("Failed to add task"),null}},[e.backendUrl,m,n,t,f]),k=ee(async(u,h)=>{if(!n)return null;try{let v=`${e.backendUrl}${m}${n.id}/update_task/${u}/`,T=await fetch(v,t.getFetchOptions({method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(h)}));if(T.ok){let A=await T.json();return await f(),A}else{let A=await T.json().catch(()=>({}));return $(A.error||"Failed to update task"),null}}catch(v){return console.error("[useTasks] Failed to update task:",v),$("Failed to update task"),null}},[e.backendUrl,m,n,t,f]),p=ee(async u=>{if(!n)return!1;try{let h=`${e.backendUrl}${m}${n.id}/remove_task/${u}/`,v=await fetch(h,t.getFetchOptions({method:"DELETE"}));if(v.ok)return await f(),!0;{let T=await v.json().catch(()=>({}));return $(T.error||"Failed to remove task"),!1}}catch(h){return console.error("[useTasks] Failed to remove task:",h),$("Failed to remove task"),!1}},[e.backendUrl,m,n,t,f]),y=ee(async()=>{if(!n)return!1;try{let u=`${e.backendUrl}${m}${n.id}/clear/`,h=await fetch(u,t.getFetchOptions({method:"POST"}));if(h.ok)return await f(),!0;{let v=await h.json().catch(()=>({}));return $(v.error||"Failed to clear tasks"),!1}}catch(u){return console.error("[useTasks] Failed to clear tasks:",u),$("Failed to clear tasks"),!1}},[e.backendUrl,m,n,t,f]),g=ee(()=>$(null),[]);return{taskList:n,tasks:n?.tasks||[],progress:n?.progress||{total:0,completed:0,percent_complete:0},isLoading:i,error:w,loadTaskList:f,addTask:l,updateTask:k,removeTask:p,clearTasks:y,clearError:g}}function Ne(e,t,n){let o=l=>!l||typeof l!="object"||e.apiCaseStyle==="camel"?l:se(l),i=l=>!l||typeof l!="object"||e.apiCaseStyle==="snake"?l:ne(l),c=()=>e.authStrategy?e.authStrategy:e.authToken?"token":e.apiPaths.anonymousSession||e.anonymousSessionEndpoint?"anonymous":"none",w=(l=null)=>{let k=c(),p={},y=l||e.authToken||t().authToken;if(k==="token"&&y){let g=e.authHeader||"Authorization",u=e.authTokenPrefix!==void 0?e.authTokenPrefix:"Token";p[g]=u?`${u} ${y}`:y}else if(k==="jwt"&&y){let g=e.authHeader||"Authorization",u=e.authTokenPrefix!==void 0?e.authTokenPrefix:"Bearer";p[g]=u?`${u} ${y}`:y}else if(k==="anonymous"&&y){let g=e.authHeader||e.anonymousTokenHeader||"X-Anonymous-Token";p[g]=y}if(k==="session"){let g=Se(e.csrfCookieName);g&&(p["X-CSRFToken"]=g)}return p};return{getAuthStrategy:c,getAuthHeaders:w,getFetchOptions:(l={},k=null)=>{let p=c(),y={...l},g=w(k);return console.log("[ChatWidget] getFetchOptions - strategy:",p,"overrideToken:",k,"authHeaders:",g),y.headers={...y.headers,...g},p==="session"&&(y.credentials="include"),y},getOrCreateSession:async(l=!1)=>{let k=c(),p=t(),y=e.anonymousTokenKey||e.sessionTokenKey;if(k!=="anonymous")return e.authToken||p.authToken;if(!l){if(p.authToken)return p.authToken;let g=p.storage?.get(y);if(g)return n(u=>({...u,authToken:g})),g}try{let g=e.anonymousSessionEndpoint||e.apiPaths.anonymousSession,u=await fetch(`${e.backendUrl}${g}`,{method:"POST",headers:{"Content-Type":"application/json"}});if(u.ok){let h=await u.json();return n(v=>({...v,authToken:h.token})),p.storage?.set(y,h.token),h.token}}catch(g){console.warn("[ChatWidget] Failed to create session:",g)}return null},clearSession:()=>{let l=e.anonymousTokenKey||e.sessionTokenKey,k=t();n(p=>({...p,authToken:null})),k.storage?.set(l,null)},transformRequest:o,transformResponse:i}}function de({config:e,onStateChange:t,markdownParser:n,apiRef:o}){let[i,c]=U(e.embedded||e.forceOpen===!0),[w,$]=U(!1),[m,f]=U(!1),[l,k]=U(!1),[p,y]=U([]),[g,u]=U("chat"),[h,v]=U(!1),[T,A]=U(e.enableTTS),[D,j]=U(!1),[B,N]=U(null);ce(()=>{e.forceOpen!==void 0&&c(e.forceOpen)},[e.forceOpen]);let P=et(()=>Ce(e.containerId),[e.containerId]),[L,z]=U(e.authToken||null),H=et(()=>Ne(e,()=>({authToken:L,storage:P}),K=>{let ue=K({authToken:L,storage:P});ue.authToken!==L&&z(ue.authToken)}),[e,L,P]),s=De(e,H,P),M=Pe(e,H,P),C=Ke(e,H);ce(()=>{for(let d=s.messages.length-1;d>=0;d--){let I=s.messages[d];if(I.type==="sub_agent_start"){N({key:I.metadata?.subAgentKey,name:I.metadata?.agentName});return}if(I.type==="sub_agent_end"){N(null);return}}},[s.messages]),ce(()=>{let d=P.get(e.conversationIdKey);d&&s.loadConversation(d)},[]),ce(()=>{t&&t({isOpen:i,isExpanded:w,debugMode:m,messages:s.messages,conversationId:s.conversationId,isLoading:s.isLoading,error:s.error})},[i,w,m,s.messages,s.conversationId,s.isLoading,s.error]);let S=te(async()=>{if(e.showConversationSidebar){v(!0);try{let d=`${e.backendUrl}${e.apiPaths.conversations}?agent_key=${encodeURIComponent(e.agentKey)}`,I=await fetch(d,H.getFetchOptions({method:"GET"}));if(I.ok){let K=await I.json();y(K.results||K)}}catch(d){console.error("[ChatWidget] Failed to load conversations:",d),y([])}finally{v(!1)}}},[e,H]),b=te(()=>{let d=!l;k(d),d&&S()},[l,S]),_=te(d=>{d!==s.conversationId&&s.loadConversation(d),k(!1)},[s]),r=te(()=>{s.clearMessages(),k(!1)},[s]),x=te(d=>{s.sendMessage(d,{model:M.selectedModel,onAssistantMessage:I=>{}})},[s,T,M.selectedModel]),R=te(d=>{u(d),d==="tasks"&&C.loadTaskList()},[C]);if(ce(()=>{o&&(o.current={open:()=>c(!0),close:()=>c(!1),send:d=>x(d),clearMessages:()=>s.clearMessages(),toggleTTS:()=>A(d=>!d),stopSpeech:()=>j(!1),setAuth:d=>{d.token!==void 0&&z(d.token)},clearAuth:()=>z(null)})},[s,o,x]),!e.embedded&&!i)return J`
|
|
493
|
+
`}import{useState as ee,useCallback as Y,useRef as et,useEffect as tt}from"preact/compat";function Le(e,t,n){let[o,i]=ee([]),[l,h]=ee(!1),[u,m]=ee(null),[y,f]=ee(()=>n?.get(e.conversationIdKey)||null),[k,d]=ee(!1),[v,c]=ee(!1),[p,g]=ee(0),$=et(null),S=et(null);tt(()=>{y&&n?.set(e.conversationIdKey,y)},[y,e.conversationIdKey,n]);let E=Y(async(s,C,T)=>{$.current&&$.current.close();let _=e.apiPaths.runEvents.replace("{runId}",s),b=`${e.backendUrl}${_}`;C&&(b+=`?anonymous_token=${encodeURIComponent(C)}`);let M=new EventSource(b);$.current=M;let r="";M.addEventListener("assistant.message",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("assistant.message",a.payload);let x=a.payload.content;x&&(r+=x,i(w=>{let F=w[w.length-1];return F?.role==="assistant"&&F.id.startsWith("assistant-stream-")?[...w.slice(0,-1),{...F,content:r}]:[...w,{id:"assistant-stream-"+Date.now(),role:"assistant",content:r,timestamp:new Date,type:"message"}]}))}catch(a){console.error("[ChatWidget] Parse error:",a)}}),M.addEventListener("tool.call",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("tool.call",a.payload),i(x=>[...x,{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)}}),M.addEventListener("tool.result",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("tool.result",a.payload);let x=a.payload.result,w=x?.error;i(F=>[...F,{id:"tool-result-"+Date.now(),role:"system",content:w?`\u274C ${x.error}`:"\u2713 Done",timestamp:new Date,type:"tool_result",metadata:{toolName:a.payload.name,result:x,toolCallId:a.payload.tool_call_id}}])}catch(a){console.error("[ChatWidget] Parse error:",a)}}),M.addEventListener("custom",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("custom",a.payload),a.payload?.type==="ui_control"&&e.onUIControl&&e.onUIControl(a.payload),a.payload?.type==="agent_context"&&i(x=>[...x,{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)}}),M.addEventListener("sub_agent.start",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("sub_agent.start",a.payload),i(x=>[...x,{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)}}),M.addEventListener("sub_agent.end",R=>{try{let a=JSON.parse(R.data);e.onEvent&&e.onEvent("sub_agent.end",a.payload),i(x=>[...x,{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)}});let I=R=>{try{let a=JSON.parse(R.data);if(e.onEvent&&e.onEvent(a.type,a.payload),a.type==="run.failed"){let x=a.payload.error||"Agent run failed";m(x),i(w=>[...w,{id:"error-"+Date.now(),role:"system",content:`\u274C Error: ${x}`,timestamp:new Date,type:"error"}])}}catch(a){console.error("[ChatWidget] Parse error:",a)}h(!1),M.close(),$.current=null,r&&T&&T(r)};M.addEventListener("run.succeeded",I),M.addEventListener("run.failed",I),M.addEventListener("run.cancelled",I),M.addEventListener("run.timed_out",I),M.onerror=()=>{h(!1),M.close(),$.current=null}},[e]),P=Y(async(s,C={},T={})=>{if(!s.trim()||l)return;let _=[],b={};typeof C=="function"?b={onAssistantMessage:C}:Array.isArray(C)?(_=C,b=T):b=C||{};let{model:M,thinking:r,onAssistantMessage:I,supersedeFromMessageIndex:R}=b;h(!0),m(null);let a={id:re(),role:"user",content:s.trim(),timestamp:new Date,type:"message",files:_.length>0?_.map(x=>({name:x.name,size:x.size,type:x.type})):void 0};i(x=>[...x,a]);try{let x=await t.getOrCreateSession(),w;if(_.length>0){let B=e.apiCaseStyle!=="camel",ze=ge=>B?$e(ge):ge,q=new FormData;q.append(ze("agentKey"),e.agentKey),y&&q.append(ze("conversationId"),y),q.append("messages",JSON.stringify([{role:"user",content:s.trim()}])),q.append("metadata",JSON.stringify(B?{...e.metadata,journey_type:e.defaultJourneyType}:{...e.metadata,journeyType:e.defaultJourneyType})),M&&q.append("model",M),r&&q.append("thinking","true"),_.forEach(ge=>{q.append("files",ge)}),w=t.getFetchOptions({method:"POST",body:q},x)}else{let B=t.transformRequest({agentKey:e.agentKey,conversationId:y,messages:[{role:"user",content:s.trim()}],metadata:{...e.metadata,journeyType:e.defaultJourneyType},...M&&{model:M},...r&&{thinking:!0},...R!==void 0&&{supersedeFromMessageIndex:R}});w=t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(B)},x)}let F=await fetch(`${e.backendUrl}${e.apiPaths.runs}`,w),Z=x;if(F.status===401){t.clearSession();let B=await t.getOrCreateSession(!0);B&&(Z=B,_.length>0?w=t.getFetchOptions({method:"POST",body:w.body},B):w=t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:w.body},B),F=await fetch(`${e.backendUrl}${e.apiPaths.runs}`,w))}if(!F.ok){let B=await F.json().catch(()=>({}));throw new Error(B.error||B.detail||`HTTP ${F.status}`)}let me=await F.json(),fe=t.transformResponse(me);S.current=fe.id,!y&&fe.conversationId&&f(fe.conversationId),await E(fe.id,Z,I)}catch(x){m(x.message||"Failed to send message"),h(!1)}finally{S.current=null}},[e,t,y,l,E]),L=Y(async()=>{let s=S.current;if(!(!s||!l))try{let C=e.apiPaths.cancelRun?e.apiPaths.cancelRun.replace("{runId}",s):`${e.apiPaths.runs}${s}/cancel/`;(await fetch(`${e.backendUrl}${C}`,t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"}}))).ok&&($.current&&($.current.close(),$.current=null),h(!1),S.current=null,i(_=>[..._,{id:"cancelled-"+Date.now(),role:"system",content:"\u23F9 Run cancelled",timestamp:new Date,type:"cancelled"}]))}catch(C){console.error("[ChatWidget] Failed to cancel run:",C)}},[e,t,l]),H=Y(()=>{i([]),f(null),m(null),d(!1),g(0),n?.set(e.conversationIdKey,null)},[e.conversationIdKey,n]),W=s=>{let C={id:re(),role:s.role,timestamp:s.timestamp?new Date(s.timestamp):new Date};if(s.role==="tool")return{...C,role:"system",content:"\u2713 Done",type:"tool_result",metadata:{result:s.content,toolCallId:s.toolCallId}};if(s.role==="assistant"&&s.toolCalls&&s.toolCalls.length>0)return s.toolCalls.map(_=>({id:re(),role:"assistant",content:`\u{1F527} ${_.function?.name||_.name||"tool"}`,timestamp:C.timestamp,type:"tool_call",metadata:{toolName:_.function?.name||_.name,arguments:_.function?.arguments||_.arguments,toolCallId:_.id}}));let T=typeof s.content=="string"?s.content:JSON.stringify(s.content);return s.role==="assistant"&&!T?.trim()?null:{...C,content:T,type:"message"}},K=Y(async s=>{console.log("[ChatWidget] loadConversation called with:",s),h(!0),i([]),f(s);try{let C=await t.getOrCreateSession(),_=`${e.backendUrl}${e.apiPaths.conversations}${s}/?limit=10&offset=0`;console.log("[ChatWidget] Fetching conversation from:",_);let b=await fetch(_,t.getFetchOptions({method:"GET"},C));if(console.log("[ChatWidget] Response status:",b.status),b.ok){let M=await b.json();console.log("[ChatWidget] Raw conversation:",M);let r=t.transformResponse(M);if(console.log("[ChatWidget] Transformed conversation:",r),r.messages){let I=r.messages.flatMap(W).filter(Boolean);console.log("[ChatWidget] Mapped messages:",I),i(I)}d(r.hasMore||!1),g(r.messages?.length||0)}else b.status===404?(console.log("[ChatWidget] Conversation not found, clearing"),f(null),n?.set(e.conversationIdKey,null)):console.error("[ChatWidget] Unexpected response status:",b.status)}catch(C){console.error("[ChatWidget] Failed to load conversation:",C)}finally{h(!1)}},[e,t,n]),N=Y(async()=>{if(!(!y||v||!k)){c(!0);try{let s=await t.getOrCreateSession(),T=`${e.backendUrl}${e.apiPaths.conversations}${y}/?limit=10&offset=${p}`,_=await fetch(T,t.getFetchOptions({method:"GET"},s));if(_.ok){let b=await _.json(),M=t.transformResponse(b);if(M.messages?.length>0){let r=M.messages.flatMap(W).filter(Boolean);i(I=>[...r,...I]),g(I=>I+M.messages.length),d(M.hasMore||!1)}else d(!1)}}catch(s){console.error("[ChatWidget] Failed to load more messages:",s)}finally{c(!1)}}},[e,t,y,p,v,k]),z=Y(async(s,C,T={})=>{if(l)return;let _=o[s];if(!_||_.role!=="user")return;let b=o.slice(0,s);i(b),await P(C,{...T,supersedeFromMessageIndex:s})},[o,l,P]),U=Y(async(s,C={})=>{if(l)return;let T=o[s];if(!T)return;let _=s,b=T;if(T.role==="assistant"){for(let r=s-1;r>=0;r--)if(o[r].role==="user"){_=r,b=o[r];break}if(b.role!=="user")return}else if(T.role!=="user")return;let M=o.slice(0,_);i(M),await P(b.content,{...C,supersedeFromMessageIndex:_})},[o,l,P]);return tt(()=>()=>{$.current&&$.current.close()},[]),{messages:o,isLoading:l,error:u,conversationId:y,hasMoreMessages:k,loadingMoreMessages:v,sendMessage:P,cancelRun:L,clearMessages:H,loadConversation:K,loadMoreMessages:N,setConversationId:f,editMessage:z,retryMessage:U}}import{useState as ue,useEffect as gt,useCallback as ve}from"preact/compat";var nt="cw_thinking_enabled";function We(e,t,n){let[o,i]=ue([]),[l,h]=ue(null),[u,m]=ue(null),[y,f]=ue(!1),[k,d]=ue(!1);gt(()=>{(async()=>{if(e.showModelSelector){f(!0);try{let S=await fetch(`${e.backendUrl}${e.apiPaths.models}`,t.getFetchOptions({method:"GET"}));if(S.ok){let E=await S.json(),P=E.models||[];i(P),m(E.default);let L=n?.get(e.modelKey);L&&P.some(W=>W.id===L)?h(L):h(E.default),n?.get(nt)==="true"&&d(!0)}}catch(S){console.warn("[ChatWidget] Failed to load models:",S)}finally{f(!1)}}})()},[e.backendUrl,e.apiPaths.models,e.showModelSelector,e.modelKey,t,n]);let v=ve($=>{h($),n?.set(e.modelKey,$)},[e.modelKey,n]),c=ve($=>{d($),n?.set(nt,$?"true":"false")},[n]),p=ve(()=>o.find($=>$.id===l)||null,[o,l]),g=ve(()=>p()?.supports_thinking||!1,[p]);return{availableModels:o,selectedModel:l,defaultModel:u,isLoading:y,selectModel:v,getSelectedModelInfo:p,thinkingEnabled:k,toggleThinking:c,supportsThinking:g}}import{useState as Ke,useCallback as ne}from"preact/compat";function Ne(e,t){let[n,o]=Ke(null),[i,l]=Ke(!1),[h,u]=Ke(null),m=e.apiPaths?.tasks||"/api/agent/tasks/",y=ne(async()=>{l(!0),u(null);try{let p=`${e.backendUrl}${m}`,g=await fetch(p,t.getFetchOptions({method:"GET"}));if(g.ok){let $=await g.json();o($)}else{let $=await g.json().catch(()=>({}));u($.error||"Failed to load tasks")}}catch(p){console.error("[useTasks] Failed to load task list:",p),u("Failed to load tasks")}finally{l(!1)}},[e.backendUrl,m,t]),f=ne(async p=>{if(!n)return null;try{let g=`${e.backendUrl}${m}${n.id}/add_task/`,$=await fetch(g,t.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(p)}));if($.ok){let S=await $.json();return await y(),S}else{let S=await $.json().catch(()=>({}));return u(S.error||"Failed to add task"),null}}catch(g){return console.error("[useTasks] Failed to add task:",g),u("Failed to add task"),null}},[e.backendUrl,m,n,t,y]),k=ne(async(p,g)=>{if(!n)return null;try{let $=`${e.backendUrl}${m}${n.id}/update_task/${p}/`,S=await fetch($,t.getFetchOptions({method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)}));if(S.ok){let E=await S.json();return await y(),E}else{let E=await S.json().catch(()=>({}));return u(E.error||"Failed to update task"),null}}catch($){return console.error("[useTasks] Failed to update task:",$),u("Failed to update task"),null}},[e.backendUrl,m,n,t,y]),d=ne(async p=>{if(!n)return!1;try{let g=`${e.backendUrl}${m}${n.id}/remove_task/${p}/`,$=await fetch(g,t.getFetchOptions({method:"DELETE"}));if($.ok)return await y(),!0;{let S=await $.json().catch(()=>({}));return u(S.error||"Failed to remove task"),!1}}catch(g){return console.error("[useTasks] Failed to remove task:",g),u("Failed to remove task"),!1}},[e.backendUrl,m,n,t,y]),v=ne(async()=>{if(!n)return!1;try{let p=`${e.backendUrl}${m}${n.id}/clear/`,g=await fetch(p,t.getFetchOptions({method:"POST"}));if(g.ok)return await y(),!0;{let $=await g.json().catch(()=>({}));return u($.error||"Failed to clear tasks"),!1}}catch(p){return console.error("[useTasks] Failed to clear tasks:",p),u("Failed to clear tasks"),!1}},[e.backendUrl,m,n,t,y]),c=ne(()=>u(null),[]);return{taskList:n,tasks:n?.tasks||[],progress:n?.progress||{total:0,completed:0,percent_complete:0},isLoading:i,error:h,loadTaskList:y,addTask:f,updateTask:k,removeTask:d,clearTasks:v,clearError:c}}function He(e,t,n){let o=f=>!f||typeof f!="object"||e.apiCaseStyle==="camel"?f:oe(f),i=f=>!f||typeof f!="object"||e.apiCaseStyle==="snake"?f:ae(f),l=()=>e.authStrategy?e.authStrategy:e.authToken?"token":e.apiPaths.anonymousSession||e.anonymousSessionEndpoint?"anonymous":"none",h=(f=null)=>{let k=l(),d={},v=f||e.authToken||t().authToken;if(k==="token"&&v){let c=e.authHeader||"Authorization",p=e.authTokenPrefix!==void 0?e.authTokenPrefix:"Token";d[c]=p?`${p} ${v}`:v}else if(k==="jwt"&&v){let c=e.authHeader||"Authorization",p=e.authTokenPrefix!==void 0?e.authTokenPrefix:"Bearer";d[c]=p?`${p} ${v}`:v}else if(k==="anonymous"&&v){let c=e.authHeader||e.anonymousTokenHeader||"X-Anonymous-Token";d[c]=v}if(k==="session"){let c=_e(e.csrfCookieName);c&&(d["X-CSRFToken"]=c)}return d};return{getAuthStrategy:l,getAuthHeaders:h,getFetchOptions:(f={},k=null)=>{let d=l(),v={...f},c=h(k);return console.log("[ChatWidget] getFetchOptions - strategy:",d,"overrideToken:",k,"authHeaders:",c),v.headers={...v.headers,...c},d==="session"&&(v.credentials="include"),v},getOrCreateSession:async(f=!1)=>{let k=l(),d=t(),v=e.anonymousTokenKey||e.sessionTokenKey;if(k!=="anonymous")return e.authToken||d.authToken;if(!f){if(d.authToken)return d.authToken;let c=d.storage?.get(v);if(c)return n(p=>({...p,authToken:c})),c}try{let c=e.anonymousSessionEndpoint||e.apiPaths.anonymousSession,p=await fetch(`${e.backendUrl}${c}`,{method:"POST",headers:{"Content-Type":"application/json"}});if(p.ok){let g=await p.json();return n($=>({...$,authToken:g.token})),d.storage?.set(v,g.token),g.token}}catch(c){console.warn("[ChatWidget] Failed to create session:",c)}return null},clearSession:()=>{let f=e.anonymousTokenKey||e.sessionTokenKey,k=t();n(d=>({...d,authToken:null})),k.storage?.set(f,null)},transformRequest:o,transformResponse:i}}function he({config:e,onStateChange:t,markdownParser:n,apiRef:o}){console.log("[ChatWidget] Config:",{showConversationSidebar:e.showConversationSidebar,apiPaths:e.apiPaths});let[i,l]=j(e.embedded||e.forceOpen===!0),[h,u]=j(!1),[m,y]=j(!1),[f,k]=j(!1),[d,v]=j([]),[c,p]=j("chat"),[g,$]=j(!1),[S,E]=j(e.enableTTS),[P,L]=j(!1),[H,W]=j(null);pe(()=>{e.forceOpen!==void 0&&l(e.forceOpen)},[e.forceOpen]);let K=st(()=>Te(e.containerId),[e.containerId]),[N,z]=j(e.authToken||null),U=st(()=>He(e,()=>({authToken:N,storage:K}),Z=>{let me=Z({authToken:N,storage:K});me.authToken!==N&&z(me.authToken)}),[e,N,K]),s=Le(e,U,K),C=We(e,U,K),T=Ne(e,U);pe(()=>{for(let w=s.messages.length-1;w>=0;w--){let F=s.messages[w];if(F.type==="sub_agent_start"){W({key:F.metadata?.subAgentKey,name:F.metadata?.agentName});return}if(F.type==="sub_agent_end"){W(null);return}}},[s.messages]),pe(()=>{let w=K.get(e.conversationIdKey);console.log("[ChatWidget] Initial load - storedConvId:",w,"key:",e.conversationIdKey),console.log("[ChatWidget] apiPaths.conversations:",e.apiPaths.conversations),w&&(console.log("[ChatWidget] Loading conversation:",w),s.loadConversation(w))},[]),pe(()=>{t&&t({isOpen:i,isExpanded:h,debugMode:m,messages:s.messages,conversationId:s.conversationId,isLoading:s.isLoading,error:s.error})},[i,h,m,s.messages,s.conversationId,s.isLoading,s.error]);let _=se(async()=>{if(e.showConversationSidebar){$(!0);try{let w=`${e.backendUrl}${e.apiPaths.conversations}?agent_key=${encodeURIComponent(e.agentKey)}`,F=await fetch(w,U.getFetchOptions({method:"GET"}));if(F.ok){let Z=await F.json();v(Z.results||Z)}}catch(w){console.error("[ChatWidget] Failed to load conversations:",w),v([])}finally{$(!1)}}},[e,U]),b=se(()=>{let w=!f;k(w),w&&_()},[f,_]),M=se(w=>{w!==s.conversationId&&s.loadConversation(w),k(!1)},[s]),r=se(()=>{s.clearMessages(),k(!1)},[s]),I=se(w=>{s.sendMessage(w,{model:C.selectedModel,thinking:C.thinkingEnabled&&C.supportsThinking(),onAssistantMessage:F=>{}})},[s,S,C.selectedModel,C.thinkingEnabled,C.supportsThinking]),R=se(w=>{p(w),w==="tasks"&&T.loadTaskList()},[T]);if(pe(()=>{o&&(o.current={open:()=>l(!0),close:()=>l(!1),send:w=>I(w),clearMessages:()=>s.clearMessages(),toggleTTS:()=>E(w=>!w),stopSpeech:()=>L(!1),setAuth:w=>{w.token!==void 0&&z(w.token)},clearAuth:()=>z(null)})},[s,o,I]),!e.embedded&&!i)return J`
|
|
480
494
|
<button
|
|
481
495
|
class="cw-fab"
|
|
482
496
|
style=${{backgroundColor:e.primaryColor}}
|
|
483
|
-
onClick=${()=>
|
|
497
|
+
onClick=${()=>l(!0)}
|
|
484
498
|
>
|
|
485
499
|
<svg class="cw-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
486
500
|
<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>
|
|
487
501
|
</svg>
|
|
488
502
|
</button>
|
|
489
|
-
`;let a=["cw-widget",
|
|
490
|
-
<div class=${a} style=${{"--cw-primary":e.primaryColor}}>
|
|
503
|
+
`;let a=["cw-widget",h&&"cw-widget-expanded",e.embedded&&"cw-widget-embedded"].filter(Boolean).join(" "),x=e.headerTextColor||qe(e.primaryColor);return J`
|
|
504
|
+
<div class=${a} style=${{"--cw-primary":e.primaryColor,"--cw-header-text":x}}>
|
|
491
505
|
${e.showConversationSidebar&&J`
|
|
492
|
-
<${
|
|
493
|
-
isOpen=${
|
|
494
|
-
conversations=${
|
|
495
|
-
conversationsLoading=${
|
|
506
|
+
<${Oe}
|
|
507
|
+
isOpen=${f}
|
|
508
|
+
conversations=${d}
|
|
509
|
+
conversationsLoading=${g}
|
|
496
510
|
currentConversationId=${s.conversationId}
|
|
497
511
|
onClose=${()=>k(!1)}
|
|
498
512
|
onNewConversation=${r}
|
|
499
|
-
onSwitchConversation=${
|
|
513
|
+
onSwitchConversation=${M}
|
|
500
514
|
/>
|
|
501
515
|
`}
|
|
502
516
|
|
|
503
|
-
<${
|
|
517
|
+
<${Me}
|
|
504
518
|
config=${e}
|
|
505
519
|
debugMode=${m}
|
|
506
|
-
isExpanded=${
|
|
507
|
-
isSpeaking=${
|
|
520
|
+
isExpanded=${h}
|
|
521
|
+
isSpeaking=${P}
|
|
508
522
|
messagesCount=${s.messages.length}
|
|
509
523
|
isLoading=${s.isLoading}
|
|
510
|
-
currentAgent=${
|
|
511
|
-
onClose=${()=>
|
|
512
|
-
onToggleExpand=${()
|
|
513
|
-
onToggleDebug=${()=>
|
|
514
|
-
onToggleTTS=${()=>
|
|
524
|
+
currentAgent=${H}
|
|
525
|
+
onClose=${()=>l(!1)}
|
|
526
|
+
onToggleExpand=${()=>u(!h)}
|
|
527
|
+
onToggleDebug=${()=>y(!m)}
|
|
528
|
+
onToggleTTS=${()=>E(!S)}
|
|
515
529
|
onClear=${s.clearMessages}
|
|
516
530
|
onToggleSidebar=${b}
|
|
517
531
|
/>
|
|
@@ -519,24 +533,24 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
519
533
|
${e.showTasksTab!==!1&&J`
|
|
520
534
|
<div class="cw-tabs">
|
|
521
535
|
<button
|
|
522
|
-
class=${`cw-tab ${
|
|
536
|
+
class=${`cw-tab ${c==="chat"?"cw-tab-active":""}`}
|
|
523
537
|
onClick=${()=>R("chat")}
|
|
524
538
|
>
|
|
525
539
|
Chat
|
|
526
540
|
</button>
|
|
527
541
|
<button
|
|
528
|
-
class=${`cw-tab ${
|
|
542
|
+
class=${`cw-tab ${c==="tasks"?"cw-tab-active":""}`}
|
|
529
543
|
onClick=${()=>R("tasks")}
|
|
530
544
|
>
|
|
531
|
-
Tasks ${
|
|
545
|
+
Tasks ${T.progress.total>0?J`<span class="cw-tab-badge">${T.progress.completed}/${T.progress.total}</span>`:""}
|
|
532
546
|
</button>
|
|
533
547
|
</div>
|
|
534
548
|
`}
|
|
535
549
|
|
|
536
550
|
${m&&J`<div class="cw-status-bar"><span>🐛 Debug</span></div>`}
|
|
537
551
|
|
|
538
|
-
${
|
|
539
|
-
<${
|
|
552
|
+
${c==="chat"?J`
|
|
553
|
+
<${Ee}
|
|
540
554
|
messages=${s.messages}
|
|
541
555
|
isLoading=${s.isLoading}
|
|
542
556
|
hasMoreMessages=${s.hasMoreMessages}
|
|
@@ -552,17 +566,19 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
552
566
|
|
|
553
567
|
${s.error&&J`<div class="cw-error-bar">${s.error}</div>`}
|
|
554
568
|
|
|
555
|
-
${e.showModelSelector&&
|
|
556
|
-
<${
|
|
557
|
-
availableModels=${
|
|
558
|
-
selectedModel=${
|
|
559
|
-
onSelectModel=${
|
|
569
|
+
${e.showModelSelector&&C.availableModels.length>0&&J`
|
|
570
|
+
<${De}
|
|
571
|
+
availableModels=${C.availableModels}
|
|
572
|
+
selectedModel=${C.selectedModel}
|
|
573
|
+
onSelectModel=${C.selectModel}
|
|
574
|
+
thinkingEnabled=${C.thinkingEnabled}
|
|
575
|
+
onToggleThinking=${C.toggleThinking}
|
|
560
576
|
disabled=${s.isLoading}
|
|
561
577
|
/>
|
|
562
578
|
`}
|
|
563
579
|
|
|
564
|
-
<${
|
|
565
|
-
onSend=${
|
|
580
|
+
<${Fe}
|
|
581
|
+
onSend=${I}
|
|
566
582
|
onCancel=${s.cancelRun}
|
|
567
583
|
isLoading=${s.isLoading}
|
|
568
584
|
placeholder=${e.placeholder}
|
|
@@ -570,21 +586,21 @@ var st=Object.defineProperty;var at=(e,t,n)=>t in e?st(e,t,{enumerable:!0,config
|
|
|
570
586
|
enableVoice=${e.enableVoice}
|
|
571
587
|
/>
|
|
572
588
|
`:J`
|
|
573
|
-
<${
|
|
574
|
-
tasks=${
|
|
575
|
-
progress=${
|
|
576
|
-
isLoading=${
|
|
577
|
-
error=${
|
|
578
|
-
onUpdate=${
|
|
579
|
-
onRemove=${
|
|
580
|
-
onClear=${
|
|
581
|
-
onRefresh=${
|
|
589
|
+
<${Pe}
|
|
590
|
+
tasks=${T.tasks}
|
|
591
|
+
progress=${T.progress}
|
|
592
|
+
isLoading=${T.isLoading}
|
|
593
|
+
error=${T.error}
|
|
594
|
+
onUpdate=${T.updateTask}
|
|
595
|
+
onRemove=${T.removeTask}
|
|
596
|
+
onClear=${T.clearTasks}
|
|
597
|
+
onRefresh=${T.loadTaskList}
|
|
582
598
|
/>
|
|
583
599
|
`}
|
|
584
600
|
</div>
|
|
585
|
-
`}var
|
|
601
|
+
`}var Ue={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/"},apiCaseStyle:"auto",showConversationSidebar:!0,showClearButton:!0,showDebugButton:!0,showTTSButton:!0,showVoiceSettings:!0,showExpandButton:!0,showModelSelector:!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 Be(e){let t={...Ue.apiPaths,...e.apiPaths||{}};return{...Ue,...e,apiPaths:t}}import{render as at}from"preact/compat";import{html as $t}from"htm/preact";var be=new Map,yt=0,A=null,je=class{constructor(t={}){Ve(this,"_handleStateChange",t=>{this._state=t});this.instanceId=`cw-${++yt}`,this.config=Be(t),this.container=null,this._state={},this._apiRef={current:null},be.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._render(),console.log(`[ChatWidget] Instance ${this.instanceId} initialized`),this}_render(t={}){this.container&&at($t`<${he}
|
|
586
602
|
config=${{...this.config,...t}}
|
|
587
603
|
onStateChange=${this._handleStateChange}
|
|
588
|
-
markdownParser=${
|
|
604
|
+
markdownParser=${Je._enhancedMarkdownParser}
|
|
589
605
|
apiRef=${this._apiRef}
|
|
590
|
-
/>`,this.container)}destroy(){this.container&&(
|
|
606
|
+
/>`,this.container)}destroy(){this.container&&(at(null,this.container),this.config.containerId?this.container.classList.remove("cw-container-embedded"):this.container.remove(),this.container=null),be.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},this._render(),console.log(`[ChatWidget] Instance ${this.instanceId} config updated`)}};function ot(e={}){return new je(e).init()}function wt(e={}){return A&&A.destroy(),A=ot(e),A}function kt(){A&&(A.destroy(),A=null)}function vt(){A&&A.open()}function bt(){A&&A.close()}function Ct(e){A&&A.send(e)}function St(){A&&A.clearMessages()}function Tt(){A&&A.toggleTTS()}function _t(){A&&A.stopSpeech()}function Mt(e){A&&A.setAuth(e)}function xt(){A&&A.clearAuth()}function It(){return A?A.getState():null}function Et(){return A?A.getConfig():null}var Je={createInstance:ot,getInstance:e=>be.get(e),getAllInstances:()=>Array.from(be.values()),init:wt,destroy:kt,open:vt,close:bt,send:Ct,clearMessages:St,toggleTTS:Tt,stopSpeech:_t,setAuth:Mt,clearAuth:xt,getState:It,getConfig:Et,_enhancedMarkdownParser:null};typeof window<"u"&&(window.ChatWidget=Je);var Kn=he;export{he as ChatWidget,Je as ChatWidgetAPI,Ue as DEFAULT_CONFIG,Me as Header,Fe as InputForm,Ie as Message,Ee as MessageList,De as ModelSelector,Oe as Sidebar,Pe as TaskList,$e as camelToSnake,He as createApiClient,Te as createStorage,Kn as default,Ce as formatDate,ie as formatFileSize,re as generateId,_e as getCSRFToken,le as getFileTypeIcon,ae as keysToCamel,oe as keysToSnake,Be as mergeConfig,Se as parseMarkdown,Ge as snakeToCamel,Le as useChat,We as useModels,Ne as useTasks};
|