@green-on-grey/ui-kit 1.6.0 → 1.8.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.
@@ -0,0 +1,57 @@
1
+ import type { ReactNode } from "react";
2
+ import type { TFunction } from "i18next";
3
+ import { type AgentModelOption, type AgentOption } from "./AgentMenu";
4
+ /** A model the agent can run on, as the service of the agent gives it
5
+ * (FTR.NAB.CHAT-0001 tech §2.2: `availableModels`, `model`, `defaultModel`). */
6
+ export interface AgentModel {
7
+ connectionId: string;
8
+ model: string;
9
+ name: string;
10
+ /** The connection the model comes through: grey under its name. */
11
+ connection: string;
12
+ caps: {
13
+ image: boolean;
14
+ reasoning: boolean;
15
+ contextWindow: number;
16
+ };
17
+ }
18
+ /** What the user chose; null — the default model. */
19
+ export type AgentModelChoice = Pick<AgentModel, "connectionId" | "model"> | null;
20
+ /** The models of the agent for the block «Model». */
21
+ export interface AgentModelState {
22
+ available: AgentModel[];
23
+ /** The model in use. */
24
+ model: AgentModel | null;
25
+ defaultModel: AgentModel | null;
26
+ /** The user chose the model; false — the default one. */
27
+ chosen: boolean;
28
+ /** The fill of the context of the main conversation, in tokens. */
29
+ contextTokens: number;
30
+ }
31
+ /** The key of a model of a connection in the menu. */
32
+ export declare const agentModelKey: (m: Pick<AgentModel, "connectionId" | "model">) => string;
33
+ /** The lines of the block «Model» (FTR.NAB.CHAT-0001 R16, R17, design §3.3): with a
34
+ * choice the first line is «Default» with the default model under it; a model
35
+ * whose window the context outgrows warns; one model is shown without a choice. */
36
+ export declare function agentModelOptions(t: TFunction, lng: string, s: AgentModelState): {
37
+ options: AgentModelOption[];
38
+ value: string;
39
+ };
40
+ /** The menu of the agent, the same in every product (FTR.NAB.CMN-0005 R15;
41
+ * FTR.HMR.SPEC-0001): the name, the options of the product as tiles in two
42
+ * columns, the model when the product gives `models`, and the hint. What the
43
+ * options mean only the product knows (R7): it passes them with their icons. The
44
+ * strings are the kit's; `hint` replaces the hint of the kit where the product
45
+ * saves the agent elsewhere. */
46
+ export declare function AgentSettingsMenu({ name, value, options, models, hint, onRename, onPick, onModel, onClose }: {
47
+ name: string;
48
+ value: string;
49
+ options: AgentOption[];
50
+ models?: AgentModelState;
51
+ hint?: ReactNode;
52
+ onRename: (name: string) => void;
53
+ onPick: (key: string) => void;
54
+ onModel?: (choice: AgentModelChoice) => void;
55
+ /** Must keep its identity between renders. */
56
+ onClose: () => void;
57
+ }): import("react").JSX.Element;
@@ -2,6 +2,7 @@ export { Chat, VoiceButton } from "./Chat";
2
2
  export { ChatLayout, ConversationList, NewTopicModal } from "./ConversationList";
3
3
  export { AttachmentList, AttachmentPreview, fileSize, parseTable, previewIcon, previewKind, type LoadAttachment, type PreviewKind } from "./Attachments";
4
4
  export { AgentButton, AgentMenu, type AgentModelOption, type AgentModels, type AgentOption } from "./AgentMenu";
5
+ export { AgentSettingsMenu, agentModelKey, agentModelOptions, type AgentModel, type AgentModelChoice, type AgentModelState, } from "./AgentSettingsMenu";
5
6
  export { CommandPalette } from "./CommandPalette";
6
7
  export { ContextMeter, tokens } from "./ContextMeter";
7
8
  export { MessageView } from "./MessageView";
package/dist/chat.js CHANGED
@@ -1,4 +1,4 @@
1
- import { c as e, d as t, i as n, l as r, s as i } from "./ui-DLi5afmc.js";
1
+ import { c as e, d as t, i as n, l as r, s as i } from "./ui-DvmjcG-d.js";
2
2
  import { n as a, t as o } from "./i18n-BJ8rsBp6.js";
3
3
  import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
4
4
  import { useCallback as u, useEffect as d, useLayoutEffect as f, useMemo as p, useRef as m, useState as h } from "react";
@@ -555,16 +555,16 @@ function te({ a: e, load: i, onClose: u }) {
555
555
  }
556
556
  //#endregion
557
557
  //#region src/chat/MessageView.tsx
558
- function G(e, t) {
558
+ function ne(e, t) {
559
559
  return new Intl.DateTimeFormat(y(t), {
560
560
  hour: "2-digit",
561
561
  minute: "2-digit"
562
562
  }).format(new Date(e));
563
563
  }
564
- function K(e, t) {
564
+ function re(e, t) {
565
565
  return t || e.length <= 3 ? e : e.slice(-2);
566
566
  }
567
- var q = {
567
+ var G = {
568
568
  done: {
569
569
  icon: "check",
570
570
  cls: "ok"
@@ -578,13 +578,13 @@ var q = {
578
578
  cls: "run"
579
579
  }
580
580
  };
581
- function ne({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u }) {
581
+ function ie({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u }) {
582
582
  let { t: d, i18n: f } = g(o), [p, m] = h(!1);
583
583
  if (e.role === "note") return /* @__PURE__ */ c("div", {
584
584
  className: "sysnote",
585
585
  children: e.text
586
586
  });
587
- if (e.role === "event" && e.event) return /* @__PURE__ */ c(J, { m: e });
587
+ if (e.role === "event" && e.event) return /* @__PURE__ */ c(K, { m: e });
588
588
  let _ = e.mark && /* @__PURE__ */ l("div", {
589
589
  className: "chan",
590
590
  children: [
@@ -595,7 +595,7 @@ function ne({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u
595
595
  " ",
596
596
  e.mark.text,
597
597
  " · ",
598
- G(e.createdAt, f.language)
598
+ ne(e.createdAt, f.language)
599
599
  ]
600
600
  }), v = e.attachments && e.attachments.length > 0 && /* @__PURE__ */ c(V, {
601
601
  items: e.attachments,
@@ -636,13 +636,13 @@ function ne({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u
636
636
  "aria-expanded": p,
637
637
  children: p ? d("chat.hideSteps") : d("chat.moreSteps", { count: y.length - 2 })
638
638
  }),
639
- K(y, p).map((e) => /* @__PURE__ */ l("div", {
639
+ re(y, p).map((e) => /* @__PURE__ */ l("div", {
640
640
  className: "tool",
641
641
  title: e.title,
642
642
  children: [/* @__PURE__ */ c(t, {
643
- name: q[e.status].icon,
643
+ name: G[e.status].icon,
644
644
  size: 14,
645
- className: q[e.status].cls
645
+ className: G[e.status].cls
646
646
  }), /* @__PURE__ */ c("span", {
647
647
  className: "tx",
648
648
  children: e.text
@@ -686,7 +686,7 @@ function ne({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u
686
686
  ]
687
687
  });
688
688
  }
689
- function J({ m: e }) {
689
+ function K({ m: e }) {
690
690
  let { t: n, i18n: r } = g(o), [i, a] = h(!1), s = e.event;
691
691
  return /* @__PURE__ */ l("div", {
692
692
  className: "evdiv",
@@ -702,7 +702,7 @@ function J({ m: e }) {
702
702
  }),
703
703
  s.text,
704
704
  " · ",
705
- G(e.createdAt, r.language),
705
+ ne(e.createdAt, r.language),
706
706
  s.details && /* @__PURE__ */ l("button", {
707
707
  type: "button",
708
708
  className: "textbtn",
@@ -724,20 +724,20 @@ function J({ m: e }) {
724
724
  }
725
725
  //#endregion
726
726
  //#region src/chat/transcription.ts
727
- async function re(e, t, n) {
727
+ async function ae(e, t, n) {
728
728
  n.busy(!0);
729
729
  let r;
730
730
  try {
731
731
  r = await t(e);
732
732
  } catch (r) {
733
- n.busy(!1), n.failed(r instanceof Error && r.message ? r.message : void 0, () => void re(e, t, n));
733
+ n.busy(!1), n.failed(r instanceof Error && r.message ? r.message : void 0, () => void ae(e, t, n));
734
734
  return;
735
735
  }
736
736
  n.busy(!1), r !== null && (r ? n.text(r) : n.empty());
737
737
  }
738
738
  //#endregion
739
739
  //#region src/chat/useRecorder.ts
740
- function ie(e = 300, t) {
740
+ function oe(e = 300, t) {
741
741
  let n = typeof window < "u" && "MediaRecorder" in window && !!navigator.mediaDevices?.getUserMedia, [r, i] = h(!1), [a, o] = h(0), [s, c] = h(0), [l, f] = h(!1), p = m(null), g = m([]), _ = m(void 0), v = m(null), y = m(null), b = m(!1), x = m(t);
742
742
  d(() => {
743
743
  x.current = t;
@@ -799,78 +799,78 @@ function ie(e = 300, t) {
799
799
  cancel: T
800
800
  };
801
801
  }
802
- function ae(e) {
802
+ function se(e) {
803
803
  return `${Math.floor(e / 60)}:${String(e % 60).padStart(2, "0")}`;
804
804
  }
805
805
  //#endregion
806
806
  //#region src/chat/Chat.tsx
807
- function Y(n) {
807
+ function q(n) {
808
808
  let r = a(), i = e(), [o, u] = h(""), [g, y] = h([]), [b, S] = h(!1), [C, w] = h(null), [T, E] = h(0), [D, O] = h(!1), [k, A] = h(null), [j, ee] = h(!1), [M, N] = h(null), P = m(n.loadAttachment);
809
809
  d(() => {
810
810
  P.current = n.loadAttachment;
811
811
  });
812
- let F = !!n.loadAttachment, I = p(() => F ? (e) => P.current ? P.current(e) : Promise.reject(/* @__PURE__ */ Error("no loader")) : void 0, [F]), L = m(!1), R = m(null), z = m(null), B = m(null), V = n.voiceMaxSeconds ?? 300, H = ie(V, () => void ve()), { messages: U, busy: W = !1 } = n, G = W || U.some((e) => e.status === "pending" || e.status === "streaming"), K = n.onPendingChange;
813
- d(() => K?.(g), [g, K]);
814
- let q = U[0]?.id, J = U[U.length - 1], Y = J?.id, ce = J?.text.length, de = J?.steps?.length, X = m({ height: 0 });
812
+ let F = !!n.loadAttachment, I = p(() => F ? (e) => P.current ? P.current(e) : Promise.reject(/* @__PURE__ */ Error("no loader")) : void 0, [F]), L = m(!1), R = m(null), z = m(null), B = m(null), V = n.voiceMaxSeconds ?? 300, H = oe(V, () => void ve()), { messages: U, busy: W = !1 } = n, ne = W || U.some((e) => e.status === "pending" || e.status === "streaming"), re = n.onPendingChange;
813
+ d(() => re?.(g), [g, re]);
814
+ let G = U[0]?.id, K = U[U.length - 1], q = K?.id, ue = K?.text.length, pe = K?.steps?.length, me = m({ height: 0 });
815
815
  f(() => {
816
816
  let e = R.current;
817
817
  if (!e) return;
818
- let t = X.current;
819
- e.scrollTop = t.first !== void 0 && q !== t.first && Y === t.last ? e.scrollTop + (e.scrollHeight - t.height) : e.scrollHeight, X.current = {
820
- first: q,
821
- last: Y,
818
+ let t = me.current;
819
+ e.scrollTop = t.first !== void 0 && G !== t.first && q === t.last ? e.scrollTop + (e.scrollHeight - t.height) : e.scrollHeight, me.current = {
820
+ first: G,
821
+ last: q,
822
822
  height: e.scrollHeight
823
823
  };
824
824
  }, [
825
825
  U.length,
826
+ G,
826
827
  q,
827
- Y,
828
- ce,
829
- de
828
+ ue,
829
+ pe
830
830
  ]);
831
- let Z = n.commands && !C && o.startsWith("/") && !/\s/.test(o) ? o.slice(1) : null, Q = Z === null ? [] : _(n.commands ?? [], Z), $ = Z !== null && !D, fe = () => {
831
+ let J = n.commands && !C && o.startsWith("/") && !/\s/.test(o) ? o.slice(1) : null, Y = J === null ? [] : _(n.commands ?? [], J), X = J !== null && !D, Z = () => {
832
832
  u(""), y([]), w(null), A(null), L.current = !1;
833
- }, pe = async (e, t) => {
833
+ }, Q = async (e, t) => {
834
834
  if (n.onCommand) try {
835
- await n.onCommand(e, t), fe();
835
+ await n.onCommand(e, t), Z();
836
836
  } catch {}
837
- }, me = async (e, t = !1) => {
837
+ }, $ = async (e, t = !1) => {
838
838
  let r = e.trim();
839
839
  if (!(!r && g.length === 0 && !C || W || n.readOnly)) {
840
840
  if (!t && !C && n.commands && r.startsWith("/")) {
841
841
  let [e, ...t] = r.slice(1).split(/\s+/), i = n.commands.find((t) => t.kind === "command" && t.name === e);
842
- if (i) return pe(i.name, t.join(" "));
842
+ if (i) return Q(i.name, t.join(" "));
843
843
  if (e && !r.includes("\n")) {
844
844
  A("/" + e);
845
845
  return;
846
846
  }
847
847
  }
848
848
  try {
849
- await n.onSend(r, g.map((e) => e.id), L.current, C ?? void 0), fe();
849
+ await n.onSend(r, g.map((e) => e.id), L.current, C ?? void 0), Z();
850
850
  } catch {}
851
851
  }
852
852
  }, he = (e) => {
853
- E(0), e.kind === "skill" ? (w(e.name), u("")) : e.takesText ? u("/" + e.name + " ") : pe(e.name, ""), B.current?.focus();
853
+ E(0), e.kind === "skill" ? (w(e.name), u("")) : e.takesText ? u("/" + e.name + " ") : Q(e.name, ""), B.current?.focus();
854
854
  }, ge = (e) => {
855
- if ($ && Q.length > 0) {
855
+ if (X && Y.length > 0) {
856
856
  if (e.key === "ArrowDown" || e.key === "ArrowUp") {
857
857
  e.preventDefault();
858
858
  let t = e.key === "ArrowDown" ? 1 : -1;
859
- E((e) => (e + t + Q.length) % Q.length);
859
+ E((e) => (e + t + Y.length) % Y.length);
860
860
  return;
861
861
  }
862
862
  if (e.key === "Enter" && !e.shiftKey || e.key === "Tab") {
863
- e.preventDefault(), he(Q[Math.min(T, Q.length - 1)]);
863
+ e.preventDefault(), he(Y[Math.min(T, Y.length - 1)]);
864
864
  return;
865
865
  }
866
866
  }
867
- $ && e.key === "Escape" ? (e.preventDefault(), O(!0)) : e.key === "Backspace" && C && o === "" ? w(null) : e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && !se() && (e.preventDefault(), me(o));
867
+ X && e.key === "Escape" ? (e.preventDefault(), O(!0)) : e.key === "Backspace" && C && o === "" ? w(null) : e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && !le() && (e.preventDefault(), $(o));
868
868
  };
869
- f(() => le(R.current, () => ue(B.current)), [o]), d(() => {
869
+ f(() => de(R.current, () => fe(B.current)), [o]), d(() => {
870
870
  let e = B.current;
871
871
  if (!e || typeof ResizeObserver > "u") return;
872
872
  let t = e.clientWidth, n = new ResizeObserver(() => {
873
- e.clientWidth !== t && (t = e.clientWidth, le(R.current, () => ue(e)));
873
+ e.clientWidth !== t && (t = e.clientWidth, de(R.current, () => fe(e)));
874
874
  });
875
875
  return n.observe(e), () => n.disconnect();
876
876
  }, [H.recording]);
@@ -894,7 +894,7 @@ function Y(n) {
894
894
  };
895
895
  async function ve() {
896
896
  let e = await H.stop();
897
- e && n.onTranscribe && await re(e, n.onTranscribe, {
897
+ e && n.onTranscribe && await ae(e, n.onTranscribe, {
898
898
  busy: ee,
899
899
  empty: () => i({
900
900
  kind: "error",
@@ -949,7 +949,7 @@ function Y(n) {
949
949
  n.emptyHint
950
950
  ]
951
951
  }),
952
- U.map((e) => /* @__PURE__ */ c(ne, {
952
+ U.map((e) => /* @__PURE__ */ c(ie, {
953
953
  m: e,
954
954
  busy: W,
955
955
  onRetry: n.onRetry && (() => n.onRetry?.(e.id)),
@@ -996,9 +996,9 @@ function Y(n) {
996
996
  }) : /* @__PURE__ */ l("div", {
997
997
  className: "composer-wrap",
998
998
  children: [
999
- $ && /* @__PURE__ */ c(v, {
1000
- items: Q,
1001
- active: Math.min(T, Math.max(Q.length - 1, 0)),
999
+ X && /* @__PURE__ */ c(v, {
1000
+ items: Y,
1001
+ active: Math.min(T, Math.max(Y.length - 1, 0)),
1002
1002
  onPick: he,
1003
1003
  onHover: E
1004
1004
  }),
@@ -1035,7 +1035,7 @@ function Y(n) {
1035
1035
  children: [r("chat.unknownCommand", { name: k }), /* @__PURE__ */ c("button", {
1036
1036
  type: "button",
1037
1037
  className: "textbtn",
1038
- onClick: () => void me(o, !0),
1038
+ onClick: () => void $(o, !0),
1039
1039
  children: r("chat.sendAsText")
1040
1040
  })]
1041
1041
  }),
@@ -1068,9 +1068,9 @@ function Y(n) {
1068
1068
  /* @__PURE__ */ l("span", {
1069
1069
  className: "tm",
1070
1070
  children: [
1071
- ae(H.seconds),
1071
+ se(H.seconds),
1072
1072
  " / ",
1073
- ae(V)
1073
+ se(V)
1074
1074
  ]
1075
1075
  }),
1076
1076
  /* @__PURE__ */ c("span", {
@@ -1124,7 +1124,7 @@ function Y(n) {
1124
1124
  placeholder: j ? r("chat.voice.recognizing") : be,
1125
1125
  "aria-label": be,
1126
1126
  disabled: j,
1127
- "aria-expanded": $,
1127
+ "aria-expanded": X,
1128
1128
  "aria-autocomplete": n.commands ? "list" : void 0,
1129
1129
  onChange: (e) => {
1130
1130
  u(e.target.value), O(!1), E(0), A(null);
@@ -1136,9 +1136,9 @@ function Y(n) {
1136
1136
  context: n.context,
1137
1137
  onCompact: n.onCompact,
1138
1138
  onReset: n.onReset,
1139
- busy: G
1139
+ busy: ne
1140
1140
  }),
1141
- n.onTranscribe && !H.recording && /* @__PURE__ */ c(oe, {
1141
+ n.onTranscribe && !H.recording && /* @__PURE__ */ c(ce, {
1142
1142
  supported: H.supported,
1143
1143
  recognizing: j,
1144
1144
  onStart: () => void H.start()
@@ -1152,7 +1152,7 @@ function Y(n) {
1152
1152
  className: "iconbtn fill",
1153
1153
  "aria-label": r("chat.send"),
1154
1154
  disabled: !o.trim() && g.length === 0 && !C || W || j,
1155
- onClick: () => me(o),
1155
+ onClick: () => $(o),
1156
1156
  children: /* @__PURE__ */ c(t, { name: "send" })
1157
1157
  }))
1158
1158
  ]
@@ -1172,7 +1172,7 @@ function Y(n) {
1172
1172
  ]
1173
1173
  });
1174
1174
  }
1175
- function oe({ supported: e, recognizing: n, onStart: r }) {
1175
+ function ce({ supported: e, recognizing: n, onStart: r }) {
1176
1176
  let i = a();
1177
1177
  return n ? /* @__PURE__ */ l("span", {
1178
1178
  className: "voicewait",
@@ -1195,15 +1195,15 @@ function oe({ supported: e, recognizing: n, onStart: r }) {
1195
1195
  children: /* @__PURE__ */ c(t, { name: "mic" })
1196
1196
  });
1197
1197
  }
1198
- function se() {
1198
+ function le() {
1199
1199
  return typeof window < "u" && !!window.matchMedia?.("(hover: none) and (pointer: coarse)").matches;
1200
1200
  }
1201
- var ce = (e) => e.scrollHeight - e.scrollTop - e.clientHeight < 2;
1202
- function le(e, t) {
1203
- let n = !!e && ce(e);
1201
+ var ue = (e) => e.scrollHeight - e.scrollTop - e.clientHeight < 2;
1202
+ function de(e, t) {
1203
+ let n = !!e && ue(e);
1204
1204
  t(), e && n && (e.scrollTop = e.scrollHeight);
1205
1205
  }
1206
- function ue(e) {
1206
+ function fe(e) {
1207
1207
  if (!e) return;
1208
1208
  e.style.overflowY = "hidden", e.style.height = "auto";
1209
1209
  let t = e.scrollHeight + e.offsetHeight - e.clientHeight;
@@ -1211,7 +1211,7 @@ function ue(e) {
1211
1211
  }
1212
1212
  //#endregion
1213
1213
  //#region src/chat/ConversationList.tsx
1214
- function de({ conversations: e, currentId: n, open: r, onPick: i, onClose: o, onCreate: u }) {
1214
+ function pe({ conversations: e, currentId: n, open: r, onPick: i, onClose: o, onCreate: u }) {
1215
1215
  let f = a(), [p, m] = h(!1);
1216
1216
  d(() => {
1217
1217
  if (!r) return;
@@ -1287,19 +1287,19 @@ function de({ conversations: e, currentId: n, open: r, onPick: i, onClose: o, on
1287
1287
  "aria-label": f("close"),
1288
1288
  onClick: o
1289
1289
  }),
1290
- p && u && /* @__PURE__ */ c(Z, {
1290
+ p && u && /* @__PURE__ */ c(J, {
1291
1291
  onClose: () => m(!1),
1292
1292
  onCreate: u
1293
1293
  })
1294
1294
  ] });
1295
1295
  }
1296
- function X({ narrow: e, children: t }) {
1296
+ function me({ narrow: e, children: t }) {
1297
1297
  return /* @__PURE__ */ c("div", {
1298
1298
  className: `nb-app${e ? " narrow" : ""}`,
1299
1299
  children: t
1300
1300
  });
1301
1301
  }
1302
- function Z({ onClose: e, onCreate: t }) {
1302
+ function J({ onClose: e, onCreate: t }) {
1303
1303
  let r = a(), [i, o] = h(""), [u, d] = h(!1), [f, p] = h(null), m = async () => {
1304
1304
  if (i.trim() && !u) {
1305
1305
  d(!0), p(null);
@@ -1351,7 +1351,7 @@ function Z({ onClose: e, onCreate: t }) {
1351
1351
  }
1352
1352
  //#endregion
1353
1353
  //#region src/chat/AgentMenu.tsx
1354
- function Q({ icon: e, label: n, title: r, expanded: i, small: a, disabled: o, onClick: s }) {
1354
+ function Y({ icon: e, label: n, title: r, expanded: i, small: a, disabled: o, onClick: s }) {
1355
1355
  return /* @__PURE__ */ c("button", {
1356
1356
  type: "button",
1357
1357
  className: `agentbtn${a ? " s" : ""}`,
@@ -1367,7 +1367,7 @@ function Q({ icon: e, label: n, title: r, expanded: i, small: a, disabled: o, on
1367
1367
  })
1368
1368
  });
1369
1369
  }
1370
- function $({ label: e, name: n, options: r, value: o, optionsLabel: u, hint: d, narrow: f, models: p, onRename: m, onPick: g, onClose: _ }) {
1370
+ function X({ label: e, name: n, options: r, value: o, optionsLabel: u, hint: d, narrow: f, models: p, onRename: m, onPick: g, onClose: _ }) {
1371
1371
  let v = a(), [y, b] = h(n), x = i(!0, _);
1372
1372
  return /* @__PURE__ */ l("div", {
1373
1373
  className: `agentmenu${f ? " narrow" : ""}`,
@@ -1478,6 +1478,66 @@ function $({ label: e, name: n, options: r, value: o, optionsLabel: u, hint: d,
1478
1478
  });
1479
1479
  }
1480
1480
  //#endregion
1481
- export { Q as AgentButton, $ as AgentMenu, V as AttachmentList, te as AttachmentPreview, Y as Chat, X as ChatLayout, v as CommandPalette, x as ContextMeter, de as ConversationList, ne as MessageView, Z as NewTopicModal, oe as VoiceButton, A as fileSize, L as parseTable, O as previewIcon, E as previewKind, b as tokens, ie as useRecorder };
1481
+ //#region src/chat/AgentSettingsMenu.tsx
1482
+ var Z = (e) => `${e.connectionId}/${e.model}`;
1483
+ function Q(e, t, n) {
1484
+ let r = (n) => [
1485
+ ...n.caps.image ? [{
1486
+ icon: "image",
1487
+ text: e("agent.capImage")
1488
+ }] : [],
1489
+ ...n.caps.reasoning ? [{
1490
+ icon: "brain",
1491
+ text: e("agent.capReasoning")
1492
+ }] : [],
1493
+ ...n.caps.contextWindow > 0 ? [{ text: b(n.caps.contextWindow, t) }] : []
1494
+ ], i = (t) => t.caps.contextWindow > 0 && n.contextTokens > .8 * t.caps.contextWindow ? e("agent.modelCompactWarn") : void 0, a = n.available.length > 1, o = n.available.map((e) => ({
1495
+ key: Z(e),
1496
+ label: e.name,
1497
+ sub: e.connection,
1498
+ badges: r(e),
1499
+ warn: a ? i(e) : void 0
1500
+ }));
1501
+ return {
1502
+ options: a ? [{
1503
+ key: "",
1504
+ label: e("agent.modelDefault"),
1505
+ sub: n.defaultModel?.name ?? "—",
1506
+ warn: n.defaultModel ? i(n.defaultModel) : void 0
1507
+ }, ...o] : o,
1508
+ value: n.chosen && n.model ? Z(n.model) : a ? "" : n.model ? Z(n.model) : ""
1509
+ };
1510
+ }
1511
+ function $({ name: e, value: t, options: n, models: r, hint: i, onRename: o, onPick: s, onModel: l, onClose: u }) {
1512
+ let d = a(), { i18n: f } = g(), p = r && l ? Q(d, f.language, r) : null;
1513
+ return /* @__PURE__ */ c(X, {
1514
+ label: d("agent.menu"),
1515
+ name: e,
1516
+ value: t,
1517
+ optionsLabel: d("agent.options"),
1518
+ hint: i ?? d("agent.everywhere"),
1519
+ options: n,
1520
+ models: p ? {
1521
+ label: d("agent.model"),
1522
+ options: p.options,
1523
+ value: p.value,
1524
+ onPick: (e) => {
1525
+ if (!r || !l) return;
1526
+ if (!e) return l(null);
1527
+ let t = r.available.find((t) => Z(t) === e);
1528
+ t && l({
1529
+ connectionId: t.connectionId,
1530
+ model: t.model
1531
+ });
1532
+ },
1533
+ empty: d("agent.noModels")
1534
+ } : void 0,
1535
+ onRename: o,
1536
+ onPick: s,
1537
+ onClose: u
1538
+ });
1539
+ }
1540
+ //#endregion
1541
+ export { Y as AgentButton, X as AgentMenu, $ as AgentSettingsMenu, V as AttachmentList, te as AttachmentPreview, q as Chat, me as ChatLayout, v as CommandPalette, x as ContextMeter, pe as ConversationList, ie as MessageView, J as NewTopicModal, ce as VoiceButton, Z as agentModelKey, Q as agentModelOptions, A as fileSize, L as parseTable, O as previewIcon, E as previewKind, b as tokens, oe as useRecorder };
1482
1542
 
1483
1543
  //# sourceMappingURL=chat.js.map