@agno-hq/chat-react 0.3.0 → 0.3.1
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/README.md +83 -1
- package/dist/chat/index.cjs +98 -78
- package/dist/chat/index.d.cts +222 -112
- package/dist/chat/index.d.ts +222 -112
- package/dist/chat/index.js +2 -2
- package/dist/{chunk-ROFIOWGX.cjs → chunk-55HQJGLP.cjs} +2 -5
- package/dist/chunk-55HQJGLP.cjs.map +1 -0
- package/dist/{chunk-62IEW2HM.js → chunk-6V2YIPHF.js} +2 -5
- package/dist/chunk-6V2YIPHF.js.map +1 -0
- package/dist/{chunk-MUOMZG4V.js → chunk-BZC2674Z.js} +405 -130
- package/dist/chunk-BZC2674Z.js.map +1 -0
- package/dist/{chunk-ERCKKOF4.cjs → chunk-JEPFGKHH.cjs} +444 -164
- package/dist/chunk-JEPFGKHH.cjs.map +1 -0
- package/dist/core/index.cjs +19 -19
- package/dist/core/index.js +1 -1
- package/dist/index.cjs +117 -97
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/styles.css +272 -65
- package/package.json +1 -1
- package/dist/chunk-62IEW2HM.js.map +0 -1
- package/dist/chunk-ERCKKOF4.cjs.map +0 -1
- package/dist/chunk-MUOMZG4V.js.map +0 -1
- package/dist/chunk-ROFIOWGX.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk55HQJGLP_cjs = require('./chunk-55HQJGLP.cjs');
|
|
4
4
|
var React7 = require('react');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
@@ -18,7 +18,7 @@ function useAgnoChat(options) {
|
|
|
18
18
|
const { entity, userId, onEvent, onSessionId } = options;
|
|
19
19
|
const client = React7.useMemo(() => {
|
|
20
20
|
if (options.client) return options.client;
|
|
21
|
-
return new
|
|
21
|
+
return new chunk55HQJGLP_cjs.AgnoClient({ baseUrl: options.baseUrl ?? "", headers: options.headers });
|
|
22
22
|
}, [options.client, options.baseUrl, JSON.stringify(options.headers)]);
|
|
23
23
|
const [messages, setMessages] = React7.useState(options.initialMessages ?? []);
|
|
24
24
|
const [events, setEvents] = React7.useState([]);
|
|
@@ -106,7 +106,7 @@ function useAgnoChat(options) {
|
|
|
106
106
|
writeEvents(chan, e);
|
|
107
107
|
patchActive(chan, (m) => ({ ...m, events: [...m.events ?? [], e] }));
|
|
108
108
|
onEvent?.(e);
|
|
109
|
-
const label2 =
|
|
109
|
+
const label2 = chunk55HQJGLP_cjs.activityLabel(e);
|
|
110
110
|
if (label2) writeActivity(chan, label2);
|
|
111
111
|
if (e.session_id && !chan?.park && e.session_id !== sessionIdRef.current) {
|
|
112
112
|
sessionIdRef.current = e.session_id;
|
|
@@ -123,16 +123,16 @@ function useAgnoChat(options) {
|
|
|
123
123
|
if (chan?.park) chan.park.runId = e.run_id;
|
|
124
124
|
else runIdRef.current = e.run_id;
|
|
125
125
|
}
|
|
126
|
-
if (
|
|
126
|
+
if (chunk55HQJGLP_cjs.isSubRunEvent(e)) {
|
|
127
127
|
const kind = entityRef.current?.type === "workflow" ? "executor" : "member";
|
|
128
|
-
patchActive(chan, (m) =>
|
|
128
|
+
patchActive(chan, (m) => chunk55HQJGLP_cjs.applySubRunEvent(m, e, kind));
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
|
-
if (
|
|
132
|
-
patchActive(chan, (m) =>
|
|
131
|
+
if (chunk55HQJGLP_cjs.isStepEvent(e)) {
|
|
132
|
+
patchActive(chan, (m) => chunk55HQJGLP_cjs.applyStepEvent(m, e));
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
|
-
if (
|
|
135
|
+
if (chunk55HQJGLP_cjs.isStartedEvent(e)) {
|
|
136
136
|
patchActive(chan, (m) => ({
|
|
137
137
|
...m,
|
|
138
138
|
run_id: e.run_id ?? m.run_id,
|
|
@@ -141,22 +141,22 @@ function useAgnoChat(options) {
|
|
|
141
141
|
}));
|
|
142
142
|
return;
|
|
143
143
|
}
|
|
144
|
-
if (
|
|
145
|
-
const incoming =
|
|
144
|
+
if (chunk55HQJGLP_cjs.isToolEvent(e)) {
|
|
145
|
+
const incoming = chunk55HQJGLP_cjs.toolsFromEvent(e);
|
|
146
146
|
if (incoming.length) {
|
|
147
147
|
patchActive(chan, (m) => {
|
|
148
148
|
let tool_calls = m.tool_calls ?? [];
|
|
149
|
-
for (const t of incoming) tool_calls =
|
|
149
|
+
for (const t of incoming) tool_calls = chunk55HQJGLP_cjs.mergeTool(tool_calls, t);
|
|
150
150
|
return { ...m, tool_calls };
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
153
|
return;
|
|
154
154
|
}
|
|
155
|
-
if (
|
|
156
|
-
patchActive(chan, (m) =>
|
|
155
|
+
if (chunk55HQJGLP_cjs.isContentEvent(e)) {
|
|
156
|
+
patchActive(chan, (m) => chunk55HQJGLP_cjs.applyContentEvent(m, e));
|
|
157
157
|
return;
|
|
158
158
|
}
|
|
159
|
-
if (
|
|
159
|
+
if (chunk55HQJGLP_cjs.isReasoningStepEvent(e)) {
|
|
160
160
|
const incoming = e.reasoning_steps ?? e.extra_data?.reasoning_steps ?? [];
|
|
161
161
|
if (incoming.length) {
|
|
162
162
|
patchActive(chan, (m) => ({
|
|
@@ -166,36 +166,36 @@ function useAgnoChat(options) {
|
|
|
166
166
|
}
|
|
167
167
|
return;
|
|
168
168
|
}
|
|
169
|
-
if (
|
|
169
|
+
if (chunk55HQJGLP_cjs.isReasoningCompletedEvent(e)) {
|
|
170
170
|
const steps = e.reasoning_steps ?? e.extra_data?.reasoning_steps;
|
|
171
171
|
if (steps?.length) patchActive(chan, (m) => ({ ...m, reasoning_steps: steps }));
|
|
172
172
|
return;
|
|
173
173
|
}
|
|
174
|
-
if (
|
|
174
|
+
if (chunk55HQJGLP_cjs.isFollowupsCompletedEvent(e)) {
|
|
175
175
|
const followups = e.followups;
|
|
176
176
|
if (followups?.length) patchActive(chan, (m) => ({ ...m, followups }));
|
|
177
177
|
return;
|
|
178
178
|
}
|
|
179
|
-
if (
|
|
179
|
+
if (chunk55HQJGLP_cjs.isPausedEvent(e)) {
|
|
180
180
|
const requirements = e.requirements ?? [];
|
|
181
|
-
const pausedTools2 =
|
|
181
|
+
const pausedTools2 = chunk55HQJGLP_cjs.toolsFromEvent(e);
|
|
182
182
|
writeStatus(chan, "paused");
|
|
183
183
|
writeActivity(chan, "Waiting for input");
|
|
184
184
|
patchActive(chan, (m) => {
|
|
185
185
|
let tool_calls = m.tool_calls ?? [];
|
|
186
|
-
for (const t of pausedTools2) tool_calls =
|
|
186
|
+
for (const t of pausedTools2) tool_calls = chunk55HQJGLP_cjs.mergeTool(tool_calls, t);
|
|
187
187
|
return { ...m, status: "paused", streaming: false, requirements, tool_calls };
|
|
188
188
|
});
|
|
189
189
|
return;
|
|
190
190
|
}
|
|
191
|
-
if (
|
|
191
|
+
if (chunk55HQJGLP_cjs.isCompletedEvent(e)) {
|
|
192
192
|
patchActive(chan, (m) => {
|
|
193
193
|
const next = { ...m, streaming: false, status: "completed" };
|
|
194
194
|
if (typeof e.content === "string" && e.content) next.content = e.content;
|
|
195
|
-
const tools =
|
|
195
|
+
const tools = chunk55HQJGLP_cjs.toolsFromEvent(e);
|
|
196
196
|
if (tools.length) {
|
|
197
197
|
let tc = m.tool_calls ?? [];
|
|
198
|
-
for (const t of tools) tc =
|
|
198
|
+
for (const t of tools) tc = chunk55HQJGLP_cjs.mergeTool(tc, t);
|
|
199
199
|
next.tool_calls = tc;
|
|
200
200
|
}
|
|
201
201
|
if (e.reasoning_steps?.length) next.reasoning_steps = e.reasoning_steps;
|
|
@@ -209,12 +209,12 @@ function useAgnoChat(options) {
|
|
|
209
209
|
});
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
|
-
if (
|
|
212
|
+
if (chunk55HQJGLP_cjs.isCancelledEvent(e)) {
|
|
213
213
|
patchActive(chan, (m) => ({ ...m, streaming: false, status: "cancelled" }));
|
|
214
214
|
writeStatus(chan, "cancelled");
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
217
|
-
if (
|
|
217
|
+
if (chunk55HQJGLP_cjs.isErrorEvent(e)) {
|
|
218
218
|
const msg = typeof e.content === "string" ? e.content : e.error || "Error during run";
|
|
219
219
|
patchActive(chan, (m) => ({ ...m, streaming: false, status: "error", error: msg }));
|
|
220
220
|
writeError(chan, msg);
|
|
@@ -483,7 +483,7 @@ function useAgnoChat(options) {
|
|
|
483
483
|
setError(null);
|
|
484
484
|
try {
|
|
485
485
|
const runs = await client.getSessionRuns(ent.type, id, ent.db_id);
|
|
486
|
-
setMessages(
|
|
486
|
+
setMessages(chunk55HQJGLP_cjs.sessionRunsToMessages(runs));
|
|
487
487
|
} catch (err) {
|
|
488
488
|
setError(err instanceof Error ? err.message : String(err));
|
|
489
489
|
}
|
|
@@ -583,6 +583,7 @@ function ChatProvider({
|
|
|
583
583
|
renderMarkdown,
|
|
584
584
|
resolveLinkPreview,
|
|
585
585
|
codeCopy,
|
|
586
|
+
linkComponent,
|
|
586
587
|
chat: externalChat,
|
|
587
588
|
as,
|
|
588
589
|
className,
|
|
@@ -593,8 +594,8 @@ function ChatProvider({
|
|
|
593
594
|
const internal = useAgnoChat(externalChat ? { entity: null } : options);
|
|
594
595
|
const chat = externalChat ?? internal;
|
|
595
596
|
const value = React7.useMemo(
|
|
596
|
-
() => ({ chat, classNames: classNames ?? {}, renderMarkdown, resolveLinkPreview, codeCopy }),
|
|
597
|
-
[chat, classNames, renderMarkdown, resolveLinkPreview, codeCopy]
|
|
597
|
+
() => ({ chat, classNames: classNames ?? {}, renderMarkdown, resolveLinkPreview, codeCopy, linkComponent }),
|
|
598
|
+
[chat, classNames, renderMarkdown, resolveLinkPreview, codeCopy, linkComponent]
|
|
598
599
|
);
|
|
599
600
|
const Wrapper = as === false ? null : as ?? "div";
|
|
600
601
|
return /* @__PURE__ */ jsxRuntime.jsx(ChatContext.Provider, { value, children: Wrapper ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -627,6 +628,9 @@ function useResolvedChat(explicit) {
|
|
|
627
628
|
function useCodeCopy() {
|
|
628
629
|
return useOptionalChatContext()?.codeCopy;
|
|
629
630
|
}
|
|
631
|
+
function useLinkComponent() {
|
|
632
|
+
return useOptionalChatContext()?.linkComponent;
|
|
633
|
+
}
|
|
630
634
|
function useResolvedClassNames(explicit) {
|
|
631
635
|
const ctx = useOptionalChatContext();
|
|
632
636
|
return React7.useMemo(() => ({ ...ctx?.classNames, ...explicit }), [ctx?.classNames, explicit]);
|
|
@@ -639,11 +643,13 @@ var ChevronDown = icon(lucideReact.ChevronDown);
|
|
|
639
643
|
var ArrowUp = icon(lucideReact.ArrowUp);
|
|
640
644
|
var Paperclip = icon(lucideReact.Paperclip);
|
|
641
645
|
var FileIcon = icon(lucideReact.File);
|
|
646
|
+
var FileType = icon(lucideReact.FileType2);
|
|
642
647
|
var FileAudio = icon(lucideReact.FileAudio);
|
|
643
648
|
var FileVideo = icon(lucideReact.FileVideo);
|
|
644
649
|
var Wrench = icon(lucideReact.Wrench);
|
|
645
650
|
var BookOpen = icon(lucideReact.BookOpen);
|
|
646
651
|
var Globe = icon(lucideReact.Globe);
|
|
652
|
+
var LinkIcon = icon(lucideReact.Link);
|
|
647
653
|
var Brain = icon(lucideReact.Brain);
|
|
648
654
|
var Box = icon(lucideReact.Box);
|
|
649
655
|
var Plus = icon(lucideReact.Plus);
|
|
@@ -846,7 +852,16 @@ function ChatLauncher({
|
|
|
846
852
|
function markFor(type) {
|
|
847
853
|
if (type.startsWith("audio/")) return FileAudio;
|
|
848
854
|
if (type.startsWith("video/")) return FileVideo;
|
|
849
|
-
return
|
|
855
|
+
return FileType;
|
|
856
|
+
}
|
|
857
|
+
function formatSize(bytes) {
|
|
858
|
+
return bytes >= 1024 * 1024 ? `${Math.round(bytes / (1024 * 1024) * 10) / 10}MB` : `${Math.max(1, Math.round(bytes / 1024))}KB`;
|
|
859
|
+
}
|
|
860
|
+
function kindOf(file) {
|
|
861
|
+
const dot = file.name.lastIndexOf(".");
|
|
862
|
+
if (dot > 0 && dot < file.name.length - 1) return file.name.slice(dot + 1);
|
|
863
|
+
const subtype = file.type.split("/")[1];
|
|
864
|
+
return subtype || "file";
|
|
850
865
|
}
|
|
851
866
|
function Item({ file, onRemove }) {
|
|
852
867
|
const isImage = file.type.startsWith("image/");
|
|
@@ -861,15 +876,19 @@ function Item({ file, onRemove }) {
|
|
|
861
876
|
};
|
|
862
877
|
}, [file, isImage]);
|
|
863
878
|
const Mark = markFor(file.type);
|
|
864
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-file", children: [
|
|
865
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
866
|
-
isImage && url ? /* @__PURE__ */ jsxRuntime.jsx("img", { className: "agno-file__thumb", src: url, alt: file.name }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-file__card", children: [
|
|
879
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-file", isImage && url ? "agno-file--image" : "agno-file--card"), children: [
|
|
880
|
+
isImage && url ? /* @__PURE__ */ jsxRuntime.jsx("img", { className: "agno-file__thumb", src: url, alt: file.name }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
867
881
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-file__mark", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(Mark, { size: 16 }) }),
|
|
868
882
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "agno-file__meta", children: [
|
|
869
883
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-file__name", title: file.name, children: file.name }),
|
|
870
|
-
/* @__PURE__ */ jsxRuntime.
|
|
884
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "agno-file__type", children: [
|
|
885
|
+
kindOf(file),
|
|
886
|
+
" \u2022 ",
|
|
887
|
+
formatSize(file.size)
|
|
888
|
+
] })
|
|
871
889
|
] })
|
|
872
|
-
] })
|
|
890
|
+
] }),
|
|
891
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "agno-file__remove", onClick: onRemove, "aria-label": `Remove ${file.name}`, children: /* @__PURE__ */ jsxRuntime.jsx(Close, { size: 12 }) })
|
|
873
892
|
] });
|
|
874
893
|
}
|
|
875
894
|
function FilePreview({ files, onRemove, onClear, className }) {
|
|
@@ -879,20 +898,51 @@ function FilePreview({ files, onRemove, onClear, className }) {
|
|
|
879
898
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "agno-files__count", children: [
|
|
880
899
|
files.length,
|
|
881
900
|
" ",
|
|
882
|
-
files.length > 1 ? "
|
|
883
|
-
" attached"
|
|
901
|
+
files.length > 1 ? "attachments" : "attachment"
|
|
884
902
|
] }),
|
|
885
903
|
onClear && /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "agno-files__clear", onClick: onClear, children: [
|
|
886
|
-
/* @__PURE__ */ jsxRuntime.jsx(Close, { size:
|
|
887
|
-
"clear "
|
|
888
|
-
files.length > 1 ? "all" : ""
|
|
904
|
+
/* @__PURE__ */ jsxRuntime.jsx(Close, { size: 14 }),
|
|
905
|
+
"clear all"
|
|
889
906
|
] })
|
|
890
907
|
] }),
|
|
891
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-files__row", children: files.map((file, i) => /* @__PURE__ */ jsxRuntime.jsx(Item, { file, onRemove: () => onRemove(i) }, `${file.name}-${file.lastModified}-${i}`)) })
|
|
908
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-files__strip", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-files__row", children: files.map((file, i) => /* @__PURE__ */ jsxRuntime.jsx(Item, { file, onRemove: () => onRemove(i) }, `${file.name}-${file.lastModified}-${i}`)) }) })
|
|
892
909
|
] });
|
|
893
910
|
}
|
|
894
|
-
var
|
|
895
|
-
|
|
911
|
+
var BOUNDS = {
|
|
912
|
+
dock: { min: 31, max: 213 },
|
|
913
|
+
compact: { min: 24, max: 120 }
|
|
914
|
+
};
|
|
915
|
+
function fileAccepted(file, accept) {
|
|
916
|
+
if (!accept) return true;
|
|
917
|
+
const name = file.name.toLowerCase();
|
|
918
|
+
const type = file.type.toLowerCase();
|
|
919
|
+
return accept.split(",").map((rule) => rule.trim().toLowerCase()).filter(Boolean).some((rule) => {
|
|
920
|
+
if (rule.startsWith(".")) return name.endsWith(rule);
|
|
921
|
+
if (rule.endsWith("/*")) return type.startsWith(rule.slice(0, -1));
|
|
922
|
+
return type === rule;
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
function admitFiles(current, incoming, limits) {
|
|
926
|
+
const { accept, maxFiles, maxFileSize, maxTotalSize } = limits;
|
|
927
|
+
const files = [...current];
|
|
928
|
+
let total = current.reduce((sum, f) => sum + f.size, 0);
|
|
929
|
+
let error = null;
|
|
930
|
+
const refuse = (reason) => {
|
|
931
|
+
error ?? (error = reason);
|
|
932
|
+
};
|
|
933
|
+
for (const file of incoming) {
|
|
934
|
+
if (!fileAccepted(file, accept)) refuse("Cannot add this file type");
|
|
935
|
+
else if (maxFileSize != null && file.size > maxFileSize) refuse(`Cannot add files over ${formatSize(maxFileSize)}`);
|
|
936
|
+
else if (maxFiles != null && files.length >= maxFiles) refuse(`Cannot add more than ${maxFiles} attachments`);
|
|
937
|
+
else if (maxTotalSize != null && total + file.size > maxTotalSize) refuse("Cannot add more files");
|
|
938
|
+
else {
|
|
939
|
+
files.push(file);
|
|
940
|
+
total += file.size;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
return { files, error };
|
|
944
|
+
}
|
|
945
|
+
var hasFiles = (e) => Array.from(e.dataTransfer.types).includes("Files");
|
|
896
946
|
function ChatInput({
|
|
897
947
|
onSend,
|
|
898
948
|
onStop,
|
|
@@ -900,6 +950,19 @@ function ChatInput({
|
|
|
900
950
|
busy,
|
|
901
951
|
placeholder,
|
|
902
952
|
allowFiles = false,
|
|
953
|
+
compact = false,
|
|
954
|
+
accept,
|
|
955
|
+
maxFiles,
|
|
956
|
+
maxFileSize,
|
|
957
|
+
maxTotalSize,
|
|
958
|
+
value: controlled,
|
|
959
|
+
onValueChange,
|
|
960
|
+
textareaRef: externalRef,
|
|
961
|
+
textareaProps,
|
|
962
|
+
renderTextarea,
|
|
963
|
+
above,
|
|
964
|
+
below,
|
|
965
|
+
dropLabel = "Drop files to attach",
|
|
903
966
|
leading,
|
|
904
967
|
trailing,
|
|
905
968
|
className,
|
|
@@ -907,109 +970,213 @@ function ChatInput({
|
|
|
907
970
|
}) {
|
|
908
971
|
const ctx = useOptionalChatContext();
|
|
909
972
|
const cn = useResolvedClassNames(classNames);
|
|
910
|
-
const [
|
|
911
|
-
const
|
|
973
|
+
const [internal, setInternal] = React7.useState("");
|
|
974
|
+
const value = controlled ?? internal;
|
|
975
|
+
const setValue = (next) => {
|
|
976
|
+
if (controlled === void 0) setInternal(next);
|
|
977
|
+
onValueChange?.(next);
|
|
978
|
+
};
|
|
979
|
+
const [files, setFilesState] = React7.useState([]);
|
|
980
|
+
const filesRef = React7.useRef([]);
|
|
981
|
+
const setFiles = (next) => {
|
|
982
|
+
filesRef.current = next;
|
|
983
|
+
setFilesState(next);
|
|
984
|
+
};
|
|
985
|
+
const [fileError, setFileError] = React7.useState(null);
|
|
986
|
+
const [dragging, setDragging] = React7.useState(false);
|
|
987
|
+
const dragDepth = React7.useRef(0);
|
|
912
988
|
const fileRef = React7.useRef(null);
|
|
913
989
|
const textareaRef = React7.useRef(null);
|
|
990
|
+
const setTextareaRef = React7.useCallback(
|
|
991
|
+
(el2) => {
|
|
992
|
+
textareaRef.current = el2;
|
|
993
|
+
if (typeof externalRef === "function") externalRef(el2);
|
|
994
|
+
else if (externalRef) externalRef.current = el2;
|
|
995
|
+
},
|
|
996
|
+
[externalRef]
|
|
997
|
+
);
|
|
914
998
|
const adjustHeight = React7.useCallback(() => {
|
|
915
999
|
const el2 = textareaRef.current;
|
|
916
|
-
if (!el2) return;
|
|
917
|
-
|
|
918
|
-
el2.style.height = `${
|
|
919
|
-
|
|
1000
|
+
if (!el2 || renderTextarea) return;
|
|
1001
|
+
const { min, max } = compact ? BOUNDS.compact : BOUNDS.dock;
|
|
1002
|
+
el2.style.height = `${min}px`;
|
|
1003
|
+
el2.style.height = `${Math.min(Math.max(el2.scrollHeight, min), max)}px`;
|
|
1004
|
+
}, [renderTextarea, compact]);
|
|
920
1005
|
React7.useEffect(adjustHeight, [value, adjustHeight]);
|
|
921
1006
|
const send = onSend ?? ((message, attached) => void ctx?.chat.sendMessage(message, attached ? { files: attached } : void 0));
|
|
922
1007
|
const stop = onStop ?? (ctx ? () => void ctx.chat.cancel() : void 0);
|
|
923
1008
|
const isBusy = busy ?? ctx?.chat.isStreaming ?? false;
|
|
924
1009
|
const isDisabled = disabled ?? ctx?.chat.isPaused ?? false;
|
|
925
|
-
const
|
|
1010
|
+
const limits = { accept, maxFiles, maxFileSize, maxTotalSize };
|
|
1011
|
+
const addFiles = (incoming) => {
|
|
1012
|
+
if (!incoming.length) return;
|
|
1013
|
+
const next = admitFiles(filesRef.current, incoming, limits);
|
|
1014
|
+
setFiles(next.files);
|
|
1015
|
+
setFileError(next.error);
|
|
1016
|
+
if (fileRef.current) fileRef.current.value = "";
|
|
1017
|
+
};
|
|
1018
|
+
const submit = async () => {
|
|
926
1019
|
const text = value.trim();
|
|
927
1020
|
if (!text && files.length === 0) return;
|
|
928
|
-
|
|
1021
|
+
const sent = files.length ? files : void 0;
|
|
1022
|
+
const result = await send(text, sent);
|
|
1023
|
+
if (result === false) return;
|
|
929
1024
|
setValue("");
|
|
930
1025
|
setFiles([]);
|
|
1026
|
+
setFileError(null);
|
|
931
1027
|
};
|
|
932
1028
|
const canSend = !isDisabled && !isBusy && (Boolean(value.trim()) || files.length > 0);
|
|
933
|
-
|
|
1029
|
+
const onKeyDown = (e) => {
|
|
1030
|
+
textareaProps?.onKeyDown?.(e);
|
|
1031
|
+
if (e.defaultPrevented) return;
|
|
1032
|
+
if (e.key === "Enter" && !e.nativeEvent.isComposing && !e.shiftKey) {
|
|
1033
|
+
e.preventDefault();
|
|
1034
|
+
if (canSend) void submit();
|
|
1035
|
+
}
|
|
1036
|
+
};
|
|
1037
|
+
const onDragEnter = (e) => {
|
|
1038
|
+
if (!allowFiles || !hasFiles(e)) return;
|
|
1039
|
+
e.preventDefault();
|
|
1040
|
+
dragDepth.current += 1;
|
|
1041
|
+
setDragging(true);
|
|
1042
|
+
};
|
|
1043
|
+
const onDragOver = (e) => {
|
|
1044
|
+
if (!allowFiles || !hasFiles(e)) return;
|
|
1045
|
+
e.preventDefault();
|
|
1046
|
+
e.dataTransfer.dropEffect = "copy";
|
|
1047
|
+
};
|
|
1048
|
+
const onDragLeave = (e) => {
|
|
1049
|
+
if (!allowFiles || dragDepth.current === 0) return;
|
|
1050
|
+
e.preventDefault();
|
|
1051
|
+
dragDepth.current = Math.max(0, dragDepth.current - 1);
|
|
1052
|
+
if (dragDepth.current === 0) setDragging(false);
|
|
1053
|
+
};
|
|
1054
|
+
const onDrop = (e) => {
|
|
1055
|
+
if (!allowFiles || !hasFiles(e)) return;
|
|
1056
|
+
e.preventDefault();
|
|
1057
|
+
dragDepth.current = 0;
|
|
1058
|
+
setDragging(false);
|
|
1059
|
+
addFiles(Array.from(e.dataTransfer.files));
|
|
1060
|
+
textareaRef.current?.focus();
|
|
1061
|
+
};
|
|
1062
|
+
const fieldProps = {
|
|
1063
|
+
rows: 1,
|
|
1064
|
+
...textareaProps,
|
|
1065
|
+
ref: setTextareaRef,
|
|
1066
|
+
className: cx("agno-input__textarea", cn.textarea, textareaProps?.className),
|
|
1067
|
+
value,
|
|
1068
|
+
placeholder: placeholder ?? (isBusy ? "Running..." : "Ask anything..."),
|
|
1069
|
+
disabled: isDisabled,
|
|
1070
|
+
onChange: (e) => {
|
|
1071
|
+
setValue(e.target.value);
|
|
1072
|
+
textareaProps?.onChange?.(e);
|
|
1073
|
+
},
|
|
1074
|
+
onKeyDown
|
|
1075
|
+
};
|
|
1076
|
+
const iconSize = compact ? 14 : 16;
|
|
1077
|
+
const field = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-input__field", children: renderTextarea ? renderTextarea(fieldProps) : /* @__PURE__ */ jsxRuntime.jsx("textarea", { ...fieldProps }) });
|
|
1078
|
+
const attach = allowFiles && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
934
1079
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
935
|
-
|
|
1080
|
+
"button",
|
|
936
1081
|
{
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1082
|
+
type: "button",
|
|
1083
|
+
className: cx("agno-btn", compact ? "agno-btn--ghost" : "agno-btn--outline", "agno-btn--icon", cn.attachButton),
|
|
1084
|
+
onClick: () => fileRef.current?.click(),
|
|
1085
|
+
disabled: isDisabled,
|
|
1086
|
+
"aria-label": files.length ? `Attach files; ${files.length} attached` : "Attach files",
|
|
1087
|
+
title: files.length ? files.map((f) => f.name).join(", ") : void 0,
|
|
1088
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Paperclip, { size: iconSize })
|
|
941
1089
|
}
|
|
942
1090
|
),
|
|
943
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
944
|
-
"
|
|
1091
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1092
|
+
"input",
|
|
945
1093
|
{
|
|
946
|
-
ref:
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
onChange: (e) => setValue(e.target.value),
|
|
953
|
-
onKeyDown: (e) => {
|
|
954
|
-
if (e.key === "Enter" && !e.nativeEvent.isComposing && !e.shiftKey) {
|
|
955
|
-
e.preventDefault();
|
|
956
|
-
if (canSend) submit();
|
|
957
|
-
}
|
|
958
|
-
}
|
|
1094
|
+
ref: fileRef,
|
|
1095
|
+
type: "file",
|
|
1096
|
+
multiple: true,
|
|
1097
|
+
hidden: true,
|
|
1098
|
+
accept,
|
|
1099
|
+
onChange: (e) => addFiles(Array.from(e.target.files ?? []))
|
|
959
1100
|
}
|
|
960
|
-
)
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1000
|
-
"button",
|
|
1101
|
+
)
|
|
1102
|
+
] });
|
|
1103
|
+
const primary = isBusy && stop ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1104
|
+
"button",
|
|
1105
|
+
{
|
|
1106
|
+
type: "button",
|
|
1107
|
+
className: cx("agno-btn", "agno-btn--destructive", "agno-btn--icon", cn.stopButton),
|
|
1108
|
+
onClick: stop,
|
|
1109
|
+
"aria-label": "Stop",
|
|
1110
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Stop, { size: iconSize })
|
|
1111
|
+
}
|
|
1112
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1113
|
+
"button",
|
|
1114
|
+
{
|
|
1115
|
+
type: "button",
|
|
1116
|
+
className: cx("agno-btn", "agno-btn--icon", cn.sendButton),
|
|
1117
|
+
onClick: () => void submit(),
|
|
1118
|
+
disabled: !canSend,
|
|
1119
|
+
"aria-label": "Send",
|
|
1120
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUp, { size: iconSize })
|
|
1121
|
+
}
|
|
1122
|
+
);
|
|
1123
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1124
|
+
"div",
|
|
1125
|
+
{
|
|
1126
|
+
className: cx("agno-input", compact && "agno-input--compact", cn.input, className),
|
|
1127
|
+
"data-dragging": dragging ? "true" : void 0,
|
|
1128
|
+
onDragEnter,
|
|
1129
|
+
onDragOver,
|
|
1130
|
+
onDragLeave,
|
|
1131
|
+
onDrop,
|
|
1132
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-input__dock", children: [
|
|
1133
|
+
dragging && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-input__drop", cn.dropOverlay), "aria-hidden": true, children: [
|
|
1134
|
+
/* @__PURE__ */ jsxRuntime.jsx(Paperclip, { size: 16 }),
|
|
1135
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: dropLabel })
|
|
1136
|
+
] }),
|
|
1137
|
+
above,
|
|
1138
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1139
|
+
FilePreview,
|
|
1001
1140
|
{
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1141
|
+
files,
|
|
1142
|
+
onRemove: (i) => {
|
|
1143
|
+
setFiles(filesRef.current.filter((_, j) => j !== i));
|
|
1144
|
+
setFileError(null);
|
|
1145
|
+
},
|
|
1146
|
+
onClear: () => {
|
|
1147
|
+
setFiles([]);
|
|
1148
|
+
setFileError(null);
|
|
1149
|
+
},
|
|
1150
|
+
className: cn.files
|
|
1008
1151
|
}
|
|
1009
|
-
)
|
|
1152
|
+
),
|
|
1153
|
+
fileError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx("agno-input__error", cn.fileError), role: "alert", children: fileError }),
|
|
1154
|
+
compact ? (
|
|
1155
|
+
// One line: the field, then every control beside it.
|
|
1156
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-input__row", cn.inputRow), children: [
|
|
1157
|
+
leading,
|
|
1158
|
+
field,
|
|
1159
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-input__actions", children: [
|
|
1160
|
+
attach,
|
|
1161
|
+
trailing,
|
|
1162
|
+
primary
|
|
1163
|
+
] })
|
|
1164
|
+
] })
|
|
1165
|
+
) : field,
|
|
1166
|
+
below,
|
|
1167
|
+
!compact && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-input__row", cn.inputRow), children: [
|
|
1168
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-input__actions", children: [
|
|
1169
|
+
leading,
|
|
1170
|
+
attach
|
|
1171
|
+
] }),
|
|
1172
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-input__actions", children: [
|
|
1173
|
+
trailing,
|
|
1174
|
+
primary
|
|
1175
|
+
] })
|
|
1176
|
+
] })
|
|
1010
1177
|
] })
|
|
1011
|
-
|
|
1012
|
-
|
|
1178
|
+
}
|
|
1179
|
+
);
|
|
1013
1180
|
}
|
|
1014
1181
|
function normalizeFollowups(items) {
|
|
1015
1182
|
if (!items?.length) return [];
|
|
@@ -1532,20 +1699,15 @@ var PREVIEW_WIDTH = 320;
|
|
|
1532
1699
|
var GAP = 8;
|
|
1533
1700
|
var OPEN_DELAY = 140;
|
|
1534
1701
|
var CLOSE_DELAY = 120;
|
|
1535
|
-
function usePlacement(anchor, open) {
|
|
1702
|
+
function usePlacement(anchor, open, { width = PREVIEW_WIDTH, align = "center" } = {}) {
|
|
1536
1703
|
const [placement, setPlacement] = React7.useState(null);
|
|
1537
1704
|
useIsomorphicLayoutEffect(() => {
|
|
1538
1705
|
if (!open || !anchor) return;
|
|
1539
1706
|
const place = () => {
|
|
1540
1707
|
const rect = anchor.getBoundingClientRect();
|
|
1541
1708
|
const side = rect.top > 220 ? "top" : "bottom";
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1544
|
-
Math.min(
|
|
1545
|
-
rect.left + rect.width / 2 - PREVIEW_WIDTH / 2,
|
|
1546
|
-
window.innerWidth - PREVIEW_WIDTH - GAP
|
|
1547
|
-
)
|
|
1548
|
-
);
|
|
1709
|
+
const wanted = align === "center" ? rect.left + rect.width / 2 - width / 2 : rect.left;
|
|
1710
|
+
const left = Math.max(GAP, Math.min(wanted, window.innerWidth - width - GAP));
|
|
1549
1711
|
setPlacement({
|
|
1550
1712
|
top: side === "top" ? rect.top - GAP : rect.bottom + GAP,
|
|
1551
1713
|
left,
|
|
@@ -1559,7 +1721,7 @@ function usePlacement(anchor, open) {
|
|
|
1559
1721
|
window.removeEventListener("scroll", place, true);
|
|
1560
1722
|
window.removeEventListener("resize", place);
|
|
1561
1723
|
};
|
|
1562
|
-
}, [anchor, open]);
|
|
1724
|
+
}, [anchor, open, width, align]);
|
|
1563
1725
|
return placement;
|
|
1564
1726
|
}
|
|
1565
1727
|
function HoverPreview({
|
|
@@ -1661,16 +1823,20 @@ function labelOf(children) {
|
|
|
1661
1823
|
}
|
|
1662
1824
|
function CitationMarker({
|
|
1663
1825
|
source,
|
|
1664
|
-
className
|
|
1826
|
+
className,
|
|
1827
|
+
Link
|
|
1665
1828
|
}) {
|
|
1666
|
-
|
|
1829
|
+
const props = {
|
|
1830
|
+
className: cx("agno-cite", className),
|
|
1831
|
+
href: source.url ?? `#${source.anchorId}`,
|
|
1832
|
+
"aria-label": `Source ${source.index}: ${source.title}`
|
|
1833
|
+
};
|
|
1834
|
+
return /* @__PURE__ */ jsxRuntime.jsx(HoverPreview, { source, className: "agno-cite__wrap", children: Link && source.url ? /* @__PURE__ */ jsxRuntime.jsx(Link, { ...props, children: source.index }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1667
1835
|
"a",
|
|
1668
1836
|
{
|
|
1669
|
-
|
|
1670
|
-
href: source.url ?? `#${source.anchorId}`,
|
|
1837
|
+
...props,
|
|
1671
1838
|
target: source.url ? "_blank" : void 0,
|
|
1672
1839
|
rel: source.url ? "noreferrer noopener" : void 0,
|
|
1673
|
-
"aria-label": `Source ${source.index}: ${source.title}`,
|
|
1674
1840
|
children: source.index
|
|
1675
1841
|
}
|
|
1676
1842
|
) });
|
|
@@ -1769,8 +1935,8 @@ function elementsFor(ctx) {
|
|
|
1769
1935
|
...rest
|
|
1770
1936
|
}) {
|
|
1771
1937
|
const cited = citationForLink(labelOf(children), href, ctx);
|
|
1772
|
-
if (cited) return /* @__PURE__ */ jsxRuntime.jsx(CitationMarker, { source: cited, className: ctx.markerClass });
|
|
1773
|
-
const link = /* @__PURE__ */ jsxRuntime.jsx("a", { href, target: "_blank", rel: "noreferrer noopener", ...rest, children });
|
|
1938
|
+
if (cited) return /* @__PURE__ */ jsxRuntime.jsx(CitationMarker, { source: cited, className: ctx.markerClass, Link: ctx.Link });
|
|
1939
|
+
const link = ctx.Link && href ? /* @__PURE__ */ jsxRuntime.jsx(ctx.Link, { href, ...rest, children }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href, target: "_blank", rel: "noreferrer noopener", ...rest, children });
|
|
1774
1940
|
const source = sourceForUrl(href, ctx.sources);
|
|
1775
1941
|
if (!href || !/^https?:\/\//i.test(href) || !source && !ctx.canResolve) return link;
|
|
1776
1942
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1836,23 +2002,27 @@ function Markdown({
|
|
|
1836
2002
|
sources,
|
|
1837
2003
|
streaming,
|
|
1838
2004
|
codeCopy,
|
|
2005
|
+
linkComponent,
|
|
1839
2006
|
options
|
|
1840
2007
|
}) {
|
|
1841
2008
|
const fromMessage = useSources();
|
|
1842
2009
|
const cn = useResolvedClassNames();
|
|
1843
2010
|
const canResolve = Boolean(useLinkPreviewResolver());
|
|
1844
2011
|
const fromProvider = useCodeCopy();
|
|
2012
|
+
const providerLink = useLinkComponent();
|
|
1845
2013
|
const cited = sources ?? fromMessage;
|
|
1846
2014
|
const copy = codeCopy ?? fromProvider ?? true;
|
|
2015
|
+
const Link = linkComponent ?? providerLink;
|
|
1847
2016
|
const components = React7.useMemo(
|
|
1848
2017
|
() => elementsFor({
|
|
1849
2018
|
sources: cited,
|
|
1850
2019
|
canResolve,
|
|
1851
2020
|
markerClass: cn.citationMarker,
|
|
1852
2021
|
copyClass: cn.copyButton,
|
|
1853
|
-
codeCopy: copy
|
|
2022
|
+
codeCopy: copy,
|
|
2023
|
+
Link
|
|
1854
2024
|
}),
|
|
1855
|
-
[cited, canResolve, cn.citationMarker, cn.copyButton, copy]
|
|
2025
|
+
[cited, canResolve, cn.citationMarker, cn.copyButton, copy, Link]
|
|
1856
2026
|
);
|
|
1857
2027
|
const text = React7.useMemo(() => linkCitations(content, cited), [content, cited]);
|
|
1858
2028
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1936,7 +2106,7 @@ function isNoiseEvent(e) {
|
|
|
1936
2106
|
}
|
|
1937
2107
|
var isMemoryEvent = (e) => eventName(e).includes("MemoryUpdate");
|
|
1938
2108
|
var isMemoryCompleted = (e) => eventName(e).includes("MemoryUpdateCompleted");
|
|
1939
|
-
var isReasoningEvent = (e) =>
|
|
2109
|
+
var isReasoningEvent = (e) => chunk55HQJGLP_cjs.isReasoningStepEvent(e) || chunk55HQJGLP_cjs.isReasoningCompletedEvent(e) || eventName(e).includes("ReasoningStarted");
|
|
1940
2110
|
function formatDuration(seconds) {
|
|
1941
2111
|
return seconds < 10 ? `${seconds.toFixed(1)}s` : `${Math.round(seconds)}s`;
|
|
1942
2112
|
}
|
|
@@ -1970,14 +2140,14 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
1970
2140
|
if (member) put(`member:${runId}`, { kind: "member", id: `member-${runId}`, member });
|
|
1971
2141
|
continue;
|
|
1972
2142
|
}
|
|
1973
|
-
if (
|
|
2143
|
+
if (chunk55HQJGLP_cjs.isToolEvent(e)) {
|
|
1974
2144
|
if (hideTools) continue;
|
|
1975
|
-
for (const tool of
|
|
2145
|
+
for (const tool of chunk55HQJGLP_cjs.toolsFromEvent(e)) {
|
|
1976
2146
|
const key = `tool:${tool.tool_call_id ?? tool.tool_name}`;
|
|
1977
2147
|
const at = indexOf.get(key);
|
|
1978
2148
|
const previous = at != null ? steps[at].tool : void 0;
|
|
1979
2149
|
const merged = { ...previous, ...tool };
|
|
1980
|
-
if (!
|
|
2150
|
+
if (!chunk55HQJGLP_cjs.isToolCompletedEvent(e) && previous?.result != null) merged.result = previous.result;
|
|
1981
2151
|
put(key, { kind: "tool", id: key, tool: merged });
|
|
1982
2152
|
}
|
|
1983
2153
|
continue;
|
|
@@ -1988,7 +2158,7 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
1988
2158
|
const at = indexOf.get(key);
|
|
1989
2159
|
const previous = at != null ? steps[at].steps : [];
|
|
1990
2160
|
const incoming = e.reasoning_steps ?? e.extra_data?.reasoning_steps ?? [];
|
|
1991
|
-
const completed =
|
|
2161
|
+
const completed = chunk55HQJGLP_cjs.isReasoningCompletedEvent(e);
|
|
1992
2162
|
put(key, {
|
|
1993
2163
|
kind: "reasoning",
|
|
1994
2164
|
id: key,
|
|
@@ -2023,7 +2193,7 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
2023
2193
|
label: "Run Continued",
|
|
2024
2194
|
icon: "continued"
|
|
2025
2195
|
});
|
|
2026
|
-
} else if (
|
|
2196
|
+
} else if (chunk55HQJGLP_cjs.isCompletedEvent(e)) {
|
|
2027
2197
|
put(`completed:${runKey}`, {
|
|
2028
2198
|
kind: "status",
|
|
2029
2199
|
id: `completed-${runKey}`,
|
|
@@ -2031,16 +2201,16 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
2031
2201
|
detail: durationOf(e),
|
|
2032
2202
|
icon: "run"
|
|
2033
2203
|
});
|
|
2034
|
-
} else if (
|
|
2204
|
+
} else if (chunk55HQJGLP_cjs.isPausedEvent(e)) {
|
|
2035
2205
|
put(`paused:${runKey}`, { kind: "status", id: `paused-${runKey}`, label: "Run Paused", icon: "run" });
|
|
2036
|
-
} else if (
|
|
2206
|
+
} else if (chunk55HQJGLP_cjs.isCancelledEvent(e)) {
|
|
2037
2207
|
put(`cancelled:${runKey}`, {
|
|
2038
2208
|
kind: "status",
|
|
2039
2209
|
id: `cancelled-${runKey}`,
|
|
2040
2210
|
label: "Run Cancelled",
|
|
2041
2211
|
icon: "run"
|
|
2042
2212
|
});
|
|
2043
|
-
} else if (
|
|
2213
|
+
} else if (chunk55HQJGLP_cjs.isErrorEvent(e)) {
|
|
2044
2214
|
const detail = typeof e.content === "string" ? e.content : e.error;
|
|
2045
2215
|
put(`error:${runKey}`, { kind: "status", id: `error-${runKey}`, label: detail || "Run Error", icon: "run" });
|
|
2046
2216
|
}
|
|
@@ -2088,7 +2258,7 @@ function runDuration(message) {
|
|
|
2088
2258
|
function liveActivity(message) {
|
|
2089
2259
|
const events = message.events ?? [];
|
|
2090
2260
|
for (let i = events.length - 1; i >= 0; i--) {
|
|
2091
|
-
const label2 =
|
|
2261
|
+
const label2 = chunk55HQJGLP_cjs.activityLabel(events[i]);
|
|
2092
2262
|
if (label2) return label2;
|
|
2093
2263
|
}
|
|
2094
2264
|
return message.activity ?? null;
|
|
@@ -2263,12 +2433,25 @@ function SourceCard({
|
|
|
2263
2433
|
className
|
|
2264
2434
|
}) {
|
|
2265
2435
|
const cn = useResolvedClassNames();
|
|
2436
|
+
const Link = useLinkComponent();
|
|
2266
2437
|
const { preview } = useLinkPreview(source.url, false);
|
|
2267
2438
|
const body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2268
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2269
|
-
|
|
2439
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2440
|
+
Favicon,
|
|
2441
|
+
{
|
|
2442
|
+
className: "agno-source__icon",
|
|
2443
|
+
url: preview?.favicon ?? source.url,
|
|
2444
|
+
kind: source.kind,
|
|
2445
|
+
size: 24
|
|
2446
|
+
}
|
|
2447
|
+
),
|
|
2448
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-source__title", children: preview?.title ?? source.title }),
|
|
2449
|
+
source.url && /* @__PURE__ */ jsxRuntime.jsx(LinkIcon, { className: "agno-source__link" })
|
|
2270
2450
|
] });
|
|
2271
2451
|
const classes = cx("agno-source", `agno-source--${source.kind}`, cn.sourceCard, className);
|
|
2452
|
+
if (source.url && Link) {
|
|
2453
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Link, { id: source.anchorId, className: classes, href: source.url, title: source.url, children: body });
|
|
2454
|
+
}
|
|
2272
2455
|
return source.url ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2273
2456
|
"a",
|
|
2274
2457
|
{
|
|
@@ -2282,33 +2465,118 @@ function SourceCard({
|
|
|
2282
2465
|
}
|
|
2283
2466
|
) : /* @__PURE__ */ jsxRuntime.jsx("div", { id: source.anchorId, className: classes, children: body });
|
|
2284
2467
|
}
|
|
2468
|
+
var LIST_WIDTH = 240;
|
|
2469
|
+
function SourcesOverflow({ sources }) {
|
|
2470
|
+
const [open, setOpen] = React7.useState(false);
|
|
2471
|
+
const [anchor, setAnchor] = React7.useState(null);
|
|
2472
|
+
const timer = React7.useRef(null);
|
|
2473
|
+
const id = React7.useId();
|
|
2474
|
+
const placement = usePlacement(anchor, open, { width: LIST_WIDTH, align: "start" });
|
|
2475
|
+
const schedule = React7.useCallback((next) => {
|
|
2476
|
+
if (timer.current) clearTimeout(timer.current);
|
|
2477
|
+
timer.current = setTimeout(() => setOpen(next), next ? OPEN_DELAY : CLOSE_DELAY);
|
|
2478
|
+
}, []);
|
|
2479
|
+
React7.useEffect(
|
|
2480
|
+
() => () => {
|
|
2481
|
+
if (timer.current) clearTimeout(timer.current);
|
|
2482
|
+
},
|
|
2483
|
+
[]
|
|
2484
|
+
);
|
|
2485
|
+
React7.useEffect(() => {
|
|
2486
|
+
if (!open) return;
|
|
2487
|
+
const onKey = (e) => {
|
|
2488
|
+
if (e.key === "Escape") setOpen(false);
|
|
2489
|
+
};
|
|
2490
|
+
document.addEventListener("keydown", onKey);
|
|
2491
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
2492
|
+
}, [open]);
|
|
2493
|
+
const [mounted, setMounted] = React7.useState(false);
|
|
2494
|
+
React7.useEffect(() => setMounted(true), []);
|
|
2495
|
+
const light = anchor?.closest(".agno-light") ? "agno-light" : void 0;
|
|
2496
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2497
|
+
"span",
|
|
2498
|
+
{
|
|
2499
|
+
className: "agno-sources__overflow",
|
|
2500
|
+
ref: setAnchor,
|
|
2501
|
+
onMouseEnter: () => schedule(true),
|
|
2502
|
+
onMouseLeave: () => schedule(false),
|
|
2503
|
+
children: [
|
|
2504
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2505
|
+
"button",
|
|
2506
|
+
{
|
|
2507
|
+
type: "button",
|
|
2508
|
+
className: "agno-sources__more",
|
|
2509
|
+
"aria-label": `${sources.length} more sources`,
|
|
2510
|
+
"aria-expanded": open,
|
|
2511
|
+
"aria-controls": open ? id : void 0,
|
|
2512
|
+
onClick: () => setOpen((v) => !v),
|
|
2513
|
+
onFocus: () => setOpen(true),
|
|
2514
|
+
onBlur: () => schedule(false),
|
|
2515
|
+
children: [
|
|
2516
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-sources__stack", "aria-hidden": true, children: sources.slice(0, 3).map((source) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2517
|
+
Favicon,
|
|
2518
|
+
{
|
|
2519
|
+
className: "agno-sources__stack-icon",
|
|
2520
|
+
url: source.url,
|
|
2521
|
+
kind: source.kind,
|
|
2522
|
+
size: 24
|
|
2523
|
+
},
|
|
2524
|
+
source.anchorId
|
|
2525
|
+
)) }),
|
|
2526
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "agno-sources__more-label", children: [
|
|
2527
|
+
"+",
|
|
2528
|
+
sources.length,
|
|
2529
|
+
" more"
|
|
2530
|
+
] })
|
|
2531
|
+
]
|
|
2532
|
+
}
|
|
2533
|
+
),
|
|
2534
|
+
mounted && open && placement && reactDom.createPortal(
|
|
2535
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2536
|
+
"div",
|
|
2537
|
+
{
|
|
2538
|
+
id,
|
|
2539
|
+
role: "group",
|
|
2540
|
+
"aria-label": "More sources",
|
|
2541
|
+
className: cx("agno-sources__list", `agno-sources__list--${placement.side}`, light),
|
|
2542
|
+
style: { top: placement.top, left: placement.left, width: LIST_WIDTH },
|
|
2543
|
+
onMouseEnter: () => schedule(true),
|
|
2544
|
+
onMouseLeave: () => schedule(false),
|
|
2545
|
+
onFocus: () => schedule(true),
|
|
2546
|
+
onBlur: () => schedule(false),
|
|
2547
|
+
children: sources.map((source) => /* @__PURE__ */ jsxRuntime.jsx(SourceCard, { source, className: "agno-source--row" }, source.anchorId))
|
|
2548
|
+
}
|
|
2549
|
+
),
|
|
2550
|
+
document.body
|
|
2551
|
+
)
|
|
2552
|
+
]
|
|
2553
|
+
}
|
|
2554
|
+
);
|
|
2555
|
+
}
|
|
2285
2556
|
function Citations({
|
|
2286
2557
|
references,
|
|
2287
2558
|
citations,
|
|
2288
2559
|
sources: given,
|
|
2289
|
-
title = "Sources",
|
|
2290
|
-
max =
|
|
2560
|
+
title = "Sources used",
|
|
2561
|
+
max = 3,
|
|
2291
2562
|
className,
|
|
2292
2563
|
classNames
|
|
2293
2564
|
}) {
|
|
2294
2565
|
const cn = useResolvedClassNames(classNames);
|
|
2295
2566
|
const uid = React7.useId();
|
|
2296
|
-
const [expanded, setExpanded] = React7.useState(false);
|
|
2297
2567
|
const sources = React7.useMemo(
|
|
2298
2568
|
() => given ?? collectSources(references, citations, uid),
|
|
2299
2569
|
[given, references, citations, uid]
|
|
2300
2570
|
);
|
|
2301
2571
|
if (sources.length === 0) return null;
|
|
2302
|
-
const limit = max > 0
|
|
2572
|
+
const limit = max > 0 ? max : sources.length;
|
|
2303
2573
|
const visible = sources.slice(0, limit);
|
|
2304
|
-
const hidden = sources.
|
|
2574
|
+
const hidden = sources.slice(limit);
|
|
2305
2575
|
return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: cx("agno-sources", cn.citations, className), "aria-label": title, children: [
|
|
2306
2576
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-sources__head", children: title }),
|
|
2307
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
hidden,
|
|
2311
|
-
" more"
|
|
2577
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-sources__grid", children: [
|
|
2578
|
+
visible.map((source) => /* @__PURE__ */ jsxRuntime.jsx(SourceCard, { source }, source.anchorId)),
|
|
2579
|
+
hidden.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(SourcesOverflow, { sources: hidden })
|
|
2312
2580
|
] })
|
|
2313
2581
|
] });
|
|
2314
2582
|
}
|
|
@@ -2524,6 +2792,7 @@ function ChatWindow({
|
|
|
2524
2792
|
userInitials,
|
|
2525
2793
|
emptyState,
|
|
2526
2794
|
allowFiles,
|
|
2795
|
+
compactInput,
|
|
2527
2796
|
disabled,
|
|
2528
2797
|
renderMarkdown,
|
|
2529
2798
|
showErrors,
|
|
@@ -2532,6 +2801,7 @@ function ChatWindow({
|
|
|
2532
2801
|
hideFollowups,
|
|
2533
2802
|
onFollowup,
|
|
2534
2803
|
followupsTitle,
|
|
2804
|
+
renderMessage,
|
|
2535
2805
|
header,
|
|
2536
2806
|
composer,
|
|
2537
2807
|
className,
|
|
@@ -2558,6 +2828,7 @@ function ChatWindow({
|
|
|
2558
2828
|
renderMarkdown: markdown,
|
|
2559
2829
|
classNames: cn,
|
|
2560
2830
|
emptyState,
|
|
2831
|
+
renderMessage,
|
|
2561
2832
|
footer: pausedMessage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2562
2833
|
HumanInput,
|
|
2563
2834
|
{
|
|
@@ -2600,6 +2871,7 @@ function ChatWindow({
|
|
|
2600
2871
|
disabled: disabled || chat.isPaused,
|
|
2601
2872
|
placeholder,
|
|
2602
2873
|
allowFiles,
|
|
2874
|
+
compact: compactInput,
|
|
2603
2875
|
classNames: cn
|
|
2604
2876
|
}
|
|
2605
2877
|
)
|
|
@@ -2897,7 +3169,7 @@ function SessionList({
|
|
|
2897
3169
|
}
|
|
2898
3170
|
function AgnoChat(props) {
|
|
2899
3171
|
const client = React7.useMemo(
|
|
2900
|
-
() => props.client ?? new
|
|
3172
|
+
() => props.client ?? new chunk55HQJGLP_cjs.AgnoClient({ baseUrl: props.baseUrl ?? "", headers: props.headers }),
|
|
2901
3173
|
[props.client, props.baseUrl, props.headers]
|
|
2902
3174
|
);
|
|
2903
3175
|
const [discovered, setDiscovered] = React7.useState(props.entities ?? []);
|
|
@@ -2988,6 +3260,7 @@ function AgnoChat(props) {
|
|
|
2988
3260
|
chat,
|
|
2989
3261
|
placeholder: props.placeholder,
|
|
2990
3262
|
allowFiles: props.allowFiles ?? true,
|
|
3263
|
+
compactInput: props.compactInput,
|
|
2991
3264
|
disabled: !entity,
|
|
2992
3265
|
renderMarkdown: props.renderMarkdown,
|
|
2993
3266
|
showErrors: props.showErrors,
|
|
@@ -3005,6 +3278,7 @@ function AgnoChat(props) {
|
|
|
3005
3278
|
disabled: !entity || chat.isPaused,
|
|
3006
3279
|
placeholder: props.placeholder,
|
|
3007
3280
|
allowFiles: props.allowFiles ?? true,
|
|
3281
|
+
compact: props.compactInput,
|
|
3008
3282
|
classNames: cn,
|
|
3009
3283
|
trailing: showPicker ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3010
3284
|
EntitySelector,
|
|
@@ -3033,6 +3307,7 @@ function AgnoChat(props) {
|
|
|
3033
3307
|
renderMarkdown: props.renderMarkdown,
|
|
3034
3308
|
resolveLinkPreview: props.resolveLinkPreview,
|
|
3035
3309
|
codeCopy: props.codeCopy,
|
|
3310
|
+
linkComponent: props.linkComponent,
|
|
3036
3311
|
as: false,
|
|
3037
3312
|
children: root
|
|
3038
3313
|
}
|
|
@@ -3199,7 +3474,7 @@ function fold(events) {
|
|
|
3199
3474
|
last.created_at = e.created_at ?? last.created_at;
|
|
3200
3475
|
continue;
|
|
3201
3476
|
}
|
|
3202
|
-
rows.push({ event: name, source, count: 1, created_at: e.created_at, detail:
|
|
3477
|
+
rows.push({ event: name, source, count: 1, created_at: e.created_at, detail: chunk55HQJGLP_cjs.activityLabel(e) });
|
|
3203
3478
|
}
|
|
3204
3479
|
return rows;
|
|
3205
3480
|
}
|
|
@@ -3251,12 +3526,14 @@ exports.Favicon = Favicon;
|
|
|
3251
3526
|
exports.FileAudio = FileAudio;
|
|
3252
3527
|
exports.FileIcon = FileIcon;
|
|
3253
3528
|
exports.FilePreview = FilePreview;
|
|
3529
|
+
exports.FileType = FileType;
|
|
3254
3530
|
exports.FileVideo = FileVideo;
|
|
3255
3531
|
exports.Followups = Followups;
|
|
3256
3532
|
exports.Globe = Globe;
|
|
3257
3533
|
exports.GridLoader = GridLoader;
|
|
3258
3534
|
exports.HoverPreview = HoverPreview;
|
|
3259
3535
|
exports.HumanInput = HumanInput;
|
|
3536
|
+
exports.LinkIcon = LinkIcon;
|
|
3260
3537
|
exports.LinkPreviewCard = LinkPreviewCard;
|
|
3261
3538
|
exports.Markdown = Markdown;
|
|
3262
3539
|
exports.MemberResponses = MemberResponses;
|
|
@@ -3281,12 +3558,14 @@ exports.ToolCalls = ToolCalls;
|
|
|
3281
3558
|
exports.Trash = Trash;
|
|
3282
3559
|
exports.WorkflowSteps = WorkflowSteps;
|
|
3283
3560
|
exports.Wrench = Wrench;
|
|
3561
|
+
exports.admitFiles = admitFiles;
|
|
3284
3562
|
exports.behindTheScenesItems = behindTheScenesItems;
|
|
3285
3563
|
exports.behindTheScenesLabel = behindTheScenesLabel;
|
|
3286
3564
|
exports.collectSources = collectSources;
|
|
3287
3565
|
exports.cx = cx;
|
|
3288
3566
|
exports.displayUrl = displayUrl;
|
|
3289
3567
|
exports.faviconUrl = faviconUrl;
|
|
3568
|
+
exports.fileAccepted = fileAccepted;
|
|
3290
3569
|
exports.getProviderIcon = getProviderIcon;
|
|
3291
3570
|
exports.hasBehindTheScenes = hasBehindTheScenes;
|
|
3292
3571
|
exports.linkCitations = linkCitations;
|
|
@@ -3297,6 +3576,7 @@ exports.sourceHost = sourceHost;
|
|
|
3297
3576
|
exports.sourcesFromMarkdown = sourcesFromMarkdown;
|
|
3298
3577
|
exports.useAgnoChat = useAgnoChat;
|
|
3299
3578
|
exports.useChatContext = useChatContext;
|
|
3579
|
+
exports.useLinkComponent = useLinkComponent;
|
|
3300
3580
|
exports.useLinkPreview = useLinkPreview;
|
|
3301
3581
|
exports.useOptionalChatContext = useOptionalChatContext;
|
|
3302
3582
|
exports.useResolvedChat = useResolvedChat;
|
|
@@ -3304,5 +3584,5 @@ exports.useResolvedClassNames = useResolvedClassNames;
|
|
|
3304
3584
|
exports.useSources = useSources;
|
|
3305
3585
|
exports.withoutSourcesLine = withoutSourcesLine;
|
|
3306
3586
|
exports.writeClipboard = writeClipboard;
|
|
3307
|
-
//# sourceMappingURL=chunk-
|
|
3308
|
-
//# sourceMappingURL=chunk-
|
|
3587
|
+
//# sourceMappingURL=chunk-JEPFGKHH.cjs.map
|
|
3588
|
+
//# sourceMappingURL=chunk-JEPFGKHH.cjs.map
|