@agno-hq/chat-react 0.3.0 → 0.3.2
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 +226 -113
- package/dist/chat/index.d.ts +226 -113
- 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-ERCKKOF4.cjs → chunk-Q73XHL35.cjs} +452 -170
- package/dist/chunk-Q73XHL35.cjs.map +1 -0
- package/dist/{chunk-MUOMZG4V.js → chunk-XTP3TMEZ.js} +413 -136
- package/dist/chunk-XTP3TMEZ.js.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);
|
|
@@ -656,9 +662,7 @@ var Pulse = icon(lucideReact.Activity);
|
|
|
656
662
|
var Trash = icon(lucideReact.Trash2);
|
|
657
663
|
var ChatBubble = icon(lucideReact.MessageSquare);
|
|
658
664
|
var Spinner = icon(lucideReact.LoaderCircle, 12);
|
|
659
|
-
|
|
660
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Square, { size, className, fill: "currentColor", strokeWidth: 0 });
|
|
661
|
-
}
|
|
665
|
+
var Stop = icon(lucideReact.Square, 10.67);
|
|
662
666
|
function AgnoMark({ size = 24, className }) {
|
|
663
667
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
664
668
|
"svg",
|
|
@@ -846,7 +850,16 @@ function ChatLauncher({
|
|
|
846
850
|
function markFor(type) {
|
|
847
851
|
if (type.startsWith("audio/")) return FileAudio;
|
|
848
852
|
if (type.startsWith("video/")) return FileVideo;
|
|
849
|
-
return
|
|
853
|
+
return FileType;
|
|
854
|
+
}
|
|
855
|
+
function formatSize(bytes) {
|
|
856
|
+
return bytes >= 1024 * 1024 ? `${Math.round(bytes / (1024 * 1024) * 10) / 10}MB` : `${Math.max(1, Math.round(bytes / 1024))}KB`;
|
|
857
|
+
}
|
|
858
|
+
function kindOf(file) {
|
|
859
|
+
const dot = file.name.lastIndexOf(".");
|
|
860
|
+
if (dot > 0 && dot < file.name.length - 1) return file.name.slice(dot + 1);
|
|
861
|
+
const subtype = file.type.split("/")[1];
|
|
862
|
+
return subtype || "file";
|
|
850
863
|
}
|
|
851
864
|
function Item({ file, onRemove }) {
|
|
852
865
|
const isImage = file.type.startsWith("image/");
|
|
@@ -861,15 +874,19 @@ function Item({ file, onRemove }) {
|
|
|
861
874
|
};
|
|
862
875
|
}, [file, isImage]);
|
|
863
876
|
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: [
|
|
877
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-file", isImage && url ? "agno-file--image" : "agno-file--card"), children: [
|
|
878
|
+
isImage && url ? /* @__PURE__ */ jsxRuntime.jsx("img", { className: "agno-file__thumb", src: url, alt: file.name }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
867
879
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-file__mark", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(Mark, { size: 16 }) }),
|
|
868
880
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "agno-file__meta", children: [
|
|
869
881
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-file__name", title: file.name, children: file.name }),
|
|
870
|
-
/* @__PURE__ */ jsxRuntime.
|
|
882
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "agno-file__type", children: [
|
|
883
|
+
kindOf(file),
|
|
884
|
+
" \u2022 ",
|
|
885
|
+
formatSize(file.size)
|
|
886
|
+
] })
|
|
871
887
|
] })
|
|
872
|
-
] })
|
|
888
|
+
] }),
|
|
889
|
+
/* @__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
890
|
] });
|
|
874
891
|
}
|
|
875
892
|
function FilePreview({ files, onRemove, onClear, className }) {
|
|
@@ -879,20 +896,51 @@ function FilePreview({ files, onRemove, onClear, className }) {
|
|
|
879
896
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "agno-files__count", children: [
|
|
880
897
|
files.length,
|
|
881
898
|
" ",
|
|
882
|
-
files.length > 1 ? "
|
|
883
|
-
" attached"
|
|
899
|
+
files.length > 1 ? "attachments" : "attachment"
|
|
884
900
|
] }),
|
|
885
901
|
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" : ""
|
|
902
|
+
/* @__PURE__ */ jsxRuntime.jsx(Close, { size: 14 }),
|
|
903
|
+
"clear all"
|
|
889
904
|
] })
|
|
890
905
|
] }),
|
|
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}`)) })
|
|
906
|
+
/* @__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
907
|
] });
|
|
893
908
|
}
|
|
894
|
-
var
|
|
895
|
-
|
|
909
|
+
var BOUNDS = {
|
|
910
|
+
dock: { min: 31, max: 213 },
|
|
911
|
+
compact: { min: 24, max: 120 }
|
|
912
|
+
};
|
|
913
|
+
function fileAccepted(file, accept) {
|
|
914
|
+
if (!accept) return true;
|
|
915
|
+
const name = file.name.toLowerCase();
|
|
916
|
+
const type = file.type.toLowerCase();
|
|
917
|
+
return accept.split(",").map((rule) => rule.trim().toLowerCase()).filter(Boolean).some((rule) => {
|
|
918
|
+
if (rule.startsWith(".")) return name.endsWith(rule);
|
|
919
|
+
if (rule.endsWith("/*")) return type.startsWith(rule.slice(0, -1));
|
|
920
|
+
return type === rule;
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
function admitFiles(current, incoming, limits) {
|
|
924
|
+
const { accept, maxFiles, maxFileSize, maxTotalSize } = limits;
|
|
925
|
+
const files = [...current];
|
|
926
|
+
let total = current.reduce((sum, f) => sum + f.size, 0);
|
|
927
|
+
let error = null;
|
|
928
|
+
const refuse = (reason) => {
|
|
929
|
+
error ?? (error = reason);
|
|
930
|
+
};
|
|
931
|
+
for (const file of incoming) {
|
|
932
|
+
if (!fileAccepted(file, accept)) refuse("Cannot add this file type");
|
|
933
|
+
else if (maxFileSize != null && file.size > maxFileSize) refuse(`Cannot add files over ${formatSize(maxFileSize)}`);
|
|
934
|
+
else if (maxFiles != null && files.length >= maxFiles) refuse(`Cannot add more than ${maxFiles} attachments`);
|
|
935
|
+
else if (maxTotalSize != null && total + file.size > maxTotalSize) refuse("Cannot add more files");
|
|
936
|
+
else {
|
|
937
|
+
files.push(file);
|
|
938
|
+
total += file.size;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
return { files, error };
|
|
942
|
+
}
|
|
943
|
+
var hasFiles = (e) => Array.from(e.dataTransfer.types).includes("Files");
|
|
896
944
|
function ChatInput({
|
|
897
945
|
onSend,
|
|
898
946
|
onStop,
|
|
@@ -900,6 +948,19 @@ function ChatInput({
|
|
|
900
948
|
busy,
|
|
901
949
|
placeholder,
|
|
902
950
|
allowFiles = false,
|
|
951
|
+
compact = false,
|
|
952
|
+
accept,
|
|
953
|
+
maxFiles,
|
|
954
|
+
maxFileSize,
|
|
955
|
+
maxTotalSize,
|
|
956
|
+
value: controlled,
|
|
957
|
+
onValueChange,
|
|
958
|
+
textareaRef: externalRef,
|
|
959
|
+
textareaProps,
|
|
960
|
+
renderTextarea,
|
|
961
|
+
above,
|
|
962
|
+
below,
|
|
963
|
+
dropLabel = "Drop files to attach",
|
|
903
964
|
leading,
|
|
904
965
|
trailing,
|
|
905
966
|
className,
|
|
@@ -907,109 +968,216 @@ function ChatInput({
|
|
|
907
968
|
}) {
|
|
908
969
|
const ctx = useOptionalChatContext();
|
|
909
970
|
const cn = useResolvedClassNames(classNames);
|
|
910
|
-
const [
|
|
911
|
-
const
|
|
971
|
+
const [internal, setInternal] = React7.useState("");
|
|
972
|
+
const value = controlled ?? internal;
|
|
973
|
+
const setValue = (next) => {
|
|
974
|
+
if (controlled === void 0) setInternal(next);
|
|
975
|
+
onValueChange?.(next);
|
|
976
|
+
};
|
|
977
|
+
const [files, setFilesState] = React7.useState([]);
|
|
978
|
+
const filesRef = React7.useRef([]);
|
|
979
|
+
const setFiles = (next) => {
|
|
980
|
+
filesRef.current = next;
|
|
981
|
+
setFilesState(next);
|
|
982
|
+
};
|
|
983
|
+
const [fileError, setFileError] = React7.useState(null);
|
|
984
|
+
const [dragging, setDragging] = React7.useState(false);
|
|
985
|
+
const dragDepth = React7.useRef(0);
|
|
912
986
|
const fileRef = React7.useRef(null);
|
|
913
987
|
const textareaRef = React7.useRef(null);
|
|
988
|
+
const setTextareaRef = React7.useCallback(
|
|
989
|
+
(el2) => {
|
|
990
|
+
textareaRef.current = el2;
|
|
991
|
+
if (typeof externalRef === "function") externalRef(el2);
|
|
992
|
+
else if (externalRef) externalRef.current = el2;
|
|
993
|
+
},
|
|
994
|
+
[externalRef]
|
|
995
|
+
);
|
|
914
996
|
const adjustHeight = React7.useCallback(() => {
|
|
915
997
|
const el2 = textareaRef.current;
|
|
916
|
-
if (!el2) return;
|
|
917
|
-
|
|
918
|
-
el2.style.height = `${
|
|
919
|
-
|
|
998
|
+
if (!el2 || renderTextarea) return;
|
|
999
|
+
const { min, max } = compact ? BOUNDS.compact : BOUNDS.dock;
|
|
1000
|
+
el2.style.height = `${min}px`;
|
|
1001
|
+
el2.style.height = `${Math.min(Math.max(el2.scrollHeight, min), max)}px`;
|
|
1002
|
+
}, [renderTextarea, compact]);
|
|
920
1003
|
React7.useEffect(adjustHeight, [value, adjustHeight]);
|
|
921
1004
|
const send = onSend ?? ((message, attached) => void ctx?.chat.sendMessage(message, attached ? { files: attached } : void 0));
|
|
922
1005
|
const stop = onStop ?? (ctx ? () => void ctx.chat.cancel() : void 0);
|
|
923
1006
|
const isBusy = busy ?? ctx?.chat.isStreaming ?? false;
|
|
924
1007
|
const isDisabled = disabled ?? ctx?.chat.isPaused ?? false;
|
|
925
|
-
const
|
|
1008
|
+
const limits = { accept, maxFiles, maxFileSize, maxTotalSize };
|
|
1009
|
+
const addFiles = (incoming) => {
|
|
1010
|
+
if (!incoming.length) return;
|
|
1011
|
+
const next = admitFiles(filesRef.current, incoming, limits);
|
|
1012
|
+
setFiles(next.files);
|
|
1013
|
+
setFileError(next.error);
|
|
1014
|
+
if (fileRef.current) fileRef.current.value = "";
|
|
1015
|
+
};
|
|
1016
|
+
const submit = async () => {
|
|
926
1017
|
const text = value.trim();
|
|
927
1018
|
if (!text && files.length === 0) return;
|
|
928
|
-
|
|
1019
|
+
const sent = files.length ? files : void 0;
|
|
1020
|
+
const result = await send(text, sent);
|
|
1021
|
+
if (result === false) return;
|
|
929
1022
|
setValue("");
|
|
930
1023
|
setFiles([]);
|
|
1024
|
+
setFileError(null);
|
|
931
1025
|
};
|
|
932
1026
|
const canSend = !isDisabled && !isBusy && (Boolean(value.trim()) || files.length > 0);
|
|
933
|
-
|
|
1027
|
+
const onKeyDown = (e) => {
|
|
1028
|
+
textareaProps?.onKeyDown?.(e);
|
|
1029
|
+
if (e.defaultPrevented) return;
|
|
1030
|
+
if (e.key === "Enter" && !e.nativeEvent.isComposing && !e.shiftKey) {
|
|
1031
|
+
e.preventDefault();
|
|
1032
|
+
if (canSend) void submit();
|
|
1033
|
+
}
|
|
1034
|
+
};
|
|
1035
|
+
const onDragEnter = (e) => {
|
|
1036
|
+
if (!allowFiles || !hasFiles(e)) return;
|
|
1037
|
+
e.preventDefault();
|
|
1038
|
+
dragDepth.current += 1;
|
|
1039
|
+
setDragging(true);
|
|
1040
|
+
};
|
|
1041
|
+
const onDragOver = (e) => {
|
|
1042
|
+
if (!allowFiles || !hasFiles(e)) return;
|
|
1043
|
+
e.preventDefault();
|
|
1044
|
+
e.dataTransfer.dropEffect = "copy";
|
|
1045
|
+
};
|
|
1046
|
+
const onDragLeave = (e) => {
|
|
1047
|
+
if (!allowFiles || dragDepth.current === 0) return;
|
|
1048
|
+
e.preventDefault();
|
|
1049
|
+
dragDepth.current = Math.max(0, dragDepth.current - 1);
|
|
1050
|
+
if (dragDepth.current === 0) setDragging(false);
|
|
1051
|
+
};
|
|
1052
|
+
const onDrop = (e) => {
|
|
1053
|
+
if (!allowFiles || !hasFiles(e)) return;
|
|
1054
|
+
e.preventDefault();
|
|
1055
|
+
dragDepth.current = 0;
|
|
1056
|
+
setDragging(false);
|
|
1057
|
+
addFiles(Array.from(e.dataTransfer.files));
|
|
1058
|
+
textareaRef.current?.focus();
|
|
1059
|
+
};
|
|
1060
|
+
const fieldProps = {
|
|
1061
|
+
rows: 1,
|
|
1062
|
+
...textareaProps,
|
|
1063
|
+
ref: setTextareaRef,
|
|
1064
|
+
className: cx("agno-input__textarea", cn.textarea, textareaProps?.className),
|
|
1065
|
+
value,
|
|
1066
|
+
placeholder: placeholder ?? (isBusy ? "Running..." : "Ask anything..."),
|
|
1067
|
+
disabled: isDisabled,
|
|
1068
|
+
onChange: (e) => {
|
|
1069
|
+
setValue(e.target.value);
|
|
1070
|
+
textareaProps?.onChange?.(e);
|
|
1071
|
+
},
|
|
1072
|
+
onKeyDown
|
|
1073
|
+
};
|
|
1074
|
+
const iconSize = compact ? 14 : 16;
|
|
1075
|
+
const field = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-input__field", children: renderTextarea ? renderTextarea(fieldProps) : /* @__PURE__ */ jsxRuntime.jsx("textarea", { ...fieldProps }) });
|
|
1076
|
+
const attach = allowFiles && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
934
1077
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
935
|
-
|
|
1078
|
+
"button",
|
|
936
1079
|
{
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1080
|
+
type: "button",
|
|
1081
|
+
className: cx("agno-btn", compact ? "agno-btn--ghost" : "agno-btn--outline", "agno-btn--icon", cn.attachButton),
|
|
1082
|
+
onClick: () => fileRef.current?.click(),
|
|
1083
|
+
disabled: isDisabled,
|
|
1084
|
+
"aria-label": files.length ? `Attach files; ${files.length} attached` : "Attach files",
|
|
1085
|
+
title: files.length ? files.map((f) => f.name).join(", ") : void 0,
|
|
1086
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Paperclip, { size: iconSize })
|
|
941
1087
|
}
|
|
942
1088
|
),
|
|
943
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
944
|
-
"
|
|
1089
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1090
|
+
"input",
|
|
945
1091
|
{
|
|
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
|
-
}
|
|
1092
|
+
ref: fileRef,
|
|
1093
|
+
type: "file",
|
|
1094
|
+
multiple: true,
|
|
1095
|
+
hidden: true,
|
|
1096
|
+
accept,
|
|
1097
|
+
onChange: (e) => addFiles(Array.from(e.target.files ?? []))
|
|
959
1098
|
}
|
|
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
|
-
|
|
1000
|
-
|
|
1099
|
+
)
|
|
1100
|
+
] });
|
|
1101
|
+
const primary = isBusy && stop ? (
|
|
1102
|
+
// The same button the arrow sends from, with AgentOS's square-stop in it.
|
|
1103
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1104
|
+
"button",
|
|
1105
|
+
{
|
|
1106
|
+
type: "button",
|
|
1107
|
+
className: cx("agno-btn", "agno-btn--icon", cn.stopButton),
|
|
1108
|
+
onClick: stop,
|
|
1109
|
+
"aria-label": "Stop",
|
|
1110
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Stop, {})
|
|
1111
|
+
}
|
|
1112
|
+
)
|
|
1113
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1114
|
+
"button",
|
|
1115
|
+
{
|
|
1116
|
+
type: "button",
|
|
1117
|
+
className: cx("agno-btn", "agno-btn--icon", cn.sendButton),
|
|
1118
|
+
onClick: () => void submit(),
|
|
1119
|
+
disabled: !canSend,
|
|
1120
|
+
"aria-label": "Send",
|
|
1121
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUp, { size: iconSize })
|
|
1122
|
+
}
|
|
1123
|
+
);
|
|
1124
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1125
|
+
"div",
|
|
1126
|
+
{
|
|
1127
|
+
className: cx("agno-input", compact && "agno-input--compact", cn.input, className),
|
|
1128
|
+
"data-dragging": dragging ? "true" : void 0,
|
|
1129
|
+
onDragEnter,
|
|
1130
|
+
onDragOver,
|
|
1131
|
+
onDragLeave,
|
|
1132
|
+
onDrop,
|
|
1133
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-input__dock", children: [
|
|
1134
|
+
dragging && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-input__drop", cn.dropOverlay), "aria-hidden": true, children: [
|
|
1135
|
+
/* @__PURE__ */ jsxRuntime.jsx(Paperclip, { size: 16 }),
|
|
1136
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: dropLabel })
|
|
1137
|
+
] }),
|
|
1138
|
+
above,
|
|
1139
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1140
|
+
FilePreview,
|
|
1001
1141
|
{
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1142
|
+
files,
|
|
1143
|
+
onRemove: (i) => {
|
|
1144
|
+
setFiles(filesRef.current.filter((_, j) => j !== i));
|
|
1145
|
+
setFileError(null);
|
|
1146
|
+
},
|
|
1147
|
+
onClear: () => {
|
|
1148
|
+
setFiles([]);
|
|
1149
|
+
setFileError(null);
|
|
1150
|
+
},
|
|
1151
|
+
className: cn.files
|
|
1008
1152
|
}
|
|
1009
|
-
)
|
|
1153
|
+
),
|
|
1154
|
+
fileError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx("agno-input__error", cn.fileError), role: "alert", children: fileError }),
|
|
1155
|
+
compact ? (
|
|
1156
|
+
// One line: the field, then every control beside it.
|
|
1157
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-input__row", cn.inputRow), children: [
|
|
1158
|
+
leading,
|
|
1159
|
+
field,
|
|
1160
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-input__actions", children: [
|
|
1161
|
+
attach,
|
|
1162
|
+
trailing,
|
|
1163
|
+
primary
|
|
1164
|
+
] })
|
|
1165
|
+
] })
|
|
1166
|
+
) : field,
|
|
1167
|
+
below,
|
|
1168
|
+
!compact && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-input__row", cn.inputRow), children: [
|
|
1169
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-input__actions", children: [
|
|
1170
|
+
leading,
|
|
1171
|
+
attach
|
|
1172
|
+
] }),
|
|
1173
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-input__actions", children: [
|
|
1174
|
+
trailing,
|
|
1175
|
+
primary
|
|
1176
|
+
] })
|
|
1177
|
+
] })
|
|
1010
1178
|
] })
|
|
1011
|
-
|
|
1012
|
-
|
|
1179
|
+
}
|
|
1180
|
+
);
|
|
1013
1181
|
}
|
|
1014
1182
|
function normalizeFollowups(items) {
|
|
1015
1183
|
if (!items?.length) return [];
|
|
@@ -1532,20 +1700,15 @@ var PREVIEW_WIDTH = 320;
|
|
|
1532
1700
|
var GAP = 8;
|
|
1533
1701
|
var OPEN_DELAY = 140;
|
|
1534
1702
|
var CLOSE_DELAY = 120;
|
|
1535
|
-
function usePlacement(anchor, open) {
|
|
1703
|
+
function usePlacement(anchor, open, { width = PREVIEW_WIDTH, align = "center" } = {}) {
|
|
1536
1704
|
const [placement, setPlacement] = React7.useState(null);
|
|
1537
1705
|
useIsomorphicLayoutEffect(() => {
|
|
1538
1706
|
if (!open || !anchor) return;
|
|
1539
1707
|
const place = () => {
|
|
1540
1708
|
const rect = anchor.getBoundingClientRect();
|
|
1541
1709
|
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
|
-
);
|
|
1710
|
+
const wanted = align === "center" ? rect.left + rect.width / 2 - width / 2 : rect.left;
|
|
1711
|
+
const left = Math.max(GAP, Math.min(wanted, window.innerWidth - width - GAP));
|
|
1549
1712
|
setPlacement({
|
|
1550
1713
|
top: side === "top" ? rect.top - GAP : rect.bottom + GAP,
|
|
1551
1714
|
left,
|
|
@@ -1559,7 +1722,7 @@ function usePlacement(anchor, open) {
|
|
|
1559
1722
|
window.removeEventListener("scroll", place, true);
|
|
1560
1723
|
window.removeEventListener("resize", place);
|
|
1561
1724
|
};
|
|
1562
|
-
}, [anchor, open]);
|
|
1725
|
+
}, [anchor, open, width, align]);
|
|
1563
1726
|
return placement;
|
|
1564
1727
|
}
|
|
1565
1728
|
function HoverPreview({
|
|
@@ -1661,16 +1824,20 @@ function labelOf(children) {
|
|
|
1661
1824
|
}
|
|
1662
1825
|
function CitationMarker({
|
|
1663
1826
|
source,
|
|
1664
|
-
className
|
|
1827
|
+
className,
|
|
1828
|
+
Link
|
|
1665
1829
|
}) {
|
|
1666
|
-
|
|
1830
|
+
const props = {
|
|
1831
|
+
className: cx("agno-cite", className),
|
|
1832
|
+
href: source.url ?? `#${source.anchorId}`,
|
|
1833
|
+
"aria-label": `Source ${source.index}: ${source.title}`
|
|
1834
|
+
};
|
|
1835
|
+
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
1836
|
"a",
|
|
1668
1837
|
{
|
|
1669
|
-
|
|
1670
|
-
href: source.url ?? `#${source.anchorId}`,
|
|
1838
|
+
...props,
|
|
1671
1839
|
target: source.url ? "_blank" : void 0,
|
|
1672
1840
|
rel: source.url ? "noreferrer noopener" : void 0,
|
|
1673
|
-
"aria-label": `Source ${source.index}: ${source.title}`,
|
|
1674
1841
|
children: source.index
|
|
1675
1842
|
}
|
|
1676
1843
|
) });
|
|
@@ -1769,8 +1936,8 @@ function elementsFor(ctx) {
|
|
|
1769
1936
|
...rest
|
|
1770
1937
|
}) {
|
|
1771
1938
|
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 });
|
|
1939
|
+
if (cited) return /* @__PURE__ */ jsxRuntime.jsx(CitationMarker, { source: cited, className: ctx.markerClass, Link: ctx.Link });
|
|
1940
|
+
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
1941
|
const source = sourceForUrl(href, ctx.sources);
|
|
1775
1942
|
if (!href || !/^https?:\/\//i.test(href) || !source && !ctx.canResolve) return link;
|
|
1776
1943
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1836,23 +2003,27 @@ function Markdown({
|
|
|
1836
2003
|
sources,
|
|
1837
2004
|
streaming,
|
|
1838
2005
|
codeCopy,
|
|
2006
|
+
linkComponent,
|
|
1839
2007
|
options
|
|
1840
2008
|
}) {
|
|
1841
2009
|
const fromMessage = useSources();
|
|
1842
2010
|
const cn = useResolvedClassNames();
|
|
1843
2011
|
const canResolve = Boolean(useLinkPreviewResolver());
|
|
1844
2012
|
const fromProvider = useCodeCopy();
|
|
2013
|
+
const providerLink = useLinkComponent();
|
|
1845
2014
|
const cited = sources ?? fromMessage;
|
|
1846
2015
|
const copy = codeCopy ?? fromProvider ?? true;
|
|
2016
|
+
const Link = linkComponent ?? providerLink;
|
|
1847
2017
|
const components = React7.useMemo(
|
|
1848
2018
|
() => elementsFor({
|
|
1849
2019
|
sources: cited,
|
|
1850
2020
|
canResolve,
|
|
1851
2021
|
markerClass: cn.citationMarker,
|
|
1852
2022
|
copyClass: cn.copyButton,
|
|
1853
|
-
codeCopy: copy
|
|
2023
|
+
codeCopy: copy,
|
|
2024
|
+
Link
|
|
1854
2025
|
}),
|
|
1855
|
-
[cited, canResolve, cn.citationMarker, cn.copyButton, copy]
|
|
2026
|
+
[cited, canResolve, cn.citationMarker, cn.copyButton, copy, Link]
|
|
1856
2027
|
);
|
|
1857
2028
|
const text = React7.useMemo(() => linkCitations(content, cited), [content, cited]);
|
|
1858
2029
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1936,7 +2107,7 @@ function isNoiseEvent(e) {
|
|
|
1936
2107
|
}
|
|
1937
2108
|
var isMemoryEvent = (e) => eventName(e).includes("MemoryUpdate");
|
|
1938
2109
|
var isMemoryCompleted = (e) => eventName(e).includes("MemoryUpdateCompleted");
|
|
1939
|
-
var isReasoningEvent = (e) =>
|
|
2110
|
+
var isReasoningEvent = (e) => chunk55HQJGLP_cjs.isReasoningStepEvent(e) || chunk55HQJGLP_cjs.isReasoningCompletedEvent(e) || eventName(e).includes("ReasoningStarted");
|
|
1940
2111
|
function formatDuration(seconds) {
|
|
1941
2112
|
return seconds < 10 ? `${seconds.toFixed(1)}s` : `${Math.round(seconds)}s`;
|
|
1942
2113
|
}
|
|
@@ -1970,14 +2141,14 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
1970
2141
|
if (member) put(`member:${runId}`, { kind: "member", id: `member-${runId}`, member });
|
|
1971
2142
|
continue;
|
|
1972
2143
|
}
|
|
1973
|
-
if (
|
|
2144
|
+
if (chunk55HQJGLP_cjs.isToolEvent(e)) {
|
|
1974
2145
|
if (hideTools) continue;
|
|
1975
|
-
for (const tool of
|
|
2146
|
+
for (const tool of chunk55HQJGLP_cjs.toolsFromEvent(e)) {
|
|
1976
2147
|
const key = `tool:${tool.tool_call_id ?? tool.tool_name}`;
|
|
1977
2148
|
const at = indexOf.get(key);
|
|
1978
2149
|
const previous = at != null ? steps[at].tool : void 0;
|
|
1979
2150
|
const merged = { ...previous, ...tool };
|
|
1980
|
-
if (!
|
|
2151
|
+
if (!chunk55HQJGLP_cjs.isToolCompletedEvent(e) && previous?.result != null) merged.result = previous.result;
|
|
1981
2152
|
put(key, { kind: "tool", id: key, tool: merged });
|
|
1982
2153
|
}
|
|
1983
2154
|
continue;
|
|
@@ -1988,7 +2159,7 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
1988
2159
|
const at = indexOf.get(key);
|
|
1989
2160
|
const previous = at != null ? steps[at].steps : [];
|
|
1990
2161
|
const incoming = e.reasoning_steps ?? e.extra_data?.reasoning_steps ?? [];
|
|
1991
|
-
const completed =
|
|
2162
|
+
const completed = chunk55HQJGLP_cjs.isReasoningCompletedEvent(e);
|
|
1992
2163
|
put(key, {
|
|
1993
2164
|
kind: "reasoning",
|
|
1994
2165
|
id: key,
|
|
@@ -2023,7 +2194,7 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
2023
2194
|
label: "Run Continued",
|
|
2024
2195
|
icon: "continued"
|
|
2025
2196
|
});
|
|
2026
|
-
} else if (
|
|
2197
|
+
} else if (chunk55HQJGLP_cjs.isCompletedEvent(e)) {
|
|
2027
2198
|
put(`completed:${runKey}`, {
|
|
2028
2199
|
kind: "status",
|
|
2029
2200
|
id: `completed-${runKey}`,
|
|
@@ -2031,16 +2202,16 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
2031
2202
|
detail: durationOf(e),
|
|
2032
2203
|
icon: "run"
|
|
2033
2204
|
});
|
|
2034
|
-
} else if (
|
|
2205
|
+
} else if (chunk55HQJGLP_cjs.isPausedEvent(e)) {
|
|
2035
2206
|
put(`paused:${runKey}`, { kind: "status", id: `paused-${runKey}`, label: "Run Paused", icon: "run" });
|
|
2036
|
-
} else if (
|
|
2207
|
+
} else if (chunk55HQJGLP_cjs.isCancelledEvent(e)) {
|
|
2037
2208
|
put(`cancelled:${runKey}`, {
|
|
2038
2209
|
kind: "status",
|
|
2039
2210
|
id: `cancelled-${runKey}`,
|
|
2040
2211
|
label: "Run Cancelled",
|
|
2041
2212
|
icon: "run"
|
|
2042
2213
|
});
|
|
2043
|
-
} else if (
|
|
2214
|
+
} else if (chunk55HQJGLP_cjs.isErrorEvent(e)) {
|
|
2044
2215
|
const detail = typeof e.content === "string" ? e.content : e.error;
|
|
2045
2216
|
put(`error:${runKey}`, { kind: "status", id: `error-${runKey}`, label: detail || "Run Error", icon: "run" });
|
|
2046
2217
|
}
|
|
@@ -2088,7 +2259,7 @@ function runDuration(message) {
|
|
|
2088
2259
|
function liveActivity(message) {
|
|
2089
2260
|
const events = message.events ?? [];
|
|
2090
2261
|
for (let i = events.length - 1; i >= 0; i--) {
|
|
2091
|
-
const label2 =
|
|
2262
|
+
const label2 = chunk55HQJGLP_cjs.activityLabel(events[i]);
|
|
2092
2263
|
if (label2) return label2;
|
|
2093
2264
|
}
|
|
2094
2265
|
return message.activity ?? null;
|
|
@@ -2263,12 +2434,25 @@ function SourceCard({
|
|
|
2263
2434
|
className
|
|
2264
2435
|
}) {
|
|
2265
2436
|
const cn = useResolvedClassNames();
|
|
2437
|
+
const Link = useLinkComponent();
|
|
2266
2438
|
const { preview } = useLinkPreview(source.url, false);
|
|
2267
2439
|
const body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2268
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2269
|
-
|
|
2440
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2441
|
+
Favicon,
|
|
2442
|
+
{
|
|
2443
|
+
className: "agno-source__icon",
|
|
2444
|
+
url: preview?.favicon ?? source.url,
|
|
2445
|
+
kind: source.kind,
|
|
2446
|
+
size: 24
|
|
2447
|
+
}
|
|
2448
|
+
),
|
|
2449
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-source__title", children: preview?.title ?? source.title }),
|
|
2450
|
+
source.url && /* @__PURE__ */ jsxRuntime.jsx(LinkIcon, { className: "agno-source__link" })
|
|
2270
2451
|
] });
|
|
2271
2452
|
const classes = cx("agno-source", `agno-source--${source.kind}`, cn.sourceCard, className);
|
|
2453
|
+
if (source.url && Link) {
|
|
2454
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Link, { id: source.anchorId, className: classes, href: source.url, title: source.url, children: body });
|
|
2455
|
+
}
|
|
2272
2456
|
return source.url ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2273
2457
|
"a",
|
|
2274
2458
|
{
|
|
@@ -2282,33 +2466,118 @@ function SourceCard({
|
|
|
2282
2466
|
}
|
|
2283
2467
|
) : /* @__PURE__ */ jsxRuntime.jsx("div", { id: source.anchorId, className: classes, children: body });
|
|
2284
2468
|
}
|
|
2469
|
+
var LIST_WIDTH = 240;
|
|
2470
|
+
function SourcesOverflow({ sources }) {
|
|
2471
|
+
const [open, setOpen] = React7.useState(false);
|
|
2472
|
+
const [anchor, setAnchor] = React7.useState(null);
|
|
2473
|
+
const timer = React7.useRef(null);
|
|
2474
|
+
const id = React7.useId();
|
|
2475
|
+
const placement = usePlacement(anchor, open, { width: LIST_WIDTH, align: "start" });
|
|
2476
|
+
const schedule = React7.useCallback((next) => {
|
|
2477
|
+
if (timer.current) clearTimeout(timer.current);
|
|
2478
|
+
timer.current = setTimeout(() => setOpen(next), next ? OPEN_DELAY : CLOSE_DELAY);
|
|
2479
|
+
}, []);
|
|
2480
|
+
React7.useEffect(
|
|
2481
|
+
() => () => {
|
|
2482
|
+
if (timer.current) clearTimeout(timer.current);
|
|
2483
|
+
},
|
|
2484
|
+
[]
|
|
2485
|
+
);
|
|
2486
|
+
React7.useEffect(() => {
|
|
2487
|
+
if (!open) return;
|
|
2488
|
+
const onKey = (e) => {
|
|
2489
|
+
if (e.key === "Escape") setOpen(false);
|
|
2490
|
+
};
|
|
2491
|
+
document.addEventListener("keydown", onKey);
|
|
2492
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
2493
|
+
}, [open]);
|
|
2494
|
+
const [mounted, setMounted] = React7.useState(false);
|
|
2495
|
+
React7.useEffect(() => setMounted(true), []);
|
|
2496
|
+
const light = anchor?.closest(".agno-light") ? "agno-light" : void 0;
|
|
2497
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2498
|
+
"span",
|
|
2499
|
+
{
|
|
2500
|
+
className: "agno-sources__overflow",
|
|
2501
|
+
ref: setAnchor,
|
|
2502
|
+
onMouseEnter: () => schedule(true),
|
|
2503
|
+
onMouseLeave: () => schedule(false),
|
|
2504
|
+
children: [
|
|
2505
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2506
|
+
"button",
|
|
2507
|
+
{
|
|
2508
|
+
type: "button",
|
|
2509
|
+
className: "agno-sources__more",
|
|
2510
|
+
"aria-label": `${sources.length} more sources`,
|
|
2511
|
+
"aria-expanded": open,
|
|
2512
|
+
"aria-controls": open ? id : void 0,
|
|
2513
|
+
onClick: () => setOpen((v) => !v),
|
|
2514
|
+
onFocus: () => setOpen(true),
|
|
2515
|
+
onBlur: () => schedule(false),
|
|
2516
|
+
children: [
|
|
2517
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-sources__stack", "aria-hidden": true, children: sources.slice(0, 3).map((source) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2518
|
+
Favicon,
|
|
2519
|
+
{
|
|
2520
|
+
className: "agno-sources__stack-icon",
|
|
2521
|
+
url: source.url,
|
|
2522
|
+
kind: source.kind,
|
|
2523
|
+
size: 24
|
|
2524
|
+
},
|
|
2525
|
+
source.anchorId
|
|
2526
|
+
)) }),
|
|
2527
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "agno-sources__more-label", children: [
|
|
2528
|
+
"+",
|
|
2529
|
+
sources.length,
|
|
2530
|
+
" more"
|
|
2531
|
+
] })
|
|
2532
|
+
]
|
|
2533
|
+
}
|
|
2534
|
+
),
|
|
2535
|
+
mounted && open && placement && reactDom.createPortal(
|
|
2536
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2537
|
+
"div",
|
|
2538
|
+
{
|
|
2539
|
+
id,
|
|
2540
|
+
role: "group",
|
|
2541
|
+
"aria-label": "More sources",
|
|
2542
|
+
className: cx("agno-sources__list", `agno-sources__list--${placement.side}`, light),
|
|
2543
|
+
style: { top: placement.top, left: placement.left, width: LIST_WIDTH },
|
|
2544
|
+
onMouseEnter: () => schedule(true),
|
|
2545
|
+
onMouseLeave: () => schedule(false),
|
|
2546
|
+
onFocus: () => schedule(true),
|
|
2547
|
+
onBlur: () => schedule(false),
|
|
2548
|
+
children: sources.map((source) => /* @__PURE__ */ jsxRuntime.jsx(SourceCard, { source, className: "agno-source--row" }, source.anchorId))
|
|
2549
|
+
}
|
|
2550
|
+
),
|
|
2551
|
+
document.body
|
|
2552
|
+
)
|
|
2553
|
+
]
|
|
2554
|
+
}
|
|
2555
|
+
);
|
|
2556
|
+
}
|
|
2285
2557
|
function Citations({
|
|
2286
2558
|
references,
|
|
2287
2559
|
citations,
|
|
2288
2560
|
sources: given,
|
|
2289
|
-
title = "Sources",
|
|
2290
|
-
max =
|
|
2561
|
+
title = "Sources used",
|
|
2562
|
+
max = 3,
|
|
2291
2563
|
className,
|
|
2292
2564
|
classNames
|
|
2293
2565
|
}) {
|
|
2294
2566
|
const cn = useResolvedClassNames(classNames);
|
|
2295
2567
|
const uid = React7.useId();
|
|
2296
|
-
const [expanded, setExpanded] = React7.useState(false);
|
|
2297
2568
|
const sources = React7.useMemo(
|
|
2298
2569
|
() => given ?? collectSources(references, citations, uid),
|
|
2299
2570
|
[given, references, citations, uid]
|
|
2300
2571
|
);
|
|
2301
2572
|
if (sources.length === 0) return null;
|
|
2302
|
-
const limit = max > 0
|
|
2573
|
+
const limit = max > 0 ? max : sources.length;
|
|
2303
2574
|
const visible = sources.slice(0, limit);
|
|
2304
|
-
const hidden = sources.
|
|
2575
|
+
const hidden = sources.slice(limit);
|
|
2305
2576
|
return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: cx("agno-sources", cn.citations, className), "aria-label": title, children: [
|
|
2306
2577
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-sources__head", children: title }),
|
|
2307
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
hidden,
|
|
2311
|
-
" more"
|
|
2578
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-sources__grid", children: [
|
|
2579
|
+
visible.map((source) => /* @__PURE__ */ jsxRuntime.jsx(SourceCard, { source }, source.anchorId)),
|
|
2580
|
+
hidden.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(SourcesOverflow, { sources: hidden })
|
|
2312
2581
|
] })
|
|
2313
2582
|
] });
|
|
2314
2583
|
}
|
|
@@ -2362,10 +2631,11 @@ function Message({
|
|
|
2362
2631
|
}, [message.references, message.citations, message.content, uid]);
|
|
2363
2632
|
const isUser = message.role === "user";
|
|
2364
2633
|
const isAgent = message.role === "agent";
|
|
2365
|
-
const
|
|
2634
|
+
const hasSources = isAgent && !hideSources && sources.length > 0;
|
|
2635
|
+
const showSources = hasSources && !message.streaming;
|
|
2366
2636
|
const content = React7.useMemo(
|
|
2367
|
-
() =>
|
|
2368
|
-
[message.content,
|
|
2637
|
+
() => hasSources && message.content ? withoutSourcesLine(message.content) : message.content,
|
|
2638
|
+
[message.content, hasSources]
|
|
2369
2639
|
);
|
|
2370
2640
|
const hasActivity = !message.content && !hasBehindTheScenes(message, { hideReasoning, hideTools });
|
|
2371
2641
|
const kind = isUser ? "user" : isAgent ? entityType : "system";
|
|
@@ -2524,6 +2794,7 @@ function ChatWindow({
|
|
|
2524
2794
|
userInitials,
|
|
2525
2795
|
emptyState,
|
|
2526
2796
|
allowFiles,
|
|
2797
|
+
compactInput,
|
|
2527
2798
|
disabled,
|
|
2528
2799
|
renderMarkdown,
|
|
2529
2800
|
showErrors,
|
|
@@ -2532,6 +2803,7 @@ function ChatWindow({
|
|
|
2532
2803
|
hideFollowups,
|
|
2533
2804
|
onFollowup,
|
|
2534
2805
|
followupsTitle,
|
|
2806
|
+
renderMessage,
|
|
2535
2807
|
header,
|
|
2536
2808
|
composer,
|
|
2537
2809
|
className,
|
|
@@ -2558,6 +2830,7 @@ function ChatWindow({
|
|
|
2558
2830
|
renderMarkdown: markdown,
|
|
2559
2831
|
classNames: cn,
|
|
2560
2832
|
emptyState,
|
|
2833
|
+
renderMessage,
|
|
2561
2834
|
footer: pausedMessage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2562
2835
|
HumanInput,
|
|
2563
2836
|
{
|
|
@@ -2600,6 +2873,7 @@ function ChatWindow({
|
|
|
2600
2873
|
disabled: disabled || chat.isPaused,
|
|
2601
2874
|
placeholder,
|
|
2602
2875
|
allowFiles,
|
|
2876
|
+
compact: compactInput,
|
|
2603
2877
|
classNames: cn
|
|
2604
2878
|
}
|
|
2605
2879
|
)
|
|
@@ -2897,7 +3171,7 @@ function SessionList({
|
|
|
2897
3171
|
}
|
|
2898
3172
|
function AgnoChat(props) {
|
|
2899
3173
|
const client = React7.useMemo(
|
|
2900
|
-
() => props.client ?? new
|
|
3174
|
+
() => props.client ?? new chunk55HQJGLP_cjs.AgnoClient({ baseUrl: props.baseUrl ?? "", headers: props.headers }),
|
|
2901
3175
|
[props.client, props.baseUrl, props.headers]
|
|
2902
3176
|
);
|
|
2903
3177
|
const [discovered, setDiscovered] = React7.useState(props.entities ?? []);
|
|
@@ -2988,6 +3262,7 @@ function AgnoChat(props) {
|
|
|
2988
3262
|
chat,
|
|
2989
3263
|
placeholder: props.placeholder,
|
|
2990
3264
|
allowFiles: props.allowFiles ?? true,
|
|
3265
|
+
compactInput: props.compactInput,
|
|
2991
3266
|
disabled: !entity,
|
|
2992
3267
|
renderMarkdown: props.renderMarkdown,
|
|
2993
3268
|
showErrors: props.showErrors,
|
|
@@ -3005,6 +3280,7 @@ function AgnoChat(props) {
|
|
|
3005
3280
|
disabled: !entity || chat.isPaused,
|
|
3006
3281
|
placeholder: props.placeholder,
|
|
3007
3282
|
allowFiles: props.allowFiles ?? true,
|
|
3283
|
+
compact: props.compactInput,
|
|
3008
3284
|
classNames: cn,
|
|
3009
3285
|
trailing: showPicker ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3010
3286
|
EntitySelector,
|
|
@@ -3033,6 +3309,7 @@ function AgnoChat(props) {
|
|
|
3033
3309
|
renderMarkdown: props.renderMarkdown,
|
|
3034
3310
|
resolveLinkPreview: props.resolveLinkPreview,
|
|
3035
3311
|
codeCopy: props.codeCopy,
|
|
3312
|
+
linkComponent: props.linkComponent,
|
|
3036
3313
|
as: false,
|
|
3037
3314
|
children: root
|
|
3038
3315
|
}
|
|
@@ -3199,7 +3476,7 @@ function fold(events) {
|
|
|
3199
3476
|
last.created_at = e.created_at ?? last.created_at;
|
|
3200
3477
|
continue;
|
|
3201
3478
|
}
|
|
3202
|
-
rows.push({ event: name, source, count: 1, created_at: e.created_at, detail:
|
|
3479
|
+
rows.push({ event: name, source, count: 1, created_at: e.created_at, detail: chunk55HQJGLP_cjs.activityLabel(e) });
|
|
3203
3480
|
}
|
|
3204
3481
|
return rows;
|
|
3205
3482
|
}
|
|
@@ -3251,12 +3528,14 @@ exports.Favicon = Favicon;
|
|
|
3251
3528
|
exports.FileAudio = FileAudio;
|
|
3252
3529
|
exports.FileIcon = FileIcon;
|
|
3253
3530
|
exports.FilePreview = FilePreview;
|
|
3531
|
+
exports.FileType = FileType;
|
|
3254
3532
|
exports.FileVideo = FileVideo;
|
|
3255
3533
|
exports.Followups = Followups;
|
|
3256
3534
|
exports.Globe = Globe;
|
|
3257
3535
|
exports.GridLoader = GridLoader;
|
|
3258
3536
|
exports.HoverPreview = HoverPreview;
|
|
3259
3537
|
exports.HumanInput = HumanInput;
|
|
3538
|
+
exports.LinkIcon = LinkIcon;
|
|
3260
3539
|
exports.LinkPreviewCard = LinkPreviewCard;
|
|
3261
3540
|
exports.Markdown = Markdown;
|
|
3262
3541
|
exports.MemberResponses = MemberResponses;
|
|
@@ -3281,12 +3560,14 @@ exports.ToolCalls = ToolCalls;
|
|
|
3281
3560
|
exports.Trash = Trash;
|
|
3282
3561
|
exports.WorkflowSteps = WorkflowSteps;
|
|
3283
3562
|
exports.Wrench = Wrench;
|
|
3563
|
+
exports.admitFiles = admitFiles;
|
|
3284
3564
|
exports.behindTheScenesItems = behindTheScenesItems;
|
|
3285
3565
|
exports.behindTheScenesLabel = behindTheScenesLabel;
|
|
3286
3566
|
exports.collectSources = collectSources;
|
|
3287
3567
|
exports.cx = cx;
|
|
3288
3568
|
exports.displayUrl = displayUrl;
|
|
3289
3569
|
exports.faviconUrl = faviconUrl;
|
|
3570
|
+
exports.fileAccepted = fileAccepted;
|
|
3290
3571
|
exports.getProviderIcon = getProviderIcon;
|
|
3291
3572
|
exports.hasBehindTheScenes = hasBehindTheScenes;
|
|
3292
3573
|
exports.linkCitations = linkCitations;
|
|
@@ -3297,6 +3578,7 @@ exports.sourceHost = sourceHost;
|
|
|
3297
3578
|
exports.sourcesFromMarkdown = sourcesFromMarkdown;
|
|
3298
3579
|
exports.useAgnoChat = useAgnoChat;
|
|
3299
3580
|
exports.useChatContext = useChatContext;
|
|
3581
|
+
exports.useLinkComponent = useLinkComponent;
|
|
3300
3582
|
exports.useLinkPreview = useLinkPreview;
|
|
3301
3583
|
exports.useOptionalChatContext = useOptionalChatContext;
|
|
3302
3584
|
exports.useResolvedChat = useResolvedChat;
|
|
@@ -3304,5 +3586,5 @@ exports.useResolvedClassNames = useResolvedClassNames;
|
|
|
3304
3586
|
exports.useSources = useSources;
|
|
3305
3587
|
exports.withoutSourcesLine = withoutSourcesLine;
|
|
3306
3588
|
exports.writeClipboard = writeClipboard;
|
|
3307
|
-
//# sourceMappingURL=chunk-
|
|
3308
|
-
//# sourceMappingURL=chunk-
|
|
3589
|
+
//# sourceMappingURL=chunk-Q73XHL35.cjs.map
|
|
3590
|
+
//# sourceMappingURL=chunk-Q73XHL35.cjs.map
|