@agno-hq/chat-react 0.3.1 → 0.3.3
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 +35 -5
- package/dist/chat/index.cjs +94 -82
- package/dist/chat/index.d.cts +72 -17
- package/dist/chat/index.d.ts +72 -17
- package/dist/chat/index.js +1 -1
- package/dist/{chunk-JEPFGKHH.cjs → chunk-3IEYJIYJ.cjs} +249 -222
- package/dist/chunk-3IEYJIYJ.cjs.map +1 -0
- package/dist/{chunk-BZC2674Z.js → chunk-E4CFQ457.js} +103 -79
- package/dist/chunk-E4CFQ457.js.map +1 -0
- package/dist/index.cjs +95 -83
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/styles.css +57 -19
- package/package.json +9 -11
- package/dist/chunk-BZC2674Z.js.map +0 -1
- package/dist/chunk-JEPFGKHH.cjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunk55HQJGLP_cjs = require('./chunk-55HQJGLP.cjs');
|
|
4
|
-
var
|
|
4
|
+
var React8 = require('react');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
7
|
var lucideReact = require('lucide-react');
|
|
@@ -9,43 +9,43 @@ var streamdown = require('streamdown');
|
|
|
9
9
|
|
|
10
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var React8__default = /*#__PURE__*/_interopDefault(React8);
|
|
13
13
|
|
|
14
14
|
var messageCounter = 0;
|
|
15
15
|
var nextId = () => `m${Date.now().toString(36)}-${(messageCounter++).toString(36)}`;
|
|
16
16
|
var nowSeconds = () => Math.floor(Date.now() / 1e3);
|
|
17
17
|
function useAgnoChat(options) {
|
|
18
18
|
const { entity, userId, onEvent, onSessionId } = options;
|
|
19
|
-
const client =
|
|
19
|
+
const client = React8.useMemo(() => {
|
|
20
20
|
if (options.client) return options.client;
|
|
21
21
|
return new chunk55HQJGLP_cjs.AgnoClient({ baseUrl: options.baseUrl ?? "", headers: options.headers });
|
|
22
22
|
}, [options.client, options.baseUrl, JSON.stringify(options.headers)]);
|
|
23
|
-
const [messages, setMessages] =
|
|
24
|
-
const [events, setEvents] =
|
|
25
|
-
const [currentEvent, setCurrentEvent] =
|
|
26
|
-
const [status, setStatus] =
|
|
27
|
-
const [activity, setActivity] =
|
|
28
|
-
const [error, setError] =
|
|
29
|
-
const [sessionId, setSessionId] =
|
|
30
|
-
const [sessions, setSessions] =
|
|
31
|
-
const [sessionsLoading, setSessionsLoading] =
|
|
32
|
-
const [backgroundRunning, setBackgroundRunning] =
|
|
33
|
-
const abortRef =
|
|
34
|
-
const channelRef =
|
|
35
|
-
const backgroundRef =
|
|
36
|
-
const activeMsgIdRef =
|
|
37
|
-
const runIdRef =
|
|
38
|
-
const entityRef =
|
|
39
|
-
const sessionIdRef =
|
|
40
|
-
const pendingSessionNameRef =
|
|
41
|
-
const bumpedSessionRef =
|
|
42
|
-
|
|
23
|
+
const [messages, setMessages] = React8.useState(options.initialMessages ?? []);
|
|
24
|
+
const [events, setEvents] = React8.useState([]);
|
|
25
|
+
const [currentEvent, setCurrentEvent] = React8.useState(null);
|
|
26
|
+
const [status, setStatus] = React8.useState("idle");
|
|
27
|
+
const [activity, setActivity] = React8.useState(null);
|
|
28
|
+
const [error, setError] = React8.useState(null);
|
|
29
|
+
const [sessionId, setSessionId] = React8.useState(options.sessionId);
|
|
30
|
+
const [sessions, setSessions] = React8.useState([]);
|
|
31
|
+
const [sessionsLoading, setSessionsLoading] = React8.useState(false);
|
|
32
|
+
const [backgroundRunning, setBackgroundRunning] = React8.useState([]);
|
|
33
|
+
const abortRef = React8.useRef(null);
|
|
34
|
+
const channelRef = React8.useRef(null);
|
|
35
|
+
const backgroundRef = React8.useRef(/* @__PURE__ */ new Map());
|
|
36
|
+
const activeMsgIdRef = React8.useRef(null);
|
|
37
|
+
const runIdRef = React8.useRef(void 0);
|
|
38
|
+
const entityRef = React8.useRef(entity);
|
|
39
|
+
const sessionIdRef = React8.useRef(options.sessionId);
|
|
40
|
+
const pendingSessionNameRef = React8.useRef(void 0);
|
|
41
|
+
const bumpedSessionRef = React8.useRef(void 0);
|
|
42
|
+
React8.useEffect(() => {
|
|
43
43
|
entityRef.current = entity;
|
|
44
44
|
}, [entity]);
|
|
45
|
-
|
|
45
|
+
React8.useEffect(() => {
|
|
46
46
|
sessionIdRef.current = sessionId;
|
|
47
47
|
}, [sessionId]);
|
|
48
|
-
const upsertSession =
|
|
48
|
+
const upsertSession = React8.useCallback((id, createdAt) => {
|
|
49
49
|
setSessions((prev) => {
|
|
50
50
|
const existing = prev.find((s) => s.session_id === id);
|
|
51
51
|
const rest = prev.filter((s) => s.session_id !== id);
|
|
@@ -58,11 +58,11 @@ function useAgnoChat(options) {
|
|
|
58
58
|
return [entry, ...rest];
|
|
59
59
|
});
|
|
60
60
|
}, []);
|
|
61
|
-
const viewRef =
|
|
62
|
-
|
|
61
|
+
const viewRef = React8.useRef({ messages, events, status, activity, error });
|
|
62
|
+
React8.useEffect(() => {
|
|
63
63
|
viewRef.current = { messages, events, status, activity, error };
|
|
64
64
|
});
|
|
65
|
-
const writeMessages =
|
|
65
|
+
const writeMessages = React8.useCallback(
|
|
66
66
|
(chan, fn) => {
|
|
67
67
|
const park = chan?.park;
|
|
68
68
|
if (park) park.messages = fn(park.messages);
|
|
@@ -70,7 +70,7 @@ function useAgnoChat(options) {
|
|
|
70
70
|
},
|
|
71
71
|
[]
|
|
72
72
|
);
|
|
73
|
-
const writeEvents =
|
|
73
|
+
const writeEvents = React8.useCallback((chan, e) => {
|
|
74
74
|
const park = chan?.park;
|
|
75
75
|
if (park) park.events = [...park.events, e];
|
|
76
76
|
else {
|
|
@@ -78,22 +78,22 @@ function useAgnoChat(options) {
|
|
|
78
78
|
setCurrentEvent(e);
|
|
79
79
|
}
|
|
80
80
|
}, []);
|
|
81
|
-
const writeStatus =
|
|
81
|
+
const writeStatus = React8.useCallback((chan, status2) => {
|
|
82
82
|
const park = chan?.park;
|
|
83
83
|
if (park) park.status = status2;
|
|
84
84
|
else setStatus(status2);
|
|
85
85
|
}, []);
|
|
86
|
-
const writeActivity =
|
|
86
|
+
const writeActivity = React8.useCallback((chan, activity2) => {
|
|
87
87
|
const park = chan?.park;
|
|
88
88
|
if (park) park.activity = activity2;
|
|
89
89
|
else setActivity(activity2);
|
|
90
90
|
}, []);
|
|
91
|
-
const writeError =
|
|
91
|
+
const writeError = React8.useCallback((chan, message) => {
|
|
92
92
|
const park = chan?.park;
|
|
93
93
|
if (park) park.error = message;
|
|
94
94
|
else setError(message);
|
|
95
95
|
}, []);
|
|
96
|
-
const patchActive =
|
|
96
|
+
const patchActive = React8.useCallback(
|
|
97
97
|
(chan, patch) => {
|
|
98
98
|
const id = chan?.park ? chan.park.activeMsgId : activeMsgIdRef.current;
|
|
99
99
|
if (!id) return;
|
|
@@ -101,7 +101,7 @@ function useAgnoChat(options) {
|
|
|
101
101
|
},
|
|
102
102
|
[writeMessages]
|
|
103
103
|
);
|
|
104
|
-
const applyEvent =
|
|
104
|
+
const applyEvent = React8.useCallback(
|
|
105
105
|
(chan, e) => {
|
|
106
106
|
writeEvents(chan, e);
|
|
107
107
|
patchActive(chan, (m) => ({ ...m, events: [...m.events ?? [], e] }));
|
|
@@ -233,7 +233,7 @@ function useAgnoChat(options) {
|
|
|
233
233
|
writeStatus
|
|
234
234
|
]
|
|
235
235
|
);
|
|
236
|
-
const parkRun =
|
|
236
|
+
const parkRun = React8.useCallback((chan, sessionId2) => {
|
|
237
237
|
const view = viewRef.current;
|
|
238
238
|
chan.park = {
|
|
239
239
|
sessionId: sessionId2,
|
|
@@ -253,7 +253,7 @@ function useAgnoChat(options) {
|
|
|
253
253
|
activeMsgIdRef.current = null;
|
|
254
254
|
runIdRef.current = void 0;
|
|
255
255
|
}, []);
|
|
256
|
-
const resumeRun =
|
|
256
|
+
const resumeRun = React8.useCallback((sessionId2) => {
|
|
257
257
|
const chan = backgroundRef.current.get(sessionId2);
|
|
258
258
|
const park = chan?.park;
|
|
259
259
|
if (!chan || !park) return false;
|
|
@@ -273,7 +273,7 @@ function useAgnoChat(options) {
|
|
|
273
273
|
setError(park.error);
|
|
274
274
|
return true;
|
|
275
275
|
}, []);
|
|
276
|
-
const releaseCurrentRun =
|
|
276
|
+
const releaseCurrentRun = React8.useCallback(() => {
|
|
277
277
|
const chan = channelRef.current;
|
|
278
278
|
if (!chan || chan.park) return;
|
|
279
279
|
const from = sessionIdRef.current;
|
|
@@ -285,7 +285,7 @@ function useAgnoChat(options) {
|
|
|
285
285
|
abortRef.current = null;
|
|
286
286
|
}
|
|
287
287
|
}, [parkRun]);
|
|
288
|
-
const drive =
|
|
288
|
+
const drive = React8.useCallback(
|
|
289
289
|
async (starter) => {
|
|
290
290
|
const controller = new AbortController();
|
|
291
291
|
const chan = { controller, park: null };
|
|
@@ -321,7 +321,7 @@ function useAgnoChat(options) {
|
|
|
321
321
|
},
|
|
322
322
|
[applyEvent, patchActive, writeActivity, writeError, writeStatus]
|
|
323
323
|
);
|
|
324
|
-
const sendMessage =
|
|
324
|
+
const sendMessage = React8.useCallback(
|
|
325
325
|
async (message, sendOptions) => {
|
|
326
326
|
const ent = entityRef.current;
|
|
327
327
|
if (!ent) {
|
|
@@ -364,7 +364,7 @@ function useAgnoChat(options) {
|
|
|
364
364
|
},
|
|
365
365
|
[client, drive, userId]
|
|
366
366
|
);
|
|
367
|
-
const continueRun =
|
|
367
|
+
const continueRun = React8.useCallback(
|
|
368
368
|
async (resolution) => {
|
|
369
369
|
const ent = entityRef.current;
|
|
370
370
|
const runId = runIdRef.current;
|
|
@@ -388,15 +388,15 @@ function useAgnoChat(options) {
|
|
|
388
388
|
},
|
|
389
389
|
[client, drive, patchActive, userId]
|
|
390
390
|
);
|
|
391
|
-
const activeMessage =
|
|
391
|
+
const activeMessage = React8.useMemo(
|
|
392
392
|
() => messages.find((m) => m.id === activeMsgIdRef.current) ?? null,
|
|
393
393
|
[messages]
|
|
394
394
|
);
|
|
395
|
-
const pausedTools =
|
|
395
|
+
const pausedTools = React8.useMemo(
|
|
396
396
|
() => (activeMessage?.tool_calls ?? []).filter((t) => t.requires_confirmation || t.requires_user_input),
|
|
397
397
|
[activeMessage]
|
|
398
398
|
);
|
|
399
|
-
const respondToConfirmation =
|
|
399
|
+
const respondToConfirmation = React8.useCallback(
|
|
400
400
|
async (approve) => {
|
|
401
401
|
const ent = entityRef.current;
|
|
402
402
|
if (ent?.type === "workflow") {
|
|
@@ -409,7 +409,7 @@ function useAgnoChat(options) {
|
|
|
409
409
|
},
|
|
410
410
|
[activeMessage, continueRun, pausedTools]
|
|
411
411
|
);
|
|
412
|
-
const submitUserInput =
|
|
412
|
+
const submitUserInput = React8.useCallback(
|
|
413
413
|
async (values) => {
|
|
414
414
|
const ent = entityRef.current;
|
|
415
415
|
if (ent?.type === "workflow") {
|
|
@@ -435,7 +435,7 @@ function useAgnoChat(options) {
|
|
|
435
435
|
},
|
|
436
436
|
[activeMessage, continueRun, pausedTools]
|
|
437
437
|
);
|
|
438
|
-
const cancel =
|
|
438
|
+
const cancel = React8.useCallback(async () => {
|
|
439
439
|
abortRef.current?.abort();
|
|
440
440
|
channelRef.current = null;
|
|
441
441
|
const ent = entityRef.current;
|
|
@@ -445,7 +445,7 @@ function useAgnoChat(options) {
|
|
|
445
445
|
patchActive(null, (m) => m.streaming ? { ...m, streaming: false, status: "cancelled" } : m);
|
|
446
446
|
if (ent && runId) await client.cancelRun(ent.type, ent.id, runId, sessionIdRef.current);
|
|
447
447
|
}, [client, patchActive]);
|
|
448
|
-
const refreshSessions =
|
|
448
|
+
const refreshSessions = React8.useCallback(async () => {
|
|
449
449
|
const ent = entityRef.current;
|
|
450
450
|
if (!ent) {
|
|
451
451
|
setSessions([]);
|
|
@@ -464,7 +464,7 @@ function useAgnoChat(options) {
|
|
|
464
464
|
setSessionsLoading(false);
|
|
465
465
|
}
|
|
466
466
|
}, [client]);
|
|
467
|
-
const loadSession =
|
|
467
|
+
const loadSession = React8.useCallback(
|
|
468
468
|
async (id) => {
|
|
469
469
|
const ent = entityRef.current;
|
|
470
470
|
if (!ent) return;
|
|
@@ -490,7 +490,7 @@ function useAgnoChat(options) {
|
|
|
490
490
|
},
|
|
491
491
|
[client, onSessionId, releaseCurrentRun, resumeRun]
|
|
492
492
|
);
|
|
493
|
-
const deleteSession =
|
|
493
|
+
const deleteSession = React8.useCallback(
|
|
494
494
|
async (id) => {
|
|
495
495
|
const ent = entityRef.current;
|
|
496
496
|
const ok = await client.deleteSession(id, ent?.db_id);
|
|
@@ -511,7 +511,7 @@ function useAgnoChat(options) {
|
|
|
511
511
|
},
|
|
512
512
|
[client]
|
|
513
513
|
);
|
|
514
|
-
const reset =
|
|
514
|
+
const reset = React8.useCallback(() => {
|
|
515
515
|
releaseCurrentRun();
|
|
516
516
|
activeMsgIdRef.current = null;
|
|
517
517
|
runIdRef.current = void 0;
|
|
@@ -526,7 +526,7 @@ function useAgnoChat(options) {
|
|
|
526
526
|
setError(null);
|
|
527
527
|
setSessionId(void 0);
|
|
528
528
|
}, [releaseCurrentRun]);
|
|
529
|
-
|
|
529
|
+
React8.useEffect(() => {
|
|
530
530
|
const background = backgroundRef.current;
|
|
531
531
|
return () => {
|
|
532
532
|
abortRef.current?.abort();
|
|
@@ -534,7 +534,7 @@ function useAgnoChat(options) {
|
|
|
534
534
|
background.clear();
|
|
535
535
|
};
|
|
536
536
|
}, []);
|
|
537
|
-
const streamingMessage =
|
|
537
|
+
const streamingMessage = React8.useMemo(
|
|
538
538
|
() => messages.find((m) => m.role === "agent" && m.streaming) ?? null,
|
|
539
539
|
[messages]
|
|
540
540
|
);
|
|
@@ -576,7 +576,7 @@ function cx(...parts) {
|
|
|
576
576
|
const out = parts.filter(Boolean).join(" ");
|
|
577
577
|
return out || void 0;
|
|
578
578
|
}
|
|
579
|
-
var ChatContext =
|
|
579
|
+
var ChatContext = React8.createContext(null);
|
|
580
580
|
function ChatProvider({
|
|
581
581
|
children,
|
|
582
582
|
classNames,
|
|
@@ -593,7 +593,7 @@ function ChatProvider({
|
|
|
593
593
|
}) {
|
|
594
594
|
const internal = useAgnoChat(externalChat ? { entity: null } : options);
|
|
595
595
|
const chat = externalChat ?? internal;
|
|
596
|
-
const value =
|
|
596
|
+
const value = React8.useMemo(
|
|
597
597
|
() => ({ chat, classNames: classNames ?? {}, renderMarkdown, resolveLinkPreview, codeCopy, linkComponent }),
|
|
598
598
|
[chat, classNames, renderMarkdown, resolveLinkPreview, codeCopy, linkComponent]
|
|
599
599
|
);
|
|
@@ -608,12 +608,12 @@ function ChatProvider({
|
|
|
608
608
|
) : children });
|
|
609
609
|
}
|
|
610
610
|
function useChatContext() {
|
|
611
|
-
const value =
|
|
611
|
+
const value = React8.useContext(ChatContext);
|
|
612
612
|
if (!value) throw new Error("useChatContext must be used inside a <ChatProvider>");
|
|
613
613
|
return value;
|
|
614
614
|
}
|
|
615
615
|
function useOptionalChatContext() {
|
|
616
|
-
return
|
|
616
|
+
return React8.useContext(ChatContext);
|
|
617
617
|
}
|
|
618
618
|
function useResolvedChat(explicit) {
|
|
619
619
|
const ctx = useOptionalChatContext();
|
|
@@ -633,7 +633,7 @@ function useLinkComponent() {
|
|
|
633
633
|
}
|
|
634
634
|
function useResolvedClassNames(explicit) {
|
|
635
635
|
const ctx = useOptionalChatContext();
|
|
636
|
-
return
|
|
636
|
+
return React8.useMemo(() => ({ ...ctx?.classNames, ...explicit }), [ctx?.classNames, explicit]);
|
|
637
637
|
}
|
|
638
638
|
var STROKE = 1.5;
|
|
639
639
|
var icon = (Component, defaultSize = 16) => function Icon({ size = defaultSize, className }) {
|
|
@@ -662,9 +662,7 @@ var Pulse = icon(lucideReact.Activity);
|
|
|
662
662
|
var Trash = icon(lucideReact.Trash2);
|
|
663
663
|
var ChatBubble = icon(lucideReact.MessageSquare);
|
|
664
664
|
var Spinner = icon(lucideReact.LoaderCircle, 12);
|
|
665
|
-
|
|
666
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Square, { size, className, fill: "currentColor", strokeWidth: 0 });
|
|
667
|
-
}
|
|
665
|
+
var Stop = icon(lucideReact.Square, 10.67);
|
|
668
666
|
function AgnoMark({ size = 24, className }) {
|
|
669
667
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
670
668
|
"svg",
|
|
@@ -780,19 +778,19 @@ function ChatLauncher({
|
|
|
780
778
|
portal = true,
|
|
781
779
|
className
|
|
782
780
|
}) {
|
|
783
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
781
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React8.useState(defaultOpen);
|
|
784
782
|
const isOpen = open ?? uncontrolledOpen;
|
|
785
|
-
const opened =
|
|
783
|
+
const opened = React8.useRef(isOpen);
|
|
786
784
|
if (isOpen) opened.current = true;
|
|
787
785
|
const mounted = keepMounted ? opened.current : isOpen;
|
|
788
|
-
const setOpen =
|
|
786
|
+
const setOpen = React8.useCallback(
|
|
789
787
|
(next) => {
|
|
790
788
|
if (open === void 0) setUncontrolledOpen(next);
|
|
791
789
|
onOpenChange?.(next);
|
|
792
790
|
},
|
|
793
791
|
[open, onOpenChange]
|
|
794
792
|
);
|
|
795
|
-
|
|
793
|
+
React8.useEffect(() => {
|
|
796
794
|
if (!isOpen || !closeOnEscape) return;
|
|
797
795
|
const onKeyDown = (e) => {
|
|
798
796
|
if (e.key === "Escape") setOpen(false);
|
|
@@ -800,7 +798,7 @@ function ChatLauncher({
|
|
|
800
798
|
document.addEventListener("keydown", onKeyDown);
|
|
801
799
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
802
800
|
}, [isOpen, closeOnEscape, setOpen]);
|
|
803
|
-
|
|
801
|
+
React8.useEffect(() => {
|
|
804
802
|
if (!isOpen || panel !== "fullscreen") return;
|
|
805
803
|
const previous = document.body.style.overflow;
|
|
806
804
|
document.body.style.overflow = "hidden";
|
|
@@ -808,8 +806,8 @@ function ChatLauncher({
|
|
|
808
806
|
document.body.style.overflow = previous;
|
|
809
807
|
};
|
|
810
808
|
}, [isOpen, panel]);
|
|
811
|
-
const [canPortal, setCanPortal] =
|
|
812
|
-
|
|
809
|
+
const [canPortal, setCanPortal] = React8.useState(false);
|
|
810
|
+
React8.useEffect(() => setCanPortal(true), []);
|
|
813
811
|
const classes = [
|
|
814
812
|
"agno-launcher",
|
|
815
813
|
`agno-launcher--${position}`,
|
|
@@ -865,8 +863,8 @@ function kindOf(file) {
|
|
|
865
863
|
}
|
|
866
864
|
function Item({ file, onRemove }) {
|
|
867
865
|
const isImage = file.type.startsWith("image/");
|
|
868
|
-
const [url, setUrl] =
|
|
869
|
-
|
|
866
|
+
const [url, setUrl] = React8.useState(null);
|
|
867
|
+
React8.useEffect(() => {
|
|
870
868
|
if (!isImage) return;
|
|
871
869
|
const objectUrl = URL.createObjectURL(file);
|
|
872
870
|
setUrl(objectUrl);
|
|
@@ -970,24 +968,24 @@ function ChatInput({
|
|
|
970
968
|
}) {
|
|
971
969
|
const ctx = useOptionalChatContext();
|
|
972
970
|
const cn = useResolvedClassNames(classNames);
|
|
973
|
-
const [internal, setInternal] =
|
|
971
|
+
const [internal, setInternal] = React8.useState("");
|
|
974
972
|
const value = controlled ?? internal;
|
|
975
973
|
const setValue = (next) => {
|
|
976
974
|
if (controlled === void 0) setInternal(next);
|
|
977
975
|
onValueChange?.(next);
|
|
978
976
|
};
|
|
979
|
-
const [files, setFilesState] =
|
|
980
|
-
const filesRef =
|
|
977
|
+
const [files, setFilesState] = React8.useState([]);
|
|
978
|
+
const filesRef = React8.useRef([]);
|
|
981
979
|
const setFiles = (next) => {
|
|
982
980
|
filesRef.current = next;
|
|
983
981
|
setFilesState(next);
|
|
984
982
|
};
|
|
985
|
-
const [fileError, setFileError] =
|
|
986
|
-
const [dragging, setDragging] =
|
|
987
|
-
const dragDepth =
|
|
988
|
-
const fileRef =
|
|
989
|
-
const textareaRef =
|
|
990
|
-
const setTextareaRef =
|
|
983
|
+
const [fileError, setFileError] = React8.useState(null);
|
|
984
|
+
const [dragging, setDragging] = React8.useState(false);
|
|
985
|
+
const dragDepth = React8.useRef(0);
|
|
986
|
+
const fileRef = React8.useRef(null);
|
|
987
|
+
const textareaRef = React8.useRef(null);
|
|
988
|
+
const setTextareaRef = React8.useCallback(
|
|
991
989
|
(el2) => {
|
|
992
990
|
textareaRef.current = el2;
|
|
993
991
|
if (typeof externalRef === "function") externalRef(el2);
|
|
@@ -995,14 +993,14 @@ function ChatInput({
|
|
|
995
993
|
},
|
|
996
994
|
[externalRef]
|
|
997
995
|
);
|
|
998
|
-
const adjustHeight =
|
|
996
|
+
const adjustHeight = React8.useCallback(() => {
|
|
999
997
|
const el2 = textareaRef.current;
|
|
1000
998
|
if (!el2 || renderTextarea) return;
|
|
1001
999
|
const { min, max } = compact ? BOUNDS.compact : BOUNDS.dock;
|
|
1002
1000
|
el2.style.height = `${min}px`;
|
|
1003
1001
|
el2.style.height = `${Math.min(Math.max(el2.scrollHeight, min), max)}px`;
|
|
1004
1002
|
}, [renderTextarea, compact]);
|
|
1005
|
-
|
|
1003
|
+
React8.useEffect(adjustHeight, [value, adjustHeight]);
|
|
1006
1004
|
const send = onSend ?? ((message, attached) => void ctx?.chat.sendMessage(message, attached ? { files: attached } : void 0));
|
|
1007
1005
|
const stop = onStop ?? (ctx ? () => void ctx.chat.cancel() : void 0);
|
|
1008
1006
|
const isBusy = busy ?? ctx?.chat.isStreaming ?? false;
|
|
@@ -1100,15 +1098,18 @@ function ChatInput({
|
|
|
1100
1098
|
}
|
|
1101
1099
|
)
|
|
1102
1100
|
] });
|
|
1103
|
-
const primary = isBusy && stop ?
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
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
|
+
)
|
|
1112
1113
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1113
1114
|
"button",
|
|
1114
1115
|
{
|
|
@@ -1251,11 +1252,11 @@ function HumanInput({
|
|
|
1251
1252
|
onResolve,
|
|
1252
1253
|
className
|
|
1253
1254
|
}) {
|
|
1254
|
-
const asks =
|
|
1255
|
-
const [choices, setChoices] =
|
|
1256
|
-
const [values, setValues] =
|
|
1257
|
-
const [reasons, setReasons] =
|
|
1258
|
-
const [openArgs, setOpenArgs] =
|
|
1255
|
+
const asks = React8.useMemo(() => buildAsks(message, entityType), [message, entityType]);
|
|
1256
|
+
const [choices, setChoices] = React8.useState({});
|
|
1257
|
+
const [values, setValues] = React8.useState({});
|
|
1258
|
+
const [reasons, setReasons] = React8.useState({});
|
|
1259
|
+
const [openArgs, setOpenArgs] = React8.useState({});
|
|
1259
1260
|
if (asks.length === 0) return null;
|
|
1260
1261
|
const setValue = (id, name, value) => setValues((v) => ({ ...v, [id]: { ...v[id] ?? {}, [name]: value } }));
|
|
1261
1262
|
const valueFor = (ask, field) => values[ask.id]?.[field.name] ?? field.value ?? (isBoolField(field) ? false : "");
|
|
@@ -1398,11 +1399,14 @@ function sourceHost(url) {
|
|
|
1398
1399
|
}
|
|
1399
1400
|
}
|
|
1400
1401
|
function faviconUrl(url) {
|
|
1401
|
-
|
|
1402
|
+
return faviconFallbacks(url)[0];
|
|
1403
|
+
}
|
|
1404
|
+
function faviconFallbacks(url) {
|
|
1405
|
+
if (!url) return [];
|
|
1402
1406
|
try {
|
|
1403
|
-
return
|
|
1407
|
+
return ["/favicon.ico", "/favicon.svg"].map((path) => new URL(path, url).href);
|
|
1404
1408
|
} catch {
|
|
1405
|
-
return
|
|
1409
|
+
return [];
|
|
1406
1410
|
}
|
|
1407
1411
|
}
|
|
1408
1412
|
function displayUrl(url) {
|
|
@@ -1526,10 +1530,10 @@ function linkCitations(content, sources) {
|
|
|
1526
1530
|
);
|
|
1527
1531
|
}).join("");
|
|
1528
1532
|
}
|
|
1529
|
-
var SourcesContext =
|
|
1533
|
+
var SourcesContext = React8.createContext([]);
|
|
1530
1534
|
var SourcesProvider = SourcesContext.Provider;
|
|
1531
1535
|
function useSources() {
|
|
1532
|
-
return
|
|
1536
|
+
return React8.useContext(SourcesContext);
|
|
1533
1537
|
}
|
|
1534
1538
|
var THEMES = { light: "github-light", dark: "monokai" };
|
|
1535
1539
|
var highlighter;
|
|
@@ -1576,10 +1580,10 @@ function normalizeLanguage(language) {
|
|
|
1576
1580
|
return lang || void 0;
|
|
1577
1581
|
}
|
|
1578
1582
|
function useHighlight(code, language) {
|
|
1579
|
-
const [, rerender] =
|
|
1583
|
+
const [, rerender] = React8.useReducer((n) => n + 1, 0);
|
|
1580
1584
|
const lang = normalizeLanguage(language);
|
|
1581
1585
|
const ready = Boolean(lang && loaded.has(lang));
|
|
1582
|
-
|
|
1586
|
+
React8.useEffect(() => {
|
|
1583
1587
|
if (!lang || ready || unsupported.has(lang)) return;
|
|
1584
1588
|
let cancelled = false;
|
|
1585
1589
|
void ensureLanguage(lang).then(() => {
|
|
@@ -1589,7 +1593,7 @@ function useHighlight(code, language) {
|
|
|
1589
1593
|
cancelled = true;
|
|
1590
1594
|
};
|
|
1591
1595
|
}, [lang, ready]);
|
|
1592
|
-
return
|
|
1596
|
+
return React8.useMemo(() => {
|
|
1593
1597
|
if (!lang || !ready || !highlighter) return null;
|
|
1594
1598
|
try {
|
|
1595
1599
|
return highlighter.codeToTokens(code, { lang, themes: THEMES, defaultColor: false }).tokens;
|
|
@@ -1598,7 +1602,7 @@ function useHighlight(code, language) {
|
|
|
1598
1602
|
}
|
|
1599
1603
|
}, [code, lang, ready]);
|
|
1600
1604
|
}
|
|
1601
|
-
var useIsomorphicLayoutEffect = typeof window === "undefined" ?
|
|
1605
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? React8.useEffect : React8.useLayoutEffect;
|
|
1602
1606
|
var caches = /* @__PURE__ */ new WeakMap();
|
|
1603
1607
|
var inflight = /* @__PURE__ */ new WeakMap();
|
|
1604
1608
|
function cacheFor(store, key) {
|
|
@@ -1615,9 +1619,9 @@ function useLinkPreviewResolver() {
|
|
|
1615
1619
|
function useLinkPreview(url, enabled) {
|
|
1616
1620
|
const resolve = useLinkPreviewResolver();
|
|
1617
1621
|
const cached = url && resolve ? cacheFor(caches, resolve).get(url) : void 0;
|
|
1618
|
-
const [preview, setPreview] =
|
|
1619
|
-
const [loading2, setLoading] =
|
|
1620
|
-
|
|
1622
|
+
const [preview, setPreview] = React8.useState(cached ?? null);
|
|
1623
|
+
const [loading2, setLoading] = React8.useState(false);
|
|
1624
|
+
React8.useEffect(() => {
|
|
1621
1625
|
if (!enabled || !url || !resolve) return;
|
|
1622
1626
|
const store = cacheFor(caches, resolve);
|
|
1623
1627
|
if (store.has(url)) {
|
|
@@ -1654,10 +1658,11 @@ function Favicon({
|
|
|
1654
1658
|
size = 14,
|
|
1655
1659
|
className
|
|
1656
1660
|
}) {
|
|
1657
|
-
const
|
|
1658
|
-
const [
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
+
const candidates = React8.useMemo(() => faviconFallbacks(url), [url]);
|
|
1662
|
+
const [attempt, setAttempt] = React8.useState(0);
|
|
1663
|
+
const src = candidates[attempt];
|
|
1664
|
+
React8.useEffect(() => setAttempt(0), [url]);
|
|
1665
|
+
if (kind === "document" || !src) {
|
|
1661
1666
|
const Glyph2 = kind === "document" ? BookOpen : Globe;
|
|
1662
1667
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("agno-favicon", "agno-favicon--glyph", className), "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(Glyph2, { size }) });
|
|
1663
1668
|
}
|
|
@@ -1671,7 +1676,7 @@ function Favicon({
|
|
|
1671
1676
|
height: size,
|
|
1672
1677
|
loading: "lazy",
|
|
1673
1678
|
decoding: "async",
|
|
1674
|
-
onError: () =>
|
|
1679
|
+
onError: () => setAttempt((n) => n + 1),
|
|
1675
1680
|
"aria-hidden": true
|
|
1676
1681
|
}
|
|
1677
1682
|
);
|
|
@@ -1700,7 +1705,7 @@ var GAP = 8;
|
|
|
1700
1705
|
var OPEN_DELAY = 140;
|
|
1701
1706
|
var CLOSE_DELAY = 120;
|
|
1702
1707
|
function usePlacement(anchor, open, { width = PREVIEW_WIDTH, align = "center" } = {}) {
|
|
1703
|
-
const [placement, setPlacement] =
|
|
1708
|
+
const [placement, setPlacement] = React8.useState(null);
|
|
1704
1709
|
useIsomorphicLayoutEffect(() => {
|
|
1705
1710
|
if (!open || !anchor) return;
|
|
1706
1711
|
const place = () => {
|
|
@@ -1730,15 +1735,15 @@ function HoverPreview({
|
|
|
1730
1735
|
disabled,
|
|
1731
1736
|
className
|
|
1732
1737
|
}) {
|
|
1733
|
-
const [open, setOpen] =
|
|
1734
|
-
const [awake, setAwake] =
|
|
1735
|
-
const [anchor, setAnchor] =
|
|
1736
|
-
const timer =
|
|
1737
|
-
const id =
|
|
1738
|
+
const [open, setOpen] = React8.useState(false);
|
|
1739
|
+
const [awake, setAwake] = React8.useState(false);
|
|
1740
|
+
const [anchor, setAnchor] = React8.useState(null);
|
|
1741
|
+
const timer = React8.useRef(null);
|
|
1742
|
+
const id = React8.useId();
|
|
1738
1743
|
const cn = useResolvedClassNames();
|
|
1739
1744
|
const { preview, loading: loading2 } = useLinkPreview(source.url, awake);
|
|
1740
1745
|
const placement = usePlacement(anchor, open);
|
|
1741
|
-
const schedule =
|
|
1746
|
+
const schedule = React8.useCallback((next) => {
|
|
1742
1747
|
if (timer.current) clearTimeout(timer.current);
|
|
1743
1748
|
timer.current = setTimeout(
|
|
1744
1749
|
() => {
|
|
@@ -1748,13 +1753,13 @@ function HoverPreview({
|
|
|
1748
1753
|
next ? OPEN_DELAY : CLOSE_DELAY
|
|
1749
1754
|
);
|
|
1750
1755
|
}, []);
|
|
1751
|
-
|
|
1756
|
+
React8.useEffect(
|
|
1752
1757
|
() => () => {
|
|
1753
1758
|
if (timer.current) clearTimeout(timer.current);
|
|
1754
1759
|
},
|
|
1755
1760
|
[]
|
|
1756
1761
|
);
|
|
1757
|
-
|
|
1762
|
+
React8.useEffect(() => {
|
|
1758
1763
|
if (!open) return;
|
|
1759
1764
|
const onKey = (e) => {
|
|
1760
1765
|
if (e.key === "Escape") setOpen(false);
|
|
@@ -1762,10 +1767,10 @@ function HoverPreview({
|
|
|
1762
1767
|
document.addEventListener("keydown", onKey);
|
|
1763
1768
|
return () => document.removeEventListener("keydown", onKey);
|
|
1764
1769
|
}, [open]);
|
|
1765
|
-
const [mounted, setMounted] =
|
|
1766
|
-
|
|
1770
|
+
const [mounted, setMounted] = React8.useState(false);
|
|
1771
|
+
React8.useEffect(() => setMounted(true), []);
|
|
1767
1772
|
if (disabled) return children;
|
|
1768
|
-
const trigger =
|
|
1773
|
+
const trigger = React8.isValidElement(children) ? React8.cloneElement(children, {
|
|
1769
1774
|
"aria-describedby": open ? id : void 0
|
|
1770
1775
|
}) : children;
|
|
1771
1776
|
const light = anchor?.closest(".agno-light") ? "agno-light" : void 0;
|
|
@@ -1802,45 +1807,6 @@ function HoverPreview({
|
|
|
1802
1807
|
}
|
|
1803
1808
|
);
|
|
1804
1809
|
}
|
|
1805
|
-
function el(tag, className) {
|
|
1806
|
-
return function Element({ node: _node, className: _theirs, ...rest }) {
|
|
1807
|
-
return React7__default.default.createElement(tag, { className, ...rest });
|
|
1808
|
-
};
|
|
1809
|
-
}
|
|
1810
|
-
function sourceForUrl(url, sources) {
|
|
1811
|
-
return url ? sources.find((s) => s.url === url) : void 0;
|
|
1812
|
-
}
|
|
1813
|
-
function citationForLink(label2, href, ctx) {
|
|
1814
|
-
if (!/^\d+$/.test(label2.trim())) return void 0;
|
|
1815
|
-
return sourceForUrl(href, ctx.sources) ?? ctx.sources.find((s) => s.index === Number(label2.trim()));
|
|
1816
|
-
}
|
|
1817
|
-
function labelOf(children) {
|
|
1818
|
-
if (typeof children === "string") return children;
|
|
1819
|
-
if (Array.isArray(children) && children.length === 1 && typeof children[0] === "string") {
|
|
1820
|
-
return children[0];
|
|
1821
|
-
}
|
|
1822
|
-
return "";
|
|
1823
|
-
}
|
|
1824
|
-
function CitationMarker({
|
|
1825
|
-
source,
|
|
1826
|
-
className,
|
|
1827
|
-
Link
|
|
1828
|
-
}) {
|
|
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(
|
|
1835
|
-
"a",
|
|
1836
|
-
{
|
|
1837
|
-
...props,
|
|
1838
|
-
target: source.url ? "_blank" : void 0,
|
|
1839
|
-
rel: source.url ? "noreferrer noopener" : void 0,
|
|
1840
|
-
children: source.index
|
|
1841
|
-
}
|
|
1842
|
-
) });
|
|
1843
|
-
}
|
|
1844
1810
|
var COPIED_FOR = 1600;
|
|
1845
1811
|
var CLIPBOARD_TIMEOUT = 400;
|
|
1846
1812
|
async function writeClipboard(text) {
|
|
@@ -1866,38 +1832,78 @@ async function writeClipboard(text) {
|
|
|
1866
1832
|
return false;
|
|
1867
1833
|
}
|
|
1868
1834
|
}
|
|
1869
|
-
function CopyButton({ text, className }) {
|
|
1870
|
-
const [copied, setCopied] =
|
|
1871
|
-
|
|
1835
|
+
function CopyButton({ text, label: label2 = "Copy", size = 14, className }) {
|
|
1836
|
+
const [copied, setCopied] = React8.useState(false);
|
|
1837
|
+
React8.useEffect(() => {
|
|
1872
1838
|
if (!copied) return;
|
|
1873
1839
|
const timer = setTimeout(() => setCopied(false), COPIED_FOR);
|
|
1874
1840
|
return () => clearTimeout(timer);
|
|
1875
1841
|
}, [copied]);
|
|
1876
1842
|
const copy = async () => {
|
|
1877
|
-
if (await writeClipboard(text())) setCopied(true);
|
|
1843
|
+
if (await writeClipboard(typeof text === "function" ? text() : text)) setCopied(true);
|
|
1878
1844
|
};
|
|
1845
|
+
const name = copied ? "Copied" : label2;
|
|
1879
1846
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1880
1847
|
"button",
|
|
1881
1848
|
{
|
|
1882
1849
|
type: "button",
|
|
1883
|
-
className: cx("agno-
|
|
1850
|
+
className: cx("agno-copy", copied && "is-copied", className),
|
|
1884
1851
|
onClick: copy,
|
|
1885
|
-
"aria-label":
|
|
1886
|
-
title:
|
|
1887
|
-
children: copied ? /* @__PURE__ */ jsxRuntime.jsx(Check, { size
|
|
1852
|
+
"aria-label": name,
|
|
1853
|
+
title: name,
|
|
1854
|
+
children: copied ? /* @__PURE__ */ jsxRuntime.jsx(Check, { size }) : /* @__PURE__ */ jsxRuntime.jsx(Copy, { size })
|
|
1888
1855
|
}
|
|
1889
1856
|
);
|
|
1890
1857
|
}
|
|
1858
|
+
function el(tag, className) {
|
|
1859
|
+
return function Element({ node: _node, className: _theirs, ...rest }) {
|
|
1860
|
+
return React8__default.default.createElement(tag, { className, ...rest });
|
|
1861
|
+
};
|
|
1862
|
+
}
|
|
1863
|
+
function sourceForUrl(url, sources) {
|
|
1864
|
+
return url ? sources.find((s) => s.url === url) : void 0;
|
|
1865
|
+
}
|
|
1866
|
+
function citationForLink(label2, href, ctx) {
|
|
1867
|
+
if (!/^\d+$/.test(label2.trim())) return void 0;
|
|
1868
|
+
return sourceForUrl(href, ctx.sources) ?? ctx.sources.find((s) => s.index === Number(label2.trim()));
|
|
1869
|
+
}
|
|
1870
|
+
function labelOf(children) {
|
|
1871
|
+
if (typeof children === "string") return children;
|
|
1872
|
+
if (Array.isArray(children) && children.length === 1 && typeof children[0] === "string") {
|
|
1873
|
+
return children[0];
|
|
1874
|
+
}
|
|
1875
|
+
return "";
|
|
1876
|
+
}
|
|
1877
|
+
function CitationMarker({
|
|
1878
|
+
source,
|
|
1879
|
+
className,
|
|
1880
|
+
Link
|
|
1881
|
+
}) {
|
|
1882
|
+
const props = {
|
|
1883
|
+
className: cx("agno-cite", className),
|
|
1884
|
+
href: source.url ?? `#${source.anchorId}`,
|
|
1885
|
+
"aria-label": `Source ${source.index}: ${source.title}`
|
|
1886
|
+
};
|
|
1887
|
+
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(
|
|
1888
|
+
"a",
|
|
1889
|
+
{
|
|
1890
|
+
...props,
|
|
1891
|
+
target: source.url ? "_blank" : void 0,
|
|
1892
|
+
rel: source.url ? "noreferrer noopener" : void 0,
|
|
1893
|
+
children: source.index
|
|
1894
|
+
}
|
|
1895
|
+
) });
|
|
1896
|
+
}
|
|
1891
1897
|
function textOf(children) {
|
|
1892
1898
|
if (typeof children === "string") return children;
|
|
1893
1899
|
if (typeof children === "number") return String(children);
|
|
1894
1900
|
if (Array.isArray(children)) return children.map(textOf).join("");
|
|
1895
|
-
if (
|
|
1901
|
+
if (React8__default.default.isValidElement(children)) return textOf(children.props.children);
|
|
1896
1902
|
return "";
|
|
1897
1903
|
}
|
|
1898
1904
|
function fencedCode(children) {
|
|
1899
1905
|
const child = Array.isArray(children) ? children[0] : children;
|
|
1900
|
-
if (!
|
|
1906
|
+
if (!React8__default.default.isValidElement(child)) {
|
|
1901
1907
|
return { code: textOf(children) };
|
|
1902
1908
|
}
|
|
1903
1909
|
const language = /(?:^|\s)language-([^\s]+)/.exec(child.props.className ?? "")?.[1];
|
|
@@ -1911,16 +1917,16 @@ function CodeBlock({
|
|
|
1911
1917
|
copyClass,
|
|
1912
1918
|
codeCopy
|
|
1913
1919
|
}) {
|
|
1914
|
-
const { language, code } =
|
|
1920
|
+
const { language, code } = React8.useMemo(() => fencedCode(children), [children]);
|
|
1915
1921
|
const highlighted = useHighlight(code, language);
|
|
1916
1922
|
const lines = highlighted ?? plainLines(code);
|
|
1917
1923
|
const label2 = normalizeLanguage(language) ?? "text";
|
|
1918
1924
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-md-code-block", "data-language": label2, children: [
|
|
1919
1925
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-md-code-head", children: [
|
|
1920
1926
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-md-code-lang", children: label2 }),
|
|
1921
|
-
codeCopy && /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { className: copyClass, text: () => code })
|
|
1927
|
+
codeCopy && /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { className: cx("agno-md-copy", copyClass), text: () => code, label: "Copy code", size: 13 })
|
|
1922
1928
|
] }),
|
|
1923
|
-
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "agno-md-pre", style: { "--agno-code-gutter": `${String(lines.length).length}ch` }, children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: language ? `language-${language}` : void 0, children: lines.map((tokens, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1929
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "agno-md-pre", style: { "--agno-code-gutter": `${String(lines.length).length}ch` }, children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: language ? `language-${language}` : void 0, children: lines.map((tokens, i) => /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
|
|
1924
1930
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-md-line", children: tokens.map((token, j) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: token.htmlStyle, children: token.content }, j)) }),
|
|
1925
1931
|
i < lines.length - 1 && "\n"
|
|
1926
1932
|
] }, i)) }) })
|
|
@@ -2013,7 +2019,7 @@ function Markdown({
|
|
|
2013
2019
|
const cited = sources ?? fromMessage;
|
|
2014
2020
|
const copy = codeCopy ?? fromProvider ?? true;
|
|
2015
2021
|
const Link = linkComponent ?? providerLink;
|
|
2016
|
-
const components =
|
|
2022
|
+
const components = React8.useMemo(
|
|
2017
2023
|
() => elementsFor({
|
|
2018
2024
|
sources: cited,
|
|
2019
2025
|
canResolve,
|
|
@@ -2024,7 +2030,7 @@ function Markdown({
|
|
|
2024
2030
|
}),
|
|
2025
2031
|
[cited, canResolve, cn.citationMarker, cn.copyButton, copy, Link]
|
|
2026
2032
|
);
|
|
2027
|
-
const text =
|
|
2033
|
+
const text = React8.useMemo(() => linkCitations(content, cited), [content, cited]);
|
|
2028
2034
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2029
2035
|
streamdown.Streamdown,
|
|
2030
2036
|
{
|
|
@@ -2048,7 +2054,7 @@ function hasDetail(tool) {
|
|
|
2048
2054
|
return Boolean(tool.tool_args && Object.keys(tool.tool_args).length) || tool.result != null;
|
|
2049
2055
|
}
|
|
2050
2056
|
function ToolCalls({ tools }) {
|
|
2051
|
-
const [openIndex, setOpenIndex] =
|
|
2057
|
+
const [openIndex, setOpenIndex] = React8.useState(null);
|
|
2052
2058
|
if (!tools || tools.length === 0) return null;
|
|
2053
2059
|
const open = openIndex != null ? tools[openIndex] : void 0;
|
|
2054
2060
|
const openStatus = open ? statusOf(open) : void 0;
|
|
@@ -2285,7 +2291,7 @@ function Step({
|
|
|
2285
2291
|
busy,
|
|
2286
2292
|
children
|
|
2287
2293
|
}) {
|
|
2288
|
-
const [open, setOpen] =
|
|
2294
|
+
const [open, setOpen] = React8.useState(false);
|
|
2289
2295
|
if (!children) {
|
|
2290
2296
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-bts__step", children: [
|
|
2291
2297
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-bts__step-label", children: label2 }),
|
|
@@ -2330,7 +2336,7 @@ function BehindTheScenes({
|
|
|
2330
2336
|
className,
|
|
2331
2337
|
classNames
|
|
2332
2338
|
}) {
|
|
2333
|
-
const [open, setOpen] =
|
|
2339
|
+
const [open, setOpen] = React8.useState(defaultOpen);
|
|
2334
2340
|
const items = behindTheScenesItems(message, { hideReasoning, hideTools });
|
|
2335
2341
|
if (items.length === 0) return null;
|
|
2336
2342
|
const label2 = behindTheScenesLabel(message, streaming, activity);
|
|
@@ -2467,22 +2473,22 @@ function SourceCard({
|
|
|
2467
2473
|
}
|
|
2468
2474
|
var LIST_WIDTH = 240;
|
|
2469
2475
|
function SourcesOverflow({ sources }) {
|
|
2470
|
-
const [open, setOpen] =
|
|
2471
|
-
const [anchor, setAnchor] =
|
|
2472
|
-
const timer =
|
|
2473
|
-
const id =
|
|
2476
|
+
const [open, setOpen] = React8.useState(false);
|
|
2477
|
+
const [anchor, setAnchor] = React8.useState(null);
|
|
2478
|
+
const timer = React8.useRef(null);
|
|
2479
|
+
const id = React8.useId();
|
|
2474
2480
|
const placement = usePlacement(anchor, open, { width: LIST_WIDTH, align: "start" });
|
|
2475
|
-
const schedule =
|
|
2481
|
+
const schedule = React8.useCallback((next) => {
|
|
2476
2482
|
if (timer.current) clearTimeout(timer.current);
|
|
2477
2483
|
timer.current = setTimeout(() => setOpen(next), next ? OPEN_DELAY : CLOSE_DELAY);
|
|
2478
2484
|
}, []);
|
|
2479
|
-
|
|
2485
|
+
React8.useEffect(
|
|
2480
2486
|
() => () => {
|
|
2481
2487
|
if (timer.current) clearTimeout(timer.current);
|
|
2482
2488
|
},
|
|
2483
2489
|
[]
|
|
2484
2490
|
);
|
|
2485
|
-
|
|
2491
|
+
React8.useEffect(() => {
|
|
2486
2492
|
if (!open) return;
|
|
2487
2493
|
const onKey = (e) => {
|
|
2488
2494
|
if (e.key === "Escape") setOpen(false);
|
|
@@ -2490,8 +2496,8 @@ function SourcesOverflow({ sources }) {
|
|
|
2490
2496
|
document.addEventListener("keydown", onKey);
|
|
2491
2497
|
return () => document.removeEventListener("keydown", onKey);
|
|
2492
2498
|
}, [open]);
|
|
2493
|
-
const [mounted, setMounted] =
|
|
2494
|
-
|
|
2499
|
+
const [mounted, setMounted] = React8.useState(false);
|
|
2500
|
+
React8.useEffect(() => setMounted(true), []);
|
|
2495
2501
|
const light = anchor?.closest(".agno-light") ? "agno-light" : void 0;
|
|
2496
2502
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2497
2503
|
"span",
|
|
@@ -2563,8 +2569,8 @@ function Citations({
|
|
|
2563
2569
|
classNames
|
|
2564
2570
|
}) {
|
|
2565
2571
|
const cn = useResolvedClassNames(classNames);
|
|
2566
|
-
const uid =
|
|
2567
|
-
const sources =
|
|
2572
|
+
const uid = React8.useId();
|
|
2573
|
+
const sources = React8.useMemo(
|
|
2568
2574
|
() => given ?? collectSources(references, citations, uid),
|
|
2569
2575
|
[given, references, citations, uid]
|
|
2570
2576
|
);
|
|
@@ -2580,6 +2586,20 @@ function Citations({
|
|
|
2580
2586
|
] })
|
|
2581
2587
|
] });
|
|
2582
2588
|
}
|
|
2589
|
+
function MessageActions({
|
|
2590
|
+
message,
|
|
2591
|
+
hideCopy,
|
|
2592
|
+
children,
|
|
2593
|
+
className,
|
|
2594
|
+
classNames
|
|
2595
|
+
}) {
|
|
2596
|
+
const cn = useResolvedClassNames(classNames);
|
|
2597
|
+
if (hideCopy && !children) return null;
|
|
2598
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-msg__actions", cn.messageActions, className), role: "toolbar", "aria-label": "Message actions", children: [
|
|
2599
|
+
!hideCopy && /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { className: cx("agno-msg__action", cn.messageCopyButton), text: message.content, label: "Copy message" }),
|
|
2600
|
+
children
|
|
2601
|
+
] });
|
|
2602
|
+
}
|
|
2583
2603
|
function audioSrc(a) {
|
|
2584
2604
|
if (a.url) return a.url;
|
|
2585
2605
|
if (a.base64_audio) return `data:${a.mime_type ?? "audio/mpeg"};base64,${a.base64_audio}`;
|
|
@@ -2620,20 +2640,23 @@ function Message({
|
|
|
2620
2640
|
hideReasoning,
|
|
2621
2641
|
hideTools,
|
|
2622
2642
|
hideSources,
|
|
2643
|
+
hideActions,
|
|
2644
|
+
actions,
|
|
2623
2645
|
onFollowup
|
|
2624
2646
|
}) {
|
|
2625
2647
|
const cn = useResolvedClassNames(classNames);
|
|
2626
|
-
const uid =
|
|
2627
|
-
const sources =
|
|
2648
|
+
const uid = React8.useId();
|
|
2649
|
+
const sources = React8.useMemo(() => {
|
|
2628
2650
|
const cited = collectSources(message.references, message.citations, uid);
|
|
2629
2651
|
return cited.length ? cited : sourcesFromMarkdown(message.content, uid);
|
|
2630
2652
|
}, [message.references, message.citations, message.content, uid]);
|
|
2631
2653
|
const isUser = message.role === "user";
|
|
2632
2654
|
const isAgent = message.role === "agent";
|
|
2633
|
-
const
|
|
2634
|
-
const
|
|
2635
|
-
|
|
2636
|
-
|
|
2655
|
+
const hasSources = isAgent && !hideSources && sources.length > 0;
|
|
2656
|
+
const showSources = hasSources && !message.streaming;
|
|
2657
|
+
const content = React8.useMemo(
|
|
2658
|
+
() => hasSources && message.content ? withoutSourcesLine(message.content) : message.content,
|
|
2659
|
+
[message.content, hasSources]
|
|
2637
2660
|
);
|
|
2638
2661
|
const hasActivity = !message.content && !hasBehindTheScenes(message, { hideReasoning, hideTools });
|
|
2639
2662
|
const kind = isUser ? "user" : isAgent ? entityType : "system";
|
|
@@ -2685,7 +2708,8 @@ function Message({
|
|
|
2685
2708
|
showSources && /* @__PURE__ */ jsxRuntime.jsx(Citations, { sources, classNames: cn }),
|
|
2686
2709
|
isAgent && onFollowup && !message.streaming && /* @__PURE__ */ jsxRuntime.jsx(Followups, { items: message.followups, onSelect: onFollowup, classNames: cn }),
|
|
2687
2710
|
message.error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-msg__error", children: message.error }),
|
|
2688
|
-
children
|
|
2711
|
+
children,
|
|
2712
|
+
isAgent && !hideActions && !message.streaming && message.content && /* @__PURE__ */ jsxRuntime.jsx(MessageActions, { message, classNames: cn, children: actions })
|
|
2689
2713
|
] }) })
|
|
2690
2714
|
]
|
|
2691
2715
|
}
|
|
@@ -2712,10 +2736,10 @@ function MessageList({
|
|
|
2712
2736
|
const runActivity = activity !== void 0 ? activity : ctx?.chat.activity;
|
|
2713
2737
|
const markdown = renderMarkdown ?? ctx?.renderMarkdown;
|
|
2714
2738
|
const kind = entityType ?? ctx?.chat.entityType;
|
|
2715
|
-
const endRef =
|
|
2716
|
-
const stick =
|
|
2717
|
-
const userScrolled =
|
|
2718
|
-
const containerRef =
|
|
2739
|
+
const endRef = React8.useRef(null);
|
|
2740
|
+
const stick = React8.useRef(true);
|
|
2741
|
+
const userScrolled = React8.useRef(false);
|
|
2742
|
+
const containerRef = React8.useRef(null);
|
|
2719
2743
|
const markUserScroll = () => {
|
|
2720
2744
|
userScrolled.current = true;
|
|
2721
2745
|
};
|
|
@@ -2727,7 +2751,7 @@ function MessageList({
|
|
|
2727
2751
|
else if (userScrolled.current) stick.current = false;
|
|
2728
2752
|
userScrolled.current = false;
|
|
2729
2753
|
};
|
|
2730
|
-
|
|
2754
|
+
React8.useEffect(() => {
|
|
2731
2755
|
if (stick.current) endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
2732
2756
|
}, [items, runActivity, runStatus]);
|
|
2733
2757
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2745,7 +2769,7 @@ function MessageList({
|
|
|
2745
2769
|
items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("agno-list__empty", cn.empty), children: emptyState ?? "Start the conversation." }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-list__inner", children: [
|
|
2746
2770
|
items.map((m) => {
|
|
2747
2771
|
const live = m.streaming && runStatus === "streaming" ? runActivity : void 0;
|
|
2748
|
-
return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2772
|
+
return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: renderMessage(m, live) }, m.id) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2749
2773
|
Message,
|
|
2750
2774
|
{
|
|
2751
2775
|
message: m,
|
|
@@ -3016,10 +3040,10 @@ function EntitySelector({
|
|
|
3016
3040
|
classNames
|
|
3017
3041
|
}) {
|
|
3018
3042
|
const cn = useResolvedClassNames(classNames);
|
|
3019
|
-
const [open, setOpen] =
|
|
3020
|
-
const rootRef =
|
|
3043
|
+
const [open, setOpen] = React8.useState(false);
|
|
3044
|
+
const rootRef = React8.useRef(null);
|
|
3021
3045
|
const key = (e) => `${e.type}:${e.id}`;
|
|
3022
|
-
|
|
3046
|
+
React8.useEffect(() => {
|
|
3023
3047
|
if (!open) return;
|
|
3024
3048
|
const onDocClick = (e) => {
|
|
3025
3049
|
if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(false);
|
|
@@ -3168,14 +3192,14 @@ function SessionList({
|
|
|
3168
3192
|
] });
|
|
3169
3193
|
}
|
|
3170
3194
|
function AgnoChat(props) {
|
|
3171
|
-
const client =
|
|
3195
|
+
const client = React8.useMemo(
|
|
3172
3196
|
() => props.client ?? new chunk55HQJGLP_cjs.AgnoClient({ baseUrl: props.baseUrl ?? "", headers: props.headers }),
|
|
3173
3197
|
[props.client, props.baseUrl, props.headers]
|
|
3174
3198
|
);
|
|
3175
|
-
const [discovered, setDiscovered] =
|
|
3176
|
-
const [selected, setSelected] =
|
|
3177
|
-
const [discoveryDone, setDiscoveryDone] =
|
|
3178
|
-
|
|
3199
|
+
const [discovered, setDiscovered] = React8.useState(props.entities ?? []);
|
|
3200
|
+
const [selected, setSelected] = React8.useState(props.defaultEntity ?? null);
|
|
3201
|
+
const [discoveryDone, setDiscoveryDone] = React8.useState(Boolean(props.entity || props.entities));
|
|
3202
|
+
React8.useEffect(() => {
|
|
3179
3203
|
if (props.entity && !props.showEntityPicker || props.entities) return;
|
|
3180
3204
|
let cancelled = false;
|
|
3181
3205
|
setDiscoveryDone(false);
|
|
@@ -3192,10 +3216,10 @@ function AgnoChat(props) {
|
|
|
3192
3216
|
const entity = props.entity ?? selected;
|
|
3193
3217
|
const chat = useAgnoChat({ client, entity, userId: props.userId });
|
|
3194
3218
|
const { refreshSessions } = chat;
|
|
3195
|
-
|
|
3219
|
+
React8.useEffect(() => {
|
|
3196
3220
|
if (props.showSessions && entity) refreshSessions();
|
|
3197
3221
|
}, [props.showSessions, entity?.type, entity?.id, refreshSessions]);
|
|
3198
|
-
|
|
3222
|
+
React8.useEffect(() => {
|
|
3199
3223
|
if (props.showSessions && entity && chat.status === "completed") refreshSessions();
|
|
3200
3224
|
}, [chat.status]);
|
|
3201
3225
|
const onSelect = (e) => {
|
|
@@ -3210,7 +3234,7 @@ function AgnoChat(props) {
|
|
|
3210
3234
|
const noEntities = !props.entity && discoveryDone && entities.length === 0;
|
|
3211
3235
|
const launcher = props.mode === "launcher";
|
|
3212
3236
|
const fullscreen = props.panel === "fullscreen";
|
|
3213
|
-
const [selfOpen, setSelfOpen] =
|
|
3237
|
+
const [selfOpen, setSelfOpen] = React8.useState(props.defaultOpen ?? false);
|
|
3214
3238
|
const isOpen = props.open ?? selfOpen;
|
|
3215
3239
|
const setOpen = (next) => {
|
|
3216
3240
|
if (props.open === void 0) setSelfOpen(next);
|
|
@@ -3335,7 +3359,7 @@ function Reasoning({
|
|
|
3335
3359
|
steps,
|
|
3336
3360
|
defaultOpen = false
|
|
3337
3361
|
}) {
|
|
3338
|
-
const [open, setOpen] =
|
|
3362
|
+
const [open, setOpen] = React8.useState(defaultOpen);
|
|
3339
3363
|
if (!steps || steps.length === 0) return null;
|
|
3340
3364
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-reasoning", children: [
|
|
3341
3365
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3381,7 +3405,7 @@ function statusDot(status) {
|
|
|
3381
3405
|
return "running";
|
|
3382
3406
|
}
|
|
3383
3407
|
function MemberCard({ member, renderMarkdown }) {
|
|
3384
|
-
const [open, setOpen] =
|
|
3408
|
+
const [open, setOpen] = React8.useState(true);
|
|
3385
3409
|
const label2 = member.kind === "executor" ? "Step executor" : "Member";
|
|
3386
3410
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-member", children: [
|
|
3387
3411
|
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "agno-member__head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
@@ -3413,7 +3437,7 @@ function MemberResponses({
|
|
|
3413
3437
|
] });
|
|
3414
3438
|
}
|
|
3415
3439
|
function StepRow({ step, renderMarkdown }) {
|
|
3416
|
-
const [open, setOpen] =
|
|
3440
|
+
const [open, setOpen] = React8.useState(false);
|
|
3417
3441
|
const hasBody = Boolean(step.content || step.error);
|
|
3418
3442
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `agno-step agno-step--${step.status}`, children: [
|
|
3419
3443
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3483,9 +3507,9 @@ function EventLog({
|
|
|
3483
3507
|
autoScroll = true,
|
|
3484
3508
|
maxHeight = 240
|
|
3485
3509
|
}) {
|
|
3486
|
-
const ref =
|
|
3487
|
-
const rows =
|
|
3488
|
-
|
|
3510
|
+
const ref = React8.useRef(null);
|
|
3511
|
+
const rows = React8.useMemo(() => fold(events), [events]);
|
|
3512
|
+
React8.useEffect(() => {
|
|
3489
3513
|
if (autoScroll && ref.current) ref.current.scrollTop = ref.current.scrollHeight;
|
|
3490
3514
|
}, [rows, autoScroll]);
|
|
3491
3515
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-eventlog", ref, style: { maxHeight }, children: [
|
|
@@ -3519,6 +3543,7 @@ exports.ChevronDown = ChevronDown;
|
|
|
3519
3543
|
exports.Citations = Citations;
|
|
3520
3544
|
exports.Close = Close;
|
|
3521
3545
|
exports.Copy = Copy;
|
|
3546
|
+
exports.CopyButton = CopyButton;
|
|
3522
3547
|
exports.EntityBadge = EntityBadge;
|
|
3523
3548
|
exports.EntitySelector = EntitySelector;
|
|
3524
3549
|
exports.EventLog = EventLog;
|
|
@@ -3539,6 +3564,7 @@ exports.Markdown = Markdown;
|
|
|
3539
3564
|
exports.MemberResponses = MemberResponses;
|
|
3540
3565
|
exports.Memory = Memory;
|
|
3541
3566
|
exports.Message = Message;
|
|
3567
|
+
exports.MessageActions = MessageActions;
|
|
3542
3568
|
exports.MessageList = MessageList;
|
|
3543
3569
|
exports.Multimedia = Multimedia;
|
|
3544
3570
|
exports.Paperclip = Paperclip;
|
|
@@ -3564,6 +3590,7 @@ exports.behindTheScenesLabel = behindTheScenesLabel;
|
|
|
3564
3590
|
exports.collectSources = collectSources;
|
|
3565
3591
|
exports.cx = cx;
|
|
3566
3592
|
exports.displayUrl = displayUrl;
|
|
3593
|
+
exports.faviconFallbacks = faviconFallbacks;
|
|
3567
3594
|
exports.faviconUrl = faviconUrl;
|
|
3568
3595
|
exports.fileAccepted = fileAccepted;
|
|
3569
3596
|
exports.getProviderIcon = getProviderIcon;
|
|
@@ -3584,5 +3611,5 @@ exports.useResolvedClassNames = useResolvedClassNames;
|
|
|
3584
3611
|
exports.useSources = useSources;
|
|
3585
3612
|
exports.withoutSourcesLine = withoutSourcesLine;
|
|
3586
3613
|
exports.writeClipboard = writeClipboard;
|
|
3587
|
-
//# sourceMappingURL=chunk-
|
|
3588
|
-
//# sourceMappingURL=chunk-
|
|
3614
|
+
//# sourceMappingURL=chunk-3IEYJIYJ.cjs.map
|
|
3615
|
+
//# sourceMappingURL=chunk-3IEYJIYJ.cjs.map
|