claudius-chat-widget 1.10.0 → 1.12.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/claudius.js CHANGED
@@ -1,9 +1,9 @@
1
- var Ee = Object.defineProperty;
2
- var Re = (e, t, r) => t in e ? Ee(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
3
- var G = (e, t, r) => Re(e, typeof t != "symbol" ? t + "" : t, r);
4
- import { jsx as i, jsxs as h, Fragment as Te } from "react/jsx-runtime";
5
- import { useMemo as Y, useState as k, useRef as C, useCallback as M, useEffect as H, forwardRef as Me, memo as J, useId as Ce } from "react";
6
- class U extends Error {
1
+ var Se = Object.defineProperty;
2
+ var Ce = (t, e, r) => e in t ? Se(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
3
+ var q = (t, e, r) => Ce(t, typeof e != "symbol" ? e + "" : e, r);
4
+ import { jsx as a, jsxs as b, Fragment as Ne } from "react/jsx-runtime";
5
+ import { useMemo as ne, useState as A, useRef as O, useCallback as L, useEffect as U, forwardRef as ke, memo as ue, useId as Le } from "react";
6
+ class H extends Error {
7
7
  /**
8
8
  * Create a {@link ChatApiError}.
9
9
  *
@@ -12,8 +12,8 @@ class U extends Error {
12
12
  * @param code - Optional machine-readable error code (e.g. `"TIMEOUT"`, `"NETWORK_ERROR"`).
13
13
  * @param retryAfter - Seconds to wait before retrying, from the `Retry-After` header.
14
14
  */
15
- constructor(t, r, s, n) {
16
- super(t), this.status = r, this.code = s, this.retryAfter = n, this.name = "ChatApiError";
15
+ constructor(e, r, n, s) {
16
+ super(e), this.status = r, this.code = n, this.retryAfter = s, this.name = "ChatApiError";
17
17
  }
18
18
  }
19
19
  class ae extends Error {
@@ -22,21 +22,21 @@ class ae extends Error {
22
22
  super("Request debounced"), this.name = "DebounceError";
23
23
  }
24
24
  }
25
- const Ne = 3e4;
26
- class Se {
25
+ const Ae = 3e4;
26
+ class Oe {
27
27
  /**
28
28
  * Create a chat client for the given Worker base URL.
29
29
  *
30
30
  * @param baseUrl - Base URL of the Worker. Requests post to `${baseUrl}/api/chat`.
31
31
  * @param options - Optional retry, debounce, and timeout settings.
32
32
  */
33
- constructor(t, r) {
34
- G(this, "baseUrl");
35
- G(this, "maxRetries");
36
- G(this, "debounceMs");
37
- G(this, "timeoutMs");
38
- G(this, "lastSendTime", 0);
39
- this.baseUrl = t, this.maxRetries = (r == null ? void 0 : r.maxRetries) ?? 2, this.debounceMs = (r == null ? void 0 : r.debounceMs) ?? 300, this.timeoutMs = (r == null ? void 0 : r.timeoutMs) ?? Ne;
33
+ constructor(e, r) {
34
+ q(this, "baseUrl");
35
+ q(this, "maxRetries");
36
+ q(this, "debounceMs");
37
+ q(this, "timeoutMs");
38
+ q(this, "lastSendTime", 0);
39
+ this.baseUrl = e, this.maxRetries = (r == null ? void 0 : r.maxRetries) ?? 2, this.debounceMs = (r == null ? void 0 : r.debounceMs) ?? 300, this.timeoutMs = (r == null ? void 0 : r.timeoutMs) ?? Ae;
40
40
  }
41
41
  /**
42
42
  * Send the conversation to the chat endpoint and return the assistant's
@@ -48,422 +48,639 @@ class Se {
48
48
  * @throws {@link DebounceError} when called within the debounce window.
49
49
  * @throws {@link ChatApiError} when the request fails after all retries.
50
50
  */
51
- async sendMessage(t) {
51
+ async sendMessage(e) {
52
52
  if (this.debounceMs > 0 && Date.now() - this.lastSendTime < this.debounceMs)
53
53
  throw new ae();
54
54
  this.lastSendTime = Date.now();
55
55
  let r;
56
- for (let s = 0; s <= this.maxRetries; s++)
56
+ for (let n = 0; n <= this.maxRetries; n++)
57
57
  try {
58
- const n = await this.fetchWithTimeout(t);
59
- if (n.ok)
60
- return await n.json();
61
- const o = await n.json().catch(() => ({})), c = n.headers.get("Retry-After"), a = c ? Number(c) : void 0;
62
- if (r = new U(
63
- o.error ?? `Request failed with status ${n.status}`,
64
- n.status,
58
+ const s = await this.fetchWithTimeout(e);
59
+ if (s.ok)
60
+ return await s.json();
61
+ const o = await s.json().catch(() => ({})), i = s.headers.get("Retry-After"), u = i ? Number(i) : void 0;
62
+ if (r = new H(
63
+ o.error ?? `Request failed with status ${s.status}`,
64
+ s.status,
65
65
  o.code,
66
- a
67
- ), !this.isRetryable(n.status))
66
+ u
67
+ ), !this.isRetryable(s.status))
68
68
  throw r;
69
- if (s < this.maxRetries) {
70
- const u = this.getRetryDelay(n, s);
71
- await this.delay(u);
69
+ if (n < this.maxRetries) {
70
+ const c = this.getRetryDelay(s, n);
71
+ await this.delay(c);
72
72
  }
73
- } catch (n) {
74
- if (n instanceof U) {
75
- if (!this.isRetryable(n.status, n.code))
76
- throw n;
77
- if (r = n, s < this.maxRetries) {
78
- const o = this.getRetryDelay(null, s);
73
+ } catch (s) {
74
+ if (s instanceof H) {
75
+ if (!this.isRetryable(s.status, s.code))
76
+ throw s;
77
+ if (r = s, n < this.maxRetries) {
78
+ const o = this.getRetryDelay(null, n);
79
79
  await this.delay(o);
80
80
  }
81
- } else if (r = new U(
81
+ } else if (r = new H(
82
82
  "Failed to connect. Please try again.",
83
83
  0,
84
84
  "NETWORK_ERROR"
85
- ), s < this.maxRetries) {
86
- const o = this.getRetryDelay(null, s);
85
+ ), n < this.maxRetries) {
86
+ const o = this.getRetryDelay(null, n);
87
87
  await this.delay(o);
88
88
  }
89
89
  }
90
90
  throw r;
91
91
  }
92
- async fetchWithTimeout(t) {
92
+ /**
93
+ * Send the conversation to the streaming chat endpoint and resolve with the
94
+ * assistant's full reply once the stream completes. Text deltas are
95
+ * delivered through {@link ChatStreamOptions.onChunk} as they arrive.
96
+ *
97
+ * Falls back to {@link sendMessage} (non-streaming) when the browser can't
98
+ * read response streams or the Worker doesn't expose `/api/chat/stream`
99
+ * (HTTP 404/405), so callers never need their own feature detection.
100
+ *
101
+ * Failures before the first byte follow the same retry policy as
102
+ * {@link sendMessage}; once streaming has begun there are no automatic
103
+ * retries. Aborting via {@link ChatStreamOptions.signal} is not an error:
104
+ * the promise resolves with the partial reply and `aborted: true`.
105
+ *
106
+ * @param messages - The full conversation so far, oldest message first.
107
+ * @param options - Chunk callback and cancellation signal.
108
+ * @throws {@link DebounceError} when called within the debounce window.
109
+ * @throws {@link ChatApiError} when the request fails after all retries, or
110
+ * the stream errors or is interrupted mid-reply (code `"STREAM_ERROR"`).
111
+ */
112
+ async streamMessage(e, r = {}) {
113
+ var s;
114
+ if (typeof ReadableStream > "u")
115
+ return this.sendMessage(e);
116
+ if (this.debounceMs > 0 && Date.now() - this.lastSendTime < this.debounceMs)
117
+ throw new ae();
118
+ this.lastSendTime = Date.now();
119
+ let n;
120
+ for (let o = 0; o <= this.maxRetries; o++) {
121
+ let i;
122
+ try {
123
+ i = await this.fetchStream(e, r.signal);
124
+ } catch (c) {
125
+ if ((s = r.signal) != null && s.aborted)
126
+ return { reply: "", aborted: !0 };
127
+ if (n = c instanceof H ? c : new H(
128
+ "Failed to connect. Please try again.",
129
+ 0,
130
+ "NETWORK_ERROR"
131
+ ), !this.isRetryable(n.status, n.code))
132
+ throw n;
133
+ o < this.maxRetries && await this.delay(this.getRetryDelay(null, o));
134
+ continue;
135
+ }
136
+ if (i.status === 404 || i.status === 405)
137
+ return this.lastSendTime = 0, this.sendMessage(e);
138
+ if (!i.ok) {
139
+ const c = await i.json().catch(() => ({})), l = i.headers.get("Retry-After");
140
+ if (n = new H(
141
+ c.error ?? `Request failed with status ${i.status}`,
142
+ i.status,
143
+ c.code,
144
+ l ? Number(l) : void 0
145
+ ), !this.isRetryable(i.status))
146
+ throw n;
147
+ o < this.maxRetries && await this.delay(this.getRetryDelay(i, o));
148
+ continue;
149
+ }
150
+ if (!(i.headers.get("Content-Type") ?? "").includes("text/event-stream"))
151
+ try {
152
+ return await i.json();
153
+ } catch {
154
+ return this.lastSendTime = 0, this.sendMessage(e);
155
+ }
156
+ return i.body ? this.readSseStream(i.body, r) : (this.lastSendTime = 0, this.sendMessage(e));
157
+ }
158
+ throw n;
159
+ }
160
+ /**
161
+ * Consumes an SSE body, invoking `onChunk` per `chunk` event, resolving on
162
+ * `done`, throwing on `error` events or an interrupted connection, and
163
+ * resolving with the partial text when the caller aborts.
164
+ */
165
+ async readSseStream(e, r) {
166
+ var l, f, y, I, E, T;
167
+ const n = e.getReader(), s = new TextDecoder();
168
+ let o = "", i = "", u;
169
+ const c = () => {
170
+ n.cancel().catch(() => {
171
+ });
172
+ };
173
+ (l = r.signal) == null || l.addEventListener("abort", c, { once: !0 });
174
+ try {
175
+ for (; ; ) {
176
+ let x;
177
+ try {
178
+ x = await n.read();
179
+ } catch (C) {
180
+ if ((f = r.signal) != null && f.aborted) break;
181
+ throw C;
182
+ }
183
+ if ((y = r.signal) != null && y.aborted || x.done) break;
184
+ o += s.decode(x.value, { stream: !0 });
185
+ let w;
186
+ for (; (w = o.indexOf(`
187
+
188
+ `)) !== -1; ) {
189
+ const C = o.slice(0, w);
190
+ o = o.slice(w + 2);
191
+ const v = Ie(C);
192
+ if (v) {
193
+ if (v.event === "chunk") {
194
+ const g = typeof v.data.text == "string" ? v.data.text : "";
195
+ g && (i += g, (I = r.onChunk) == null || I.call(r, g, i));
196
+ } else if (v.event === "done")
197
+ u = {
198
+ reply: typeof v.data.reply == "string" ? v.data.reply : i,
199
+ sources: v.data.sources
200
+ };
201
+ else if (v.event === "error")
202
+ throw new H(
203
+ typeof v.data.error == "string" ? v.data.error : "Something went wrong. Please try again.",
204
+ 0,
205
+ "STREAM_ERROR"
206
+ );
207
+ }
208
+ }
209
+ }
210
+ } finally {
211
+ (E = r.signal) == null || E.removeEventListener("abort", c), n.releaseLock();
212
+ }
213
+ if ((T = r.signal) != null && T.aborted)
214
+ return { reply: i, aborted: !0 };
215
+ if (u) return u;
216
+ throw new H(
217
+ "Connection interrupted. Please try again.",
218
+ 0,
219
+ "STREAM_ERROR"
220
+ );
221
+ }
222
+ async fetchStream(e, r) {
223
+ const n = new AbortController(), s = () => n.abort();
224
+ r == null || r.addEventListener("abort", s, { once: !0 });
225
+ let o = !1;
226
+ const i = this.timeoutMs > 0 ? setTimeout(() => {
227
+ o = !0, n.abort();
228
+ }, this.timeoutMs) : void 0;
229
+ try {
230
+ return await fetch(`${this.baseUrl}/api/chat/stream`, {
231
+ method: "POST",
232
+ headers: { "Content-Type": "application/json" },
233
+ body: JSON.stringify({ messages: e }),
234
+ signal: n.signal
235
+ });
236
+ } catch (u) {
237
+ throw o ? new H(
238
+ "Request timed out. Please try again.",
239
+ 0,
240
+ "TIMEOUT"
241
+ ) : u;
242
+ } finally {
243
+ i !== void 0 && clearTimeout(i), r == null || r.removeEventListener("abort", s);
244
+ }
245
+ }
246
+ async fetchWithTimeout(e) {
93
247
  if (this.timeoutMs <= 0)
94
248
  return fetch(`${this.baseUrl}/api/chat`, {
95
249
  method: "POST",
96
250
  headers: { "Content-Type": "application/json" },
97
- body: JSON.stringify({ messages: t })
251
+ body: JSON.stringify({ messages: e })
98
252
  });
99
- const r = new AbortController(), s = setTimeout(() => r.abort(), this.timeoutMs);
253
+ const r = new AbortController(), n = setTimeout(() => r.abort(), this.timeoutMs);
100
254
  try {
101
255
  return await fetch(`${this.baseUrl}/api/chat`, {
102
256
  method: "POST",
103
257
  headers: { "Content-Type": "application/json" },
104
- body: JSON.stringify({ messages: t }),
258
+ body: JSON.stringify({ messages: e }),
105
259
  signal: r.signal
106
260
  });
107
- } catch (n) {
108
- throw r.signal.aborted ? new U(
261
+ } catch (s) {
262
+ throw r.signal.aborted ? new H(
109
263
  "Request timed out. Please try again.",
110
264
  0,
111
265
  "TIMEOUT"
112
- ) : n;
266
+ ) : s;
113
267
  } finally {
114
- clearTimeout(s);
268
+ clearTimeout(n);
115
269
  }
116
270
  }
117
- isRetryable(t, r) {
118
- return r === "TIMEOUT" || r === "NETWORK_ERROR" ? !0 : t === 429 || t === 503;
271
+ isRetryable(e, r) {
272
+ return r === "TIMEOUT" || r === "NETWORK_ERROR" ? !0 : e === 429 || e === 503;
119
273
  }
120
- getRetryDelay(t, r) {
121
- if (t && t.status === 429) {
122
- const s = t.headers.get("Retry-After");
123
- if (s) {
124
- const n = Number(s);
125
- return Math.min(n * 1e3, 6e4);
274
+ getRetryDelay(e, r) {
275
+ if (e && e.status === 429) {
276
+ const n = e.headers.get("Retry-After");
277
+ if (n) {
278
+ const s = Number(n);
279
+ return Math.min(s * 1e3, 6e4);
126
280
  }
127
281
  }
128
282
  return r === 0 ? 1e3 : 3e3;
129
283
  }
130
- delay(t) {
131
- return new Promise((r) => setTimeout(r, t));
284
+ delay(e) {
285
+ return new Promise((r) => setTimeout(r, e));
132
286
  }
133
287
  }
134
- function ue(e) {
135
- return typeof e == "string" ? { content: e } : e;
288
+ function Ie(t) {
289
+ let e = "message";
290
+ const r = [];
291
+ for (const n of t.split(`
292
+ `))
293
+ n.startsWith("event:") ? e = n.slice(6).trim() : n.startsWith("data:") && r.push(n.slice(5).trimStart());
294
+ if (r.length === 0) return null;
295
+ try {
296
+ const n = JSON.parse(r.join(`
297
+ `));
298
+ return typeof n != "object" || n === null ? null : { event: e, data: n };
299
+ } catch {
300
+ return null;
301
+ }
136
302
  }
137
- function Q(e, t, r) {
138
- console.error(`[claudius] plugin "${e.name}" failed in ${t}:`, r);
303
+ function ye(t) {
304
+ return typeof t == "string" ? { content: t } : t;
139
305
  }
140
- async function Le(e, t, r) {
141
- let s = t;
142
- for (const n of e) {
143
- if (!n.onBeforeSend) continue;
306
+ function le(t, e, r) {
307
+ console.error(`[claudius] plugin "${t.name}" failed in ${e}:`, r);
308
+ }
309
+ async function De(t, e, r) {
310
+ let n = e;
311
+ for (const s of t) {
312
+ if (!s.onBeforeSend) continue;
144
313
  let o = null;
145
- const c = {
314
+ const i = {
146
315
  ...r,
147
- respondWith(a) {
316
+ respondWith(u) {
148
317
  o = {
149
318
  type: "respond",
150
- message: s,
151
- reply: ue(a)
319
+ message: n,
320
+ reply: ye(u)
152
321
  };
153
322
  },
154
- abort(a) {
155
- o = { type: "abort", reason: a };
323
+ abort(u) {
324
+ o = { type: "abort", reason: u };
156
325
  }
157
326
  };
158
327
  try {
159
- const a = await n.onBeforeSend(s, c);
328
+ const u = await s.onBeforeSend(n, i);
160
329
  if (o) return o;
161
- a && (s = a);
162
- } catch (a) {
163
- Q(n, "onBeforeSend", a);
330
+ u && (n = u);
331
+ } catch (u) {
332
+ le(s, "onBeforeSend", u);
164
333
  }
165
334
  }
166
- return { type: "send", message: s };
335
+ return { type: "send", message: n };
167
336
  }
168
- async function ke(e, t, r) {
169
- let s = t;
170
- for (const n of e)
171
- if (n.onAfterReceive)
337
+ async function _e(t, e, r) {
338
+ let n = e;
339
+ for (const s of t)
340
+ if (s.onAfterReceive)
172
341
  try {
173
- const o = await n.onAfterReceive(s, r);
174
- o && (s = o);
342
+ const o = await s.onAfterReceive(n, r);
343
+ o && (n = o);
175
344
  } catch (o) {
176
- Q(n, "onAfterReceive", o);
345
+ le(s, "onAfterReceive", o);
177
346
  }
178
- return s;
347
+ return n;
179
348
  }
180
- async function Ae(e, t, r) {
181
- for (const s of e) {
182
- if (!s.onError) continue;
183
- let n = null;
349
+ async function He(t, e, r) {
350
+ for (const n of t) {
351
+ if (!n.onError) continue;
352
+ let s = null;
184
353
  const o = {
185
354
  ...r,
186
- respondWith(c) {
187
- n = ue(c);
355
+ respondWith(i) {
356
+ s = ye(i);
188
357
  }
189
358
  };
190
359
  try {
191
- if (await s.onError(t, o), n) return n;
192
- } catch (c) {
193
- Q(s, "onError", c);
360
+ if (await n.onError(e, o), s) return s;
361
+ } catch (i) {
362
+ le(n, "onError", i);
194
363
  }
195
364
  }
196
365
  return null;
197
366
  }
198
- const Oe = 200, Ie = "claudius:messages";
199
- function De(e, t) {
367
+ const je = 200, Be = "claudius:messages";
368
+ function $e(t, e) {
200
369
  let r;
201
370
  try {
202
- r = new URL(t).host;
371
+ r = new URL(e).host;
203
372
  } catch {
204
- r = t;
373
+ r = e;
205
374
  }
206
- return `${e}:${r}`;
375
+ return `${t}:${r}`;
207
376
  }
208
- function Z() {
377
+ function ce() {
209
378
  try {
210
379
  return typeof sessionStorage < "u" ? sessionStorage : null;
211
380
  } catch {
212
381
  return null;
213
382
  }
214
383
  }
215
- function _e(e) {
216
- const t = Z();
217
- if (!t) return [];
384
+ function Pe(t) {
385
+ const e = ce();
386
+ if (!e) return [];
218
387
  try {
219
- const r = t.getItem(e);
388
+ const r = e.getItem(t);
220
389
  if (!r) return [];
221
- const s = JSON.parse(r);
222
- return Array.isArray(s) ? s : [];
390
+ const n = JSON.parse(r);
391
+ return Array.isArray(n) ? n : [];
223
392
  } catch {
224
393
  return [];
225
394
  }
226
395
  }
227
- function He({
228
- apiUrl: e,
229
- persistMessages: t = !0,
230
- storageKeyPrefix: r = Ie,
231
- timeoutMs: s,
232
- translations: n,
233
- plugins: o
396
+ function Ge({
397
+ apiUrl: t,
398
+ persistMessages: e = !0,
399
+ storageKeyPrefix: r = Be,
400
+ timeoutMs: n,
401
+ translations: s,
402
+ plugins: o,
403
+ streaming: i = !0
234
404
  }) {
235
- const c = Y(
236
- () => new Se(e, { debounceMs: 0, timeoutMs: s }),
237
- [e, s]
238
- ), a = De(r, e), u = t ? _e(a) : [], [l, d] = k(u), [R, p] = k(!1), [w, y] = k(null), [b, x] = k(!1), v = C(u.length), N = C(!1), E = C(u), I = C(o ?? []);
239
- I.current = o ?? [];
240
- const A = M(
241
- (f) => {
242
- if (!t) return;
243
- const g = Z();
244
- if (g)
405
+ const u = ne(
406
+ () => new Oe(t, { debounceMs: 0, timeoutMs: n }),
407
+ [t, n]
408
+ ), c = $e(r, t), l = e ? Pe(c) : [], [f, y] = A(l), [I, E] = A(!1), [T, x] = A(!1), [w, C] = A(
409
+ null
410
+ ), [v, g] = A(null), [S, j] = A(!1), W = O(l.length), $ = O(!1), p = O(l), Y = O(null), B = O(o ?? []);
411
+ B.current = o ?? [];
412
+ const _ = L(
413
+ (d) => {
414
+ if (!e) return;
415
+ const N = ce();
416
+ if (N)
245
417
  try {
246
- const L = f.slice(-Oe);
247
- g.setItem(a, JSON.stringify(L));
418
+ const k = d.slice(-je);
419
+ N.setItem(c, JSON.stringify(k));
248
420
  } catch {
249
421
  }
250
422
  },
251
- [t, a]
252
- ), D = () => (v.current += 1, `msg-${v.current}`), S = M(
253
- (f, g) => {
254
- if (!n)
255
- return g ?? "Something went wrong. Please try again.";
256
- switch (f) {
423
+ [e, c]
424
+ ), h = () => (W.current += 1, `msg-${W.current}`), F = L(
425
+ (d, N) => {
426
+ if (!s)
427
+ return N ?? "Something went wrong. Please try again.";
428
+ switch (d) {
257
429
  case "TIMEOUT":
258
- return n.errorTimeout;
430
+ return s.errorTimeout;
259
431
  case "NETWORK_ERROR":
260
- return n.errorConnection;
432
+ return s.errorConnection;
261
433
  case "RATE_LIMITED":
262
- return g != null && g.includes("minute") ? n.errorRateLimitMinute : n.errorRateLimitHour;
434
+ return N != null && N.includes("minute") ? s.errorRateLimitMinute : s.errorRateLimitHour;
263
435
  case "VALIDATION_ERROR":
264
436
  case "CONFIG_ERROR":
265
437
  case "SERVICE_ERROR":
266
438
  case "UNKNOWN_ERROR":
267
439
  default:
268
- return g ?? n.errorGeneric;
440
+ return N ?? s.errorGeneric;
269
441
  }
270
442
  },
271
- [n]
272
- ), j = M((f) => !(f instanceof U) || f.code === "TIMEOUT" || f.code === "NETWORK_ERROR" || f.code === "RATE_LIMITED" || f.code === "SERVICE_ERROR" || f.code === "UNKNOWN_ERROR" || f.status >= 500 || f.status === 0, []), m = M(
273
- async (f) => {
274
- p(!0), N.current = !0, y(null), x(!1);
443
+ [s]
444
+ ), Z = L((d) => !(d instanceof H) || d.code === "TIMEOUT" || d.code === "NETWORK_ERROR" || d.code === "RATE_LIMITED" || d.code === "SERVICE_ERROR" || d.code === "UNKNOWN_ERROR" || d.status >= 500 || d.status === 0, []), K = L(
445
+ async (d) => {
446
+ E(!0), $.current = !0, g(null), j(!1);
447
+ const N = i && typeof u.streamMessage == "function";
448
+ let k = null;
449
+ const V = (m) => {
450
+ if (k === null) {
451
+ k = h(), C(k);
452
+ const R = [
453
+ ...p.current,
454
+ { id: k, role: "assistant", content: m }
455
+ ];
456
+ p.current = R, y(R);
457
+ } else {
458
+ const R = k, D = p.current.map(
459
+ (M) => M.id === R ? { ...M, content: m } : M
460
+ );
461
+ p.current = D, y(D);
462
+ }
463
+ };
275
464
  try {
276
- const g = await c.sendMessage(f);
277
- let L = {
278
- id: D(),
465
+ let m, R, D = !1;
466
+ if (N) {
467
+ const P = new AbortController();
468
+ Y.current = P, x(!0);
469
+ const J = await u.streamMessage(d, {
470
+ signal: P.signal,
471
+ onChunk: (de, te) => V(te)
472
+ });
473
+ m = J.reply, R = J.sources, D = J.aborted ?? !1;
474
+ } else {
475
+ const P = await u.sendMessage(d);
476
+ m = P.reply, R = P.sources;
477
+ }
478
+ if (D && !m) return;
479
+ let M = {
480
+ id: k ?? h(),
279
481
  role: "assistant",
280
- content: g.reply,
281
- sources: g.sources
482
+ content: m,
483
+ sources: R
282
484
  };
283
- I.current.length > 0 && (L = await ke(
284
- I.current,
285
- L,
286
- { messages: f, apiUrl: e }
485
+ B.current.length > 0 && !D && (M = await _e(
486
+ B.current,
487
+ M,
488
+ { messages: d, apiUrl: t }
287
489
  ));
288
- const T = [...f, L];
289
- E.current = T, d(T), A(T);
290
- } catch (g) {
291
- if (g instanceof ae) return;
292
- if (I.current.length > 0) {
293
- const L = g instanceof Error ? g : new Error(String(g)), T = await Ae(I.current, L, {
294
- messages: f,
295
- apiUrl: e
490
+ const z = k !== null ? p.current.map(
491
+ (P) => P.id === M.id ? M : P
492
+ ) : [...d, M];
493
+ p.current = z, y(z), _(z);
494
+ } catch (m) {
495
+ if (m instanceof ae) return;
496
+ if (k !== null) {
497
+ _(p.current), m instanceof H ? g(F(m.code, m.message)) : g(
498
+ (s == null ? void 0 : s.errorConnection) ?? "Failed to connect. Please try again."
499
+ ), j(!1);
500
+ return;
501
+ }
502
+ if (B.current.length > 0) {
503
+ const R = m instanceof Error ? m : new Error(String(m)), D = await He(B.current, R, {
504
+ messages: d,
505
+ apiUrl: t
296
506
  });
297
- if (T) {
298
- const B = {
299
- id: D(),
507
+ if (D) {
508
+ const M = {
509
+ id: h(),
300
510
  role: "assistant",
301
- content: T.content,
302
- sources: T.sources
303
- }, O = [...f, B];
304
- E.current = O, d(O), A(O), y(null), x(!1);
511
+ content: D.content,
512
+ sources: D.sources
513
+ }, z = [...d, M];
514
+ p.current = z, y(z), _(z), g(null), j(!1);
305
515
  return;
306
516
  }
307
517
  }
308
- g instanceof U ? y(S(g.code, g.message)) : y(
309
- (n == null ? void 0 : n.errorConnection) ?? "Failed to connect. Please try again."
310
- ), x(j(g));
518
+ m instanceof H ? g(F(m.code, m.message)) : g(
519
+ (s == null ? void 0 : s.errorConnection) ?? "Failed to connect. Please try again."
520
+ ), j(Z(m));
311
521
  } finally {
312
- p(!1), N.current = !1;
522
+ E(!1), $.current = !1, x(!1), C(null), Y.current = null;
313
523
  }
314
524
  },
315
525
  [
316
- e,
317
- c,
318
- S,
319
- j,
320
- A,
321
- n
526
+ t,
527
+ u,
528
+ F,
529
+ Z,
530
+ _,
531
+ i,
532
+ s
322
533
  ]
323
- ), P = M(
324
- async (f) => {
325
- const g = f.trim();
326
- if (!g || N.current) return;
327
- const L = {
328
- id: D(),
534
+ ), se = L(() => {
535
+ var d;
536
+ (d = Y.current) == null || d.abort();
537
+ }, []), oe = L(
538
+ async (d) => {
539
+ const N = d.trim();
540
+ if (!N || $.current) return;
541
+ const k = {
542
+ id: h(),
329
543
  role: "user",
330
- content: g
544
+ content: N
331
545
  };
332
- let T = L;
333
- if (I.current.length > 0) {
334
- const O = await Le(I.current, L, {
335
- messages: E.current,
336
- apiUrl: e
546
+ let V = k;
547
+ if (B.current.length > 0) {
548
+ const R = await De(B.current, k, {
549
+ messages: p.current,
550
+ apiUrl: t
337
551
  });
338
- if (O.type === "abort") return;
339
- if (O.type === "respond") {
340
- const z = {
341
- id: D(),
552
+ if (R.type === "abort") return;
553
+ if (R.type === "respond") {
554
+ const D = {
555
+ id: h(),
342
556
  role: "assistant",
343
- content: O.reply.content,
344
- sources: O.reply.sources
345
- }, $ = [
346
- ...E.current,
347
- O.message,
348
- z
557
+ content: R.reply.content,
558
+ sources: R.reply.sources
559
+ }, M = [
560
+ ...p.current,
561
+ R.message,
562
+ D
349
563
  ];
350
- E.current = $, d($), A($), y(null), x(!1);
564
+ p.current = M, y(M), _(M), g(null), j(!1);
351
565
  return;
352
566
  }
353
- T = O.message;
567
+ V = R.message;
354
568
  }
355
- const B = [...E.current, T];
356
- E.current = B, d(B), A(B), await m(B);
569
+ const m = [...p.current, V];
570
+ p.current = m, y(m), _(m), await K(m);
357
571
  },
358
- [e, A, m]
359
- ), V = M(async () => {
360
- if (N.current) return;
361
- const f = E.current[E.current.length - 1];
362
- !f || f.role !== "user" || await m(E.current);
363
- }, [m]), K = M(() => {
364
- if (E.current = [], d([]), y(null), x(!1), t) {
365
- const f = Z();
366
- if (!f) return;
572
+ [t, _, K]
573
+ ), Q = L(async () => {
574
+ if ($.current) return;
575
+ const d = p.current[p.current.length - 1];
576
+ !d || d.role !== "user" || await K(p.current);
577
+ }, [K]), ee = L(() => {
578
+ if (p.current = [], y([]), g(null), j(!1), e) {
579
+ const d = ce();
580
+ if (!d) return;
367
581
  try {
368
- f.removeItem(a);
582
+ d.removeItem(c);
369
583
  } catch {
370
584
  }
371
585
  }
372
- }, [t, a]);
586
+ }, [e, c]);
373
587
  return {
374
- messages: l,
375
- isLoading: R,
376
- error: w,
377
- canRetry: b,
378
- sendMessage: P,
379
- retry: V,
380
- clearMessages: K
588
+ messages: f,
589
+ isLoading: I,
590
+ isStreaming: T,
591
+ streamingMessageId: w,
592
+ error: v,
593
+ canRetry: S,
594
+ sendMessage: oe,
595
+ stop: se,
596
+ retry: Q,
597
+ clearMessages: ee
381
598
  };
382
599
  }
383
- function Be(e) {
384
- const [t, r] = k(() => typeof window > "u" ? !1 : window.matchMedia(e).matches);
385
- return H(() => {
386
- const s = window.matchMedia(e);
387
- r(s.matches);
388
- const n = (o) => r(o.matches);
389
- return s.addEventListener("change", n), () => s.removeEventListener("change", n);
390
- }, [e]), t;
600
+ function Ue(t) {
601
+ const [e, r] = A(() => typeof window > "u" ? !1 : window.matchMedia(t).matches);
602
+ return U(() => {
603
+ const n = window.matchMedia(t);
604
+ r(n.matches);
605
+ const s = (o) => r(o.matches);
606
+ return n.addEventListener("change", s), () => n.removeEventListener("change", s);
607
+ }, [t]), e;
391
608
  }
392
- function F(e, t) {
393
- return e instanceof RegExp ? e.test(t) : t.toLowerCase().includes(e.toLowerCase());
609
+ function re(t, e) {
610
+ return t instanceof RegExp ? t.test(e) : e.toLowerCase().includes(t.toLowerCase());
394
611
  }
395
- function $e() {
396
- const e = document.documentElement, t = document.body, r = e.scrollTop || t.scrollTop || 0, s = Math.max(e.scrollHeight, t.scrollHeight), n = e.clientHeight || window.innerHeight, o = s - n;
612
+ function We() {
613
+ const t = document.documentElement, e = document.body, r = t.scrollTop || e.scrollTop || 0, n = Math.max(t.scrollHeight, e.scrollHeight), s = t.clientHeight || window.innerHeight, o = n - s;
397
614
  return o <= 0 ? 100 : r / o * 100;
398
615
  }
399
- function je({
400
- triggers: e,
401
- enabled: t,
616
+ function ze({
617
+ triggers: t,
618
+ enabled: e,
402
619
  onOpen: r,
403
- onGreeting: s
620
+ onGreeting: n
404
621
  }) {
405
- H(() => {
406
- if (!t || !e || e.length === 0) return;
407
- const n = /* @__PURE__ */ new Set(), o = [], c = typeof window < "u" ? window.location.href : "", a = (u, l) => {
408
- n.has(u) || (n.add(u), l === "open" ? r() : s(l.greeting));
622
+ U(() => {
623
+ if (!e || !t || t.length === 0) return;
624
+ const s = /* @__PURE__ */ new Set(), o = [], i = typeof window < "u" ? window.location.href : "", u = (c, l) => {
625
+ s.has(c) || (s.add(c), l === "open" ? r() : n(l.greeting));
409
626
  };
410
- return e.forEach((u, l) => {
411
- switch (u.on) {
627
+ return t.forEach((c, l) => {
628
+ switch (c.on) {
412
629
  case "url": {
413
- F(u.pattern, c) && a(l, u.action);
630
+ re(c.pattern, i) && u(l, c.action);
414
631
  break;
415
632
  }
416
633
  case "time": {
417
- if (u.matchUrl && !F(u.matchUrl, c))
634
+ if (c.matchUrl && !re(c.matchUrl, i))
418
635
  return;
419
- const d = window.setTimeout(
420
- () => a(l, u.action),
421
- Math.max(0, u.seconds * 1e3)
636
+ const f = window.setTimeout(
637
+ () => u(l, c.action),
638
+ Math.max(0, c.seconds * 1e3)
422
639
  );
423
- o.push(() => window.clearTimeout(d));
640
+ o.push(() => window.clearTimeout(f));
424
641
  break;
425
642
  }
426
643
  case "scroll": {
427
- if (u.matchUrl && !F(u.matchUrl, c))
644
+ if (c.matchUrl && !re(c.matchUrl, i))
428
645
  return;
429
- const d = () => {
430
- $e() >= u.percent && a(l, u.action);
646
+ const f = () => {
647
+ We() >= c.percent && u(l, c.action);
431
648
  };
432
- d(), window.addEventListener("scroll", d, { passive: !0 }), o.push(() => window.removeEventListener("scroll", d));
649
+ f(), window.addEventListener("scroll", f, { passive: !0 }), o.push(() => window.removeEventListener("scroll", f));
433
650
  break;
434
651
  }
435
652
  case "exit-intent": {
436
- if (u.matchUrl && !F(u.matchUrl, c))
653
+ if (c.matchUrl && !re(c.matchUrl, i))
437
654
  return;
438
- const d = (R) => {
439
- R.clientY <= 0 && a(l, u.action);
655
+ const f = (y) => {
656
+ y.clientY <= 0 && u(l, c.action);
440
657
  };
441
- document.addEventListener("mouseleave", d), o.push(
442
- () => document.removeEventListener("mouseleave", d)
658
+ document.addEventListener("mouseleave", f), o.push(
659
+ () => document.removeEventListener("mouseleave", f)
443
660
  );
444
661
  break;
445
662
  }
446
663
  }
447
664
  }), () => {
448
- o.forEach((u) => u());
665
+ o.forEach((c) => c());
449
666
  };
450
- }, [e, t, r, s]);
667
+ }, [t, e, r, n]);
451
668
  }
452
- const Pe = {
669
+ const Fe = {
453
670
  "bottom-right": "bottom-6 right-6",
454
671
  "bottom-left": "bottom-6 left-6",
455
672
  "top-right": "top-6 right-6",
456
673
  "top-left": "top-6 left-6"
457
- }, Ge = Me(function({ isOpen: t, onClick: r, position: s = "bottom-right", translations: n }, o) {
458
- const c = t ? (n == null ? void 0 : n.closeChat) ?? "Close chat" : (n == null ? void 0 : n.openChat) ?? "Open chat";
459
- return /* @__PURE__ */ i(
674
+ }, Ye = ke(function({ isOpen: e, onClick: r, position: n = "bottom-right", translations: s }, o) {
675
+ const i = e ? (s == null ? void 0 : s.closeChat) ?? "Close chat" : (s == null ? void 0 : s.openChat) ?? "Open chat";
676
+ return /* @__PURE__ */ a(
460
677
  "button",
461
678
  {
462
679
  ref: o,
463
680
  onClick: r,
464
- "aria-label": c,
465
- className: `fixed ${Pe[s]} z-50 flex h-14 w-14 items-center justify-center rounded-claudius-full bg-claudius-accent text-claudius-accent-text shadow-claudius-floating transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-claudius-accent focus:ring-offset-2`,
466
- children: t ? /* @__PURE__ */ h(
681
+ "aria-label": i,
682
+ className: `fixed ${Fe[n]} z-50 flex h-14 w-14 items-center justify-center rounded-claudius-full bg-claudius-accent text-claudius-accent-text shadow-claudius-floating transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-claudius-accent focus:ring-offset-2`,
683
+ children: e ? /* @__PURE__ */ b(
467
684
  "svg",
468
685
  {
469
686
  width: "24",
@@ -476,11 +693,11 @@ const Pe = {
476
693
  strokeLinejoin: "round",
477
694
  "aria-hidden": "true",
478
695
  children: [
479
- /* @__PURE__ */ i("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
480
- /* @__PURE__ */ i("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
696
+ /* @__PURE__ */ a("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
697
+ /* @__PURE__ */ a("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
481
698
  ]
482
699
  }
483
- ) : /* @__PURE__ */ i(
700
+ ) : /* @__PURE__ */ a(
484
701
  "svg",
485
702
  {
486
703
  width: "24",
@@ -492,25 +709,25 @@ const Pe = {
492
709
  strokeLinecap: "round",
493
710
  strokeLinejoin: "round",
494
711
  "aria-hidden": "true",
495
- children: /* @__PURE__ */ i("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
712
+ children: /* @__PURE__ */ a("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
496
713
  }
497
714
  )
498
715
  }
499
716
  );
500
- }), Ue = J(function({
501
- count: t,
717
+ }), Ve = ue(function({
718
+ count: e,
502
719
  isActive: r,
503
- onClick: s
720
+ onClick: n
504
721
  }) {
505
- return /* @__PURE__ */ h(
722
+ return /* @__PURE__ */ b(
506
723
  "button",
507
724
  {
508
- onClick: s,
725
+ onClick: n,
509
726
  "aria-label": "View sources",
510
727
  title: "View sources",
511
728
  className: `group relative flex h-7 w-7 items-center justify-center rounded-claudius-full transition-colors ${r ? "bg-claudius-accent text-claudius-accent-text" : "text-claudius-text-muted hover:bg-claudius-surface-muted hover:text-claudius-text"}`,
512
729
  children: [
513
- /* @__PURE__ */ h(
730
+ /* @__PURE__ */ b(
514
731
  "svg",
515
732
  {
516
733
  width: "14",
@@ -523,36 +740,72 @@ const Pe = {
523
740
  strokeLinejoin: "round",
524
741
  "aria-hidden": "true",
525
742
  children: [
526
- /* @__PURE__ */ i("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
527
- /* @__PURE__ */ i("polyline", { points: "14 2 14 8 20 8" }),
528
- /* @__PURE__ */ i("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
529
- /* @__PURE__ */ i("line", { x1: "16", y1: "17", x2: "8", y2: "17" })
743
+ /* @__PURE__ */ a("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
744
+ /* @__PURE__ */ a("polyline", { points: "14 2 14 8 20 8" }),
745
+ /* @__PURE__ */ a("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
746
+ /* @__PURE__ */ a("line", { x1: "16", y1: "17", x2: "8", y2: "17" })
530
747
  ]
531
748
  }
532
749
  ),
533
- /* @__PURE__ */ i("span", { className: "absolute -right-1 -top-1 flex h-4 min-w-4 items-center justify-center rounded-claudius-full bg-claudius-accent px-1 text-[10px] font-bold text-claudius-accent-text", children: t })
750
+ /* @__PURE__ */ a("span", { className: "absolute -right-1 -top-1 flex h-4 min-w-4 items-center justify-center rounded-claudius-full bg-claudius-accent px-1 text-[10px] font-bold text-claudius-accent-text", children: e })
534
751
  ]
535
752
  }
536
753
  );
537
- }), We = ["http:", "https:"];
538
- function le(e) {
539
- if (!e || typeof e != "string")
754
+ }), Ke = ["http:", "https:"];
755
+ function xe(t) {
756
+ if (!t || typeof t != "string")
540
757
  return null;
541
- const t = e.trim();
542
- if (!t)
758
+ const e = t.trim();
759
+ if (!e)
543
760
  return null;
544
761
  try {
545
- const r = new URL(t);
546
- return We.includes(r.protocol) ? t : null;
762
+ const r = new URL(e);
763
+ return Ke.includes(r.protocol) ? e : null;
547
764
  } catch {
548
765
  return null;
549
766
  }
550
767
  }
551
- const ne = /(https?:\/\/[^\s)]+)/, se = /(\*\*[^*]+\*\*)/, oe = /(\*[^*]+\*)/;
552
- function ze(e, t) {
553
- const r = e.match(/[.,;:!?'"]+$/), s = r ? e.slice(0, -r[0].length) : e, n = r ? r[0] : "", o = le(s);
554
- return o ? /* @__PURE__ */ h(Te, { children: [
555
- /* @__PURE__ */ h(
768
+ function qe(t) {
769
+ const e = t.lastIndexOf(`
770
+ `), r = e === -1 ? "" : t.slice(0, e + 1);
771
+ let n = e === -1 ? t : t.slice(e + 1);
772
+ return n = Ze(n), n = Qe(n), r + n;
773
+ }
774
+ function Je(t) {
775
+ const e = [];
776
+ for (let r = 0; r < t.length - 1; r++)
777
+ t[r] === "*" && t[r + 1] === "*" && (e.push(r), r++);
778
+ return e;
779
+ }
780
+ function Xe(t) {
781
+ const e = [];
782
+ for (let r = 0; r < t.length; r++)
783
+ if (t[r] === "*") {
784
+ if (t[r + 1] === "*") {
785
+ r++;
786
+ continue;
787
+ }
788
+ e.push(r);
789
+ }
790
+ return e;
791
+ }
792
+ function Ze(t) {
793
+ const e = Je(t);
794
+ if (e.length % 2 === 0) return t;
795
+ const r = e[e.length - 1], n = t.slice(r + 2);
796
+ return n.trim() === "" ? t.slice(0, r) + n : t + "**";
797
+ }
798
+ function Qe(t) {
799
+ const e = Xe(t);
800
+ if (e.length % 2 === 0) return t;
801
+ const r = e[e.length - 1], n = t.slice(r + 1);
802
+ return n.trim() === "" ? t.slice(0, r) + n : t + "*";
803
+ }
804
+ const he = /(https?:\/\/[^\s)]+)/, me = /(\*\*[^*]+\*\*)/, ge = /(\*[^*]+\*)/;
805
+ function et(t, e) {
806
+ const r = t.match(/[.,;:!?'"]+$/), n = r ? t.slice(0, -r[0].length) : t, s = r ? r[0] : "", o = xe(n);
807
+ return o ? /* @__PURE__ */ b(Ne, { children: [
808
+ /* @__PURE__ */ b(
556
809
  "a",
557
810
  {
558
811
  href: o,
@@ -561,114 +814,136 @@ function ze(e, t) {
561
814
  className: "underline font-medium hover:opacity-80 text-claudius-link",
562
815
  children: [
563
816
  o.replace(/^https?:\/\//, ""),
564
- /* @__PURE__ */ i("span", { className: "sr-only", children: " (opens in a new tab)" })
817
+ /* @__PURE__ */ a("span", { className: "sr-only", children: " (opens in a new tab)" })
565
818
  ]
566
819
  },
567
- t
820
+ e
568
821
  ),
569
- n
570
- ] }) : e;
822
+ s
823
+ ] }) : t;
571
824
  }
572
- function Fe(e, t) {
573
- const r = e.split(se), s = [];
574
- return r.forEach((n, o) => {
575
- if (se.test(n)) {
576
- const c = n.slice(2, -2);
577
- s.push(/* @__PURE__ */ i("strong", { children: c }, `${t}-b${o}`));
825
+ function tt(t, e) {
826
+ const r = t.split(me), n = [];
827
+ return r.forEach((s, o) => {
828
+ if (me.test(s)) {
829
+ const i = s.slice(2, -2);
830
+ n.push(/* @__PURE__ */ a("strong", { children: i }, `${e}-b${o}`));
578
831
  } else
579
- n.split(oe).forEach((a, u) => {
580
- if (oe.test(a)) {
581
- const l = a.slice(1, -1);
582
- s.push(/* @__PURE__ */ i("em", { children: l }, `${t}-b${o}-i${u}`));
832
+ s.split(ge).forEach((u, c) => {
833
+ if (ge.test(u)) {
834
+ const l = u.slice(1, -1);
835
+ n.push(/* @__PURE__ */ a("em", { children: l }, `${e}-b${o}-i${c}`));
583
836
  } else
584
- a.split(ne).forEach((d, R) => {
585
- ne.test(d) ? s.push(
586
- ze(d, `${t}-b${o}-i${u}-u${R}`)
587
- ) : d && s.push(d);
837
+ u.split(he).forEach((f, y) => {
838
+ he.test(f) ? n.push(
839
+ et(f, `${e}-b${o}-i${c}-u${y}`)
840
+ ) : f && n.push(f);
588
841
  });
589
842
  });
590
- }), s;
843
+ }), n;
591
844
  }
592
- function Ye(e) {
593
- const t = e.split(`
845
+ function rt(t) {
846
+ const e = t.split(`
594
847
  `);
595
- return t.map((r, s) => /* @__PURE__ */ h("span", { children: [
596
- Fe(r, `l${s}`),
597
- s < t.length - 1 && /* @__PURE__ */ i("br", {})
598
- ] }, s));
848
+ return e.map((r, n) => /* @__PURE__ */ b("span", { children: [
849
+ tt(r, `l${n}`),
850
+ n < e.length - 1 && /* @__PURE__ */ a("br", {})
851
+ ] }, n));
599
852
  }
600
- const Ve = J(function({
601
- role: t,
853
+ const nt = ue(function({
854
+ role: e,
602
855
  content: r,
856
+ isStreaming: n = !1,
603
857
  sources: s,
604
- onSourceClick: n,
605
- isSourceActive: o
858
+ onSourceClick: o,
859
+ isSourceActive: i
606
860
  }) {
607
- const c = t === "user";
608
- return /* @__PURE__ */ h("div", { className: `${c ? "ml-auto" : "mr-auto"} max-w-[85%]`, children: [
609
- /* @__PURE__ */ i(
861
+ const u = e === "user", c = n ? qe(r) : r;
862
+ return /* @__PURE__ */ b("div", { className: `${u ? "ml-auto" : "mr-auto"} max-w-[85%]`, children: [
863
+ /* @__PURE__ */ a(
610
864
  "div",
611
865
  {
612
- className: `rounded-claudius-bubble px-4 py-2.5 text-sm leading-relaxed font-body ${c ? "bg-claudius-user-bubble text-claudius-user-bubble-text rounded-br-claudius-tail" : "bg-claudius-assistant-bubble text-claudius-assistant-bubble-text rounded-bl-claudius-tail"}`,
613
- children: Ye(r)
866
+ className: `rounded-claudius-bubble px-4 py-2.5 text-sm leading-relaxed font-body ${u ? "bg-claudius-user-bubble text-claudius-user-bubble-text rounded-br-claudius-tail" : "bg-claudius-assistant-bubble text-claudius-assistant-bubble-text rounded-bl-claudius-tail"}`,
867
+ children: rt(c)
614
868
  }
615
869
  ),
616
- !c && s && s.length > 0 && n && /* @__PURE__ */ i("div", { className: "mt-1", children: /* @__PURE__ */ i(
617
- Ue,
870
+ !u && s && s.length > 0 && o && /* @__PURE__ */ a("div", { className: "mt-1", children: /* @__PURE__ */ a(
871
+ Ve,
618
872
  {
619
873
  count: s.length,
620
- isActive: o ?? !1,
621
- onClick: n
874
+ isActive: i ?? !1,
875
+ onClick: o
622
876
  }
623
877
  ) })
624
878
  ] });
625
- }), X = 2e3, Ke = 1800;
626
- function qe({
627
- onSend: e,
628
- isLoading: t,
629
- placeholder: r,
630
- translations: s
879
+ }), ie = 2e3, st = 1800;
880
+ function ot({
881
+ onSend: t,
882
+ isLoading: e,
883
+ isStreaming: r = !1,
884
+ onStop: n,
885
+ placeholder: s,
886
+ translations: o
631
887
  }) {
632
- const [n, o] = k(""), c = C(null), a = n.length, u = a >= Ke, l = a >= X, d = r ?? (s == null ? void 0 : s.placeholder) ?? "Type your message...", R = (s == null ? void 0 : s.sendMessage) ?? "Send message", p = (s == null ? void 0 : s.typeYourMessage) ?? "Type your message";
633
- return H(() => {
634
- var b;
635
- t || (b = c.current) == null || b.focus();
636
- }, [t]), /* @__PURE__ */ h(
888
+ const [i, u] = A(""), c = O(null), l = i.length, f = l >= st, y = l >= ie, I = s ?? (o == null ? void 0 : o.placeholder) ?? "Type your message...", E = (o == null ? void 0 : o.sendMessage) ?? "Send message", T = (o == null ? void 0 : o.stopGenerating) ?? "Stop generating", x = (o == null ? void 0 : o.typeYourMessage) ?? "Type your message", w = r && !!n;
889
+ return U(() => {
890
+ var g;
891
+ e || (g = c.current) == null || g.focus();
892
+ }, [e]), /* @__PURE__ */ b(
637
893
  "form",
638
894
  {
639
- onSubmit: (b) => {
640
- b.preventDefault();
641
- const x = n.trim();
642
- !x || l || (e(x), o(""));
895
+ onSubmit: (g) => {
896
+ g.preventDefault();
897
+ const S = i.trim();
898
+ !S || y || (t(S), u(""));
643
899
  },
644
900
  className: "border-t border-claudius-border bg-claudius-surface p-3",
645
901
  children: [
646
- /* @__PURE__ */ h("div", { className: "flex gap-2", children: [
647
- /* @__PURE__ */ i(
902
+ /* @__PURE__ */ b("div", { className: "flex gap-2", children: [
903
+ /* @__PURE__ */ a(
648
904
  "input",
649
905
  {
650
906
  ref: c,
651
907
  type: "text",
652
- value: n,
653
- onChange: (b) => {
654
- const x = b.target.value;
655
- x.length <= X && o(x);
908
+ value: i,
909
+ onChange: (g) => {
910
+ const S = g.target.value;
911
+ S.length <= ie && u(S);
656
912
  },
657
- placeholder: d,
658
- disabled: t,
659
- "aria-label": p,
660
- "aria-describedby": u ? "char-count" : void 0,
913
+ placeholder: I,
914
+ disabled: e,
915
+ "aria-label": x,
916
+ "aria-describedby": f ? "char-count" : void 0,
661
917
  className: "flex-1 rounded-claudius-sm border border-claudius-border bg-claudius-field px-3 py-2 text-sm font-body text-claudius-text placeholder:text-claudius-text-muted focus:border-claudius-accent focus:outline-none focus:ring-1 focus:ring-claudius-accent disabled:opacity-50"
662
918
  }
663
919
  ),
664
- /* @__PURE__ */ i(
920
+ w ? /* @__PURE__ */ a(
921
+ "button",
922
+ {
923
+ type: "button",
924
+ onClick: n,
925
+ "aria-label": T,
926
+ className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm bg-claudius-accent text-claudius-accent-text transition-colors hover:opacity-90",
927
+ children: /* @__PURE__ */ a(
928
+ "svg",
929
+ {
930
+ width: "16",
931
+ height: "16",
932
+ viewBox: "0 0 24 24",
933
+ fill: "currentColor",
934
+ "aria-hidden": "true",
935
+ children: /* @__PURE__ */ a("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1.5" })
936
+ }
937
+ )
938
+ }
939
+ ) : /* @__PURE__ */ a(
665
940
  "button",
666
941
  {
667
942
  type: "submit",
668
- disabled: t || l,
669
- "aria-label": R,
943
+ disabled: e || y,
944
+ "aria-label": E,
670
945
  className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm bg-claudius-accent text-claudius-accent-text transition-colors hover:opacity-90 disabled:opacity-50",
671
- children: /* @__PURE__ */ h(
946
+ children: /* @__PURE__ */ b(
672
947
  "svg",
673
948
  {
674
949
  width: "16",
@@ -681,24 +956,24 @@ function qe({
681
956
  strokeLinejoin: "round",
682
957
  "aria-hidden": "true",
683
958
  children: [
684
- /* @__PURE__ */ i("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
685
- /* @__PURE__ */ i("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
959
+ /* @__PURE__ */ a("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
960
+ /* @__PURE__ */ a("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
686
961
  ]
687
962
  }
688
963
  )
689
964
  }
690
965
  )
691
966
  ] }),
692
- u && /* @__PURE__ */ h(
967
+ f && /* @__PURE__ */ b(
693
968
  "div",
694
969
  {
695
970
  id: "char-count",
696
- className: `mt-1 text-xs text-right ${l ? "text-claudius-error" : "text-claudius-text-muted"}`,
971
+ className: `mt-1 text-xs text-right ${y ? "text-claudius-error" : "text-claudius-text-muted"}`,
697
972
  "aria-live": "polite",
698
973
  children: [
699
- a,
974
+ l,
700
975
  "/",
701
- X
976
+ ie
702
977
  ]
703
978
  }
704
979
  )
@@ -706,40 +981,40 @@ function qe({
706
981
  }
707
982
  );
708
983
  }
709
- const Xe = ["blog", "page", "external"], Ze = {
984
+ const it = ["blog", "page", "external"], at = {
710
985
  blog: "Blog",
711
986
  page: "Page",
712
987
  external: "External"
713
988
  };
714
- function Je(e) {
989
+ function ct(t) {
715
990
  try {
716
- return new URL(e).hostname;
991
+ return new URL(t).hostname;
717
992
  } catch {
718
- return e;
993
+ return t;
719
994
  }
720
995
  }
721
- const Qe = J(function({
722
- sources: t,
996
+ const ut = ue(function({
997
+ sources: e,
723
998
  onClose: r
724
999
  }) {
725
- const s = Xe.map((o) => ({
1000
+ const n = it.map((o) => ({
726
1001
  type: o,
727
- label: Ze[o],
728
- items: t.filter((c) => c.type === o)
729
- })).filter((o) => o.items.length > 0), n = t.length === 1 ? "1 source found" : `${t.length} sources found`;
730
- return /* @__PURE__ */ h("div", { className: "absolute inset-y-0 left-0 z-10 flex w-[280px] flex-col border-r-2 border-claudius-border bg-claudius-surface rounded-r-claudius-lg transition-transform duration-200 ease-out", children: [
731
- /* @__PURE__ */ h("div", { className: "flex items-center justify-between border-b border-claudius-border px-4 py-3", children: [
732
- /* @__PURE__ */ h("div", { children: [
733
- /* @__PURE__ */ i("h3", { className: "text-sm font-heading font-semibold text-claudius-text", children: "Sources" }),
734
- /* @__PURE__ */ i("p", { className: "text-xs text-claudius-text-muted", children: n })
1002
+ label: at[o],
1003
+ items: e.filter((i) => i.type === o)
1004
+ })).filter((o) => o.items.length > 0), s = e.length === 1 ? "1 source found" : `${e.length} sources found`;
1005
+ return /* @__PURE__ */ b("div", { className: "absolute inset-y-0 left-0 z-10 flex w-[280px] flex-col border-r-2 border-claudius-border bg-claudius-surface rounded-r-claudius-lg transition-transform duration-200 ease-out", children: [
1006
+ /* @__PURE__ */ b("div", { className: "flex items-center justify-between border-b border-claudius-border px-4 py-3", children: [
1007
+ /* @__PURE__ */ b("div", { children: [
1008
+ /* @__PURE__ */ a("h3", { className: "text-sm font-heading font-semibold text-claudius-text", children: "Sources" }),
1009
+ /* @__PURE__ */ a("p", { className: "text-xs text-claudius-text-muted", children: s })
735
1010
  ] }),
736
- /* @__PURE__ */ i(
1011
+ /* @__PURE__ */ a(
737
1012
  "button",
738
1013
  {
739
1014
  onClick: r,
740
1015
  "aria-label": "Close sources",
741
1016
  className: "flex h-7 w-7 items-center justify-center rounded-claudius-full text-claudius-text-muted transition-colors hover:bg-claudius-surface-muted hover:text-claudius-text",
742
- children: /* @__PURE__ */ h(
1017
+ children: /* @__PURE__ */ b(
743
1018
  "svg",
744
1019
  {
745
1020
  width: "14",
@@ -752,70 +1027,70 @@ const Qe = J(function({
752
1027
  strokeLinejoin: "round",
753
1028
  "aria-hidden": "true",
754
1029
  children: [
755
- /* @__PURE__ */ i("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
756
- /* @__PURE__ */ i("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1030
+ /* @__PURE__ */ a("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1031
+ /* @__PURE__ */ a("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
757
1032
  ]
758
1033
  }
759
1034
  )
760
1035
  }
761
1036
  )
762
1037
  ] }),
763
- /* @__PURE__ */ i("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-4", children: s.map((o) => /* @__PURE__ */ h("div", { children: [
764
- /* @__PURE__ */ i("h4", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-claudius-text-muted", children: o.label }),
765
- /* @__PURE__ */ i("div", { className: "space-y-2", children: o.items.map((c) => {
766
- const a = le(c.url);
767
- return a ? /* @__PURE__ */ h(
1038
+ /* @__PURE__ */ a("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-4", children: n.map((o) => /* @__PURE__ */ b("div", { children: [
1039
+ /* @__PURE__ */ a("h4", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-claudius-text-muted", children: o.label }),
1040
+ /* @__PURE__ */ a("div", { className: "space-y-2", children: o.items.map((i) => {
1041
+ const u = xe(i.url);
1042
+ return u ? /* @__PURE__ */ b(
768
1043
  "a",
769
1044
  {
770
- href: a,
1045
+ href: u,
771
1046
  target: "_blank",
772
1047
  rel: "noopener noreferrer",
773
1048
  className: "block rounded-claudius-md border-2 border-claudius-border bg-claudius-surface-muted p-3 transition-colors hover:bg-claudius-border",
774
1049
  children: [
775
- /* @__PURE__ */ i("p", { className: "truncate text-sm font-medium text-claudius-text", children: c.title }),
776
- /* @__PURE__ */ i("p", { className: "mt-0.5 text-xs text-claudius-text-muted", children: Je(a) })
1050
+ /* @__PURE__ */ a("p", { className: "truncate text-sm font-medium text-claudius-text", children: i.title }),
1051
+ /* @__PURE__ */ a("p", { className: "mt-0.5 text-xs text-claudius-text-muted", children: ct(u) })
777
1052
  ]
778
1053
  },
779
- a
1054
+ u
780
1055
  ) : null;
781
1056
  }) })
782
1057
  ] }, o.type)) })
783
1058
  ] });
784
1059
  });
785
- function et({
786
- title: e,
787
- subtitle: t,
1060
+ function lt({
1061
+ title: t,
1062
+ subtitle: e,
788
1063
  titleId: r,
789
- closeLabel: s,
790
- onClose: n
1064
+ closeLabel: n,
1065
+ onClose: s
791
1066
  }) {
792
- return /* @__PURE__ */ h("div", { className: "flex items-center gap-3 bg-claudius-accent px-5 py-4", children: [
793
- /* @__PURE__ */ i(
1067
+ return /* @__PURE__ */ b("div", { className: "flex items-center gap-3 bg-claudius-accent px-5 py-4", children: [
1068
+ /* @__PURE__ */ a(
794
1069
  "div",
795
1070
  {
796
1071
  "aria-hidden": "true",
797
1072
  className: "flex h-8 w-8 items-center justify-center rounded-claudius-full bg-claudius-accent-soft text-sm font-bold text-claudius-accent-text",
798
- children: e.charAt(0).toUpperCase()
1073
+ children: t.charAt(0).toUpperCase()
799
1074
  }
800
1075
  ),
801
- /* @__PURE__ */ h("div", { className: "flex-1", children: [
802
- /* @__PURE__ */ i(
1076
+ /* @__PURE__ */ b("div", { className: "flex-1", children: [
1077
+ /* @__PURE__ */ a(
803
1078
  "h2",
804
1079
  {
805
1080
  id: r,
806
1081
  className: "text-sm font-heading font-semibold text-claudius-accent-text",
807
- children: e
1082
+ children: t
808
1083
  }
809
1084
  ),
810
- /* @__PURE__ */ i("p", { className: "text-xs text-claudius-accent-text", children: t })
1085
+ /* @__PURE__ */ a("p", { className: "text-xs text-claudius-accent-text", children: e })
811
1086
  ] }),
812
- /* @__PURE__ */ i(
1087
+ /* @__PURE__ */ a(
813
1088
  "button",
814
1089
  {
815
- onClick: n,
816
- "aria-label": s,
1090
+ onClick: s,
1091
+ "aria-label": n,
817
1092
  className: "flex h-10 w-10 items-center justify-center rounded-claudius-full text-claudius-accent-text-muted transition-colors hover:bg-claudius-accent-soft hover:text-claudius-accent-text",
818
- children: /* @__PURE__ */ h(
1093
+ children: /* @__PURE__ */ b(
819
1094
  "svg",
820
1095
  {
821
1096
  width: "18",
@@ -828,8 +1103,8 @@ function et({
828
1103
  strokeLinejoin: "round",
829
1104
  "aria-hidden": "true",
830
1105
  children: [
831
- /* @__PURE__ */ i("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
832
- /* @__PURE__ */ i("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1106
+ /* @__PURE__ */ a("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1107
+ /* @__PURE__ */ a("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
833
1108
  ]
834
1109
  }
835
1110
  )
@@ -837,270 +1112,278 @@ function et({
837
1112
  )
838
1113
  ] });
839
1114
  }
840
- function tt({
841
- message: e,
842
- retryLabel: t,
1115
+ function dt({
1116
+ message: t,
1117
+ retryLabel: e,
843
1118
  onRetry: r
844
1119
  }) {
845
- return /* @__PURE__ */ h(
1120
+ return /* @__PURE__ */ b(
846
1121
  "div",
847
1122
  {
848
1123
  role: "alert",
849
1124
  className: "mx-auto flex max-w-[90%] flex-col items-center gap-2 rounded-claudius-sm bg-claudius-error-surface px-3 py-2 text-center text-xs text-claudius-error",
850
1125
  children: [
851
- /* @__PURE__ */ i("span", { children: e }),
852
- r && /* @__PURE__ */ i(
1126
+ /* @__PURE__ */ a("span", { children: t }),
1127
+ r && /* @__PURE__ */ a(
853
1128
  "button",
854
1129
  {
855
1130
  type: "button",
856
1131
  onClick: r,
857
1132
  className: "rounded-claudius-md bg-claudius-error px-3 py-1 text-xs font-semibold text-claudius-error-text transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-claudius-error focus-visible:ring-offset-1",
858
- children: t
1133
+ children: e
859
1134
  }
860
1135
  )
861
1136
  ]
862
1137
  }
863
1138
  );
864
1139
  }
865
- function rt({ label: e }) {
866
- return /* @__PURE__ */ i(
1140
+ function ft({ label: t }) {
1141
+ return /* @__PURE__ */ a(
867
1142
  "div",
868
1143
  {
869
1144
  role: "status",
870
1145
  "aria-live": "polite",
871
- "aria-label": e,
1146
+ "aria-label": t,
872
1147
  className: "mr-auto flex max-w-[85%]",
873
- children: /* @__PURE__ */ h("div", { className: "flex gap-1 rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-3", children: [
874
- /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:0ms]" }),
875
- /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:150ms]" }),
876
- /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:300ms]" })
1148
+ children: /* @__PURE__ */ b("div", { className: "flex gap-1 rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-3", children: [
1149
+ /* @__PURE__ */ a("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:0ms]" }),
1150
+ /* @__PURE__ */ a("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:150ms]" }),
1151
+ /* @__PURE__ */ a("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:300ms]" })
877
1152
  ] })
878
1153
  }
879
1154
  );
880
1155
  }
881
- function nt(e, t, r) {
882
- const [s, n] = k(0), o = C(0), c = C(0), a = C(0), u = C(!1);
883
- return H(() => {
884
- const l = e.current;
1156
+ function ht(t, e, r) {
1157
+ const [n, s] = A(0), o = O(0), i = O(0), u = O(0), c = O(!1);
1158
+ return U(() => {
1159
+ const l = t.current;
885
1160
  if (!r || !l) return;
886
- const d = (w) => {
1161
+ const f = (E) => {
887
1162
  if (l.scrollTop > 0) {
888
- u.current = !1;
1163
+ c.current = !1;
889
1164
  return;
890
1165
  }
891
- u.current = !0, c.current = w.touches[0].clientY, a.current = Date.now();
892
- }, R = (w) => {
893
- if (!u.current) return;
894
- let y = w.touches[0].clientY - c.current;
895
- y < 0 && (y = y * 0.3), o.current = y, n(y);
896
- }, p = () => {
897
- if (!u.current) return;
898
- u.current = !1;
899
- const w = o.current, y = (Date.now() - a.current) / 1e3, b = l.getBoundingClientRect().height, x = y > 0.05 && w > 0 && w / y > 500, v = w > b * 0.3;
900
- x || v ? t() : (o.current = 0, n(0));
1166
+ c.current = !0, i.current = E.touches[0].clientY, u.current = Date.now();
1167
+ }, y = (E) => {
1168
+ if (!c.current) return;
1169
+ let T = E.touches[0].clientY - i.current;
1170
+ T < 0 && (T = T * 0.3), o.current = T, s(T);
1171
+ }, I = () => {
1172
+ if (!c.current) return;
1173
+ c.current = !1;
1174
+ const E = o.current, T = (Date.now() - u.current) / 1e3, x = l.getBoundingClientRect().height, w = T > 0.05 && E > 0 && E / T > 500, C = E > x * 0.3;
1175
+ w || C ? e() : (o.current = 0, s(0));
901
1176
  };
902
- return l.addEventListener("touchstart", d, { passive: !0 }), l.addEventListener("touchmove", R, { passive: !0 }), l.addEventListener("touchend", p), () => {
903
- l.removeEventListener("touchstart", d), l.removeEventListener("touchmove", R), l.removeEventListener("touchend", p);
1177
+ return l.addEventListener("touchstart", f, { passive: !0 }), l.addEventListener("touchmove", y, { passive: !0 }), l.addEventListener("touchend", I), () => {
1178
+ l.removeEventListener("touchstart", f), l.removeEventListener("touchmove", y), l.removeEventListener("touchend", I);
904
1179
  };
905
- }, [e, t, r]), { offsetY: s };
1180
+ }, [t, e, r]), { offsetY: n };
906
1181
  }
907
- const st = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
908
- function ot(e, t) {
909
- H(() => {
910
- const r = e.current;
1182
+ const mt = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
1183
+ function gt(t, e) {
1184
+ U(() => {
1185
+ const r = t.current;
911
1186
  if (!r) return;
912
- const s = (n) => {
913
- if (n.key !== "Tab") return;
1187
+ const n = (s) => {
1188
+ if (s.key !== "Tab") return;
914
1189
  const o = Array.from(
915
- r.querySelectorAll(st)
1190
+ r.querySelectorAll(mt)
916
1191
  ).filter((l) => !l.hasAttribute("aria-hidden"));
917
1192
  if (o.length === 0) return;
918
- const c = o[0], a = o[o.length - 1], u = document.activeElement;
919
- n.shiftKey && u === c ? (n.preventDefault(), a.focus()) : !n.shiftKey && u === a && (n.preventDefault(), c.focus());
1193
+ const i = o[0], u = o[o.length - 1], c = document.activeElement;
1194
+ s.shiftKey && c === i ? (s.preventDefault(), u.focus()) : !s.shiftKey && c === u && (s.preventDefault(), i.focus());
920
1195
  };
921
- return r.addEventListener("keydown", s), () => r.removeEventListener("keydown", s);
922
- }, [e, t]);
1196
+ return r.addEventListener("keydown", n), () => r.removeEventListener("keydown", n);
1197
+ }, [t, e]);
923
1198
  }
924
- const it = /\*\*([^*]+)\*\*/g, ct = /\*([^*]+)\*/g, at = /https?:\/\/[^\s)]+/g;
925
- function ut(e) {
926
- return e.replace(it, "$1").replace(ct, "$1").replace(at, (t) => {
1199
+ const pt = /\*\*([^*]+)\*\*/g, bt = /\*([^*]+)\*/g, yt = /https?:\/\/[^\s)]+/g;
1200
+ function xt(t) {
1201
+ return t.replace(pt, "$1").replace(bt, "$1").replace(yt, (e) => {
927
1202
  try {
928
- return new URL(t).hostname;
1203
+ return new URL(e).hostname;
929
1204
  } catch {
930
- return t;
1205
+ return e;
931
1206
  }
932
1207
  });
933
1208
  }
934
- const lt = {
1209
+ const wt = {
935
1210
  "bottom-right": "bottom-24 right-3 sm:right-6",
936
1211
  "bottom-left": "bottom-24 left-3 sm:left-6",
937
1212
  "top-right": "top-24 right-3 sm:right-6",
938
1213
  "top-left": "top-24 left-3 sm:left-6"
939
1214
  };
940
- function dt({
941
- messages: e,
942
- isLoading: t,
943
- error: r,
944
- canRetry: s = !1,
945
- onSend: n,
946
- onRetry: o,
947
- onClose: c,
948
- title: a = "Chat",
949
- subtitle: u = "Ask me anything",
950
- welcomeMessage: l = "Hi! How can I help you today?",
951
- placeholder: d,
952
- position: R = "bottom-right",
953
- translations: p,
1215
+ function vt({
1216
+ messages: t,
1217
+ isLoading: e,
1218
+ isStreaming: r = !1,
1219
+ streamingMessageId: n = null,
1220
+ error: s,
1221
+ canRetry: o = !1,
1222
+ onSend: i,
1223
+ onStop: u,
1224
+ onRetry: c,
1225
+ onClose: l,
1226
+ title: f = "Chat",
1227
+ subtitle: y = "Ask me anything",
1228
+ welcomeMessage: I = "Hi! How can I help you today?",
1229
+ placeholder: E,
1230
+ position: T = "bottom-right",
1231
+ translations: x,
954
1232
  isMobile: w = !1
955
1233
  }) {
956
- const y = Ce(), b = C(null), x = C(null), [v, N] = k(null);
957
- ot(b, !0);
958
- const { offsetY: E } = nt(
959
- x,
960
- c,
1234
+ const C = Le(), v = O(null), g = O(null), [S, j] = A(null);
1235
+ gt(v, !0);
1236
+ const { offsetY: W } = ht(
1237
+ g,
1238
+ l,
961
1239
  w
962
- ), I = E !== 0, A = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : !1;
963
- H(() => {
964
- const m = x.current;
965
- m && (m.scrollTop = m.scrollHeight);
966
- }, [e, t]), H(() => {
967
- const m = (P) => {
968
- P.key === "Escape" && !P.isComposing && c();
1240
+ ), $ = W !== 0, p = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : !1;
1241
+ U(() => {
1242
+ const h = g.current;
1243
+ h && (h.scrollTop = h.scrollHeight);
1244
+ }, [t, e]), U(() => {
1245
+ const h = (F) => {
1246
+ F.key === "Escape" && !F.isComposing && l();
969
1247
  };
970
- return document.addEventListener("keydown", m), () => document.removeEventListener("keydown", m);
971
- }, [c]);
972
- const D = (p == null ? void 0 : p.closeChat) ?? "Close chat", S = (p == null ? void 0 : p.chatMessages) ?? "Chat messages", j = [...e].reverse().find((m) => m.role === "assistant");
973
- return /* @__PURE__ */ h(
1248
+ return document.addEventListener("keydown", h), () => document.removeEventListener("keydown", h);
1249
+ }, [l]);
1250
+ const Y = (x == null ? void 0 : x.closeChat) ?? "Close chat", B = (x == null ? void 0 : x.chatMessages) ?? "Chat messages", _ = [...t].reverse().find((h) => h.role === "assistant");
1251
+ return /* @__PURE__ */ b(
974
1252
  "div",
975
1253
  {
976
- ref: b,
1254
+ ref: v,
977
1255
  role: "dialog",
978
1256
  "aria-modal": w ? "true" : void 0,
979
- "aria-labelledby": y,
980
- className: w ? "claudius-bottom-sheet fixed inset-x-0 bottom-0 z-50 flex h-[90vh] w-full flex-col overflow-hidden rounded-t-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body" : `fixed ${lt[R]} z-50 flex h-[min(500px,calc(100vh-7rem))] w-[calc(100vw-1.5rem)] max-w-[380px] sm:max-w-[400px] md:max-w-[440px] flex-col overflow-hidden rounded-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body`,
981
- style: w && !A ? { transform: `translateY(${Math.max(0, E)}px)` } : void 0,
982
- "data-dragging": I || void 0,
1257
+ "aria-labelledby": C,
1258
+ className: w ? "claudius-bottom-sheet fixed inset-x-0 bottom-0 z-50 flex h-[90vh] w-full flex-col overflow-hidden rounded-t-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body" : `fixed ${wt[T]} z-50 flex h-[min(500px,calc(100vh-7rem))] w-[calc(100vw-1.5rem)] max-w-[380px] sm:max-w-[400px] md:max-w-[440px] flex-col overflow-hidden rounded-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body`,
1259
+ style: w && !p ? { transform: `translateY(${Math.max(0, W)}px)` } : void 0,
1260
+ "data-dragging": $ || void 0,
983
1261
  children: [
984
- w && /* @__PURE__ */ i("div", { className: "flex justify-center py-2", "aria-hidden": "true", children: /* @__PURE__ */ i("div", { className: "h-1 w-8 rounded-claudius-full bg-claudius-border" }) }),
985
- /* @__PURE__ */ i(
986
- et,
1262
+ w && /* @__PURE__ */ a("div", { className: "flex justify-center py-2", "aria-hidden": "true", children: /* @__PURE__ */ a("div", { className: "h-1 w-8 rounded-claudius-full bg-claudius-border" }) }),
1263
+ /* @__PURE__ */ a(
1264
+ lt,
987
1265
  {
988
- title: a,
989
- subtitle: u,
990
- titleId: y,
991
- closeLabel: D,
992
- onClose: c
1266
+ title: f,
1267
+ subtitle: y,
1268
+ titleId: C,
1269
+ closeLabel: Y,
1270
+ onClose: l
993
1271
  }
994
1272
  ),
995
- /* @__PURE__ */ h("div", { className: "relative flex-1 overflow-hidden", children: [
996
- v && /* @__PURE__ */ i(
997
- Qe,
1273
+ /* @__PURE__ */ b("div", { className: "relative flex-1 overflow-hidden", children: [
1274
+ S && /* @__PURE__ */ a(
1275
+ ut,
998
1276
  {
999
- sources: v.sources,
1000
- onClose: () => N(null)
1277
+ sources: S.sources,
1278
+ onClose: () => j(null)
1001
1279
  }
1002
1280
  ),
1003
- /* @__PURE__ */ h(
1281
+ /* @__PURE__ */ b(
1004
1282
  "div",
1005
1283
  {
1006
- ref: x,
1284
+ ref: g,
1007
1285
  role: "log",
1008
- "aria-label": S,
1286
+ "aria-label": B,
1009
1287
  className: "h-full space-y-3 overflow-y-auto px-4 py-4",
1010
1288
  children: [
1011
- e.length === 0 && !r && /* @__PURE__ */ i("div", { className: "mr-auto flex max-w-[85%]", children: /* @__PURE__ */ i("div", { className: "rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-2.5 text-sm leading-relaxed text-claudius-assistant-bubble-text", children: l }) }),
1012
- e.map((m) => /* @__PURE__ */ i(
1013
- Ve,
1289
+ t.length === 0 && !s && /* @__PURE__ */ a("div", { className: "mr-auto flex max-w-[85%]", children: /* @__PURE__ */ a("div", { className: "rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-2.5 text-sm leading-relaxed text-claudius-assistant-bubble-text", children: I }) }),
1290
+ t.map((h) => /* @__PURE__ */ a(
1291
+ nt,
1014
1292
  {
1015
- role: m.role,
1016
- content: m.content,
1017
- sources: m.sources,
1018
- isSourceActive: (v == null ? void 0 : v.messageId) === m.id,
1293
+ role: h.role,
1294
+ content: h.content,
1295
+ isStreaming: h.id === n,
1296
+ sources: h.sources,
1297
+ isSourceActive: (S == null ? void 0 : S.messageId) === h.id,
1019
1298
  onSourceClick: () => {
1020
- (v == null ? void 0 : v.messageId) === m.id ? N(null) : m.sources && m.sources.length > 0 && N({ messageId: m.id, sources: m.sources });
1299
+ (S == null ? void 0 : S.messageId) === h.id ? j(null) : h.sources && h.sources.length > 0 && j({ messageId: h.id, sources: h.sources });
1021
1300
  }
1022
1301
  },
1023
- m.id
1302
+ h.id
1024
1303
  )),
1025
- t && /* @__PURE__ */ i(
1026
- rt,
1304
+ e && /* Once streamed tokens are rendering in a bubble, the typing
1305
+ indicator is redundant — show it only until the first token. */
1306
+ !(n !== null && t.some((h) => h.id === n)) && /* @__PURE__ */ a(
1307
+ ft,
1027
1308
  {
1028
- label: (p == null ? void 0 : p.typingIndicator) ?? "Assistant is typing"
1309
+ label: (x == null ? void 0 : x.typingIndicator) ?? "Assistant is typing"
1029
1310
  }
1030
1311
  ),
1031
- r && /* @__PURE__ */ i(
1032
- tt,
1312
+ s && /* @__PURE__ */ a(
1313
+ dt,
1033
1314
  {
1034
- message: r,
1035
- retryLabel: (p == null ? void 0 : p.errorRetry) ?? "Retry",
1036
- onRetry: s && o && !t ? o : void 0
1315
+ message: s,
1316
+ retryLabel: (x == null ? void 0 : x.errorRetry) ?? "Retry",
1317
+ onRetry: o && c && !e ? c : void 0
1037
1318
  }
1038
1319
  )
1039
1320
  ]
1040
1321
  }
1041
1322
  )
1042
1323
  ] }),
1043
- /* @__PURE__ */ i(
1324
+ /* @__PURE__ */ a(
1044
1325
  "div",
1045
1326
  {
1046
1327
  "data-claudius-live": "assistant",
1047
1328
  "aria-live": "polite",
1048
1329
  "aria-atomic": "true",
1049
1330
  className: "sr-only",
1050
- children: j ? ut(j.content) : ""
1331
+ children: _ && _.id !== n ? xt(_.content) : ""
1051
1332
  }
1052
1333
  ),
1053
- /* @__PURE__ */ i(
1054
- qe,
1334
+ /* @__PURE__ */ a(
1335
+ ot,
1055
1336
  {
1056
- onSend: n,
1057
- isLoading: t,
1058
- placeholder: d,
1059
- translations: p
1337
+ onSend: i,
1338
+ isLoading: e,
1339
+ isStreaming: r,
1340
+ onStop: u,
1341
+ placeholder: E,
1342
+ translations: x
1060
1343
  }
1061
1344
  )
1062
1345
  ]
1063
1346
  }
1064
1347
  );
1065
1348
  }
1066
- function ft({
1067
- message: e,
1068
- position: t,
1349
+ function Rt({
1350
+ message: t,
1351
+ position: e,
1069
1352
  onOpen: r,
1070
- onDismiss: s,
1071
- dismissLabel: n
1353
+ onDismiss: n,
1354
+ dismissLabel: s
1072
1355
  }) {
1073
- const o = t.startsWith("bottom"), c = t.endsWith("right"), a = [
1356
+ const o = e.startsWith("bottom"), i = e.endsWith("right"), u = [
1074
1357
  "claudius-greeting-bubble",
1075
1358
  "fixed z-40 max-w-xs",
1076
1359
  o ? "bottom-20" : "top-20",
1077
- c ? "right-4" : "left-4"
1360
+ i ? "right-4" : "left-4"
1078
1361
  ].join(" ");
1079
- return /* @__PURE__ */ h("div", { className: a, role: "status", "aria-live": "polite", children: [
1080
- /* @__PURE__ */ i(
1362
+ return /* @__PURE__ */ b("div", { className: u, role: "status", "aria-live": "polite", children: [
1363
+ /* @__PURE__ */ a(
1081
1364
  "button",
1082
1365
  {
1083
1366
  type: "button",
1084
1367
  onClick: r,
1085
1368
  className: "block w-full rounded-claudius-lg bg-claudius-surface p-4 pr-8 text-left text-sm font-body text-claudius-text shadow-claudius-floating ring-1 ring-claudius-border transition hover:shadow-claudius-floating-hover focus:outline-none focus:ring-2 focus:ring-claudius-accent",
1086
- children: e
1369
+ children: t
1087
1370
  }
1088
1371
  ),
1089
- /* @__PURE__ */ i(
1372
+ /* @__PURE__ */ a(
1090
1373
  "button",
1091
1374
  {
1092
1375
  type: "button",
1093
- onClick: (u) => {
1094
- u.stopPropagation(), s();
1376
+ onClick: (c) => {
1377
+ c.stopPropagation(), n();
1095
1378
  },
1096
- "aria-label": n,
1379
+ "aria-label": s,
1097
1380
  className: "absolute right-1 top-1 flex h-6 w-6 items-center justify-center rounded-claudius-full text-claudius-text-muted hover:bg-claudius-surface-muted focus:outline-none focus:ring-2 focus:ring-claudius-accent",
1098
- children: /* @__PURE__ */ i("span", { "aria-hidden": "true", children: "×" })
1381
+ children: /* @__PURE__ */ a("span", { "aria-hidden": "true", children: "×" })
1099
1382
  }
1100
1383
  )
1101
1384
  ] });
1102
1385
  }
1103
- const de = {
1386
+ const we = {
1104
1387
  // ChatWindow
1105
1388
  title: "Chat",
1106
1389
  subtitle: "Ask me anything",
@@ -1111,6 +1394,7 @@ const de = {
1111
1394
  // ChatInput
1112
1395
  placeholder: "Type your message...",
1113
1396
  sendMessage: "Send message",
1397
+ stopGenerating: "Stop generating",
1114
1398
  typeYourMessage: "Type your message",
1115
1399
  // ChatToggleButton
1116
1400
  openChat: "Open chat",
@@ -1123,11 +1407,11 @@ const de = {
1123
1407
  errorRateLimitMinute: "Too many requests. Please wait a minute.",
1124
1408
  errorRateLimitHour: "Hourly limit reached. Please try again later.",
1125
1409
  errorRetry: "Retry"
1126
- }, ht = de;
1127
- function $t(e) {
1128
- return { ...ht, ...e };
1410
+ }, Et = we;
1411
+ function Kt(t) {
1412
+ return { ...Et, ...t };
1129
1413
  }
1130
- const mt = {
1414
+ const Tt = {
1131
1415
  // ChatWindow
1132
1416
  title: "Chat",
1133
1417
  subtitle: "Pregúntame lo que quieras",
@@ -1138,6 +1422,7 @@ const mt = {
1138
1422
  // ChatInput
1139
1423
  placeholder: "Escribe tu mensaje...",
1140
1424
  sendMessage: "Enviar mensaje",
1425
+ stopGenerating: "Detener la respuesta",
1141
1426
  typeYourMessage: "Escribe tu mensaje",
1142
1427
  // ChatToggleButton
1143
1428
  openChat: "Abrir chat",
@@ -1150,7 +1435,7 @@ const mt = {
1150
1435
  errorRateLimitMinute: "Demasiadas solicitudes. Espera un minuto.",
1151
1436
  errorRateLimitHour: "Has alcanzado el límite por hora. Inténtalo más tarde.",
1152
1437
  errorRetry: "Reintentar"
1153
- }, gt = {
1438
+ }, Mt = {
1154
1439
  // ChatWindow
1155
1440
  title: "Chat",
1156
1441
  subtitle: "Posez-moi vos questions",
@@ -1161,6 +1446,7 @@ const mt = {
1161
1446
  // ChatInput
1162
1447
  placeholder: "Saisissez votre message...",
1163
1448
  sendMessage: "Envoyer le message",
1449
+ stopGenerating: "Arrêter la génération",
1164
1450
  typeYourMessage: "Saisissez votre message",
1165
1451
  // ChatToggleButton
1166
1452
  openChat: "Ouvrir le chat",
@@ -1173,7 +1459,7 @@ const mt = {
1173
1459
  errorRateLimitMinute: "Trop de requêtes. Veuillez patienter une minute.",
1174
1460
  errorRateLimitHour: "Limite horaire atteinte. Veuillez réessayer plus tard.",
1175
1461
  errorRetry: "Réessayer"
1176
- }, pt = {
1462
+ }, St = {
1177
1463
  // ChatWindow
1178
1464
  title: "Chat",
1179
1465
  subtitle: "Fragen Sie mich alles",
@@ -1184,6 +1470,7 @@ const mt = {
1184
1470
  // ChatInput
1185
1471
  placeholder: "Geben Sie Ihre Nachricht ein...",
1186
1472
  sendMessage: "Nachricht senden",
1473
+ stopGenerating: "Generierung stoppen",
1187
1474
  typeYourMessage: "Geben Sie Ihre Nachricht ein",
1188
1475
  // ChatToggleButton
1189
1476
  openChat: "Chat öffnen",
@@ -1196,28 +1483,28 @@ const mt = {
1196
1483
  errorRateLimitMinute: "Zu viele Anfragen. Bitte warten Sie eine Minute.",
1197
1484
  errorRateLimitHour: "Stündliches Limit erreicht. Bitte versuchen Sie es später erneut.",
1198
1485
  errorRetry: "Erneut versuchen"
1199
- }, fe = {
1200
- en: de,
1201
- es: mt,
1202
- fr: gt,
1203
- de: pt
1486
+ }, ve = {
1487
+ en: we,
1488
+ es: Tt,
1489
+ fr: Mt,
1490
+ de: St
1204
1491
  };
1205
- function ie(e) {
1206
- if (!e) return;
1207
- const t = e.toLowerCase().split("-")[0];
1208
- return Object.prototype.hasOwnProperty.call(fe, t) ? t : void 0;
1492
+ function pe(t) {
1493
+ if (!t) return;
1494
+ const e = t.toLowerCase().split("-")[0];
1495
+ return Object.prototype.hasOwnProperty.call(ve, e) ? e : void 0;
1209
1496
  }
1210
- function bt() {
1211
- const e = typeof document < "u" ? ie(document.documentElement.lang) : void 0;
1212
- if (e) return e;
1213
- const t = typeof navigator < "u" ? ie(navigator.language) : void 0;
1214
- return t || "en";
1497
+ function Ct() {
1498
+ const t = typeof document < "u" ? pe(document.documentElement.lang) : void 0;
1499
+ if (t) return t;
1500
+ const e = typeof navigator < "u" ? pe(navigator.language) : void 0;
1501
+ return e || "en";
1215
1502
  }
1216
- function yt(e = {}) {
1217
- const { locale: t, translations: r } = e, s = fe[t ?? bt()];
1218
- return r ? { ...s, ...r } : { ...s };
1503
+ function Nt(t = {}) {
1504
+ const { locale: e, translations: r } = t, n = ve[e ?? Ct()];
1505
+ return r ? { ...n, ...r } : { ...n };
1219
1506
  }
1220
- const ce = [
1507
+ const be = [
1221
1508
  "accent",
1222
1509
  "accentText",
1223
1510
  "accentSoft",
@@ -1237,11 +1524,11 @@ const ce = [
1237
1524
  "errorText",
1238
1525
  "link",
1239
1526
  "scrim"
1240
- ], xt = ["sm", "md", "lg", "full", "tail"], wt = [
1527
+ ], kt = ["sm", "md", "lg", "full", "tail"], Lt = [
1241
1528
  "elevated",
1242
1529
  "floating",
1243
1530
  "floatingHover"
1244
- ], vt = ["heading", "body"], he = {
1531
+ ], At = ["heading", "body"], Re = {
1245
1532
  default: {
1246
1533
  name: "default"
1247
1534
  },
@@ -1326,249 +1613,264 @@ const ce = [
1326
1613
  }
1327
1614
  }
1328
1615
  };
1329
- function Et(e) {
1330
- return Object.prototype.hasOwnProperty.call(he, e);
1616
+ function Ot(t) {
1617
+ return Object.prototype.hasOwnProperty.call(Re, t);
1331
1618
  }
1332
- const Rt = /* @__PURE__ */ new Set(["light", "dark", "auto"]);
1333
- function Tt(e) {
1334
- if (e === void 0)
1619
+ const It = /* @__PURE__ */ new Set(["light", "dark", "auto"]);
1620
+ function Dt(t) {
1621
+ if (t === void 0)
1335
1622
  return { mode: "light" };
1336
- if (typeof e == "string") {
1337
- if (Rt.has(e))
1338
- return { mode: e };
1339
- if (Et(e)) {
1340
- const t = he[e];
1341
- return { mode: t.colorScheme ?? "light", theme: t };
1623
+ if (typeof t == "string") {
1624
+ if (It.has(t))
1625
+ return { mode: t };
1626
+ if (Ot(t)) {
1627
+ const e = Re[t];
1628
+ return { mode: e.colorScheme ?? "light", theme: e };
1342
1629
  }
1343
- return { mode: "light", url: e };
1630
+ return { mode: "light", url: t };
1344
1631
  }
1345
- return { mode: e.colorScheme ?? "light", theme: e };
1632
+ return { mode: t.colorScheme ?? "light", theme: t };
1346
1633
  }
1347
- function Mt(e) {
1348
- return e.replace(/[A-Z]/g, (t) => `-${t.toLowerCase()}`);
1634
+ function _t(t) {
1635
+ return t.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`);
1349
1636
  }
1350
- function Ct(e, t) {
1637
+ function Ht(t, e) {
1351
1638
  console.warn(
1352
- `[Claudius] Ignoring unknown theme token "${t}" in "${e}"`
1639
+ `[Claudius] Ignoring unknown theme token "${e}" in "${t}"`
1353
1640
  );
1354
1641
  }
1355
- function W(e, t, r, s, n, o = "") {
1356
- if (n)
1357
- for (const [c, a] of Object.entries(n)) {
1358
- if (!s.includes(c)) {
1359
- Ct(t, c);
1642
+ function X(t, e, r, n, s, o = "") {
1643
+ if (s)
1644
+ for (const [i, u] of Object.entries(s)) {
1645
+ if (!n.includes(i)) {
1646
+ Ht(e, i);
1360
1647
  continue;
1361
1648
  }
1362
- typeof a == "string" && (e[`${r}${Mt(c)}${o}`] = a);
1649
+ typeof u == "string" && (t[`${r}${_t(i)}${o}`] = u);
1363
1650
  }
1364
1651
  }
1365
- function Nt(e) {
1366
- const t = {};
1367
- W(t, "colors", "--cl-color-", ce, e.colors);
1368
- for (const [r, s] of Object.entries({ ...t }))
1369
- t[`${r}-dark`] = s;
1370
- return W(
1371
- t,
1652
+ function jt(t) {
1653
+ const e = {};
1654
+ X(e, "colors", "--cl-color-", be, t.colors);
1655
+ for (const [r, n] of Object.entries({ ...e }))
1656
+ e[`${r}-dark`] = n;
1657
+ return X(
1658
+ e,
1372
1659
  "colorsDark",
1373
1660
  "--cl-color-",
1374
- ce,
1375
- e.colorsDark,
1661
+ be,
1662
+ t.colorsDark,
1376
1663
  "-dark"
1377
- ), W(t, "radii", "--cl-radius-", xt, e.radii), W(t, "shadows", "--cl-shadow-", wt, e.shadows), W(t, "fonts", "--cl-font-", vt, e.fonts), t;
1664
+ ), X(e, "radii", "--cl-radius-", kt, t.radii), X(e, "shadows", "--cl-shadow-", Lt, t.shadows), X(e, "fonts", "--cl-font-", At, t.fonts), e;
1378
1665
  }
1379
- function St(e) {
1380
- return typeof e == "object" && e !== null && !Array.isArray(e);
1666
+ function Bt(t) {
1667
+ return typeof t == "object" && t !== null && !Array.isArray(t);
1381
1668
  }
1382
- function Lt(e) {
1383
- const t = Y(() => Tt(e), [e]), [r, s] = k(null), n = t.url;
1384
- H(() => {
1385
- if (s(null), !n) return;
1386
- const u = new AbortController();
1387
- return fetch(n, { signal: u.signal }).then((l) => {
1669
+ function $t(t) {
1670
+ const e = ne(() => Dt(t), [t]), [r, n] = A(null), s = e.url;
1671
+ U(() => {
1672
+ if (n(null), !s) return;
1673
+ const c = new AbortController();
1674
+ return fetch(s, { signal: c.signal }).then((l) => {
1388
1675
  if (!l.ok)
1389
1676
  throw new Error(`HTTP ${l.status}`);
1390
1677
  return l.json();
1391
1678
  }).then((l) => {
1392
- if (!St(l))
1679
+ if (!Bt(l))
1393
1680
  throw new Error("theme JSON must be an object");
1394
- s(l);
1681
+ n(l);
1395
1682
  }).catch((l) => {
1396
- u.signal.aborted || console.error(`[Claudius] Failed to load theme from ${n}:`, l);
1397
- }), () => u.abort();
1398
- }, [n]);
1399
- const o = t.theme ?? r ?? null, c = (r == null ? void 0 : r.colorScheme) ?? t.mode, a = Y(
1400
- () => o ? Nt(o) : {},
1683
+ c.signal.aborted || console.error(`[Claudius] Failed to load theme from ${s}:`, l);
1684
+ }), () => c.abort();
1685
+ }, [s]);
1686
+ const o = e.theme ?? r ?? null, i = (r == null ? void 0 : r.colorScheme) ?? e.mode, u = ne(
1687
+ () => o ? jt(o) : {},
1401
1688
  [o]
1402
1689
  );
1403
- return { mode: c, cssVars: a };
1690
+ return { mode: i, cssVars: u };
1404
1691
  }
1405
- const me = "claudius:triggers:dismissed";
1406
- function kt() {
1692
+ const Ee = "claudius:triggers:dismissed";
1693
+ function Pt() {
1407
1694
  if (typeof window > "u") return !1;
1408
1695
  try {
1409
- return window.sessionStorage.getItem(me) === "1";
1696
+ return window.sessionStorage.getItem(Ee) === "1";
1410
1697
  } catch {
1411
1698
  return !1;
1412
1699
  }
1413
1700
  }
1414
- function At() {
1701
+ function Gt() {
1415
1702
  if (!(typeof window > "u"))
1416
1703
  try {
1417
- window.sessionStorage.setItem(me, "1");
1704
+ window.sessionStorage.setItem(Ee, "1");
1418
1705
  } catch {
1419
1706
  }
1420
1707
  }
1421
- function jt({
1422
- apiUrl: e,
1423
- title: t,
1708
+ function qt({
1709
+ apiUrl: t,
1710
+ title: e,
1424
1711
  subtitle: r,
1425
- welcomeMessage: s,
1426
- placeholder: n,
1712
+ welcomeMessage: n,
1713
+ placeholder: s,
1427
1714
  persistMessages: o,
1428
- storageKeyPrefix: c,
1429
- requestTimeoutMs: a,
1430
- theme: u = "light",
1715
+ storageKeyPrefix: i,
1716
+ requestTimeoutMs: u,
1717
+ theme: c = "light",
1431
1718
  accentColor: l,
1432
- position: d = "bottom-right",
1433
- locale: R,
1434
- translations: p,
1435
- triggers: w,
1436
- plugins: y
1719
+ position: f = "bottom-right",
1720
+ locale: y,
1721
+ translations: I,
1722
+ triggers: E,
1723
+ plugins: T,
1724
+ streaming: x = !0
1437
1725
  }) {
1438
- const [b, x] = k(!1), [v, N] = k(null), [E, I] = k(kt), A = C(!1), D = Be("(max-width: 639px)"), S = Y(
1439
- () => yt({ locale: R, translations: p }),
1440
- [R, p]
1441
- ), { messages: j, isLoading: m, error: P, canRetry: V, sendMessage: K, retry: f } = He({
1442
- apiUrl: e,
1726
+ const [w, C] = A(!1), [v, g] = A(null), [S, j] = A(Pt), W = O(!1), $ = Ue("(max-width: 639px)"), p = ne(
1727
+ () => Nt({ locale: y, translations: I }),
1728
+ [y, I]
1729
+ ), {
1730
+ messages: Y,
1731
+ isLoading: B,
1732
+ isStreaming: _,
1733
+ streamingMessageId: h,
1734
+ error: F,
1735
+ canRetry: Z,
1736
+ sendMessage: K,
1737
+ stop: se,
1738
+ retry: oe
1739
+ } = Ge({
1740
+ apiUrl: t,
1443
1741
  persistMessages: o,
1444
- storageKeyPrefix: c,
1445
- timeoutMs: a,
1446
- translations: S,
1447
- plugins: y
1448
- }), g = C(null), L = C(b), { mode: T, cssVars: B } = Lt(u), [O, z] = k(!1);
1449
- H(() => {
1450
- if (T !== "auto") return;
1451
- const _ = window.matchMedia("(prefers-color-scheme: dark)");
1452
- z(_.matches);
1453
- const re = (ve) => z(ve.matches);
1454
- return _.addEventListener("change", re), () => _.removeEventListener("change", re);
1455
- }, [T]), H(() => {
1456
- var _;
1457
- L.current && !b && ((_ = g.current) == null || _.focus()), L.current = b;
1458
- }, [b]);
1459
- const $ = M(() => {
1460
- I(!0), At();
1461
- }, []), ee = M(() => {
1462
- x(!1), A.current && (A.current = !1, $());
1463
- }, [$]), ge = M(() => {
1464
- x((_) => !_);
1465
- }, []), q = M(() => {
1466
- A.current = !0, N(null), x(!0);
1467
- }, []), pe = M((_) => {
1468
- N(_);
1469
- }, []), be = M(() => {
1470
- N(null), q();
1471
- }, [q]), ye = M(() => {
1472
- N(null), $();
1473
- }, [$]);
1474
- je({
1475
- triggers: w,
1476
- enabled: !E && !b,
1477
- onOpen: q,
1478
- onGreeting: pe
1742
+ storageKeyPrefix: i,
1743
+ timeoutMs: u,
1744
+ translations: p,
1745
+ plugins: T,
1746
+ streaming: x
1747
+ }), Q = O(null), ee = O(w), { mode: d, cssVars: N } = $t(c), [k, V] = A(!1);
1748
+ U(() => {
1749
+ if (d !== "auto") return;
1750
+ const G = window.matchMedia("(prefers-color-scheme: dark)");
1751
+ V(G.matches);
1752
+ const fe = (Me) => V(Me.matches);
1753
+ return G.addEventListener("change", fe), () => G.removeEventListener("change", fe);
1754
+ }, [d]), U(() => {
1755
+ var G;
1756
+ ee.current && !w && ((G = Q.current) == null || G.focus()), ee.current = w;
1757
+ }, [w]);
1758
+ const m = L(() => {
1759
+ j(!0), Gt();
1760
+ }, []), R = L(() => {
1761
+ C(!1), W.current && (W.current = !1, m());
1762
+ }, [m]), D = L(() => {
1763
+ C((G) => !G);
1764
+ }, []), M = L(() => {
1765
+ W.current = !0, g(null), C(!0);
1766
+ }, []), z = L((G) => {
1767
+ g(G);
1768
+ }, []), P = L(() => {
1769
+ g(null), M();
1770
+ }, [M]), J = L(() => {
1771
+ g(null), m();
1772
+ }, [m]);
1773
+ ze({
1774
+ triggers: E,
1775
+ enabled: !S && !w,
1776
+ onOpen: M,
1777
+ onGreeting: z
1479
1778
  });
1480
- const xe = T === "dark" || T === "auto" && O, te = {
1481
- ...B,
1779
+ const de = d === "dark" || d === "auto" && k, te = {
1780
+ ...N,
1482
1781
  ...l ? {
1483
1782
  "--cl-color-accent": l,
1484
1783
  "--cl-color-accent-dark": l
1485
1784
  } : {}
1486
- }, we = Object.keys(te).length > 0 ? te : void 0;
1785
+ }, Te = Object.keys(te).length > 0 ? te : void 0;
1487
1786
  return (
1488
1787
  // Outer div carries theme token vars; the inner div carries the dark-mode
1489
1788
  // attribute so the [data-claudius-dark] token reassignments in styles.css
1490
1789
  // beat inherited (inline) light values.
1491
- /* @__PURE__ */ i("div", { className: "claudius-root", style: we, children: /* @__PURE__ */ h("div", { "data-claudius-dark": xe ? "true" : "false", children: [
1492
- b && D && /* @__PURE__ */ i(
1790
+ /* @__PURE__ */ a("div", { className: "claudius-root", style: Te, children: /* @__PURE__ */ b("div", { "data-claudius-dark": de ? "true" : "false", children: [
1791
+ w && $ && /* @__PURE__ */ a(
1493
1792
  "div",
1494
1793
  {
1495
1794
  className: "claudius-scrim fixed inset-0 z-40 bg-claudius-scrim",
1496
- onClick: ee,
1795
+ onClick: R,
1497
1796
  "aria-hidden": "true"
1498
1797
  }
1499
1798
  ),
1500
- b && /* @__PURE__ */ i(
1501
- dt,
1799
+ w && /* @__PURE__ */ a(
1800
+ vt,
1502
1801
  {
1503
- messages: j,
1504
- isLoading: m,
1505
- error: P,
1506
- canRetry: V,
1802
+ messages: Y,
1803
+ isLoading: B,
1804
+ isStreaming: _,
1805
+ streamingMessageId: h,
1806
+ error: F,
1807
+ canRetry: Z,
1507
1808
  onSend: K,
1508
- onRetry: f,
1509
- onClose: ee,
1510
- title: t ?? S.title,
1511
- subtitle: r ?? S.subtitle,
1512
- welcomeMessage: s ?? S.welcomeMessage,
1513
- placeholder: n ?? S.placeholder,
1514
- position: d,
1515
- translations: S,
1516
- isMobile: D
1809
+ onStop: se,
1810
+ onRetry: oe,
1811
+ onClose: R,
1812
+ title: e ?? p.title,
1813
+ subtitle: r ?? p.subtitle,
1814
+ welcomeMessage: n ?? p.welcomeMessage,
1815
+ placeholder: s ?? p.placeholder,
1816
+ position: f,
1817
+ translations: p,
1818
+ isMobile: $
1517
1819
  }
1518
1820
  ),
1519
- !(b && D) && /* @__PURE__ */ i(
1520
- Ge,
1821
+ !(w && $) && /* @__PURE__ */ a(
1822
+ Ye,
1521
1823
  {
1522
- ref: g,
1523
- isOpen: b,
1524
- onClick: ge,
1525
- position: d,
1526
- translations: S
1824
+ ref: Q,
1825
+ isOpen: w,
1826
+ onClick: D,
1827
+ position: f,
1828
+ translations: p
1527
1829
  }
1528
1830
  ),
1529
- !b && v && /* @__PURE__ */ i(
1530
- ft,
1831
+ !w && v && /* @__PURE__ */ a(
1832
+ Rt,
1531
1833
  {
1532
1834
  message: v,
1533
- position: d,
1534
- onOpen: be,
1535
- onDismiss: ye,
1536
- dismissLabel: S.dismissGreeting
1835
+ position: f,
1836
+ onOpen: P,
1837
+ onDismiss: J,
1838
+ dismissLabel: p.dismissGreeting
1537
1839
  }
1538
1840
  )
1539
1841
  ] }) })
1540
1842
  );
1541
1843
  }
1542
- function Pt(e) {
1543
- const { onEvent: t, includeContent: r = !0 } = e, s = (n) => r ? n : "";
1844
+ function Jt(t) {
1845
+ const { onEvent: e, includeContent: r = !0 } = t, n = (s) => r ? s : "";
1544
1846
  return {
1545
1847
  name: "analytics",
1546
- onBeforeSend(n) {
1547
- t({
1848
+ onBeforeSend(s) {
1849
+ e({
1548
1850
  type: "message_sent",
1549
1851
  role: "user",
1550
- content: s(n.content),
1551
- chars: n.content.length
1852
+ content: n(s.content),
1853
+ chars: s.content.length
1552
1854
  });
1553
1855
  },
1554
- onAfterReceive(n) {
1555
- t({
1856
+ onAfterReceive(s) {
1857
+ e({
1556
1858
  type: "message_received",
1557
1859
  role: "assistant",
1558
- content: s(n.content),
1559
- chars: n.content.length
1860
+ content: n(s.content),
1861
+ chars: s.content.length
1560
1862
  });
1561
1863
  },
1562
- onError(n) {
1563
- t({
1864
+ onError(s) {
1865
+ e({
1564
1866
  type: "chat_error",
1565
- message: n.message,
1566
- code: n.code
1867
+ message: s.message,
1868
+ code: s.code
1567
1869
  });
1568
1870
  }
1569
1871
  };
1570
1872
  }
1571
- const Ot = [
1873
+ const Ut = [
1572
1874
  // Email
1573
1875
  /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
1574
1876
  // US SSN (before the looser card pattern so it wins on 9-digit groups)
@@ -1578,59 +1880,59 @@ const Ot = [
1578
1880
  // Phone: optional +1, area code, 7 digits with common separators
1579
1881
  /\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
1580
1882
  ];
1581
- function It(e, t, r) {
1582
- return t.reduce(
1883
+ function Wt(t, e, r) {
1884
+ return e.reduce(
1583
1885
  // Reset lastIndex defensively: a shared global regex is stateful.
1584
- (s, n) => (n.lastIndex = 0, s.replace(n, r)),
1585
- e
1886
+ (n, s) => (s.lastIndex = 0, n.replace(s, r)),
1887
+ t
1586
1888
  );
1587
1889
  }
1588
- function Gt(e = {}) {
1890
+ function Xt(t = {}) {
1589
1891
  const {
1590
- patterns: t = Ot,
1892
+ patterns: e = Ut,
1591
1893
  replacement: r = "[redacted]",
1592
- redactReplies: s = !1
1593
- } = e, n = (o) => {
1594
- const c = It(o.content, t, r);
1595
- if (c !== o.content)
1596
- return { ...o, content: c };
1894
+ redactReplies: n = !1
1895
+ } = t, s = (o) => {
1896
+ const i = Wt(o.content, e, r);
1897
+ if (i !== o.content)
1898
+ return { ...o, content: i };
1597
1899
  };
1598
1900
  return {
1599
1901
  name: "redact-pii",
1600
- onBeforeSend: n,
1601
- onAfterReceive: s ? n : void 0
1902
+ onBeforeSend: s,
1903
+ onAfterReceive: n ? s : void 0
1602
1904
  };
1603
1905
  }
1604
- function Dt(e, t, r) {
1605
- return typeof e == "function" ? e(t) : e instanceof RegExp ? e.test(t) : r ? t.includes(e) : t.toLowerCase().includes(e.toLowerCase());
1906
+ function zt(t, e, r) {
1907
+ return typeof t == "function" ? t(e) : t instanceof RegExp ? t.test(e) : r ? e.includes(t) : e.toLowerCase().includes(t.toLowerCase());
1606
1908
  }
1607
- function Ut(e) {
1608
- const { rules: t, caseSensitive: r = !1 } = e;
1909
+ function Zt(t) {
1910
+ const { rules: e, caseSensitive: r = !1 } = t;
1609
1911
  return {
1610
1912
  name: "canned-responses",
1611
- onBeforeSend(s, n) {
1612
- for (const o of t)
1613
- if (Dt(o.match, s.content, r)) {
1614
- n.respondWith(o.reply);
1913
+ onBeforeSend(n, s) {
1914
+ for (const o of e)
1915
+ if (zt(o.match, n.content, r)) {
1916
+ s.respondWith(o.reply);
1615
1917
  return;
1616
1918
  }
1617
1919
  }
1618
1920
  };
1619
1921
  }
1620
1922
  export {
1621
- Se as ChatApiClient,
1622
- U as ChatApiError,
1623
- jt as ChatWidget,
1624
- Ot as DEFAULT_PII_PATTERNS,
1923
+ Oe as ChatApiClient,
1924
+ H as ChatApiError,
1925
+ qt as ChatWidget,
1926
+ Ut as DEFAULT_PII_PATTERNS,
1625
1927
  ae as DebounceError,
1626
- he as builtinThemes,
1627
- $t as createTranslations,
1628
- ht as defaultTranslations,
1629
- bt as detectLocale,
1630
- fe as locales,
1631
- Pt as pluginAnalytics,
1632
- Ut as pluginCannedResponses,
1633
- Gt as pluginRedactPII,
1634
- It as redactText,
1635
- yt as resolveTranslations
1928
+ Re as builtinThemes,
1929
+ Kt as createTranslations,
1930
+ Et as defaultTranslations,
1931
+ Ct as detectLocale,
1932
+ ve as locales,
1933
+ Jt as pluginAnalytics,
1934
+ Zt as pluginCannedResponses,
1935
+ Xt as pluginRedactPII,
1936
+ Wt as redactText,
1937
+ Nt as resolveTranslations
1636
1938
  };