@green-on-grey/ui-kit 0.2.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/chat.js CHANGED
@@ -1,20 +1,175 @@
1
- import { c as e, d as t, i as n, l as r } from "./ui-CGgZtEVm.js";
2
- import { n as i, t as a } from "./i18n-BJ8rsBp6.js";
3
- import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
4
- import { useCallback as l, useEffect as u, useLayoutEffect as d, useRef as f, useState as p } from "react";
5
- import { useTranslation as m } from "react-i18next";
6
- //#region src/chat/MessageView.tsx
7
- var h = (e) => e === "zh" ? "zh-CN" : e;
1
+ import { c as e, d as t, i as n, l as r, s as i } from "./ui-joAvYmUH.js";
2
+ import { n as a, t as o } from "./i18n-BJ8rsBp6.js";
3
+ import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
4
+ import { useCallback as u, useEffect as d, useLayoutEffect as f, useRef as p, useState as m } from "react";
5
+ import { useTranslation as h } from "react-i18next";
6
+ //#region src/chat/CommandPalette.tsx
8
7
  function g(e, t) {
9
- return new Intl.DateTimeFormat(h(t), {
8
+ let n = t.toLowerCase();
9
+ return e.filter((e) => e.name.toLowerCase().includes(n) || (e.description ?? "").toLowerCase().includes(n));
10
+ }
11
+ function _({ items: e, active: n, onPick: r, onHover: i }) {
12
+ let o = a(), s = e.filter((e) => e.kind === "command"), u = e.filter((e) => e.kind === "skill"), d = (e, a) => /* @__PURE__ */ l("button", {
13
+ type: "button",
14
+ role: "option",
15
+ "aria-selected": a === n,
16
+ className: `palette-row${a === n ? " on" : ""}`,
17
+ onMouseDown: (t) => {
18
+ t.preventDefault(), r(e);
19
+ },
20
+ onMouseEnter: () => i(a),
21
+ children: [
22
+ e.kind === "skill" ? /* @__PURE__ */ c(t, {
23
+ name: "spark",
24
+ size: 14
25
+ }) : /* @__PURE__ */ c("span", {
26
+ className: "slash",
27
+ children: "/"
28
+ }),
29
+ /* @__PURE__ */ c("span", {
30
+ className: "nm",
31
+ children: e.kind === "command" ? "/" + e.name : e.name
32
+ }),
33
+ /* @__PURE__ */ c("span", {
34
+ className: "ds",
35
+ children: e.description
36
+ }),
37
+ e.source && /* @__PURE__ */ c("span", {
38
+ className: "src",
39
+ children: e.source
40
+ })
41
+ ]
42
+ }, e.kind + e.name);
43
+ return /* @__PURE__ */ l("div", {
44
+ className: "palette",
45
+ role: "listbox",
46
+ "aria-label": o("chat.palette.title"),
47
+ children: [
48
+ e.length === 0 && /* @__PURE__ */ c("div", {
49
+ className: "palette-empty",
50
+ children: o("chat.palette.empty")
51
+ }),
52
+ s.length > 0 && /* @__PURE__ */ c("div", {
53
+ className: "palette-h",
54
+ children: o("chat.palette.commands")
55
+ }),
56
+ s.map((t) => d(t, e.indexOf(t))),
57
+ e.length > 0 && /* @__PURE__ */ c("div", {
58
+ className: "palette-h",
59
+ children: o("chat.palette.skills")
60
+ }),
61
+ u.length === 0 && e.length > 0 && /* @__PURE__ */ c("div", {
62
+ className: "palette-empty",
63
+ children: o("chat.palette.noSkills")
64
+ }),
65
+ u.map((t) => d(t, e.indexOf(t)))
66
+ ]
67
+ });
68
+ }
69
+ //#endregion
70
+ //#region src/chat/ContextMeter.tsx
71
+ function v(e, t) {
72
+ return new Intl.NumberFormat(t === "zh" ? "zh-CN" : t, {
73
+ notation: "compact",
74
+ maximumFractionDigits: 1
75
+ }).format(e);
76
+ }
77
+ function y({ context: e, onCompact: n, onReset: r }) {
78
+ let s = a(), { i18n: u } = h(o), [d, f] = m(!1), p = i(d, () => f(!1)), g = e.window > 0 ? Math.min(1, e.tokens / e.window) : 0, _ = Math.round(g * 100), y = g >= .9 ? "full" : g >= .7 ? "warn" : "", b = 2 * Math.PI * 7, x = u.language;
79
+ return /* @__PURE__ */ l("div", {
80
+ className: "ctxmeter",
81
+ ref: p,
82
+ children: [/* @__PURE__ */ c("button", {
83
+ type: "button",
84
+ className: `ctxring ${y}`,
85
+ "aria-expanded": d,
86
+ onClick: () => f((e) => !e),
87
+ "aria-label": s("chat.context.meter", {
88
+ used: v(e.tokens, x),
89
+ total: v(e.window, x),
90
+ pct: _
91
+ }),
92
+ title: s("chat.context.meter", {
93
+ used: v(e.tokens, x),
94
+ total: v(e.window, x),
95
+ pct: _
96
+ }),
97
+ children: /* @__PURE__ */ l("svg", {
98
+ viewBox: "0 0 18 18",
99
+ "aria-hidden": "true",
100
+ children: [/* @__PURE__ */ c("circle", {
101
+ className: "bg",
102
+ cx: "9",
103
+ cy: "9",
104
+ r: 7
105
+ }), /* @__PURE__ */ c("circle", {
106
+ className: "fg",
107
+ cx: "9",
108
+ cy: "9",
109
+ r: 7,
110
+ strokeDasharray: `${(b * g).toFixed(1)} ${b.toFixed(1)}`,
111
+ transform: "rotate(-90 9 9)"
112
+ })]
113
+ })
114
+ }), d && /* @__PURE__ */ l("div", {
115
+ className: "ctxtip",
116
+ role: "dialog",
117
+ children: [
118
+ /* @__PURE__ */ c("div", { children: s("chat.context.meter", {
119
+ used: v(e.tokens, x),
120
+ total: v(e.window, x),
121
+ pct: _
122
+ }) }),
123
+ y === "full" && /* @__PURE__ */ c("div", {
124
+ className: "small muted",
125
+ style: { marginTop: 4 },
126
+ children: s("chat.context.full")
127
+ }),
128
+ y === "full" && (n || r) && /* @__PURE__ */ l("div", {
129
+ className: "row",
130
+ style: {
131
+ marginTop: 8,
132
+ gap: 6
133
+ },
134
+ children: [n && /* @__PURE__ */ l("button", {
135
+ type: "button",
136
+ className: "btn sm",
137
+ onClick: () => {
138
+ f(!1), n();
139
+ },
140
+ children: [/* @__PURE__ */ c(t, {
141
+ name: "compress",
142
+ size: 14
143
+ }), s("chat.context.compact")]
144
+ }), r && /* @__PURE__ */ l("button", {
145
+ type: "button",
146
+ className: "btn sm ghost",
147
+ onClick: () => {
148
+ f(!1), r();
149
+ },
150
+ children: [/* @__PURE__ */ c(t, {
151
+ name: "undo",
152
+ size: 14
153
+ }), s("chat.context.reset")]
154
+ })]
155
+ })
156
+ ]
157
+ })]
158
+ });
159
+ }
160
+ //#endregion
161
+ //#region src/chat/MessageView.tsx
162
+ var b = (e) => e === "zh" ? "zh-CN" : e;
163
+ function x(e, t) {
164
+ return new Intl.DateTimeFormat(b(t), {
10
165
  hour: "2-digit",
11
166
  minute: "2-digit"
12
167
  }).format(new Date(e));
13
168
  }
14
- function _(e, t) {
169
+ function S(e, t) {
15
170
  return t || e.length <= 3 ? e : e.slice(-2);
16
171
  }
17
- var v = {
172
+ var C = {
18
173
  done: {
19
174
  icon: "check",
20
175
  cls: "ok"
@@ -28,30 +183,31 @@ var v = {
28
183
  cls: "run"
29
184
  }
30
185
  };
31
- function y({ m: e, busy: n, onRetry: i }) {
32
- let { t: l, i18n: u } = m(a), [d, f] = p(!1);
33
- if (e.role === "note") return /* @__PURE__ */ s("div", {
186
+ function w({ m: e, busy: n, onRetry: i }) {
187
+ let { t: a, i18n: u } = h(o), [d, f] = m(!1);
188
+ if (e.role === "note") return /* @__PURE__ */ c("div", {
34
189
  className: "sysnote",
35
190
  children: e.text
36
191
  });
37
- let h = e.mark && /* @__PURE__ */ c("div", {
192
+ if (e.role === "event" && e.event) return /* @__PURE__ */ c(T, { m: e });
193
+ let p = e.mark && /* @__PURE__ */ l("div", {
38
194
  className: "chan",
39
195
  children: [
40
- /* @__PURE__ */ s(t, {
196
+ /* @__PURE__ */ c(t, {
41
197
  name: e.mark.icon,
42
198
  size: 12
43
199
  }),
44
200
  " ",
45
201
  e.mark.text,
46
202
  " · ",
47
- g(e.createdAt, u.language)
203
+ x(e.createdAt, u.language)
48
204
  ]
49
- }), y = e.attachments && e.attachments.length > 0 && /* @__PURE__ */ s("div", {
205
+ }), g = e.attachments && e.attachments.length > 0 && /* @__PURE__ */ c("div", {
50
206
  className: "atts",
51
- children: e.attachments.map((e) => /* @__PURE__ */ c("a", {
207
+ children: e.attachments.map((e) => /* @__PURE__ */ l("a", {
52
208
  href: e.href,
53
209
  children: [
54
- /* @__PURE__ */ s(t, {
210
+ /* @__PURE__ */ c(t, {
55
211
  name: "clip",
56
212
  size: 12
57
213
  }),
@@ -60,154 +216,258 @@ function y({ m: e, busy: n, onRetry: i }) {
60
216
  ]
61
217
  }, e.id))
62
218
  });
63
- if (e.role === "user") return /* @__PURE__ */ c("div", {
219
+ if (e.role === "user") return /* @__PURE__ */ l("div", {
64
220
  className: "m u",
65
221
  children: [
66
- h,
222
+ p,
67
223
  e.content,
68
- e.text && /* @__PURE__ */ s("div", {
224
+ e.text && /* @__PURE__ */ c("div", {
69
225
  className: "bub",
70
226
  children: e.text
71
227
  }),
72
- y,
73
- e.wait && /* @__PURE__ */ s("div", {
228
+ g,
229
+ e.wait && /* @__PURE__ */ c("div", {
74
230
  className: `turnstate${e.wait.state === "queued" ? " q" : ""}`,
75
231
  role: "status",
76
- children: e.wait.state === "queued" ? /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(t, {
232
+ children: e.wait.state === "queued" ? /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c(t, {
77
233
  name: "clock",
78
234
  size: 12
79
- }), l("chat.wait.queued", { count: e.wait.position })] }) : /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("span", {
235
+ }), a("chat.wait.queued", { count: e.wait.position })] }) : /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("span", {
80
236
  className: "spin",
81
237
  "aria-hidden": "true"
82
- }), l("chat.wait.starting")] })
238
+ }), a("chat.wait.starting")] })
83
239
  })
84
240
  ]
85
241
  });
86
- let b = e.steps ?? [], x = (e.status === "streaming" || e.status === "pending") && !e.text && !e.content;
87
- return /* @__PURE__ */ c("div", {
242
+ let _ = e.steps ?? [], v = (e.status === "streaming" || e.status === "pending") && !e.text && !e.content;
243
+ return /* @__PURE__ */ l("div", {
88
244
  className: "m a",
89
245
  children: [
90
- h,
91
- b.length > 3 && /* @__PURE__ */ s("button", {
246
+ p,
247
+ _.length > 3 && /* @__PURE__ */ c("button", {
92
248
  className: "tools-fold",
93
249
  onClick: () => f((e) => !e),
94
250
  "aria-expanded": d,
95
- children: d ? l("chat.hideSteps") : l("chat.moreSteps", { count: b.length - 2 })
251
+ children: d ? a("chat.hideSteps") : a("chat.moreSteps", { count: _.length - 2 })
96
252
  }),
97
- _(b, d).map((e) => /* @__PURE__ */ c("div", {
253
+ S(_, d).map((e) => /* @__PURE__ */ l("div", {
98
254
  className: "tool",
99
255
  title: e.title,
100
- children: [/* @__PURE__ */ s(t, {
101
- name: v[e.status].icon,
256
+ children: [/* @__PURE__ */ c(t, {
257
+ name: C[e.status].icon,
102
258
  size: 14,
103
- className: v[e.status].cls
104
- }), /* @__PURE__ */ s("span", {
259
+ className: C[e.status].cls
260
+ }), /* @__PURE__ */ c("span", {
105
261
  className: "tx",
106
262
  children: e.text
107
263
  })]
108
264
  }, e.id)),
109
- x && /* @__PURE__ */ s("div", {
265
+ v && /* @__PURE__ */ c("div", {
110
266
  className: "bub",
111
- children: /* @__PURE__ */ c("span", {
267
+ children: /* @__PURE__ */ l("span", {
112
268
  className: "typing",
113
- "aria-label": l("chat.typing"),
269
+ "aria-label": a("chat.typing"),
114
270
  children: [
115
- /* @__PURE__ */ s("i", {}),
116
- /* @__PURE__ */ s("i", {}),
117
- /* @__PURE__ */ s("i", {})
271
+ /* @__PURE__ */ c("i", {}),
272
+ /* @__PURE__ */ c("i", {}),
273
+ /* @__PURE__ */ c("i", {})
118
274
  ]
119
275
  })
120
276
  }),
121
- e.content ?? (e.text && /* @__PURE__ */ s("div", {
277
+ e.content ?? (e.text && /* @__PURE__ */ c("div", {
122
278
  className: "bub",
123
- children: /* @__PURE__ */ s(r, { text: e.text })
279
+ title: e.hint,
280
+ children: /* @__PURE__ */ c(r, { text: e.text })
124
281
  })),
125
- y,
126
- e.error && /* @__PURE__ */ c("div", {
282
+ g,
283
+ e.error && /* @__PURE__ */ l("div", {
127
284
  className: `llmerr${e.error.transient ? " amber" : ""}`,
128
285
  role: "alert",
129
286
  style: { marginTop: 6 },
130
- children: [/* @__PURE__ */ s("span", { children: e.error.text }), i && /* @__PURE__ */ s("div", {
287
+ children: [/* @__PURE__ */ c("span", { children: e.error.text }), i && /* @__PURE__ */ c("div", {
131
288
  className: "row",
132
- children: /* @__PURE__ */ c("button", {
289
+ children: /* @__PURE__ */ l("button", {
133
290
  className: "btn sm",
134
291
  disabled: n,
135
292
  onClick: i,
136
- children: [/* @__PURE__ */ s(t, {
293
+ children: [/* @__PURE__ */ c(t, {
137
294
  name: "refresh",
138
295
  size: 14
139
- }), l("chat.retry")]
296
+ }), a("chat.retry")]
140
297
  })
141
298
  })]
142
299
  })
143
300
  ]
144
301
  });
145
302
  }
303
+ function T({ m: e }) {
304
+ let { t: n, i18n: r } = h(o), [i, a] = m(!1), s = e.event;
305
+ return /* @__PURE__ */ l("div", {
306
+ className: "evdiv",
307
+ children: [/* @__PURE__ */ c("div", {
308
+ className: "evline",
309
+ role: "separator",
310
+ children: /* @__PURE__ */ l("span", {
311
+ className: "evchip",
312
+ children: [
313
+ /* @__PURE__ */ c(t, {
314
+ name: s.icon,
315
+ size: 12
316
+ }),
317
+ s.text,
318
+ " · ",
319
+ x(e.createdAt, r.language),
320
+ s.details && /* @__PURE__ */ l("button", {
321
+ type: "button",
322
+ className: "textbtn",
323
+ "aria-expanded": i,
324
+ onClick: () => a((e) => !e),
325
+ children: [
326
+ n("chat.event.details"),
327
+ " ",
328
+ i ? "▴" : "▾"
329
+ ]
330
+ })
331
+ ]
332
+ })
333
+ }), i && s.details && /* @__PURE__ */ c("div", {
334
+ className: "evdetails",
335
+ children: s.details
336
+ })]
337
+ });
338
+ }
146
339
  //#endregion
147
340
  //#region src/chat/useRecorder.ts
148
- function b() {
149
- let e = typeof window < "u" && "MediaRecorder" in window && !!navigator.mediaDevices?.getUserMedia, [t, n] = p(!1), [r, i] = p(0), [a, o] = p(!1), s = f(null), c = f([]), d = f(void 0), m = f(null), h = l(() => {
150
- window.clearInterval(d.current), s.current?.stream.getTracks().forEach((e) => e.stop()), s.current = null, n(!1);
151
- }, []), g = l(async () => {
152
- if (e && !s.current) {
153
- o(!1);
341
+ function E(e = 300, t) {
342
+ let n = typeof window < "u" && "MediaRecorder" in window && !!navigator.mediaDevices?.getUserMedia, [r, i] = m(!1), [a, o] = m(0), [s, c] = m(0), [l, f] = m(!1), h = p(null), g = p([]), _ = p(void 0), v = p(null), y = p(null), b = p(!1), x = p(t);
343
+ d(() => {
344
+ x.current = t;
345
+ });
346
+ let S = u(() => {
347
+ window.clearInterval(_.current), h.current?.stream.getTracks().forEach((e) => e.stop()), h.current = null, v.current?.close().catch(() => void 0), v.current = null, i(!1), c(0);
348
+ }, []), C = u(async () => {
349
+ if (n && !h.current) {
350
+ f(!1);
154
351
  try {
155
- let e = await navigator.mediaDevices.getUserMedia({ audio: !0 }), t = new MediaRecorder(e);
156
- c.current = [], t.ondataavailable = (e) => e.data.size > 0 && c.current.push(e.data), t.onstop = () => {
157
- let e = c.current.length ? new Blob(c.current, { type: t.mimeType || "audio/webm" }) : null;
158
- h(), m.current?.(e), m.current = null;
159
- }, s.current = t, t.start(), i(0), n(!0);
160
- let r = Date.now();
161
- d.current = window.setInterval(() => i(Math.floor((Date.now() - r) / 1e3)), 250);
352
+ let t = await navigator.mediaDevices.getUserMedia({ audio: !0 }), n = new MediaRecorder(t);
353
+ g.current = [], b.current = !1, n.ondataavailable = (e) => e.data.size > 0 && g.current.push(e.data), n.onstop = () => {
354
+ let e = !b.current && g.current.length ? new Blob(g.current, { type: n.mimeType || "audio/webm" }) : null;
355
+ S(), y.current?.(e), y.current = null;
356
+ };
357
+ let r = null;
358
+ try {
359
+ let e = window.AudioContext ?? window.webkitAudioContext;
360
+ e && (v.current = new e(), r = v.current.createAnalyser(), r.fftSize = 256, v.current.createMediaStreamSource(t).connect(r));
361
+ } catch {
362
+ r = null;
363
+ }
364
+ let a = r ? new Uint8Array(r.fftSize) : null;
365
+ h.current = n, n.start(), o(0), i(!0);
366
+ let s = Date.now(), l = !1;
367
+ _.current = window.setInterval(() => {
368
+ let t = Math.floor((Date.now() - s) / 1e3);
369
+ if (o(t), r && a) {
370
+ r.getByteTimeDomainData(a);
371
+ let e = 0;
372
+ for (let t of a) e = Math.max(e, Math.abs(t - 128));
373
+ c(Math.min(1, e / 64));
374
+ }
375
+ t >= e && !l && (l = !0, x.current?.());
376
+ }, 100);
162
377
  } catch {
163
- o(!0), h();
378
+ f(!0), S();
164
379
  }
165
380
  }
166
- }, [e, h]), _ = l(() => new Promise((e) => {
167
- let t = s.current;
381
+ }, [
382
+ n,
383
+ S,
384
+ e
385
+ ]), w = u(() => new Promise((e) => {
386
+ let t = h.current;
168
387
  if (!t || t.state === "inactive") return e(null);
169
- m.current = e, t.stop();
170
- }), []);
171
- return u(() => () => h(), [h]), {
172
- supported: e,
173
- recording: t,
174
- seconds: `${Math.floor(r / 60)}:${String(r % 60).padStart(2, "0")}`,
175
- error: a,
176
- start: g,
177
- stop: _
388
+ y.current = e, t.stop();
389
+ }), []), T = u(() => {
390
+ b.current = !0, w();
391
+ }, [w]);
392
+ return d(() => () => S(), [S]), {
393
+ supported: n,
394
+ recording: r,
395
+ seconds: a,
396
+ level: s,
397
+ error: l,
398
+ start: C,
399
+ stop: w,
400
+ cancel: T
178
401
  };
179
402
  }
403
+ function D(e) {
404
+ return `${Math.floor(e / 60)}:${String(e % 60).padStart(2, "0")}`;
405
+ }
180
406
  //#endregion
181
407
  //#region src/chat/Chat.tsx
182
- function x(n) {
183
- let r = i(), a = e(), [l, u] = p(""), [m, h] = p([]), [g, _] = p(!1), [v, x] = p(null), S = f(null), C = f(null), w = b(), { messages: T, busy: E = !1 } = n, D = T[0]?.id, O = T[T.length - 1], k = O?.id, A = O?.text.length, j = O?.steps?.length, M = f({ height: 0 });
184
- d(() => {
185
- let e = S.current;
408
+ function O(n) {
409
+ let r = a(), i = e(), [o, u] = m(""), [h, v] = m([]), [b, x] = m(!1), [S, C] = m(null), [T, O] = m(0), [k, A] = m(!1), [j, M] = m(null), [N, P] = m(!1), F = p(!1), I = p(null), L = p(null), R = p(null), z = n.voiceMaxSeconds ?? 300, B = E(z, () => void ae()), { messages: V, busy: H = !1 } = n, U = n.onPendingChange;
410
+ d(() => U?.(h), [h, U]);
411
+ let W = V[0]?.id, G = V[V.length - 1], K = G?.id, ee = G?.text.length, te = G?.steps?.length, q = p({ height: 0 });
412
+ f(() => {
413
+ let e = I.current;
186
414
  if (!e) return;
187
- let t = M.current;
188
- e.scrollTop = t.first !== void 0 && D !== t.first && k === t.last ? e.scrollTop + (e.scrollHeight - t.height) : e.scrollHeight, M.current = {
189
- first: D,
190
- last: k,
415
+ let t = q.current;
416
+ e.scrollTop = t.first !== void 0 && W !== t.first && K === t.last ? e.scrollTop + (e.scrollHeight - t.height) : e.scrollHeight, q.current = {
417
+ first: W,
418
+ last: K,
191
419
  height: e.scrollHeight
192
420
  };
193
421
  }, [
194
- T.length,
195
- D,
196
- k,
197
- A,
198
- j
422
+ V.length,
423
+ W,
424
+ K,
425
+ ee,
426
+ te
199
427
  ]);
200
- let N = async (e, t) => {
201
- let r = e.trim();
202
- if (!(!r && m.length === 0 || E || n.readOnly)) try {
203
- await n.onSend(r, m.map((e) => e.id), t), u(""), h([]), x(null);
428
+ let J = n.commands && !S && o.startsWith("/") && !/\s/.test(o) ? o.slice(1) : null, Y = J === null ? [] : g(n.commands ?? [], J), X = J !== null && !k, Z = () => {
429
+ u(""), v([]), C(null), M(null), F.current = !1;
430
+ }, Q = async (e, t) => {
431
+ if (n.onCommand) try {
432
+ await n.onCommand(e, t), Z();
204
433
  } catch {}
205
- }, P = async (e) => {
434
+ }, $ = async (e, t = !1) => {
435
+ let r = e.trim();
436
+ if (!(!r && h.length === 0 && !S || H || n.readOnly)) {
437
+ if (!t && !S && n.commands && r.startsWith("/")) {
438
+ let [e, ...t] = r.slice(1).split(/\s+/), i = n.commands.find((t) => t.kind === "command" && t.name === e);
439
+ if (i) return Q(i.name, t.join(" "));
440
+ if (e && !r.includes("\n")) {
441
+ M("/" + e);
442
+ return;
443
+ }
444
+ }
445
+ try {
446
+ await n.onSend(r, h.map((e) => e.id), F.current, S ?? void 0), Z();
447
+ } catch {}
448
+ }
449
+ }, ne = (e) => {
450
+ O(0), e.kind === "skill" ? (C(e.name), u("")) : e.takesText ? u("/" + e.name + " ") : Q(e.name, ""), R.current?.focus();
451
+ }, re = (e) => {
452
+ if (X && Y.length > 0) {
453
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
454
+ e.preventDefault();
455
+ let t = e.key === "ArrowDown" ? 1 : -1;
456
+ O((e) => (e + t + Y.length) % Y.length);
457
+ return;
458
+ }
459
+ if (e.key === "Enter" && !e.shiftKey || e.key === "Tab") {
460
+ e.preventDefault(), ne(Y[Math.min(T, Y.length - 1)]);
461
+ return;
462
+ }
463
+ }
464
+ X && e.key === "Escape" ? (e.preventDefault(), A(!0)) : e.key === "Backspace" && S && o === "" ? C(null) : e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && (e.preventDefault(), $(o));
465
+ }, ie = async (e) => {
206
466
  if (e?.length && n.onUpload) {
207
- _(!0);
467
+ x(!0);
208
468
  for (let t of Array.from(e)) {
209
469
  if (n.upload && t.size > n.upload.maxBytes) {
210
- a({
470
+ i({
211
471
  kind: "error",
212
472
  title: r("chat.tooLarge"),
213
473
  text: t.name
@@ -215,79 +475,82 @@ function x(n) {
215
475
  continue;
216
476
  }
217
477
  let e = await n.onUpload(t).catch(() => null);
218
- e && h((t) => [...t, e]);
478
+ e && v((t) => [...t, e]);
219
479
  }
220
- _(!1), C.current && (C.current.value = "");
480
+ x(!1), L.current && (L.current.value = "");
221
481
  }
222
- }, F = async () => {
223
- let e = await w.stop();
482
+ };
483
+ async function ae() {
484
+ let e = await B.stop();
224
485
  if (!e || !n.onTranscribe) return;
486
+ P(!0);
225
487
  let t = await n.onTranscribe(e).catch(() => null);
226
- t !== null && (t ? x(t) : a({
488
+ P(!1), t !== null && (t ? (F.current = !0, u((e) => e.trim() ? e.trimEnd() + " " + t : t), R.current?.focus()) : i({
227
489
  kind: "error",
228
490
  title: r("chat.voice.notRecognized")
229
491
  }));
230
- }, I = (e) => {
231
- (e.key === " " || e.key === "Enter") && (e.preventDefault(), !e.repeat && (w.recording ? F() : w.start()));
232
- }, L = r("chat.placeholder", { name: n.agentName });
233
- return /* @__PURE__ */ c("section", {
492
+ }
493
+ let oe = (e) => {
494
+ e.key === "Escape" && B.recording && (e.preventDefault(), B.cancel());
495
+ }, se = S ? r("chat.skillPlaceholder") : r("chat.placeholder", { name: n.agentName }), ce = z - B.seconds;
496
+ return /* @__PURE__ */ l("section", {
234
497
  className: "nb-chat",
235
498
  "aria-label": r("chat.title"),
236
499
  children: [
237
500
  n.header,
238
- /* @__PURE__ */ c("div", {
501
+ /* @__PURE__ */ l("div", {
239
502
  className: "msgs",
240
- ref: S,
503
+ ref: I,
241
504
  "aria-live": "polite",
242
505
  children: [
243
- n.hasOlder && n.onLoadOlder && /* @__PURE__ */ s("button", {
506
+ n.hasOlder && n.onLoadOlder && /* @__PURE__ */ c("button", {
244
507
  className: "btn ghost sm",
245
508
  style: { alignSelf: "center" },
246
509
  disabled: n.loadingOlder,
247
510
  onClick: n.onLoadOlder,
248
511
  children: r("chat.loadOlder")
249
512
  }),
250
- n.historyError && /* @__PURE__ */ s("div", {
513
+ n.historyError && /* @__PURE__ */ c("div", {
251
514
  className: "err-text",
252
515
  children: n.historyError
253
516
  }),
254
- T.length === 0 && !n.loading && !n.historyError && /* @__PURE__ */ c("div", {
517
+ V.length === 0 && !n.loading && !n.historyError && /* @__PURE__ */ l("div", {
255
518
  className: "empty",
256
519
  children: [
257
- /* @__PURE__ */ s("div", {
520
+ /* @__PURE__ */ c("div", {
258
521
  className: "ic",
259
- children: /* @__PURE__ */ s(t, { name: "spark" })
522
+ children: /* @__PURE__ */ c(t, { name: "spark" })
260
523
  }),
261
- /* @__PURE__ */ s("b", { children: r("chat.emptyTitle", { name: n.agentName }) }),
524
+ /* @__PURE__ */ c("b", { children: r("chat.emptyTitle", { name: n.agentName }) }),
262
525
  n.emptyHint
263
526
  ]
264
527
  }),
265
- T.map((e) => /* @__PURE__ */ s(y, {
528
+ V.map((e) => /* @__PURE__ */ c(w, {
266
529
  m: e,
267
- busy: E,
530
+ busy: H,
268
531
  onRetry: n.onRetry && (() => n.onRetry?.(e.id))
269
532
  }, e.id)),
270
- n.onConfirm && (n.confirmations ?? []).map((e) => /* @__PURE__ */ c("div", {
533
+ n.onConfirm && (n.confirmations ?? []).map((e) => /* @__PURE__ */ l("div", {
271
534
  className: "confirm",
272
535
  role: "group",
273
536
  "aria-label": r("chat.confirm.title"),
274
537
  children: [
275
- /* @__PURE__ */ c("div", {
538
+ /* @__PURE__ */ l("div", {
276
539
  className: "h",
277
- children: [/* @__PURE__ */ s(t, {
540
+ children: [/* @__PURE__ */ c(t, {
278
541
  name: "alert",
279
542
  size: 16
280
543
  }), r("chat.confirm.title")]
281
544
  }),
282
- /* @__PURE__ */ s("div", { children: r("chat.confirm.text", { action: e.summary }) }),
283
- e.preview !== void 0 && /* @__PURE__ */ s("pre", { children: e.preview }),
284
- /* @__PURE__ */ c("div", {
545
+ /* @__PURE__ */ c("div", { children: r("chat.confirm.text", { action: e.summary }) }),
546
+ e.preview !== void 0 && /* @__PURE__ */ c("pre", { children: e.preview }),
547
+ /* @__PURE__ */ l("div", {
285
548
  className: "acts",
286
- children: [/* @__PURE__ */ s("button", {
549
+ children: [/* @__PURE__ */ c("button", {
287
550
  className: "btn sm primary",
288
551
  onClick: () => n.onConfirm?.(e.id, !0),
289
552
  children: r("chat.confirm.approve")
290
- }), /* @__PURE__ */ s("button", {
553
+ }), /* @__PURE__ */ c("button", {
291
554
  className: "btn sm",
292
555
  onClick: () => n.onConfirm?.(e.id, !1),
293
556
  children: r("chat.confirm.reject")
@@ -297,132 +560,182 @@ function x(n) {
297
560
  }, e.id))
298
561
  ]
299
562
  }),
300
- n.readOnly ? /* @__PURE__ */ s("div", {
563
+ n.readOnly ? /* @__PURE__ */ c("div", {
301
564
  className: "composer",
302
565
  style: {
303
566
  justifyContent: "space-between",
304
567
  alignItems: "center"
305
568
  },
306
569
  children: n.readOnly
307
- }) : v === null ? /* @__PURE__ */ c(o, { children: [
308
- n.aboveComposer,
309
- m.length > 0 && /* @__PURE__ */ s("div", {
310
- className: "pending-files",
311
- children: m.map((e) => /* @__PURE__ */ c("span", {
312
- className: "chip",
570
+ }) : /* @__PURE__ */ l("div", {
571
+ className: "composer-wrap",
572
+ children: [
573
+ X && /* @__PURE__ */ c(_, {
574
+ items: Y,
575
+ active: Math.min(T, Math.max(Y.length - 1, 0)),
576
+ onPick: ne,
577
+ onHover: O
578
+ }),
579
+ n.aboveComposer,
580
+ h.length > 0 && /* @__PURE__ */ c("div", {
581
+ className: "pending-files",
582
+ children: h.map((e) => /* @__PURE__ */ l("span", {
583
+ className: "chip",
584
+ children: [
585
+ /* @__PURE__ */ c(t, {
586
+ name: "clip",
587
+ size: 12
588
+ }),
589
+ e.fileName,
590
+ /* @__PURE__ */ c("button", {
591
+ className: "iconbtn",
592
+ style: {
593
+ width: 18,
594
+ height: 18
595
+ },
596
+ "aria-label": r("remove"),
597
+ onClick: () => v((t) => t.filter((t) => t.id !== e.id)),
598
+ children: /* @__PURE__ */ c(t, {
599
+ name: "x",
600
+ size: 12
601
+ })
602
+ })
603
+ ]
604
+ }, e.id))
605
+ }),
606
+ j && /* @__PURE__ */ l("div", {
607
+ className: "cmd-unknown",
608
+ role: "status",
609
+ children: [r("chat.unknownCommand", { name: j }), /* @__PURE__ */ c("button", {
610
+ type: "button",
611
+ className: "textbtn",
612
+ onClick: () => void $(o, !0),
613
+ children: r("chat.sendAsText")
614
+ })]
615
+ }),
616
+ /* @__PURE__ */ l("div", {
617
+ className: "composer",
313
618
  children: [
314
- /* @__PURE__ */ s(t, {
315
- name: "clip",
316
- size: 12
619
+ n.onUpload && !B.recording && /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("button", {
620
+ className: "iconbtn",
621
+ "aria-label": r("chat.attach"),
622
+ disabled: b,
623
+ onClick: () => L.current?.click(),
624
+ children: /* @__PURE__ */ c(t, { name: "clip" })
625
+ }), /* @__PURE__ */ c("input", {
626
+ ref: L,
627
+ type: "file",
628
+ multiple: !0,
629
+ hidden: !0,
630
+ accept: n.upload?.accept,
631
+ onChange: (e) => ie(e.target.files)
632
+ })] }),
633
+ B.recording ? /* @__PURE__ */ l("div", {
634
+ className: `recbar${ce <= 15 ? " ending" : ""}`,
635
+ role: "status",
636
+ "aria-label": r("chat.voice.recordingNow"),
637
+ children: [
638
+ /* @__PURE__ */ c("span", {
639
+ className: "dot",
640
+ "aria-hidden": "true"
641
+ }),
642
+ /* @__PURE__ */ l("span", {
643
+ className: "tm",
644
+ children: [
645
+ D(B.seconds),
646
+ " / ",
647
+ D(z)
648
+ ]
649
+ }),
650
+ /* @__PURE__ */ c("span", {
651
+ className: "lvl",
652
+ "aria-hidden": "true",
653
+ children: /* @__PURE__ */ c("i", { style: { transform: `scaleX(${Math.max(.04, B.level)})` } })
654
+ }),
655
+ /* @__PURE__ */ c("button", {
656
+ type: "button",
657
+ className: "btn ghost sm",
658
+ onClick: B.cancel,
659
+ children: r("cancel")
660
+ }),
661
+ /* @__PURE__ */ c("button", {
662
+ type: "button",
663
+ className: "btn primary sm",
664
+ onKeyDown: oe,
665
+ onClick: () => void ae(),
666
+ children: r("chat.voice.done")
667
+ })
668
+ ]
669
+ }) : /* @__PURE__ */ l("div", {
670
+ className: `field${S ? " with-skill" : ""}`,
671
+ children: [S && /* @__PURE__ */ l("span", {
672
+ className: "chip skill-chip",
673
+ children: [
674
+ /* @__PURE__ */ c(t, {
675
+ name: "spark",
676
+ size: 12
677
+ }),
678
+ S,
679
+ /* @__PURE__ */ c("button", {
680
+ className: "iconbtn",
681
+ style: {
682
+ width: 18,
683
+ height: 18
684
+ },
685
+ "aria-label": r("remove"),
686
+ onClick: () => C(null),
687
+ children: /* @__PURE__ */ c(t, {
688
+ name: "x",
689
+ size: 12
690
+ })
691
+ })
692
+ ]
693
+ }), /* @__PURE__ */ c("textarea", {
694
+ ref: R,
695
+ rows: 1,
696
+ value: o,
697
+ placeholder: N ? r("chat.voice.recognizing") : se,
698
+ "aria-label": se,
699
+ disabled: N,
700
+ "aria-expanded": X,
701
+ "aria-autocomplete": n.commands ? "list" : void 0,
702
+ onChange: (e) => {
703
+ u(e.target.value), A(!1), O(0), M(null);
704
+ },
705
+ onKeyDown: re
706
+ })]
317
707
  }),
318
- e.fileName,
319
- /* @__PURE__ */ s("button", {
708
+ n.context && !B.recording && /* @__PURE__ */ c(y, {
709
+ context: n.context,
710
+ onCompact: n.onCompact,
711
+ onReset: n.onReset
712
+ }),
713
+ n.onTranscribe && !B.recording && /* @__PURE__ */ c("button", {
320
714
  className: "iconbtn",
321
- style: {
322
- width: 18,
323
- height: 18
324
- },
325
- "aria-label": r("remove"),
326
- onClick: () => h((t) => t.filter((t) => t.id !== e.id)),
327
- children: /* @__PURE__ */ s(t, {
328
- name: "x",
329
- size: 12
330
- })
331
- })
715
+ disabled: !B.supported || N,
716
+ "aria-label": r("chat.voice.start"),
717
+ title: B.supported ? r("chat.voice.start") : r("chat.voice.unsupported"),
718
+ onClick: () => void B.start(),
719
+ children: /* @__PURE__ */ c(t, { name: "mic" })
720
+ }),
721
+ !B.recording && (n.onCancel && H ? /* @__PURE__ */ c("button", {
722
+ className: "iconbtn fill",
723
+ "aria-label": r("chat.stop"),
724
+ onClick: n.onCancel,
725
+ children: /* @__PURE__ */ c(t, { name: "stop" })
726
+ }) : /* @__PURE__ */ c("button", {
727
+ className: "iconbtn fill",
728
+ "aria-label": r("chat.send"),
729
+ disabled: !o.trim() && h.length === 0 && !S || H,
730
+ onClick: () => $(o),
731
+ children: /* @__PURE__ */ c(t, { name: "send" })
732
+ }))
332
733
  ]
333
- }, e.id))
334
- }),
335
- /* @__PURE__ */ c("div", {
336
- className: "composer",
337
- children: [
338
- n.onUpload && /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("button", {
339
- className: "iconbtn",
340
- "aria-label": r("chat.attach"),
341
- disabled: g,
342
- onClick: () => C.current?.click(),
343
- children: /* @__PURE__ */ s(t, { name: "clip" })
344
- }), /* @__PURE__ */ s("input", {
345
- ref: C,
346
- type: "file",
347
- multiple: !0,
348
- hidden: !0,
349
- accept: n.upload?.accept,
350
- onChange: (e) => P(e.target.files)
351
- })] }),
352
- w.recording ? /* @__PURE__ */ s("div", {
353
- className: "rec-box",
354
- children: r("chat.voice.recording", { seconds: w.seconds })
355
- }) : /* @__PURE__ */ s("textarea", {
356
- rows: 1,
357
- value: l,
358
- placeholder: L,
359
- "aria-label": L,
360
- onChange: (e) => u(e.target.value),
361
- onKeyDown: (e) => {
362
- e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && (e.preventDefault(), N(l, !1));
363
- }
364
- }),
365
- n.onTranscribe && /* @__PURE__ */ s("button", {
366
- className: `iconbtn${w.recording ? " rec" : ""}`,
367
- disabled: !w.supported,
368
- "aria-label": w.recording ? r("chat.voice.stop") : r("chat.voice.hold"),
369
- title: w.supported ? r("chat.voice.hold") : r("chat.voice.unsupported"),
370
- onPointerDown: (e) => {
371
- e.preventDefault(), w.recording || w.start();
372
- },
373
- onPointerUp: () => w.recording && F(),
374
- onPointerLeave: () => w.recording && F(),
375
- onKeyDown: I,
376
- children: /* @__PURE__ */ s(t, { name: "mic" })
377
- }),
378
- n.onCancel && E ? /* @__PURE__ */ s("button", {
379
- className: "iconbtn fill",
380
- "aria-label": r("chat.stop"),
381
- onClick: n.onCancel,
382
- children: /* @__PURE__ */ s(t, { name: "stop" })
383
- }) : /* @__PURE__ */ s("button", {
384
- className: "iconbtn fill",
385
- "aria-label": r("chat.send"),
386
- disabled: !l.trim() && m.length === 0 || E,
387
- onClick: () => N(l, !1),
388
- children: /* @__PURE__ */ s(t, { name: "send" })
389
- })
390
- ]
391
- }),
392
- w.error && /* @__PURE__ */ s("div", {
393
- className: "err-text",
394
- style: { padding: "0 12px 8px" },
395
- children: r("chat.voice.micDenied")
396
- })
397
- ] }) : /* @__PURE__ */ c("div", {
398
- className: "transcript",
399
- style: { margin: 10 },
400
- children: [
401
- /* @__PURE__ */ s("div", {
402
- className: "small muted",
403
- style: { marginBottom: 4 },
404
- children: r("chat.voice.review")
405
734
  }),
406
- /* @__PURE__ */ s("textarea", {
407
- className: "inp",
408
- rows: 3,
409
- value: v,
410
- onChange: (e) => x(e.target.value),
411
- "aria-label": r("chat.voice.review")
412
- }),
413
- /* @__PURE__ */ c("div", {
414
- className: "row2",
415
- style: { marginTop: 8 },
416
- children: [/* @__PURE__ */ s("button", {
417
- className: "btn ghost sm",
418
- onClick: () => x(null),
419
- children: r("delete")
420
- }), /* @__PURE__ */ s("button", {
421
- className: "btn primary sm",
422
- disabled: !v.trim() || E,
423
- onClick: () => N(v, !0),
424
- children: r("chat.send")
425
- })]
735
+ B.error && /* @__PURE__ */ c("div", {
736
+ className: "err-text",
737
+ style: { padding: "0 12px 8px" },
738
+ children: r("chat.voice.micDenied")
426
739
  })
427
740
  ]
428
741
  })
@@ -431,145 +744,273 @@ function x(n) {
431
744
  }
432
745
  //#endregion
433
746
  //#region src/chat/ConversationList.tsx
434
- function S({ conversations: e, currentId: n, open: r, onPick: a, onClose: l, onCreate: d }) {
435
- let f = i(), [m, h] = p(!1);
436
- u(() => {
747
+ function k({ conversations: e, currentId: n, open: r, onPick: i, onClose: o, onCreate: u }) {
748
+ let f = a(), [p, h] = m(!1);
749
+ d(() => {
437
750
  if (!r) return;
438
- let e = (e) => e.key === "Escape" && l();
751
+ let e = (e) => e.key === "Escape" && o();
439
752
  return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
440
- }, [r, l]);
441
- let g = (e) => /* @__PURE__ */ c("button", {
753
+ }, [r, o]);
754
+ let g = (e) => /* @__PURE__ */ l("button", {
442
755
  className: `it${e.id === n ? " on" : ""}${e.group === "archive" ? " arch" : ""}`,
443
- onClick: () => a(e.id),
756
+ onClick: () => i(e.id),
444
757
  "aria-current": e.id === n,
445
758
  children: [
446
- /* @__PURE__ */ s(t, {
759
+ /* @__PURE__ */ c(t, {
447
760
  name: e.icon ?? "msg2",
448
761
  size: 16
449
762
  }),
450
- /* @__PURE__ */ s("span", {
763
+ /* @__PURE__ */ c("span", {
451
764
  className: "nm",
452
765
  children: e.title
453
766
  }),
454
- !!e.unread && /* @__PURE__ */ s("span", {
767
+ !!e.unread && /* @__PURE__ */ c("span", {
455
768
  className: "unread",
456
769
  "aria-label": f("chat.unread", { count: e.unread }),
457
770
  children: e.unread
458
771
  }),
459
- /* @__PURE__ */ s("span", {
772
+ /* @__PURE__ */ c("span", {
460
773
  className: "sub",
461
774
  children: e.when
462
775
  })
463
776
  ]
464
777
  }, e.id), _ = (t) => e.filter((e) => e.group === t), v = _("topic"), y = _("archive");
465
- return /* @__PURE__ */ c(o, { children: [
466
- /* @__PURE__ */ c("nav", {
778
+ return /* @__PURE__ */ l(s, { children: [
779
+ /* @__PURE__ */ l("nav", {
467
780
  className: `nb-side${r ? " open" : ""}`,
468
781
  "aria-label": f("chat.conversations"),
469
782
  children: [
470
- d && /* @__PURE__ */ c("button", {
783
+ u && /* @__PURE__ */ l("button", {
471
784
  className: "btn sm",
472
785
  style: {
473
786
  width: "100%",
474
787
  justifyContent: "center"
475
788
  },
476
789
  onClick: () => h(!0),
477
- children: [/* @__PURE__ */ s(t, {
790
+ children: [/* @__PURE__ */ c(t, {
478
791
  name: "plus",
479
792
  size: 15
480
793
  }), f("chat.newTopic")]
481
794
  }),
482
- /* @__PURE__ */ s("div", {
795
+ /* @__PURE__ */ c("div", {
483
796
  className: "h",
484
797
  children: f("chat.conversation")
485
798
  }),
486
799
  _("main").map(g),
487
- /* @__PURE__ */ s("div", {
800
+ /* @__PURE__ */ c("div", {
488
801
  className: "h",
489
802
  children: f("chat.topics")
490
803
  }),
491
- v.length === 0 && /* @__PURE__ */ s("div", {
804
+ v.length === 0 && /* @__PURE__ */ c("div", {
492
805
  className: "small muted",
493
806
  style: { padding: "0 10px" },
494
807
  children: f("chat.noTopics")
495
808
  }),
496
809
  v.map(g),
497
- y.length > 0 && /* @__PURE__ */ s("div", {
810
+ y.length > 0 && /* @__PURE__ */ c("div", {
498
811
  className: "h",
499
812
  children: f("chat.archive")
500
813
  }),
501
814
  y.map(g)
502
815
  ]
503
816
  }),
504
- r && /* @__PURE__ */ s("button", {
817
+ r && /* @__PURE__ */ c("button", {
505
818
  type: "button",
506
819
  className: "nb-scrim",
507
820
  "aria-label": f("close"),
508
- onClick: l
821
+ onClick: o
509
822
  }),
510
- m && d && /* @__PURE__ */ s(w, {
823
+ p && u && /* @__PURE__ */ c(j, {
511
824
  onClose: () => h(!1),
512
- onCreate: d
825
+ onCreate: u
513
826
  })
514
827
  ] });
515
828
  }
516
- function C({ narrow: e, children: t }) {
517
- return /* @__PURE__ */ s("div", {
829
+ function A({ narrow: e, children: t }) {
830
+ return /* @__PURE__ */ c("div", {
518
831
  className: `nb-app${e ? " narrow" : ""}`,
519
832
  children: t
520
833
  });
521
834
  }
522
- function w({ onClose: e, onCreate: t }) {
523
- let r = i(), [a, l] = p(""), [u, d] = p(!1), [f, m] = p(null), h = async () => {
524
- if (a.trim() && !u) {
525
- d(!0), m(null);
835
+ function j({ onClose: e, onCreate: t }) {
836
+ let r = a(), [i, o] = m(""), [u, d] = m(!1), [f, p] = m(null), h = async () => {
837
+ if (i.trim() && !u) {
838
+ d(!0), p(null);
526
839
  try {
527
- await t(a.trim()), e();
840
+ await t(i.trim()), e();
528
841
  } catch (e) {
529
- m(e instanceof Error ? e.message : String(e)), d(!1);
842
+ p(e instanceof Error ? e.message : String(e)), d(!1);
530
843
  }
531
844
  }
532
845
  };
533
- return /* @__PURE__ */ c(n, {
846
+ return /* @__PURE__ */ l(n, {
534
847
  title: r("chat.newTopic"),
535
848
  onClose: e,
536
- footer: /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("button", {
849
+ footer: /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("button", {
537
850
  className: "btn ghost",
538
851
  onClick: e,
539
852
  children: r("cancel")
540
- }), /* @__PURE__ */ s("button", {
853
+ }), /* @__PURE__ */ c("button", {
541
854
  className: "btn primary",
542
- disabled: !a.trim() || u,
855
+ disabled: !i.trim() || u,
543
856
  onClick: h,
544
857
  children: r("create")
545
858
  })] }),
546
- children: [/* @__PURE__ */ c("div", {
859
+ children: [/* @__PURE__ */ l("div", {
547
860
  className: "field",
548
861
  children: [
549
- /* @__PURE__ */ s("label", {
862
+ /* @__PURE__ */ c("label", {
550
863
  htmlFor: "topic-title",
551
864
  children: r("chat.topicTitle")
552
865
  }),
553
- /* @__PURE__ */ s("input", {
866
+ /* @__PURE__ */ c("input", {
554
867
  id: "topic-title",
555
868
  className: "inp",
556
- value: a,
869
+ value: i,
557
870
  maxLength: 120,
558
- onChange: (e) => l(e.target.value),
871
+ onChange: (e) => o(e.target.value),
559
872
  onKeyDown: (e) => e.key === "Enter" && h()
560
873
  }),
561
- /* @__PURE__ */ s("div", {
874
+ /* @__PURE__ */ c("div", {
562
875
  className: "hint",
563
876
  children: r("chat.topicHint")
564
877
  })
565
878
  ]
566
- }), f && /* @__PURE__ */ s("div", {
879
+ }), f && /* @__PURE__ */ c("div", {
567
880
  className: "err-text",
568
881
  children: f
569
882
  })]
570
883
  });
571
884
  }
572
885
  //#endregion
573
- export { x as Chat, C as ChatLayout, S as ConversationList, w as NewTopicModal, b as useRecorder };
886
+ //#region src/chat/AgentMenu.tsx
887
+ function M({ icon: e, label: n, title: r, expanded: i, small: a, disabled: o, onClick: s }) {
888
+ return /* @__PURE__ */ c("button", {
889
+ type: "button",
890
+ className: `agentbtn${a ? " s" : ""}`,
891
+ disabled: o,
892
+ "aria-label": n,
893
+ "aria-expanded": i,
894
+ title: r,
895
+ onMouseDown: (e) => i && e.stopPropagation(),
896
+ onClick: s,
897
+ children: /* @__PURE__ */ c(t, {
898
+ name: e,
899
+ size: a ? 15 : 18
900
+ })
901
+ });
902
+ }
903
+ function N({ label: e, name: n, options: r, value: o, optionsLabel: u, hint: d, narrow: f, models: p, onRename: h, onPick: g, onClose: _ }) {
904
+ let v = a(), [y, b] = m(n), x = i(!0, _);
905
+ return /* @__PURE__ */ l("div", {
906
+ className: `agentmenu${f ? " narrow" : ""}`,
907
+ ref: x,
908
+ role: "dialog",
909
+ "aria-label": e,
910
+ children: [
911
+ /* @__PURE__ */ c("div", {
912
+ className: "lab",
913
+ children: v("agentName")
914
+ }),
915
+ /* @__PURE__ */ c("input", {
916
+ className: "inp",
917
+ value: y,
918
+ maxLength: 40,
919
+ autoFocus: !0,
920
+ "aria-label": v("agentName"),
921
+ onChange: (e) => b(e.target.value),
922
+ onBlur: () => {
923
+ let e = y.trim();
924
+ e && e !== n && h(e);
925
+ },
926
+ onKeyDown: (e) => e.key === "Enter" && e.target.blur()
927
+ }),
928
+ /* @__PURE__ */ c("div", {
929
+ className: "lab",
930
+ style: { marginTop: 14 },
931
+ children: u
932
+ }),
933
+ /* @__PURE__ */ c("div", {
934
+ className: "agentoptions",
935
+ children: r.map((e) => /* @__PURE__ */ l("button", {
936
+ type: "button",
937
+ className: `agentoption${o === e.key ? " on" : ""}`,
938
+ "aria-pressed": o === e.key,
939
+ onClick: () => g(e.key),
940
+ children: [/* @__PURE__ */ c("span", {
941
+ className: "ic",
942
+ children: /* @__PURE__ */ c(t, {
943
+ name: e.icon,
944
+ size: 15
945
+ })
946
+ }), e.label]
947
+ }, e.key))
948
+ }),
949
+ p && /* @__PURE__ */ l(s, { children: [
950
+ /* @__PURE__ */ c("div", {
951
+ className: "lab",
952
+ style: { marginTop: 14 },
953
+ children: p.label
954
+ }),
955
+ p.options.length === 0 && /* @__PURE__ */ c("div", {
956
+ className: "hint",
957
+ children: p.empty
958
+ }),
959
+ /* @__PURE__ */ c("div", {
960
+ className: "agentmodels",
961
+ role: "radiogroup",
962
+ children: p.options.map((e) => {
963
+ let n = p.options.length === 1, r = n || p.value === e.key;
964
+ return /* @__PURE__ */ l("button", {
965
+ type: "button",
966
+ role: "radio",
967
+ "aria-checked": r,
968
+ disabled: n,
969
+ className: `agentmodel${r ? " on" : ""}`,
970
+ onClick: () => !r && p.onPick(e.key),
971
+ children: [!n && /* @__PURE__ */ c("span", {
972
+ className: `radio${r ? " on" : ""}`,
973
+ "aria-hidden": "true"
974
+ }), /* @__PURE__ */ l("span", {
975
+ className: "body",
976
+ children: [
977
+ /* @__PURE__ */ c("span", {
978
+ className: "nm",
979
+ children: e.label
980
+ }),
981
+ e.sub && /* @__PURE__ */ c("span", {
982
+ className: "sub",
983
+ children: e.sub
984
+ }),
985
+ e.badges && e.badges.length > 0 && /* @__PURE__ */ c("span", {
986
+ className: "badges",
987
+ children: e.badges.map((e) => /* @__PURE__ */ l("span", {
988
+ className: "cap",
989
+ children: [e.icon && /* @__PURE__ */ c(t, {
990
+ name: e.icon,
991
+ size: 11
992
+ }), e.text]
993
+ }, e.text))
994
+ }),
995
+ r && e.warn && /* @__PURE__ */ c("span", {
996
+ className: "warn",
997
+ children: e.warn
998
+ })
999
+ ]
1000
+ })]
1001
+ }, e.key);
1002
+ })
1003
+ })
1004
+ ] }),
1005
+ d && /* @__PURE__ */ c("div", {
1006
+ className: "hint",
1007
+ style: { marginTop: 10 },
1008
+ children: d
1009
+ })
1010
+ ]
1011
+ });
1012
+ }
1013
+ //#endregion
1014
+ export { M as AgentButton, N as AgentMenu, O as Chat, A as ChatLayout, _ as CommandPalette, y as ContextMeter, k as ConversationList, w as MessageView, j as NewTopicModal, v as tokens, E as useRecorder };
574
1015
 
575
1016
  //# sourceMappingURL=chat.js.map