@green-on-grey/ui-kit 1.7.0 → 1.9.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/AgentSettingsMenu.d.ts +57 -0
- package/dist/chat/MessageView.d.ts +2 -0
- package/dist/chat/index.d.ts +2 -1
- package/dist/chat/types.d.ts +8 -0
- package/dist/chat.js +155 -69
- package/dist/chat.js.map +1 -1
- package/dist/locales/index.d.ts +75 -0
- package/dist/locales.js +75 -0
- package/dist/locales.js.map +1 -1
- package/dist/manifest.json +3 -1
- package/dist/styles.css +13 -0
- package/package.json +1 -1
|
@@ -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;
|
|
@@ -13,3 +13,5 @@ export declare function MessageView({ m, busy, onRetry, loadAttachment, onOpenAt
|
|
|
13
13
|
loadAttachment?: LoadAttachment;
|
|
14
14
|
onOpenAttachment?: (a: ChatAttachment) => void;
|
|
15
15
|
}): import("react").JSX.Element;
|
|
16
|
+
/** A notice longer than this many lines is folded (FTR.NAB.CHAT-0002 design §3.1). */
|
|
17
|
+
export declare const NOTICE_LINES = 12;
|
package/dist/chat/index.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ 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
|
-
export { MessageView } from "./MessageView";
|
|
8
|
+
export { MessageView, NOTICE_LINES } from "./MessageView";
|
|
8
9
|
export { useRecorder } from "./useRecorder";
|
|
9
10
|
export type { ChatAttachment, ChatCommand, ChatConfirmation, ChatContext, ChatConversation, ChatEvent, ChatMark, ChatMessage, ChatProps, ChatStep, ChatUpload, ChatWait, ConversationListProps, } from "./types";
|
package/dist/chat/types.d.ts
CHANGED
|
@@ -66,6 +66,9 @@ export interface ChatMessage {
|
|
|
66
66
|
};
|
|
67
67
|
/** The content of the product inside the message: a mail card, a digest. */
|
|
68
68
|
content?: ReactNode;
|
|
69
|
+
/** `notice`: an answer that is a notice of a product, not words of the agent (FTR.NAB.CHAT-0002 R2):
|
|
70
|
+
* a card with a stripe, without the actions of an answer, folded past `NOTICE_LINES` lines. */
|
|
71
|
+
variant?: "notice";
|
|
69
72
|
/** The tooltip of the bubble: the model of an answer (FTR.NAB.CHAT-0001 R18). */
|
|
70
73
|
hint?: string;
|
|
71
74
|
}
|
|
@@ -99,6 +102,11 @@ export interface ChatProps {
|
|
|
99
102
|
header?: ReactNode;
|
|
100
103
|
/** The second line of the empty conversation. */
|
|
101
104
|
emptyHint?: ReactNode;
|
|
105
|
+
/** Replaces the whole empty conversation: the draft of a topic with its suggestions
|
|
106
|
+
* (FTR.HMR.DISC-0001 design §3.2). `emptyHint` is then not used. */
|
|
107
|
+
empty?: ReactNode;
|
|
108
|
+
/** The placeholder of the composer instead of «Message to <agent>»; a picked skill keeps its own. */
|
|
109
|
+
placeholder?: string;
|
|
102
110
|
loading?: boolean;
|
|
103
111
|
historyError?: ReactNode;
|
|
104
112
|
hasOlder?: boolean;
|
package/dist/chat.js
CHANGED
|
@@ -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
|
|
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
|
|
564
|
+
function re(e, t) {
|
|
565
565
|
return t || e.length <= 3 ? e : e.slice(-2);
|
|
566
566
|
}
|
|
567
|
-
var
|
|
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
|
|
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(
|
|
587
|
+
if (e.role === "event" && e.event) return /* @__PURE__ */ c(ae, { 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
|
-
|
|
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,
|
|
@@ -625,6 +625,11 @@ function ne({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u
|
|
|
625
625
|
})
|
|
626
626
|
]
|
|
627
627
|
});
|
|
628
|
+
if (e.variant === "notice") return /* @__PURE__ */ c(q, {
|
|
629
|
+
m: e,
|
|
630
|
+
mark: _,
|
|
631
|
+
atts: v
|
|
632
|
+
});
|
|
628
633
|
let y = e.steps ?? [], b = (e.status === "streaming" || e.status === "pending") && !e.text && !e.content;
|
|
629
634
|
return /* @__PURE__ */ l("div", {
|
|
630
635
|
className: "m a",
|
|
@@ -636,13 +641,13 @@ function ne({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u
|
|
|
636
641
|
"aria-expanded": p,
|
|
637
642
|
children: p ? d("chat.hideSteps") : d("chat.moreSteps", { count: y.length - 2 })
|
|
638
643
|
}),
|
|
639
|
-
|
|
644
|
+
re(y, p).map((e) => /* @__PURE__ */ l("div", {
|
|
640
645
|
className: "tool",
|
|
641
646
|
title: e.title,
|
|
642
647
|
children: [/* @__PURE__ */ c(t, {
|
|
643
|
-
name:
|
|
648
|
+
name: G[e.status].icon,
|
|
644
649
|
size: 14,
|
|
645
|
-
className:
|
|
650
|
+
className: G[e.status].cls
|
|
646
651
|
}), /* @__PURE__ */ c("span", {
|
|
647
652
|
className: "tx",
|
|
648
653
|
children: e.text
|
|
@@ -686,7 +691,28 @@ function ne({ m: e, busy: n, onRetry: i, loadAttachment: a, onOpenAttachment: u
|
|
|
686
691
|
]
|
|
687
692
|
});
|
|
688
693
|
}
|
|
689
|
-
|
|
694
|
+
var K = 12;
|
|
695
|
+
function q({ m: e, mark: t, atts: n }) {
|
|
696
|
+
let { t: i } = g(o), [a, s] = h(!1), u = !e.content && e.text.split("\n").length > 12;
|
|
697
|
+
return /* @__PURE__ */ l("div", {
|
|
698
|
+
className: "m a notice",
|
|
699
|
+
children: [
|
|
700
|
+
t,
|
|
701
|
+
e.content ?? /* @__PURE__ */ l("div", {
|
|
702
|
+
className: `bub${u && !a ? " folded" : ""}`,
|
|
703
|
+
children: [/* @__PURE__ */ c(r, { text: e.text }), u && /* @__PURE__ */ c("button", {
|
|
704
|
+
type: "button",
|
|
705
|
+
className: "textbtn",
|
|
706
|
+
"aria-expanded": a,
|
|
707
|
+
onClick: () => s((e) => !e),
|
|
708
|
+
children: i(a ? "chat.notice.less" : "chat.notice.more")
|
|
709
|
+
})]
|
|
710
|
+
}),
|
|
711
|
+
n
|
|
712
|
+
]
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
function ae({ m: e }) {
|
|
690
716
|
let { t: n, i18n: r } = g(o), [i, a] = h(!1), s = e.event;
|
|
691
717
|
return /* @__PURE__ */ l("div", {
|
|
692
718
|
className: "evdiv",
|
|
@@ -702,7 +728,7 @@ function J({ m: e }) {
|
|
|
702
728
|
}),
|
|
703
729
|
s.text,
|
|
704
730
|
" · ",
|
|
705
|
-
|
|
731
|
+
ne(e.createdAt, r.language),
|
|
706
732
|
s.details && /* @__PURE__ */ l("button", {
|
|
707
733
|
type: "button",
|
|
708
734
|
className: "textbtn",
|
|
@@ -724,20 +750,20 @@ function J({ m: e }) {
|
|
|
724
750
|
}
|
|
725
751
|
//#endregion
|
|
726
752
|
//#region src/chat/transcription.ts
|
|
727
|
-
async function
|
|
753
|
+
async function oe(e, t, n) {
|
|
728
754
|
n.busy(!0);
|
|
729
755
|
let r;
|
|
730
756
|
try {
|
|
731
757
|
r = await t(e);
|
|
732
758
|
} catch (r) {
|
|
733
|
-
n.busy(!1), n.failed(r instanceof Error && r.message ? r.message : void 0, () => void
|
|
759
|
+
n.busy(!1), n.failed(r instanceof Error && r.message ? r.message : void 0, () => void oe(e, t, n));
|
|
734
760
|
return;
|
|
735
761
|
}
|
|
736
762
|
n.busy(!1), r !== null && (r ? n.text(r) : n.empty());
|
|
737
763
|
}
|
|
738
764
|
//#endregion
|
|
739
765
|
//#region src/chat/useRecorder.ts
|
|
740
|
-
function
|
|
766
|
+
function se(e = 300, t) {
|
|
741
767
|
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
768
|
d(() => {
|
|
743
769
|
x.current = t;
|
|
@@ -799,78 +825,78 @@ function ie(e = 300, t) {
|
|
|
799
825
|
cancel: T
|
|
800
826
|
};
|
|
801
827
|
}
|
|
802
|
-
function
|
|
828
|
+
function ce(e) {
|
|
803
829
|
return `${Math.floor(e / 60)}:${String(e % 60).padStart(2, "0")}`;
|
|
804
830
|
}
|
|
805
831
|
//#endregion
|
|
806
832
|
//#region src/chat/Chat.tsx
|
|
807
|
-
function
|
|
833
|
+
function le(n) {
|
|
808
834
|
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
835
|
d(() => {
|
|
810
836
|
P.current = n.loadAttachment;
|
|
811
837
|
});
|
|
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 =
|
|
813
|
-
d(() =>
|
|
814
|
-
let
|
|
838
|
+
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 = se(V, () => void ve()), { messages: U, busy: W = !1 } = n, ne = W || U.some((e) => e.status === "pending" || e.status === "streaming"), re = n.onPendingChange;
|
|
839
|
+
d(() => re?.(g), [g, re]);
|
|
840
|
+
let G = U[0]?.id, K = U[U.length - 1], q = K?.id, ae = K?.text.length, le = K?.steps?.length, fe = m({ height: 0 });
|
|
815
841
|
f(() => {
|
|
816
842
|
let e = R.current;
|
|
817
843
|
if (!e) return;
|
|
818
|
-
let t =
|
|
819
|
-
e.scrollTop = t.first !== void 0 &&
|
|
820
|
-
first:
|
|
821
|
-
last:
|
|
844
|
+
let t = fe.current;
|
|
845
|
+
e.scrollTop = t.first !== void 0 && G !== t.first && q === t.last ? e.scrollTop + (e.scrollHeight - t.height) : e.scrollHeight, fe.current = {
|
|
846
|
+
first: G,
|
|
847
|
+
last: q,
|
|
822
848
|
height: e.scrollHeight
|
|
823
849
|
};
|
|
824
850
|
}, [
|
|
825
851
|
U.length,
|
|
852
|
+
G,
|
|
826
853
|
q,
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
de
|
|
854
|
+
ae,
|
|
855
|
+
le
|
|
830
856
|
]);
|
|
831
|
-
let
|
|
857
|
+
let J = n.commands && !C && o.startsWith("/") && !/\s/.test(o) ? o.slice(1) : null, Y = J === null ? [] : _(n.commands ?? [], J), X = J !== null && !D, he = () => {
|
|
832
858
|
u(""), y([]), w(null), A(null), L.current = !1;
|
|
833
|
-
},
|
|
859
|
+
}, Z = async (e, t) => {
|
|
834
860
|
if (n.onCommand) try {
|
|
835
|
-
await n.onCommand(e, t),
|
|
861
|
+
await n.onCommand(e, t), he();
|
|
836
862
|
} catch {}
|
|
837
|
-
},
|
|
863
|
+
}, Q = async (e, t = !1) => {
|
|
838
864
|
let r = e.trim();
|
|
839
865
|
if (!(!r && g.length === 0 && !C || W || n.readOnly)) {
|
|
840
866
|
if (!t && !C && n.commands && r.startsWith("/")) {
|
|
841
867
|
let [e, ...t] = r.slice(1).split(/\s+/), i = n.commands.find((t) => t.kind === "command" && t.name === e);
|
|
842
|
-
if (i) return
|
|
868
|
+
if (i) return Z(i.name, t.join(" "));
|
|
843
869
|
if (e && !r.includes("\n")) {
|
|
844
870
|
A("/" + e);
|
|
845
871
|
return;
|
|
846
872
|
}
|
|
847
873
|
}
|
|
848
874
|
try {
|
|
849
|
-
await n.onSend(r, g.map((e) => e.id), L.current, C ?? void 0),
|
|
875
|
+
await n.onSend(r, g.map((e) => e.id), L.current, C ?? void 0), he();
|
|
850
876
|
} catch {}
|
|
851
877
|
}
|
|
852
|
-
},
|
|
853
|
-
E(0), e.kind === "skill" ? (w(e.name), u("")) : e.takesText ? u("/" + e.name + " ") :
|
|
878
|
+
}, $ = (e) => {
|
|
879
|
+
E(0), e.kind === "skill" ? (w(e.name), u("")) : e.takesText ? u("/" + e.name + " ") : Z(e.name, ""), B.current?.focus();
|
|
854
880
|
}, ge = (e) => {
|
|
855
|
-
if (
|
|
881
|
+
if (X && Y.length > 0) {
|
|
856
882
|
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
857
883
|
e.preventDefault();
|
|
858
884
|
let t = e.key === "ArrowDown" ? 1 : -1;
|
|
859
|
-
E((e) => (e + t +
|
|
885
|
+
E((e) => (e + t + Y.length) % Y.length);
|
|
860
886
|
return;
|
|
861
887
|
}
|
|
862
888
|
if (e.key === "Enter" && !e.shiftKey || e.key === "Tab") {
|
|
863
|
-
e.preventDefault(),
|
|
889
|
+
e.preventDefault(), $(Y[Math.min(T, Y.length - 1)]);
|
|
864
890
|
return;
|
|
865
891
|
}
|
|
866
892
|
}
|
|
867
|
-
|
|
893
|
+
X && e.key === "Escape" ? (e.preventDefault(), O(!0)) : e.key === "Backspace" && C && o === "" ? w(null) : e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && !de() && (e.preventDefault(), Q(o));
|
|
868
894
|
};
|
|
869
|
-
f(() =>
|
|
895
|
+
f(() => pe(R.current, () => me(B.current)), [o]), d(() => {
|
|
870
896
|
let e = B.current;
|
|
871
897
|
if (!e || typeof ResizeObserver > "u") return;
|
|
872
898
|
let t = e.clientWidth, n = new ResizeObserver(() => {
|
|
873
|
-
e.clientWidth !== t && (t = e.clientWidth,
|
|
899
|
+
e.clientWidth !== t && (t = e.clientWidth, pe(R.current, () => me(e)));
|
|
874
900
|
});
|
|
875
901
|
return n.observe(e), () => n.disconnect();
|
|
876
902
|
}, [H.recording]);
|
|
@@ -894,7 +920,7 @@ function Y(n) {
|
|
|
894
920
|
};
|
|
895
921
|
async function ve() {
|
|
896
922
|
let e = await H.stop();
|
|
897
|
-
e && n.onTranscribe && await
|
|
923
|
+
e && n.onTranscribe && await oe(e, n.onTranscribe, {
|
|
898
924
|
busy: ee,
|
|
899
925
|
empty: () => i({
|
|
900
926
|
kind: "error",
|
|
@@ -916,7 +942,7 @@ function Y(n) {
|
|
|
916
942
|
}
|
|
917
943
|
let ye = (e) => {
|
|
918
944
|
e.key === "Escape" && H.recording && (e.preventDefault(), H.cancel());
|
|
919
|
-
}, be = C ? r("chat.skillPlaceholder") : r("chat.placeholder", { name: n.agentName }), xe = V - H.seconds;
|
|
945
|
+
}, be = C ? r("chat.skillPlaceholder") : n.placeholder ?? r("chat.placeholder", { name: n.agentName }), xe = V - H.seconds;
|
|
920
946
|
return /* @__PURE__ */ l("section", {
|
|
921
947
|
className: "nb-chat",
|
|
922
948
|
"aria-label": r("chat.title"),
|
|
@@ -938,7 +964,7 @@ function Y(n) {
|
|
|
938
964
|
className: "err-text",
|
|
939
965
|
children: n.historyError
|
|
940
966
|
}),
|
|
941
|
-
U.length === 0 && !n.loading && !n.historyError && /* @__PURE__ */ l("div", {
|
|
967
|
+
U.length === 0 && !n.loading && !n.historyError && (n.empty ?? /* @__PURE__ */ l("div", {
|
|
942
968
|
className: "empty",
|
|
943
969
|
children: [
|
|
944
970
|
/* @__PURE__ */ c("div", {
|
|
@@ -948,8 +974,8 @@ function Y(n) {
|
|
|
948
974
|
/* @__PURE__ */ c("b", { children: r("chat.emptyTitle", { name: n.agentName }) }),
|
|
949
975
|
n.emptyHint
|
|
950
976
|
]
|
|
951
|
-
}),
|
|
952
|
-
U.map((e) => /* @__PURE__ */ c(
|
|
977
|
+
})),
|
|
978
|
+
U.map((e) => /* @__PURE__ */ c(ie, {
|
|
953
979
|
m: e,
|
|
954
980
|
busy: W,
|
|
955
981
|
onRetry: n.onRetry && (() => n.onRetry?.(e.id)),
|
|
@@ -996,10 +1022,10 @@ function Y(n) {
|
|
|
996
1022
|
}) : /* @__PURE__ */ l("div", {
|
|
997
1023
|
className: "composer-wrap",
|
|
998
1024
|
children: [
|
|
999
|
-
|
|
1000
|
-
items:
|
|
1001
|
-
active: Math.min(T, Math.max(
|
|
1002
|
-
onPick:
|
|
1025
|
+
X && /* @__PURE__ */ c(v, {
|
|
1026
|
+
items: Y,
|
|
1027
|
+
active: Math.min(T, Math.max(Y.length - 1, 0)),
|
|
1028
|
+
onPick: $,
|
|
1003
1029
|
onHover: E
|
|
1004
1030
|
}),
|
|
1005
1031
|
n.aboveComposer,
|
|
@@ -1035,7 +1061,7 @@ function Y(n) {
|
|
|
1035
1061
|
children: [r("chat.unknownCommand", { name: k }), /* @__PURE__ */ c("button", {
|
|
1036
1062
|
type: "button",
|
|
1037
1063
|
className: "textbtn",
|
|
1038
|
-
onClick: () => void
|
|
1064
|
+
onClick: () => void Q(o, !0),
|
|
1039
1065
|
children: r("chat.sendAsText")
|
|
1040
1066
|
})]
|
|
1041
1067
|
}),
|
|
@@ -1068,9 +1094,9 @@ function Y(n) {
|
|
|
1068
1094
|
/* @__PURE__ */ l("span", {
|
|
1069
1095
|
className: "tm",
|
|
1070
1096
|
children: [
|
|
1071
|
-
|
|
1097
|
+
ce(H.seconds),
|
|
1072
1098
|
" / ",
|
|
1073
|
-
|
|
1099
|
+
ce(V)
|
|
1074
1100
|
]
|
|
1075
1101
|
}),
|
|
1076
1102
|
/* @__PURE__ */ c("span", {
|
|
@@ -1124,7 +1150,7 @@ function Y(n) {
|
|
|
1124
1150
|
placeholder: j ? r("chat.voice.recognizing") : be,
|
|
1125
1151
|
"aria-label": be,
|
|
1126
1152
|
disabled: j,
|
|
1127
|
-
"aria-expanded":
|
|
1153
|
+
"aria-expanded": X,
|
|
1128
1154
|
"aria-autocomplete": n.commands ? "list" : void 0,
|
|
1129
1155
|
onChange: (e) => {
|
|
1130
1156
|
u(e.target.value), O(!1), E(0), A(null);
|
|
@@ -1136,9 +1162,9 @@ function Y(n) {
|
|
|
1136
1162
|
context: n.context,
|
|
1137
1163
|
onCompact: n.onCompact,
|
|
1138
1164
|
onReset: n.onReset,
|
|
1139
|
-
busy:
|
|
1165
|
+
busy: ne
|
|
1140
1166
|
}),
|
|
1141
|
-
n.onTranscribe && !H.recording && /* @__PURE__ */ c(
|
|
1167
|
+
n.onTranscribe && !H.recording && /* @__PURE__ */ c(ue, {
|
|
1142
1168
|
supported: H.supported,
|
|
1143
1169
|
recognizing: j,
|
|
1144
1170
|
onStart: () => void H.start()
|
|
@@ -1152,7 +1178,7 @@ function Y(n) {
|
|
|
1152
1178
|
className: "iconbtn fill",
|
|
1153
1179
|
"aria-label": r("chat.send"),
|
|
1154
1180
|
disabled: !o.trim() && g.length === 0 && !C || W || j,
|
|
1155
|
-
onClick: () =>
|
|
1181
|
+
onClick: () => Q(o),
|
|
1156
1182
|
children: /* @__PURE__ */ c(t, { name: "send" })
|
|
1157
1183
|
}))
|
|
1158
1184
|
]
|
|
@@ -1172,7 +1198,7 @@ function Y(n) {
|
|
|
1172
1198
|
]
|
|
1173
1199
|
});
|
|
1174
1200
|
}
|
|
1175
|
-
function
|
|
1201
|
+
function ue({ supported: e, recognizing: n, onStart: r }) {
|
|
1176
1202
|
let i = a();
|
|
1177
1203
|
return n ? /* @__PURE__ */ l("span", {
|
|
1178
1204
|
className: "voicewait",
|
|
@@ -1195,15 +1221,15 @@ function oe({ supported: e, recognizing: n, onStart: r }) {
|
|
|
1195
1221
|
children: /* @__PURE__ */ c(t, { name: "mic" })
|
|
1196
1222
|
});
|
|
1197
1223
|
}
|
|
1198
|
-
function
|
|
1224
|
+
function de() {
|
|
1199
1225
|
return typeof window < "u" && !!window.matchMedia?.("(hover: none) and (pointer: coarse)").matches;
|
|
1200
1226
|
}
|
|
1201
|
-
var
|
|
1202
|
-
function
|
|
1203
|
-
let n = !!e &&
|
|
1227
|
+
var fe = (e) => e.scrollHeight - e.scrollTop - e.clientHeight < 2;
|
|
1228
|
+
function pe(e, t) {
|
|
1229
|
+
let n = !!e && fe(e);
|
|
1204
1230
|
t(), e && n && (e.scrollTop = e.scrollHeight);
|
|
1205
1231
|
}
|
|
1206
|
-
function
|
|
1232
|
+
function me(e) {
|
|
1207
1233
|
if (!e) return;
|
|
1208
1234
|
e.style.overflowY = "hidden", e.style.height = "auto";
|
|
1209
1235
|
let t = e.scrollHeight + e.offsetHeight - e.clientHeight;
|
|
@@ -1211,7 +1237,7 @@ function ue(e) {
|
|
|
1211
1237
|
}
|
|
1212
1238
|
//#endregion
|
|
1213
1239
|
//#region src/chat/ConversationList.tsx
|
|
1214
|
-
function
|
|
1240
|
+
function J({ conversations: e, currentId: n, open: r, onPick: i, onClose: o, onCreate: u }) {
|
|
1215
1241
|
let f = a(), [p, m] = h(!1);
|
|
1216
1242
|
d(() => {
|
|
1217
1243
|
if (!r) return;
|
|
@@ -1287,19 +1313,19 @@ function de({ conversations: e, currentId: n, open: r, onPick: i, onClose: o, on
|
|
|
1287
1313
|
"aria-label": f("close"),
|
|
1288
1314
|
onClick: o
|
|
1289
1315
|
}),
|
|
1290
|
-
p && u && /* @__PURE__ */ c(
|
|
1316
|
+
p && u && /* @__PURE__ */ c(X, {
|
|
1291
1317
|
onClose: () => m(!1),
|
|
1292
1318
|
onCreate: u
|
|
1293
1319
|
})
|
|
1294
1320
|
] });
|
|
1295
1321
|
}
|
|
1296
|
-
function
|
|
1322
|
+
function Y({ narrow: e, children: t }) {
|
|
1297
1323
|
return /* @__PURE__ */ c("div", {
|
|
1298
1324
|
className: `nb-app${e ? " narrow" : ""}`,
|
|
1299
1325
|
children: t
|
|
1300
1326
|
});
|
|
1301
1327
|
}
|
|
1302
|
-
function
|
|
1328
|
+
function X({ onClose: e, onCreate: t }) {
|
|
1303
1329
|
let r = a(), [i, o] = h(""), [u, d] = h(!1), [f, p] = h(null), m = async () => {
|
|
1304
1330
|
if (i.trim() && !u) {
|
|
1305
1331
|
d(!0), p(null);
|
|
@@ -1351,7 +1377,7 @@ function Z({ onClose: e, onCreate: t }) {
|
|
|
1351
1377
|
}
|
|
1352
1378
|
//#endregion
|
|
1353
1379
|
//#region src/chat/AgentMenu.tsx
|
|
1354
|
-
function
|
|
1380
|
+
function he({ icon: e, label: n, title: r, expanded: i, small: a, disabled: o, onClick: s }) {
|
|
1355
1381
|
return /* @__PURE__ */ c("button", {
|
|
1356
1382
|
type: "button",
|
|
1357
1383
|
className: `agentbtn${a ? " s" : ""}`,
|
|
@@ -1367,7 +1393,7 @@ function Q({ icon: e, label: n, title: r, expanded: i, small: a, disabled: o, on
|
|
|
1367
1393
|
})
|
|
1368
1394
|
});
|
|
1369
1395
|
}
|
|
1370
|
-
function
|
|
1396
|
+
function Z({ label: e, name: n, options: r, value: o, optionsLabel: u, hint: d, narrow: f, models: p, onRename: m, onPick: g, onClose: _ }) {
|
|
1371
1397
|
let v = a(), [y, b] = h(n), x = i(!0, _);
|
|
1372
1398
|
return /* @__PURE__ */ l("div", {
|
|
1373
1399
|
className: `agentmenu${f ? " narrow" : ""}`,
|
|
@@ -1478,6 +1504,66 @@ function $({ label: e, name: n, options: r, value: o, optionsLabel: u, hint: d,
|
|
|
1478
1504
|
});
|
|
1479
1505
|
}
|
|
1480
1506
|
//#endregion
|
|
1481
|
-
|
|
1507
|
+
//#region src/chat/AgentSettingsMenu.tsx
|
|
1508
|
+
var Q = (e) => `${e.connectionId}/${e.model}`;
|
|
1509
|
+
function $(e, t, n) {
|
|
1510
|
+
let r = (n) => [
|
|
1511
|
+
...n.caps.image ? [{
|
|
1512
|
+
icon: "image",
|
|
1513
|
+
text: e("agent.capImage")
|
|
1514
|
+
}] : [],
|
|
1515
|
+
...n.caps.reasoning ? [{
|
|
1516
|
+
icon: "brain",
|
|
1517
|
+
text: e("agent.capReasoning")
|
|
1518
|
+
}] : [],
|
|
1519
|
+
...n.caps.contextWindow > 0 ? [{ text: b(n.caps.contextWindow, t) }] : []
|
|
1520
|
+
], 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) => ({
|
|
1521
|
+
key: Q(e),
|
|
1522
|
+
label: e.name,
|
|
1523
|
+
sub: e.connection,
|
|
1524
|
+
badges: r(e),
|
|
1525
|
+
warn: a ? i(e) : void 0
|
|
1526
|
+
}));
|
|
1527
|
+
return {
|
|
1528
|
+
options: a ? [{
|
|
1529
|
+
key: "",
|
|
1530
|
+
label: e("agent.modelDefault"),
|
|
1531
|
+
sub: n.defaultModel?.name ?? "—",
|
|
1532
|
+
warn: n.defaultModel ? i(n.defaultModel) : void 0
|
|
1533
|
+
}, ...o] : o,
|
|
1534
|
+
value: n.chosen && n.model ? Q(n.model) : a ? "" : n.model ? Q(n.model) : ""
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
function ge({ name: e, value: t, options: n, models: r, hint: i, onRename: o, onPick: s, onModel: l, onClose: u }) {
|
|
1538
|
+
let d = a(), { i18n: f } = g(), p = r && l ? $(d, f.language, r) : null;
|
|
1539
|
+
return /* @__PURE__ */ c(Z, {
|
|
1540
|
+
label: d("agent.menu"),
|
|
1541
|
+
name: e,
|
|
1542
|
+
value: t,
|
|
1543
|
+
optionsLabel: d("agent.options"),
|
|
1544
|
+
hint: i ?? d("agent.everywhere"),
|
|
1545
|
+
options: n,
|
|
1546
|
+
models: p ? {
|
|
1547
|
+
label: d("agent.model"),
|
|
1548
|
+
options: p.options,
|
|
1549
|
+
value: p.value,
|
|
1550
|
+
onPick: (e) => {
|
|
1551
|
+
if (!r || !l) return;
|
|
1552
|
+
if (!e) return l(null);
|
|
1553
|
+
let t = r.available.find((t) => Q(t) === e);
|
|
1554
|
+
t && l({
|
|
1555
|
+
connectionId: t.connectionId,
|
|
1556
|
+
model: t.model
|
|
1557
|
+
});
|
|
1558
|
+
},
|
|
1559
|
+
empty: d("agent.noModels")
|
|
1560
|
+
} : void 0,
|
|
1561
|
+
onRename: o,
|
|
1562
|
+
onPick: s,
|
|
1563
|
+
onClose: u
|
|
1564
|
+
});
|
|
1565
|
+
}
|
|
1566
|
+
//#endregion
|
|
1567
|
+
export { he as AgentButton, Z as AgentMenu, ge as AgentSettingsMenu, V as AttachmentList, te as AttachmentPreview, le as Chat, Y as ChatLayout, v as CommandPalette, x as ContextMeter, J as ConversationList, ie as MessageView, K as NOTICE_LINES, X as NewTopicModal, ue as VoiceButton, Q as agentModelKey, $ as agentModelOptions, A as fileSize, L as parseTable, O as previewIcon, E as previewKind, b as tokens, se as useRecorder };
|
|
1482
1568
|
|
|
1483
1569
|
//# sourceMappingURL=chat.js.map
|