@agno-hq/chat-react 0.3.2 → 0.3.4
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 +81 -5
- package/dist/chat/index.cjs +99 -83
- package/dist/chat/index.d.cts +80 -16
- package/dist/chat/index.d.ts +80 -16
- package/dist/chat/index.js +2 -2
- package/dist/{chunk-RE7ZT73K.js → chunk-5QKU7OPE.js} +2 -2
- package/dist/{chunk-RE7ZT73K.js.map → chunk-5QKU7OPE.js.map} +1 -1
- package/dist/{chunk-6V2YIPHF.js → chunk-BCVKAMSO.js} +22 -4
- package/dist/chunk-BCVKAMSO.js.map +1 -0
- package/dist/{chunk-Q73XHL35.cjs → chunk-ESV52ERB.cjs} +771 -444
- package/dist/chunk-ESV52ERB.cjs.map +1 -0
- package/dist/{chunk-2WM3CCFE.cjs → chunk-HBSF434L.cjs} +2 -2
- package/dist/{chunk-2WM3CCFE.cjs.map → chunk-HBSF434L.cjs.map} +1 -1
- package/dist/{chunk-XTP3TMEZ.js → chunk-OGDPK4Z3.js} +602 -279
- package/dist/chunk-OGDPK4Z3.js.map +1 -0
- package/dist/{chunk-55HQJGLP.cjs → chunk-Y34YRC5T.cjs} +22 -3
- package/dist/chunk-Y34YRC5T.cjs.map +1 -0
- package/dist/{client-DUyVqxU9.d.cts → client-Dwk6ThnW.d.cts} +24 -12
- package/dist/{client-DUyVqxU9.d.ts → client-Dwk6ThnW.d.ts} +24 -12
- package/dist/core/index.cjs +23 -23
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/index.cjs +122 -106
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/styles.css +79 -34
- package/package.json +1 -1
- package/dist/chunk-55HQJGLP.cjs.map +0 -1
- package/dist/chunk-6V2YIPHF.js.map +0 -1
- package/dist/chunk-Q73XHL35.cjs.map +0 -1
- package/dist/chunk-XTP3TMEZ.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkY34YRC5T_cjs = require('./chunk-Y34YRC5T.cjs');
|
|
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,221 @@ 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
|
+
function useRunView(initialMessages = []) {
|
|
15
|
+
const [view, setView] = React8.useState({
|
|
16
|
+
messages: initialMessages,
|
|
17
|
+
events: [],
|
|
18
|
+
status: "idle",
|
|
19
|
+
activity: null,
|
|
20
|
+
error: null
|
|
21
|
+
});
|
|
22
|
+
const viewRef = React8.useRef(view);
|
|
23
|
+
const update = React8.useCallback((key, action) => {
|
|
24
|
+
const value = typeof action === "function" ? action(viewRef.current[key]) : action;
|
|
25
|
+
if (Object.is(value, viewRef.current[key])) return;
|
|
26
|
+
viewRef.current = { ...viewRef.current, [key]: value };
|
|
27
|
+
setView(viewRef.current);
|
|
28
|
+
}, []);
|
|
29
|
+
const setters = React8.useMemo(() => ({
|
|
30
|
+
setMessages: (action) => update("messages", action),
|
|
31
|
+
setEvents: (action) => update("events", action),
|
|
32
|
+
setStatus: (action) => update("status", action),
|
|
33
|
+
setActivity: (action) => update("activity", action),
|
|
34
|
+
setError: (action) => update("error", action)
|
|
35
|
+
}), [update]);
|
|
36
|
+
return { ...view, ...setters, viewRef };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/chat/streaming/bufferTextEvents.ts
|
|
40
|
+
var DEFAULT_STREAMING_OPTIONS = Object.freeze({
|
|
41
|
+
enabled: true,
|
|
42
|
+
flushIntervalMs: 150,
|
|
43
|
+
maxBufferEvents: 100,
|
|
44
|
+
maxBufferChars: 16384
|
|
45
|
+
});
|
|
46
|
+
var MAX_TIMEOUT_MS = 2147483647;
|
|
47
|
+
var RICH_FIELDS = [
|
|
48
|
+
"tool",
|
|
49
|
+
"tools",
|
|
50
|
+
"response_audio",
|
|
51
|
+
"images",
|
|
52
|
+
"videos",
|
|
53
|
+
"audio",
|
|
54
|
+
"image",
|
|
55
|
+
"references",
|
|
56
|
+
"citations",
|
|
57
|
+
"extra_data"
|
|
58
|
+
];
|
|
59
|
+
function isPlainText(event) {
|
|
60
|
+
return (event.event === "RunContent" || event.event === "TeamRunContent") && typeof event.content === "string" && event.content.length > 0 && RICH_FIELDS.every((key) => event[key] == null);
|
|
61
|
+
}
|
|
62
|
+
function isContinuationOf(previous, next) {
|
|
63
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(previous), ...Object.keys(next)]);
|
|
64
|
+
for (const key of keys) {
|
|
65
|
+
if (key === "content") continue;
|
|
66
|
+
const before = previous[key];
|
|
67
|
+
const after = next[key];
|
|
68
|
+
if (key === "event_index" && typeof before === "number" && typeof after === "number") {
|
|
69
|
+
if (after <= before) return false;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!Object.is(before, after)) return false;
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
function boundedNumber(value, fallback, min) {
|
|
77
|
+
return value !== void 0 && Number.isFinite(value) && value >= min ? Math.min(Math.floor(value), MAX_TIMEOUT_MS) : fallback;
|
|
78
|
+
}
|
|
79
|
+
function bufferTextEvents(deliver, options = {}) {
|
|
80
|
+
const defaults = DEFAULT_STREAMING_OPTIONS;
|
|
81
|
+
const interval = boundedNumber(
|
|
82
|
+
options.flushIntervalMs,
|
|
83
|
+
defaults.flushIntervalMs,
|
|
84
|
+
0
|
|
85
|
+
);
|
|
86
|
+
const maxEvents = boundedNumber(
|
|
87
|
+
options.maxBufferEvents,
|
|
88
|
+
defaults.maxBufferEvents,
|
|
89
|
+
1
|
|
90
|
+
);
|
|
91
|
+
const maxChars = boundedNumber(
|
|
92
|
+
options.maxBufferChars,
|
|
93
|
+
defaults.maxBufferChars,
|
|
94
|
+
1
|
|
95
|
+
);
|
|
96
|
+
const enabled = (options.enabled ?? defaults.enabled) && interval > 0;
|
|
97
|
+
let events = [];
|
|
98
|
+
let chunks = [];
|
|
99
|
+
let chars = 0;
|
|
100
|
+
let hasText = false;
|
|
101
|
+
let disposed = false;
|
|
102
|
+
let timer;
|
|
103
|
+
const isHidden = () => typeof document !== "undefined" && document.visibilityState === "hidden";
|
|
104
|
+
const onVisibilityChange = () => {
|
|
105
|
+
if (isHidden()) flush();
|
|
106
|
+
};
|
|
107
|
+
const stopObserving = () => {
|
|
108
|
+
if (typeof document !== "undefined")
|
|
109
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
110
|
+
};
|
|
111
|
+
const cancelScheduled = () => {
|
|
112
|
+
stopObserving();
|
|
113
|
+
clearTimeout(timer);
|
|
114
|
+
timer = void 0;
|
|
115
|
+
};
|
|
116
|
+
const flush = () => {
|
|
117
|
+
cancelScheduled();
|
|
118
|
+
const batch = { events, chunks };
|
|
119
|
+
events = [];
|
|
120
|
+
chunks = [];
|
|
121
|
+
chars = 0;
|
|
122
|
+
if (!disposed && (batch.events.length || batch.chunks.length))
|
|
123
|
+
deliver(batch);
|
|
124
|
+
};
|
|
125
|
+
const schedule = () => {
|
|
126
|
+
if (timer !== void 0 || disposed) return;
|
|
127
|
+
if (isHidden()) return flush();
|
|
128
|
+
if (typeof document !== "undefined")
|
|
129
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
130
|
+
timer = setTimeout(() => {
|
|
131
|
+
timer = void 0;
|
|
132
|
+
flush();
|
|
133
|
+
}, interval);
|
|
134
|
+
};
|
|
135
|
+
const deliverNow = (event) => {
|
|
136
|
+
if (!disposed) deliver({ events: [event], chunks: [event] });
|
|
137
|
+
};
|
|
138
|
+
const append = (event) => {
|
|
139
|
+
const last = chunks[chunks.length - 1];
|
|
140
|
+
if (last && isContinuationOf(last, event)) {
|
|
141
|
+
chunks[chunks.length - 1] = {
|
|
142
|
+
...event,
|
|
143
|
+
content: String(last.content) + event.content
|
|
144
|
+
};
|
|
145
|
+
} else {
|
|
146
|
+
chunks.push(event);
|
|
147
|
+
}
|
|
148
|
+
events.push(event);
|
|
149
|
+
chars += String(event.content).length;
|
|
150
|
+
};
|
|
151
|
+
return {
|
|
152
|
+
push(event) {
|
|
153
|
+
if (disposed) return;
|
|
154
|
+
if (!enabled || !isPlainText(event)) {
|
|
155
|
+
flush();
|
|
156
|
+
hasText = false;
|
|
157
|
+
deliverNow(event);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (!hasText) {
|
|
161
|
+
hasText = true;
|
|
162
|
+
deliverNow(event);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
append(event);
|
|
166
|
+
if (events.length >= maxEvents || chars >= maxChars) flush();
|
|
167
|
+
else schedule();
|
|
168
|
+
},
|
|
169
|
+
flush,
|
|
170
|
+
dispose() {
|
|
171
|
+
disposed = true;
|
|
172
|
+
cancelScheduled();
|
|
173
|
+
events = [];
|
|
174
|
+
chunks = [];
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/chat/useAgnoChat.ts
|
|
14
180
|
var messageCounter = 0;
|
|
15
181
|
var nextId = () => `m${Date.now().toString(36)}-${(messageCounter++).toString(36)}`;
|
|
16
182
|
var nowSeconds = () => Math.floor(Date.now() / 1e3);
|
|
17
183
|
function useAgnoChat(options) {
|
|
18
184
|
const { entity, userId, onEvent, onSessionId } = options;
|
|
19
|
-
const client =
|
|
185
|
+
const client = React8.useMemo(() => {
|
|
20
186
|
if (options.client) return options.client;
|
|
21
|
-
return new
|
|
187
|
+
return new chunkY34YRC5T_cjs.AgnoClient({ baseUrl: options.baseUrl ?? "", headers: options.headers });
|
|
22
188
|
}, [options.client, options.baseUrl, JSON.stringify(options.headers)]);
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
|
|
189
|
+
const {
|
|
190
|
+
messages,
|
|
191
|
+
events,
|
|
192
|
+
status,
|
|
193
|
+
activity,
|
|
194
|
+
error,
|
|
195
|
+
viewRef,
|
|
196
|
+
setMessages,
|
|
197
|
+
setEvents,
|
|
198
|
+
setStatus,
|
|
199
|
+
setActivity,
|
|
200
|
+
setError
|
|
201
|
+
} = useRunView(options.initialMessages);
|
|
202
|
+
const currentEvent = events[events.length - 1] ?? null;
|
|
203
|
+
const [sessionId, setSessionId] = React8.useState(options.sessionId);
|
|
204
|
+
const [sessions, setSessions] = React8.useState([]);
|
|
205
|
+
const [sessionsLoading, setSessionsLoading] = React8.useState(false);
|
|
206
|
+
const [backgroundRunning, setBackgroundRunning] = React8.useState([]);
|
|
207
|
+
const abortRef = React8.useRef(null);
|
|
208
|
+
const channelRef = React8.useRef(null);
|
|
209
|
+
const backgroundRef = React8.useRef(/* @__PURE__ */ new Map());
|
|
210
|
+
const activeMsgIdRef = React8.useRef(null);
|
|
211
|
+
const runIdRef = React8.useRef(void 0);
|
|
212
|
+
const streamingRef = React8.useRef(options.streaming);
|
|
213
|
+
const entityRef = React8.useRef(entity);
|
|
214
|
+
const sessionIdRef = React8.useRef(options.sessionId);
|
|
215
|
+
const pendingSessionNameRef = React8.useRef(void 0);
|
|
216
|
+
const bumpedSessionRef = React8.useRef(void 0);
|
|
217
|
+
React8.useEffect(() => {
|
|
218
|
+
streamingRef.current = options.streaming;
|
|
219
|
+
}, [options.streaming]);
|
|
220
|
+
React8.useEffect(() => {
|
|
43
221
|
entityRef.current = entity;
|
|
44
222
|
}, [entity]);
|
|
45
|
-
|
|
223
|
+
React8.useEffect(() => {
|
|
46
224
|
sessionIdRef.current = sessionId;
|
|
47
225
|
}, [sessionId]);
|
|
48
|
-
const upsertSession =
|
|
226
|
+
const upsertSession = React8.useCallback((id, createdAt) => {
|
|
49
227
|
setSessions((prev) => {
|
|
50
228
|
const existing = prev.find((s) => s.session_id === id);
|
|
51
229
|
const rest = prev.filter((s) => s.session_id !== id);
|
|
@@ -58,55 +236,45 @@ function useAgnoChat(options) {
|
|
|
58
236
|
return [entry, ...rest];
|
|
59
237
|
});
|
|
60
238
|
}, []);
|
|
61
|
-
const
|
|
62
|
-
React7.useEffect(() => {
|
|
63
|
-
viewRef.current = { messages, events, status, activity, error };
|
|
64
|
-
});
|
|
65
|
-
const writeMessages = React7.useCallback(
|
|
239
|
+
const writeMessages = React8.useCallback(
|
|
66
240
|
(chan, fn) => {
|
|
67
241
|
const park = chan?.park;
|
|
68
242
|
if (park) park.messages = fn(park.messages);
|
|
69
243
|
else setMessages(fn);
|
|
70
244
|
},
|
|
71
|
-
[]
|
|
245
|
+
[setMessages]
|
|
72
246
|
);
|
|
73
|
-
const writeEvents =
|
|
74
|
-
const park = chan
|
|
75
|
-
if (park) park.events = [...park.events,
|
|
76
|
-
else
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
}, []);
|
|
81
|
-
const writeStatus = React7.useCallback((chan, status2) => {
|
|
247
|
+
const writeEvents = React8.useCallback((chan, incoming) => {
|
|
248
|
+
const park = chan.park;
|
|
249
|
+
if (park) park.events = [...park.events, ...incoming];
|
|
250
|
+
else setEvents((previous) => [...previous, ...incoming]);
|
|
251
|
+
}, [setEvents]);
|
|
252
|
+
const writeStatus = React8.useCallback((chan, status2) => {
|
|
82
253
|
const park = chan?.park;
|
|
83
254
|
if (park) park.status = status2;
|
|
84
255
|
else setStatus(status2);
|
|
85
|
-
}, []);
|
|
86
|
-
const writeActivity =
|
|
256
|
+
}, [setStatus]);
|
|
257
|
+
const writeActivity = React8.useCallback((chan, activity2) => {
|
|
87
258
|
const park = chan?.park;
|
|
88
259
|
if (park) park.activity = activity2;
|
|
89
260
|
else setActivity(activity2);
|
|
90
|
-
}, []);
|
|
91
|
-
const writeError =
|
|
261
|
+
}, [setActivity]);
|
|
262
|
+
const writeError = React8.useCallback((chan, message) => {
|
|
92
263
|
const park = chan?.park;
|
|
93
264
|
if (park) park.error = message;
|
|
94
265
|
else setError(message);
|
|
95
|
-
}, []);
|
|
96
|
-
const patchActive =
|
|
266
|
+
}, [setError]);
|
|
267
|
+
const patchActive = React8.useCallback(
|
|
97
268
|
(chan, patch) => {
|
|
98
|
-
const id = chan
|
|
269
|
+
const id = chan ? chan.messageId : activeMsgIdRef.current;
|
|
99
270
|
if (!id) return;
|
|
100
271
|
writeMessages(chan, (prev) => prev.map((m) => m.id === id ? patch(m) : m));
|
|
101
272
|
},
|
|
102
273
|
[writeMessages]
|
|
103
274
|
);
|
|
104
|
-
const applyEvent =
|
|
275
|
+
const applyEvent = React8.useCallback(
|
|
105
276
|
(chan, e) => {
|
|
106
|
-
|
|
107
|
-
patchActive(chan, (m) => ({ ...m, events: [...m.events ?? [], e] }));
|
|
108
|
-
onEvent?.(e);
|
|
109
|
-
const label2 = chunk55HQJGLP_cjs.activityLabel(e);
|
|
277
|
+
const label2 = chunkY34YRC5T_cjs.activityLabel(e);
|
|
110
278
|
if (label2) writeActivity(chan, label2);
|
|
111
279
|
if (e.session_id && !chan?.park && e.session_id !== sessionIdRef.current) {
|
|
112
280
|
sessionIdRef.current = e.session_id;
|
|
@@ -123,16 +291,16 @@ function useAgnoChat(options) {
|
|
|
123
291
|
if (chan?.park) chan.park.runId = e.run_id;
|
|
124
292
|
else runIdRef.current = e.run_id;
|
|
125
293
|
}
|
|
126
|
-
if (
|
|
127
|
-
const kind = entityRef.current?.type === "workflow" ? "executor" : "member";
|
|
128
|
-
patchActive(chan, (m) =>
|
|
294
|
+
if (chunkY34YRC5T_cjs.isSubRunEvent(e)) {
|
|
295
|
+
const kind = (chan?.entityType ?? entityRef.current?.type) === "workflow" ? "executor" : "member";
|
|
296
|
+
patchActive(chan, (m) => chunkY34YRC5T_cjs.applySubRunEvent(m, e, kind));
|
|
129
297
|
return;
|
|
130
298
|
}
|
|
131
|
-
if (
|
|
132
|
-
patchActive(chan, (m) =>
|
|
299
|
+
if (chunkY34YRC5T_cjs.isStepEvent(e)) {
|
|
300
|
+
patchActive(chan, (m) => chunkY34YRC5T_cjs.applyStepEvent(m, e));
|
|
133
301
|
return;
|
|
134
302
|
}
|
|
135
|
-
if (
|
|
303
|
+
if (chunkY34YRC5T_cjs.isStartedEvent(e)) {
|
|
136
304
|
patchActive(chan, (m) => ({
|
|
137
305
|
...m,
|
|
138
306
|
run_id: e.run_id ?? m.run_id,
|
|
@@ -141,23 +309,23 @@ function useAgnoChat(options) {
|
|
|
141
309
|
}));
|
|
142
310
|
return;
|
|
143
311
|
}
|
|
144
|
-
if (
|
|
145
|
-
const incoming =
|
|
312
|
+
if (chunkY34YRC5T_cjs.isToolEvent(e)) {
|
|
313
|
+
const incoming = chunkY34YRC5T_cjs.toolsFromEvent(e);
|
|
146
314
|
if (incoming.length) {
|
|
147
315
|
patchActive(chan, (m) => {
|
|
148
316
|
let tool_calls = m.tool_calls ?? [];
|
|
149
|
-
for (const t of incoming) tool_calls =
|
|
317
|
+
for (const t of incoming) tool_calls = chunkY34YRC5T_cjs.mergeTool(tool_calls, t);
|
|
150
318
|
return { ...m, tool_calls };
|
|
151
319
|
});
|
|
152
320
|
}
|
|
153
321
|
return;
|
|
154
322
|
}
|
|
155
|
-
if (
|
|
156
|
-
patchActive(chan, (m) =>
|
|
323
|
+
if (chunkY34YRC5T_cjs.isContentEvent(e)) {
|
|
324
|
+
patchActive(chan, (m) => chunkY34YRC5T_cjs.applyContentEvent(m, e));
|
|
157
325
|
return;
|
|
158
326
|
}
|
|
159
|
-
if (
|
|
160
|
-
const incoming =
|
|
327
|
+
if (chunkY34YRC5T_cjs.isReasoningStepEvent(e)) {
|
|
328
|
+
const incoming = chunkY34YRC5T_cjs.reasoningStepsFromEvent(e);
|
|
161
329
|
if (incoming.length) {
|
|
162
330
|
patchActive(chan, (m) => ({
|
|
163
331
|
...m,
|
|
@@ -166,36 +334,36 @@ function useAgnoChat(options) {
|
|
|
166
334
|
}
|
|
167
335
|
return;
|
|
168
336
|
}
|
|
169
|
-
if (
|
|
170
|
-
const steps =
|
|
171
|
-
if (steps
|
|
337
|
+
if (chunkY34YRC5T_cjs.isReasoningCompletedEvent(e)) {
|
|
338
|
+
const steps = chunkY34YRC5T_cjs.reasoningStepsFromEvent(e);
|
|
339
|
+
if (steps.length) patchActive(chan, (m) => ({ ...m, reasoning_steps: steps }));
|
|
172
340
|
return;
|
|
173
341
|
}
|
|
174
|
-
if (
|
|
342
|
+
if (chunkY34YRC5T_cjs.isFollowupsCompletedEvent(e)) {
|
|
175
343
|
const followups = e.followups;
|
|
176
344
|
if (followups?.length) patchActive(chan, (m) => ({ ...m, followups }));
|
|
177
345
|
return;
|
|
178
346
|
}
|
|
179
|
-
if (
|
|
347
|
+
if (chunkY34YRC5T_cjs.isPausedEvent(e)) {
|
|
180
348
|
const requirements = e.requirements ?? [];
|
|
181
|
-
const pausedTools2 =
|
|
349
|
+
const pausedTools2 = chunkY34YRC5T_cjs.toolsFromEvent(e);
|
|
182
350
|
writeStatus(chan, "paused");
|
|
183
351
|
writeActivity(chan, "Waiting for input");
|
|
184
352
|
patchActive(chan, (m) => {
|
|
185
353
|
let tool_calls = m.tool_calls ?? [];
|
|
186
|
-
for (const t of pausedTools2) tool_calls =
|
|
187
|
-
return { ...m, status: "paused", streaming: false, requirements, tool_calls };
|
|
354
|
+
for (const t of pausedTools2) tool_calls = chunkY34YRC5T_cjs.mergeTool(tool_calls, t);
|
|
355
|
+
return { ...m, status: "paused", streaming: false, requirements, step_requirements: e.step_requirements ?? m.step_requirements, tool_calls };
|
|
188
356
|
});
|
|
189
357
|
return;
|
|
190
358
|
}
|
|
191
|
-
if (
|
|
359
|
+
if (chunkY34YRC5T_cjs.isCompletedEvent(e)) {
|
|
192
360
|
patchActive(chan, (m) => {
|
|
193
361
|
const next = { ...m, streaming: false, status: "completed" };
|
|
194
362
|
if (typeof e.content === "string" && e.content) next.content = e.content;
|
|
195
|
-
const tools =
|
|
363
|
+
const tools = chunkY34YRC5T_cjs.toolsFromEvent(e);
|
|
196
364
|
if (tools.length) {
|
|
197
365
|
let tc = m.tool_calls ?? [];
|
|
198
|
-
for (const t of tools) tc =
|
|
366
|
+
for (const t of tools) tc = chunkY34YRC5T_cjs.mergeTool(tc, t);
|
|
199
367
|
next.tool_calls = tc;
|
|
200
368
|
}
|
|
201
369
|
if (e.reasoning_steps?.length) next.reasoning_steps = e.reasoning_steps;
|
|
@@ -209,12 +377,12 @@ function useAgnoChat(options) {
|
|
|
209
377
|
});
|
|
210
378
|
return;
|
|
211
379
|
}
|
|
212
|
-
if (
|
|
380
|
+
if (chunkY34YRC5T_cjs.isCancelledEvent(e)) {
|
|
213
381
|
patchActive(chan, (m) => ({ ...m, streaming: false, status: "cancelled" }));
|
|
214
382
|
writeStatus(chan, "cancelled");
|
|
215
383
|
return;
|
|
216
384
|
}
|
|
217
|
-
if (
|
|
385
|
+
if (chunkY34YRC5T_cjs.isErrorEvent(e)) {
|
|
218
386
|
const msg = typeof e.content === "string" ? e.content : e.error || "Error during run";
|
|
219
387
|
patchActive(chan, (m) => ({ ...m, streaming: false, status: "error", error: msg }));
|
|
220
388
|
writeError(chan, msg);
|
|
@@ -223,17 +391,15 @@ function useAgnoChat(options) {
|
|
|
223
391
|
}
|
|
224
392
|
},
|
|
225
393
|
[
|
|
226
|
-
onEvent,
|
|
227
394
|
onSessionId,
|
|
228
395
|
patchActive,
|
|
229
396
|
upsertSession,
|
|
230
397
|
writeActivity,
|
|
231
398
|
writeError,
|
|
232
|
-
writeEvents,
|
|
233
399
|
writeStatus
|
|
234
400
|
]
|
|
235
401
|
);
|
|
236
|
-
const parkRun =
|
|
402
|
+
const parkRun = React8.useCallback((chan, sessionId2) => {
|
|
237
403
|
const view = viewRef.current;
|
|
238
404
|
chan.park = {
|
|
239
405
|
sessionId: sessionId2,
|
|
@@ -253,7 +419,7 @@ function useAgnoChat(options) {
|
|
|
253
419
|
activeMsgIdRef.current = null;
|
|
254
420
|
runIdRef.current = void 0;
|
|
255
421
|
}, []);
|
|
256
|
-
const resumeRun =
|
|
422
|
+
const resumeRun = React8.useCallback((sessionId2) => {
|
|
257
423
|
const chan = backgroundRef.current.get(sessionId2);
|
|
258
424
|
const park = chan?.park;
|
|
259
425
|
if (!chan || !park) return false;
|
|
@@ -267,13 +433,12 @@ function useAgnoChat(options) {
|
|
|
267
433
|
bumpedSessionRef.current = park.bumped;
|
|
268
434
|
setMessages(park.messages);
|
|
269
435
|
setEvents(park.events);
|
|
270
|
-
setCurrentEvent(park.events[park.events.length - 1] ?? null);
|
|
271
436
|
setStatus(park.status);
|
|
272
437
|
setActivity(park.activity);
|
|
273
438
|
setError(park.error);
|
|
274
439
|
return true;
|
|
275
|
-
}, []);
|
|
276
|
-
const releaseCurrentRun =
|
|
440
|
+
}, [setMessages, setEvents, setStatus, setActivity, setError]);
|
|
441
|
+
const releaseCurrentRun = React8.useCallback(() => {
|
|
277
442
|
const chan = channelRef.current;
|
|
278
443
|
if (!chan || chan.park) return;
|
|
279
444
|
const from = sessionIdRef.current;
|
|
@@ -285,32 +450,67 @@ function useAgnoChat(options) {
|
|
|
285
450
|
abortRef.current = null;
|
|
286
451
|
}
|
|
287
452
|
}, [parkRun]);
|
|
288
|
-
const drive =
|
|
453
|
+
const drive = React8.useCallback(
|
|
289
454
|
async (starter) => {
|
|
290
455
|
const controller = new AbortController();
|
|
291
|
-
|
|
456
|
+
let finished = false;
|
|
457
|
+
const isCurrent = () => !controller.signal.aborted && (channelRef.current === chan || Boolean(chan.park && backgroundRef.current.get(chan.park.sessionId) === chan));
|
|
458
|
+
const chan = {
|
|
459
|
+
controller,
|
|
460
|
+
park: null,
|
|
461
|
+
messageId: activeMsgIdRef.current,
|
|
462
|
+
entityType: entityRef.current?.type,
|
|
463
|
+
buffer: bufferTextEvents(({ events: incoming, chunks }) => {
|
|
464
|
+
if (!isCurrent()) return;
|
|
465
|
+
if (incoming.length) {
|
|
466
|
+
writeEvents(chan, incoming);
|
|
467
|
+
patchActive(chan, (m) => ({ ...m, events: [...m.events ?? [], ...incoming] }));
|
|
468
|
+
}
|
|
469
|
+
for (const chunk of chunks) applyEvent(chan, chunk);
|
|
470
|
+
}, streamingRef.current)
|
|
471
|
+
};
|
|
472
|
+
controller.signal.addEventListener("abort", () => chan.buffer.dispose(), { once: true });
|
|
292
473
|
channelRef.current = chan;
|
|
293
474
|
abortRef.current = controller;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
475
|
+
writeError(chan, null);
|
|
476
|
+
writeStatus(chan, "streaming");
|
|
477
|
+
const complete = () => {
|
|
478
|
+
if (finished || !isCurrent()) return;
|
|
479
|
+
chan.buffer.flush();
|
|
480
|
+
finished = true;
|
|
481
|
+
chan.buffer.dispose();
|
|
482
|
+
writeActivity(chan, null);
|
|
483
|
+
patchActive(chan, (m) => m.streaming ? { ...m, streaming: false, status: "completed" } : m);
|
|
484
|
+
const status2 = chan.park?.status ?? viewRef.current.status;
|
|
485
|
+
if (status2 === "streaming") writeStatus(chan, "completed");
|
|
486
|
+
};
|
|
487
|
+
const fail = (err) => {
|
|
488
|
+
if (finished || !isCurrent()) return;
|
|
489
|
+
chan.buffer.flush();
|
|
490
|
+
finished = true;
|
|
491
|
+
chan.buffer.dispose();
|
|
492
|
+
patchActive(chan, (m) => ({ ...m, streaming: false, status: "error", error: err.message }));
|
|
493
|
+
writeActivity(chan, null);
|
|
494
|
+
writeError(chan, err.message);
|
|
495
|
+
writeStatus(chan, "error");
|
|
496
|
+
};
|
|
497
|
+
try {
|
|
498
|
+
await starter({
|
|
499
|
+
signal: controller.signal,
|
|
500
|
+
onEvent: (e) => {
|
|
501
|
+
if (finished || !isCurrent()) return;
|
|
502
|
+
onEvent?.(e);
|
|
503
|
+
if (isCurrent()) chan.buffer.push(e);
|
|
504
|
+
},
|
|
505
|
+
onError: fail,
|
|
506
|
+
onComplete: complete
|
|
507
|
+
});
|
|
508
|
+
complete();
|
|
509
|
+
} catch (error2) {
|
|
510
|
+
fail(error2 instanceof Error ? error2 : new Error(String(error2)));
|
|
511
|
+
} finally {
|
|
512
|
+
chan.buffer.dispose();
|
|
513
|
+
}
|
|
314
514
|
if (chan.park) {
|
|
315
515
|
const { sessionId: sessionId2 } = chan.park;
|
|
316
516
|
setBackgroundRunning((prev) => prev.filter((s) => s !== sessionId2));
|
|
@@ -319,9 +519,9 @@ function useAgnoChat(options) {
|
|
|
319
519
|
abortRef.current = null;
|
|
320
520
|
}
|
|
321
521
|
},
|
|
322
|
-
[applyEvent, patchActive, writeActivity, writeError, writeStatus]
|
|
522
|
+
[applyEvent, onEvent, patchActive, writeActivity, writeError, writeEvents, writeStatus]
|
|
323
523
|
);
|
|
324
|
-
const sendMessage =
|
|
524
|
+
const sendMessage = React8.useCallback(
|
|
325
525
|
async (message, sendOptions) => {
|
|
326
526
|
const ent = entityRef.current;
|
|
327
527
|
if (!ent) {
|
|
@@ -348,7 +548,6 @@ function useAgnoChat(options) {
|
|
|
348
548
|
};
|
|
349
549
|
activeMsgIdRef.current = agentMsg.id;
|
|
350
550
|
setEvents([]);
|
|
351
|
-
setCurrentEvent(null);
|
|
352
551
|
setMessages((prev) => [...prev, userMsg, agentMsg]);
|
|
353
552
|
await drive(
|
|
354
553
|
(cb) => client.run({
|
|
@@ -362,9 +561,9 @@ function useAgnoChat(options) {
|
|
|
362
561
|
})
|
|
363
562
|
);
|
|
364
563
|
},
|
|
365
|
-
[client, drive, userId]
|
|
564
|
+
[client, drive, setEvents, setMessages, userId]
|
|
366
565
|
);
|
|
367
|
-
const continueRun =
|
|
566
|
+
const continueRun = React8.useCallback(
|
|
368
567
|
async (resolution) => {
|
|
369
568
|
const ent = entityRef.current;
|
|
370
569
|
const runId = runIdRef.current;
|
|
@@ -372,7 +571,7 @@ function useAgnoChat(options) {
|
|
|
372
571
|
setError("No paused run to continue.");
|
|
373
572
|
return;
|
|
374
573
|
}
|
|
375
|
-
patchActive(null, (m) => ({ ...m, streaming: true, status: "streaming", requirements: void 0 }));
|
|
574
|
+
patchActive(null, (m) => ({ ...m, streaming: true, status: "streaming", requirements: void 0, step_requirements: void 0 }));
|
|
376
575
|
await drive(
|
|
377
576
|
(cb) => client.continueRun({
|
|
378
577
|
type: ent.type,
|
|
@@ -381,6 +580,7 @@ function useAgnoChat(options) {
|
|
|
381
580
|
sessionId: sessionIdRef.current,
|
|
382
581
|
userId,
|
|
383
582
|
tools: resolution.tools,
|
|
583
|
+
requirements: resolution.requirements,
|
|
384
584
|
stepRequirements: resolution.stepRequirements,
|
|
385
585
|
...cb
|
|
386
586
|
})
|
|
@@ -388,19 +588,23 @@ function useAgnoChat(options) {
|
|
|
388
588
|
},
|
|
389
589
|
[client, drive, patchActive, userId]
|
|
390
590
|
);
|
|
391
|
-
const activeMessage =
|
|
591
|
+
const activeMessage = React8.useMemo(
|
|
392
592
|
() => messages.find((m) => m.id === activeMsgIdRef.current) ?? null,
|
|
393
593
|
[messages]
|
|
394
594
|
);
|
|
395
|
-
const pausedTools =
|
|
595
|
+
const pausedTools = React8.useMemo(
|
|
396
596
|
() => (activeMessage?.tool_calls ?? []).filter((t) => t.requires_confirmation || t.requires_user_input),
|
|
397
597
|
[activeMessage]
|
|
398
598
|
);
|
|
399
|
-
const respondToConfirmation =
|
|
599
|
+
const respondToConfirmation = React8.useCallback(
|
|
400
600
|
async (approve) => {
|
|
401
601
|
const ent = entityRef.current;
|
|
602
|
+
if (ent?.type === "team" && activeMessage?.requirements?.length) {
|
|
603
|
+
await continueRun({ requirements: activeMessage.requirements.map((r) => ({ ...r, confirmation: approve })) });
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
402
606
|
if (ent?.type === "workflow") {
|
|
403
|
-
const reqs = (activeMessage?.requirements ?? []).map((r) => ({ ...r, confirmation: approve }));
|
|
607
|
+
const reqs = activeMessage?.step_requirements?.length ? activeMessage.step_requirements.map((r) => ({ ...r, confirmed: approve })) : (activeMessage?.requirements ?? []).map((r) => ({ ...r, confirmation: approve }));
|
|
404
608
|
await continueRun({ stepRequirements: reqs });
|
|
405
609
|
return;
|
|
406
610
|
}
|
|
@@ -409,9 +613,20 @@ function useAgnoChat(options) {
|
|
|
409
613
|
},
|
|
410
614
|
[activeMessage, continueRun, pausedTools]
|
|
411
615
|
);
|
|
412
|
-
const submitUserInput =
|
|
616
|
+
const submitUserInput = React8.useCallback(
|
|
413
617
|
async (values) => {
|
|
414
618
|
const ent = entityRef.current;
|
|
619
|
+
if (ent?.type === "team" && activeMessage?.requirements?.length) {
|
|
620
|
+
const requirements = activeMessage.requirements.map((r) => ({
|
|
621
|
+
...r,
|
|
622
|
+
user_input_schema: (r.user_input_schema ?? r.tool_execution?.user_input_schema ?? []).map((f) => ({
|
|
623
|
+
...f,
|
|
624
|
+
value: f.name in values ? values[f.name] : f.value
|
|
625
|
+
}))
|
|
626
|
+
}));
|
|
627
|
+
await continueRun({ requirements });
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
415
630
|
if (ent?.type === "workflow") {
|
|
416
631
|
const reqs = (activeMessage?.requirements ?? []).map((r) => ({
|
|
417
632
|
...r,
|
|
@@ -435,17 +650,18 @@ function useAgnoChat(options) {
|
|
|
435
650
|
},
|
|
436
651
|
[activeMessage, continueRun, pausedTools]
|
|
437
652
|
);
|
|
438
|
-
const cancel =
|
|
653
|
+
const cancel = React8.useCallback(async () => {
|
|
654
|
+
channelRef.current?.buffer.flush();
|
|
439
655
|
abortRef.current?.abort();
|
|
440
656
|
channelRef.current = null;
|
|
441
657
|
const ent = entityRef.current;
|
|
442
658
|
const runId = runIdRef.current;
|
|
443
|
-
|
|
444
|
-
|
|
659
|
+
writeStatus(null, "cancelled");
|
|
660
|
+
writeActivity(null, null);
|
|
445
661
|
patchActive(null, (m) => m.streaming ? { ...m, streaming: false, status: "cancelled" } : m);
|
|
446
662
|
if (ent && runId) await client.cancelRun(ent.type, ent.id, runId, sessionIdRef.current);
|
|
447
|
-
}, [client, patchActive]);
|
|
448
|
-
const refreshSessions =
|
|
663
|
+
}, [client, patchActive, writeActivity, writeStatus]);
|
|
664
|
+
const refreshSessions = React8.useCallback(async () => {
|
|
449
665
|
const ent = entityRef.current;
|
|
450
666
|
if (!ent) {
|
|
451
667
|
setSessions([]);
|
|
@@ -464,7 +680,15 @@ function useAgnoChat(options) {
|
|
|
464
680
|
setSessionsLoading(false);
|
|
465
681
|
}
|
|
466
682
|
}, [client]);
|
|
467
|
-
const
|
|
683
|
+
const clearRunView = React8.useCallback(() => {
|
|
684
|
+
activeMsgIdRef.current = null;
|
|
685
|
+
runIdRef.current = void 0;
|
|
686
|
+
setEvents([]);
|
|
687
|
+
setStatus("idle");
|
|
688
|
+
setActivity(null);
|
|
689
|
+
setError(null);
|
|
690
|
+
}, [setEvents, setStatus, setActivity, setError]);
|
|
691
|
+
const loadSession = React8.useCallback(
|
|
468
692
|
async (id) => {
|
|
469
693
|
const ent = entityRef.current;
|
|
470
694
|
if (!ent) return;
|
|
@@ -474,23 +698,17 @@ function useAgnoChat(options) {
|
|
|
474
698
|
setSessionId(id);
|
|
475
699
|
onSessionId?.(id);
|
|
476
700
|
if (resumeRun(id)) return;
|
|
477
|
-
|
|
478
|
-
runIdRef.current = void 0;
|
|
479
|
-
setEvents([]);
|
|
480
|
-
setCurrentEvent(null);
|
|
481
|
-
setStatus("idle");
|
|
482
|
-
setActivity(null);
|
|
483
|
-
setError(null);
|
|
701
|
+
clearRunView();
|
|
484
702
|
try {
|
|
485
703
|
const runs = await client.getSessionRuns(ent.type, id, ent.db_id);
|
|
486
|
-
setMessages(
|
|
704
|
+
setMessages(chunkY34YRC5T_cjs.sessionRunsToMessages(runs));
|
|
487
705
|
} catch (err) {
|
|
488
706
|
setError(err instanceof Error ? err.message : String(err));
|
|
489
707
|
}
|
|
490
708
|
},
|
|
491
|
-
[client, onSessionId, releaseCurrentRun, resumeRun]
|
|
709
|
+
[client, clearRunView, onSessionId, releaseCurrentRun, resumeRun, setMessages]
|
|
492
710
|
);
|
|
493
|
-
const deleteSession =
|
|
711
|
+
const deleteSession = React8.useCallback(
|
|
494
712
|
async (id) => {
|
|
495
713
|
const ent = entityRef.current;
|
|
496
714
|
const ok = await client.deleteSession(id, ent?.db_id);
|
|
@@ -503,30 +721,28 @@ function useAgnoChat(options) {
|
|
|
503
721
|
}
|
|
504
722
|
setSessions((prev) => prev.filter((s) => s.session_id !== id));
|
|
505
723
|
if (sessionIdRef.current === id) {
|
|
724
|
+
channelRef.current?.controller.abort();
|
|
725
|
+
channelRef.current = null;
|
|
726
|
+
abortRef.current = null;
|
|
727
|
+
clearRunView();
|
|
506
728
|
sessionIdRef.current = void 0;
|
|
507
729
|
setSessionId(void 0);
|
|
508
730
|
setMessages([]);
|
|
509
731
|
}
|
|
510
732
|
}
|
|
511
733
|
},
|
|
512
|
-
[client]
|
|
734
|
+
[client, clearRunView, setMessages]
|
|
513
735
|
);
|
|
514
|
-
const reset =
|
|
736
|
+
const reset = React8.useCallback(() => {
|
|
515
737
|
releaseCurrentRun();
|
|
516
|
-
|
|
517
|
-
runIdRef.current = void 0;
|
|
738
|
+
clearRunView();
|
|
518
739
|
sessionIdRef.current = void 0;
|
|
519
740
|
pendingSessionNameRef.current = void 0;
|
|
520
741
|
bumpedSessionRef.current = void 0;
|
|
521
742
|
setMessages([]);
|
|
522
|
-
setEvents([]);
|
|
523
|
-
setCurrentEvent(null);
|
|
524
|
-
setStatus("idle");
|
|
525
|
-
setActivity(null);
|
|
526
|
-
setError(null);
|
|
527
743
|
setSessionId(void 0);
|
|
528
|
-
}, [releaseCurrentRun]);
|
|
529
|
-
|
|
744
|
+
}, [clearRunView, releaseCurrentRun, setMessages]);
|
|
745
|
+
React8.useEffect(() => {
|
|
530
746
|
const background = backgroundRef.current;
|
|
531
747
|
return () => {
|
|
532
748
|
abortRef.current?.abort();
|
|
@@ -534,7 +750,7 @@ function useAgnoChat(options) {
|
|
|
534
750
|
background.clear();
|
|
535
751
|
};
|
|
536
752
|
}, []);
|
|
537
|
-
const streamingMessage =
|
|
753
|
+
const streamingMessage = React8.useMemo(
|
|
538
754
|
() => messages.find((m) => m.role === "agent" && m.streaming) ?? null,
|
|
539
755
|
[messages]
|
|
540
756
|
);
|
|
@@ -576,7 +792,7 @@ function cx(...parts) {
|
|
|
576
792
|
const out = parts.filter(Boolean).join(" ");
|
|
577
793
|
return out || void 0;
|
|
578
794
|
}
|
|
579
|
-
var ChatContext =
|
|
795
|
+
var ChatContext = React8.createContext(null);
|
|
580
796
|
function ChatProvider({
|
|
581
797
|
children,
|
|
582
798
|
classNames,
|
|
@@ -593,7 +809,7 @@ function ChatProvider({
|
|
|
593
809
|
}) {
|
|
594
810
|
const internal = useAgnoChat(externalChat ? { entity: null } : options);
|
|
595
811
|
const chat = externalChat ?? internal;
|
|
596
|
-
const value =
|
|
812
|
+
const value = React8.useMemo(
|
|
597
813
|
() => ({ chat, classNames: classNames ?? {}, renderMarkdown, resolveLinkPreview, codeCopy, linkComponent }),
|
|
598
814
|
[chat, classNames, renderMarkdown, resolveLinkPreview, codeCopy, linkComponent]
|
|
599
815
|
);
|
|
@@ -608,12 +824,12 @@ function ChatProvider({
|
|
|
608
824
|
) : children });
|
|
609
825
|
}
|
|
610
826
|
function useChatContext() {
|
|
611
|
-
const value =
|
|
827
|
+
const value = React8.useContext(ChatContext);
|
|
612
828
|
if (!value) throw new Error("useChatContext must be used inside a <ChatProvider>");
|
|
613
829
|
return value;
|
|
614
830
|
}
|
|
615
831
|
function useOptionalChatContext() {
|
|
616
|
-
return
|
|
832
|
+
return React8.useContext(ChatContext);
|
|
617
833
|
}
|
|
618
834
|
function useResolvedChat(explicit) {
|
|
619
835
|
const ctx = useOptionalChatContext();
|
|
@@ -633,7 +849,7 @@ function useLinkComponent() {
|
|
|
633
849
|
}
|
|
634
850
|
function useResolvedClassNames(explicit) {
|
|
635
851
|
const ctx = useOptionalChatContext();
|
|
636
|
-
return
|
|
852
|
+
return React8.useMemo(() => ({ ...ctx?.classNames, ...explicit }), [ctx?.classNames, explicit]);
|
|
637
853
|
}
|
|
638
854
|
var STROKE = 1.5;
|
|
639
855
|
var icon = (Component, defaultSize = 16) => function Icon({ size = defaultSize, className }) {
|
|
@@ -778,19 +994,19 @@ function ChatLauncher({
|
|
|
778
994
|
portal = true,
|
|
779
995
|
className
|
|
780
996
|
}) {
|
|
781
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
997
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React8.useState(defaultOpen);
|
|
782
998
|
const isOpen = open ?? uncontrolledOpen;
|
|
783
|
-
const opened =
|
|
999
|
+
const opened = React8.useRef(isOpen);
|
|
784
1000
|
if (isOpen) opened.current = true;
|
|
785
1001
|
const mounted = keepMounted ? opened.current : isOpen;
|
|
786
|
-
const setOpen =
|
|
1002
|
+
const setOpen = React8.useCallback(
|
|
787
1003
|
(next) => {
|
|
788
1004
|
if (open === void 0) setUncontrolledOpen(next);
|
|
789
1005
|
onOpenChange?.(next);
|
|
790
1006
|
},
|
|
791
1007
|
[open, onOpenChange]
|
|
792
1008
|
);
|
|
793
|
-
|
|
1009
|
+
React8.useEffect(() => {
|
|
794
1010
|
if (!isOpen || !closeOnEscape) return;
|
|
795
1011
|
const onKeyDown = (e) => {
|
|
796
1012
|
if (e.key === "Escape") setOpen(false);
|
|
@@ -798,7 +1014,7 @@ function ChatLauncher({
|
|
|
798
1014
|
document.addEventListener("keydown", onKeyDown);
|
|
799
1015
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
800
1016
|
}, [isOpen, closeOnEscape, setOpen]);
|
|
801
|
-
|
|
1017
|
+
React8.useEffect(() => {
|
|
802
1018
|
if (!isOpen || panel !== "fullscreen") return;
|
|
803
1019
|
const previous = document.body.style.overflow;
|
|
804
1020
|
document.body.style.overflow = "hidden";
|
|
@@ -806,8 +1022,8 @@ function ChatLauncher({
|
|
|
806
1022
|
document.body.style.overflow = previous;
|
|
807
1023
|
};
|
|
808
1024
|
}, [isOpen, panel]);
|
|
809
|
-
const [canPortal, setCanPortal] =
|
|
810
|
-
|
|
1025
|
+
const [canPortal, setCanPortal] = React8.useState(false);
|
|
1026
|
+
React8.useEffect(() => setCanPortal(true), []);
|
|
811
1027
|
const classes = [
|
|
812
1028
|
"agno-launcher",
|
|
813
1029
|
`agno-launcher--${position}`,
|
|
@@ -863,8 +1079,8 @@ function kindOf(file) {
|
|
|
863
1079
|
}
|
|
864
1080
|
function Item({ file, onRemove }) {
|
|
865
1081
|
const isImage = file.type.startsWith("image/");
|
|
866
|
-
const [url, setUrl] =
|
|
867
|
-
|
|
1082
|
+
const [url, setUrl] = React8.useState(null);
|
|
1083
|
+
React8.useEffect(() => {
|
|
868
1084
|
if (!isImage) return;
|
|
869
1085
|
const objectUrl = URL.createObjectURL(file);
|
|
870
1086
|
setUrl(objectUrl);
|
|
@@ -968,24 +1184,24 @@ function ChatInput({
|
|
|
968
1184
|
}) {
|
|
969
1185
|
const ctx = useOptionalChatContext();
|
|
970
1186
|
const cn = useResolvedClassNames(classNames);
|
|
971
|
-
const [internal, setInternal] =
|
|
1187
|
+
const [internal, setInternal] = React8.useState("");
|
|
972
1188
|
const value = controlled ?? internal;
|
|
973
1189
|
const setValue = (next) => {
|
|
974
1190
|
if (controlled === void 0) setInternal(next);
|
|
975
1191
|
onValueChange?.(next);
|
|
976
1192
|
};
|
|
977
|
-
const [files, setFilesState] =
|
|
978
|
-
const filesRef =
|
|
1193
|
+
const [files, setFilesState] = React8.useState([]);
|
|
1194
|
+
const filesRef = React8.useRef([]);
|
|
979
1195
|
const setFiles = (next) => {
|
|
980
1196
|
filesRef.current = next;
|
|
981
1197
|
setFilesState(next);
|
|
982
1198
|
};
|
|
983
|
-
const [fileError, setFileError] =
|
|
984
|
-
const [dragging, setDragging] =
|
|
985
|
-
const dragDepth =
|
|
986
|
-
const fileRef =
|
|
987
|
-
const textareaRef =
|
|
988
|
-
const setTextareaRef =
|
|
1199
|
+
const [fileError, setFileError] = React8.useState(null);
|
|
1200
|
+
const [dragging, setDragging] = React8.useState(false);
|
|
1201
|
+
const dragDepth = React8.useRef(0);
|
|
1202
|
+
const fileRef = React8.useRef(null);
|
|
1203
|
+
const textareaRef = React8.useRef(null);
|
|
1204
|
+
const setTextareaRef = React8.useCallback(
|
|
989
1205
|
(el2) => {
|
|
990
1206
|
textareaRef.current = el2;
|
|
991
1207
|
if (typeof externalRef === "function") externalRef(el2);
|
|
@@ -993,14 +1209,14 @@ function ChatInput({
|
|
|
993
1209
|
},
|
|
994
1210
|
[externalRef]
|
|
995
1211
|
);
|
|
996
|
-
const adjustHeight =
|
|
1212
|
+
const adjustHeight = React8.useCallback(() => {
|
|
997
1213
|
const el2 = textareaRef.current;
|
|
998
1214
|
if (!el2 || renderTextarea) return;
|
|
999
1215
|
const { min, max } = compact ? BOUNDS.compact : BOUNDS.dock;
|
|
1000
1216
|
el2.style.height = `${min}px`;
|
|
1001
1217
|
el2.style.height = `${Math.min(Math.max(el2.scrollHeight, min), max)}px`;
|
|
1002
1218
|
}, [renderTextarea, compact]);
|
|
1003
|
-
|
|
1219
|
+
React8.useEffect(adjustHeight, [value, adjustHeight]);
|
|
1004
1220
|
const send = onSend ?? ((message, attached) => void ctx?.chat.sendMessage(message, attached ? { files: attached } : void 0));
|
|
1005
1221
|
const stop = onStop ?? (ctx ? () => void ctx.chat.cancel() : void 0);
|
|
1006
1222
|
const isBusy = busy ?? ctx?.chat.isStreaming ?? false;
|
|
@@ -1226,6 +1442,16 @@ function Followups({
|
|
|
1226
1442
|
}
|
|
1227
1443
|
var isBoolField = (f) => f.field_type === "bool" || f.field_type === "boolean";
|
|
1228
1444
|
function buildAsks(message, entityType) {
|
|
1445
|
+
if (entityType === "workflow" && message.step_requirements?.length) {
|
|
1446
|
+
return message.step_requirements.map((r) => ({
|
|
1447
|
+
id: r.step_id,
|
|
1448
|
+
name: r.step_name,
|
|
1449
|
+
needsConfirmation: Boolean(r.requires_confirmation) && r.confirmed == null,
|
|
1450
|
+
fields: [],
|
|
1451
|
+
stepRequirement: r,
|
|
1452
|
+
unsupported: !r.requires_confirmation || Boolean(r.requires_user_input || r.requires_route_selection || r.requires_output_review)
|
|
1453
|
+
}));
|
|
1454
|
+
}
|
|
1229
1455
|
const fromTools = (message.tool_calls ?? []).filter((t) => t.requires_confirmation || t.requires_user_input).map((t) => ({
|
|
1230
1456
|
id: t.tool_call_id ?? `${t.tool_name}`,
|
|
1231
1457
|
name: t.tool_name,
|
|
@@ -1238,11 +1464,11 @@ function buildAsks(message, entityType) {
|
|
|
1238
1464
|
id: r.id,
|
|
1239
1465
|
name: r.tool_execution?.tool_name,
|
|
1240
1466
|
args: r.tool_execution?.tool_args,
|
|
1241
|
-
needsConfirmation: Boolean(r.tool_execution?.requires_confirmation) || r.confirmation == null,
|
|
1467
|
+
needsConfirmation: entityType === "workflow" ? Boolean(r.tool_execution?.requires_confirmation) || r.confirmation == null : Boolean(r.tool_execution?.requires_confirmation) && r.confirmation == null,
|
|
1242
1468
|
fields: r.user_input_schema ?? r.tool_execution?.user_input_schema ?? [],
|
|
1243
1469
|
requirement: r
|
|
1244
1470
|
}));
|
|
1245
|
-
if (entityType === "workflow") return fromReqs.length ? fromReqs : fromTools;
|
|
1471
|
+
if (entityType === "workflow" || entityType === "team") return fromReqs.length ? fromReqs : fromTools;
|
|
1246
1472
|
return fromTools.length ? fromTools : fromReqs;
|
|
1247
1473
|
}
|
|
1248
1474
|
function HumanInput({
|
|
@@ -1252,20 +1478,35 @@ function HumanInput({
|
|
|
1252
1478
|
onResolve,
|
|
1253
1479
|
className
|
|
1254
1480
|
}) {
|
|
1255
|
-
const asks =
|
|
1256
|
-
const [choices, setChoices] =
|
|
1257
|
-
const [values, setValues] =
|
|
1258
|
-
const [reasons, setReasons] =
|
|
1259
|
-
const [openArgs, setOpenArgs] =
|
|
1481
|
+
const asks = React8.useMemo(() => buildAsks(message, entityType), [message, entityType]);
|
|
1482
|
+
const [choices, setChoices] = React8.useState({});
|
|
1483
|
+
const [values, setValues] = React8.useState({});
|
|
1484
|
+
const [reasons, setReasons] = React8.useState({});
|
|
1485
|
+
const [openArgs, setOpenArgs] = React8.useState({});
|
|
1260
1486
|
if (asks.length === 0) return null;
|
|
1261
1487
|
const setValue = (id, name, value) => setValues((v) => ({ ...v, [id]: { ...v[id] ?? {}, [name]: value } }));
|
|
1262
1488
|
const valueFor = (ask, field) => values[ask.id]?.[field.name] ?? field.value ?? (isBoolField(field) ? false : "");
|
|
1263
1489
|
const fillFields = (ask) => ask.fields.map((f) => ({ ...f, value: valueFor(ask, f) }));
|
|
1264
|
-
const ready = asks.every((a) => !a.needsConfirmation || choices[a.id]);
|
|
1490
|
+
const ready = asks.every((a) => !a.unsupported && (!a.needsConfirmation || choices[a.id]));
|
|
1265
1491
|
const submit = () => {
|
|
1492
|
+
if (entityType === "team" && asks.every((a) => a.requirement)) {
|
|
1493
|
+
const requirements = asks.map((a) => ({
|
|
1494
|
+
...a.requirement,
|
|
1495
|
+
...a.needsConfirmation ? { confirmation: choices[a.id] === "confirm" } : {},
|
|
1496
|
+
...a.fields.length ? { user_input_schema: fillFields(a) } : {},
|
|
1497
|
+
...reasons[a.id] ? { confirmation_note: reasons[a.id] } : {}
|
|
1498
|
+
}));
|
|
1499
|
+
onResolve({ requirements });
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1266
1502
|
if (entityType === "workflow") {
|
|
1267
1503
|
const stepRequirements = asks.map((a) => {
|
|
1268
1504
|
const approved = a.needsConfirmation ? choices[a.id] === "confirm" : true;
|
|
1505
|
+
if (a.stepRequirement) return {
|
|
1506
|
+
...a.stepRequirement,
|
|
1507
|
+
confirmed: approved,
|
|
1508
|
+
...reasons[a.id] ? { rejection_feedback: reasons[a.id] } : {}
|
|
1509
|
+
};
|
|
1269
1510
|
return {
|
|
1270
1511
|
id: a.id,
|
|
1271
1512
|
confirmation: approved,
|
|
@@ -1278,7 +1519,7 @@ function HumanInput({
|
|
|
1278
1519
|
return;
|
|
1279
1520
|
}
|
|
1280
1521
|
const tools = asks.map((a) => {
|
|
1281
|
-
const base = a.tool ?? { tool_call_id: a.id, tool_name: a.name };
|
|
1522
|
+
const base = a.tool ?? a.requirement?.tool_execution ?? { tool_call_id: a.id, tool_name: a.name };
|
|
1282
1523
|
const approved = a.needsConfirmation ? choices[a.id] === "confirm" : true;
|
|
1283
1524
|
return {
|
|
1284
1525
|
...base,
|
|
@@ -1291,6 +1532,7 @@ function HumanInput({
|
|
|
1291
1532
|
};
|
|
1292
1533
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-hitl", className), children: [
|
|
1293
1534
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-hitl__title", children: "Your input is needed" }),
|
|
1535
|
+
asks.some((a) => a.unsupported) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-hitl__notice", role: "status", children: "This workflow needs an input type this chat does not support yet." }),
|
|
1294
1536
|
asks.map((ask) => {
|
|
1295
1537
|
const choice = choices[ask.id];
|
|
1296
1538
|
const hasArgs = ask.args && Object.keys(ask.args).length > 0;
|
|
@@ -1399,11 +1641,14 @@ function sourceHost(url) {
|
|
|
1399
1641
|
}
|
|
1400
1642
|
}
|
|
1401
1643
|
function faviconUrl(url) {
|
|
1402
|
-
|
|
1644
|
+
return faviconFallbacks(url)[0];
|
|
1645
|
+
}
|
|
1646
|
+
function faviconFallbacks(url) {
|
|
1647
|
+
if (!url) return [];
|
|
1403
1648
|
try {
|
|
1404
|
-
return
|
|
1649
|
+
return ["/favicon.ico", "/favicon.svg"].map((path) => new URL(path, url).href);
|
|
1405
1650
|
} catch {
|
|
1406
|
-
return
|
|
1651
|
+
return [];
|
|
1407
1652
|
}
|
|
1408
1653
|
}
|
|
1409
1654
|
function displayUrl(url) {
|
|
@@ -1527,79 +1772,12 @@ function linkCitations(content, sources) {
|
|
|
1527
1772
|
);
|
|
1528
1773
|
}).join("");
|
|
1529
1774
|
}
|
|
1530
|
-
var SourcesContext =
|
|
1775
|
+
var SourcesContext = React8.createContext([]);
|
|
1531
1776
|
var SourcesProvider = SourcesContext.Provider;
|
|
1532
1777
|
function useSources() {
|
|
1533
|
-
return
|
|
1534
|
-
}
|
|
1535
|
-
var THEMES = { light: "github-light", dark: "monokai" };
|
|
1536
|
-
var highlighter;
|
|
1537
|
-
var booting;
|
|
1538
|
-
var loading = /* @__PURE__ */ new Map();
|
|
1539
|
-
var loaded = /* @__PURE__ */ new Set();
|
|
1540
|
-
var unsupported = /* @__PURE__ */ new Set();
|
|
1541
|
-
async function boot() {
|
|
1542
|
-
if (highlighter) return highlighter;
|
|
1543
|
-
booting ?? (booting = (async () => {
|
|
1544
|
-
const [{ createHighlighterCore }, { createJavaScriptRegexEngine }, { bundledThemes }] = await Promise.all([import('shiki/core'), import('shiki/engine/javascript'), import('shiki/themes')]);
|
|
1545
|
-
highlighter = await createHighlighterCore({
|
|
1546
|
-
themes: [bundledThemes[THEMES.light], bundledThemes[THEMES.dark]],
|
|
1547
|
-
langs: [],
|
|
1548
|
-
// No WASM: the JS engine keeps this a plain import. `forgiving` skips
|
|
1549
|
-
// the odd grammar rule it can't translate rather than failing the block.
|
|
1550
|
-
engine: createJavaScriptRegexEngine({ forgiving: true })
|
|
1551
|
-
});
|
|
1552
|
-
return highlighter;
|
|
1553
|
-
})());
|
|
1554
|
-
return booting;
|
|
1555
|
-
}
|
|
1556
|
-
function ensureLanguage(lang) {
|
|
1557
|
-
let pending = loading.get(lang);
|
|
1558
|
-
if (!pending) {
|
|
1559
|
-
pending = (async () => {
|
|
1560
|
-
const [core, { bundledLanguages }] = await Promise.all([boot(), import('shiki/langs')]);
|
|
1561
|
-
const grammar = bundledLanguages[lang];
|
|
1562
|
-
if (!grammar) {
|
|
1563
|
-
unsupported.add(lang);
|
|
1564
|
-
return;
|
|
1565
|
-
}
|
|
1566
|
-
await core.loadLanguage(grammar);
|
|
1567
|
-
loaded.add(lang);
|
|
1568
|
-
})().catch(() => {
|
|
1569
|
-
unsupported.add(lang);
|
|
1570
|
-
});
|
|
1571
|
-
loading.set(lang, pending);
|
|
1572
|
-
}
|
|
1573
|
-
return pending;
|
|
1574
|
-
}
|
|
1575
|
-
function normalizeLanguage(language) {
|
|
1576
|
-
const lang = language?.trim().toLowerCase();
|
|
1577
|
-
return lang || void 0;
|
|
1578
|
-
}
|
|
1579
|
-
function useHighlight(code, language) {
|
|
1580
|
-
const [, rerender] = React7.useReducer((n) => n + 1, 0);
|
|
1581
|
-
const lang = normalizeLanguage(language);
|
|
1582
|
-
const ready = Boolean(lang && loaded.has(lang));
|
|
1583
|
-
React7.useEffect(() => {
|
|
1584
|
-
if (!lang || ready || unsupported.has(lang)) return;
|
|
1585
|
-
let cancelled = false;
|
|
1586
|
-
void ensureLanguage(lang).then(() => {
|
|
1587
|
-
if (!cancelled) rerender();
|
|
1588
|
-
});
|
|
1589
|
-
return () => {
|
|
1590
|
-
cancelled = true;
|
|
1591
|
-
};
|
|
1592
|
-
}, [lang, ready]);
|
|
1593
|
-
return React7.useMemo(() => {
|
|
1594
|
-
if (!lang || !ready || !highlighter) return null;
|
|
1595
|
-
try {
|
|
1596
|
-
return highlighter.codeToTokens(code, { lang, themes: THEMES, defaultColor: false }).tokens;
|
|
1597
|
-
} catch {
|
|
1598
|
-
return null;
|
|
1599
|
-
}
|
|
1600
|
-
}, [code, lang, ready]);
|
|
1778
|
+
return React8.useContext(SourcesContext);
|
|
1601
1779
|
}
|
|
1602
|
-
var useIsomorphicLayoutEffect = typeof window === "undefined" ?
|
|
1780
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? React8.useEffect : React8.useLayoutEffect;
|
|
1603
1781
|
var caches = /* @__PURE__ */ new WeakMap();
|
|
1604
1782
|
var inflight = /* @__PURE__ */ new WeakMap();
|
|
1605
1783
|
function cacheFor(store, key) {
|
|
@@ -1616,9 +1794,9 @@ function useLinkPreviewResolver() {
|
|
|
1616
1794
|
function useLinkPreview(url, enabled) {
|
|
1617
1795
|
const resolve = useLinkPreviewResolver();
|
|
1618
1796
|
const cached = url && resolve ? cacheFor(caches, resolve).get(url) : void 0;
|
|
1619
|
-
const [preview, setPreview] =
|
|
1620
|
-
const [loading2, setLoading] =
|
|
1621
|
-
|
|
1797
|
+
const [preview, setPreview] = React8.useState(cached ?? null);
|
|
1798
|
+
const [loading2, setLoading] = React8.useState(false);
|
|
1799
|
+
React8.useEffect(() => {
|
|
1622
1800
|
if (!enabled || !url || !resolve) return;
|
|
1623
1801
|
const store = cacheFor(caches, resolve);
|
|
1624
1802
|
if (store.has(url)) {
|
|
@@ -1655,10 +1833,11 @@ function Favicon({
|
|
|
1655
1833
|
size = 14,
|
|
1656
1834
|
className
|
|
1657
1835
|
}) {
|
|
1658
|
-
const
|
|
1659
|
-
const [
|
|
1660
|
-
|
|
1661
|
-
|
|
1836
|
+
const candidates = React8.useMemo(() => faviconFallbacks(url), [url]);
|
|
1837
|
+
const [attempt, setAttempt] = React8.useState(0);
|
|
1838
|
+
const src = candidates[attempt];
|
|
1839
|
+
React8.useEffect(() => setAttempt(0), [url]);
|
|
1840
|
+
if (kind === "document" || !src) {
|
|
1662
1841
|
const Glyph2 = kind === "document" ? BookOpen : Globe;
|
|
1663
1842
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("agno-favicon", "agno-favicon--glyph", className), "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(Glyph2, { size }) });
|
|
1664
1843
|
}
|
|
@@ -1672,7 +1851,7 @@ function Favicon({
|
|
|
1672
1851
|
height: size,
|
|
1673
1852
|
loading: "lazy",
|
|
1674
1853
|
decoding: "async",
|
|
1675
|
-
onError: () =>
|
|
1854
|
+
onError: () => setAttempt((n) => n + 1),
|
|
1676
1855
|
"aria-hidden": true
|
|
1677
1856
|
}
|
|
1678
1857
|
);
|
|
@@ -1701,7 +1880,7 @@ var GAP = 8;
|
|
|
1701
1880
|
var OPEN_DELAY = 140;
|
|
1702
1881
|
var CLOSE_DELAY = 120;
|
|
1703
1882
|
function usePlacement(anchor, open, { width = PREVIEW_WIDTH, align = "center" } = {}) {
|
|
1704
|
-
const [placement, setPlacement] =
|
|
1883
|
+
const [placement, setPlacement] = React8.useState(null);
|
|
1705
1884
|
useIsomorphicLayoutEffect(() => {
|
|
1706
1885
|
if (!open || !anchor) return;
|
|
1707
1886
|
const place = () => {
|
|
@@ -1731,15 +1910,15 @@ function HoverPreview({
|
|
|
1731
1910
|
disabled,
|
|
1732
1911
|
className
|
|
1733
1912
|
}) {
|
|
1734
|
-
const [open, setOpen] =
|
|
1735
|
-
const [awake, setAwake] =
|
|
1736
|
-
const [anchor, setAnchor] =
|
|
1737
|
-
const timer =
|
|
1738
|
-
const id =
|
|
1913
|
+
const [open, setOpen] = React8.useState(false);
|
|
1914
|
+
const [awake, setAwake] = React8.useState(false);
|
|
1915
|
+
const [anchor, setAnchor] = React8.useState(null);
|
|
1916
|
+
const timer = React8.useRef(null);
|
|
1917
|
+
const id = React8.useId();
|
|
1739
1918
|
const cn = useResolvedClassNames();
|
|
1740
1919
|
const { preview, loading: loading2 } = useLinkPreview(source.url, awake);
|
|
1741
1920
|
const placement = usePlacement(anchor, open);
|
|
1742
|
-
const schedule =
|
|
1921
|
+
const schedule = React8.useCallback((next) => {
|
|
1743
1922
|
if (timer.current) clearTimeout(timer.current);
|
|
1744
1923
|
timer.current = setTimeout(
|
|
1745
1924
|
() => {
|
|
@@ -1749,13 +1928,13 @@ function HoverPreview({
|
|
|
1749
1928
|
next ? OPEN_DELAY : CLOSE_DELAY
|
|
1750
1929
|
);
|
|
1751
1930
|
}, []);
|
|
1752
|
-
|
|
1931
|
+
React8.useEffect(
|
|
1753
1932
|
() => () => {
|
|
1754
1933
|
if (timer.current) clearTimeout(timer.current);
|
|
1755
1934
|
},
|
|
1756
1935
|
[]
|
|
1757
1936
|
);
|
|
1758
|
-
|
|
1937
|
+
React8.useEffect(() => {
|
|
1759
1938
|
if (!open) return;
|
|
1760
1939
|
const onKey = (e) => {
|
|
1761
1940
|
if (e.key === "Escape") setOpen(false);
|
|
@@ -1763,10 +1942,10 @@ function HoverPreview({
|
|
|
1763
1942
|
document.addEventListener("keydown", onKey);
|
|
1764
1943
|
return () => document.removeEventListener("keydown", onKey);
|
|
1765
1944
|
}, [open]);
|
|
1766
|
-
const [mounted, setMounted] =
|
|
1767
|
-
|
|
1945
|
+
const [mounted, setMounted] = React8.useState(false);
|
|
1946
|
+
React8.useEffect(() => setMounted(true), []);
|
|
1768
1947
|
if (disabled) return children;
|
|
1769
|
-
const trigger =
|
|
1948
|
+
const trigger = React8.isValidElement(children) ? React8.cloneElement(children, {
|
|
1770
1949
|
"aria-describedby": open ? id : void 0
|
|
1771
1950
|
}) : children;
|
|
1772
1951
|
const light = anchor?.closest(".agno-light") ? "agno-light" : void 0;
|
|
@@ -1803,36 +1982,24 @@ function HoverPreview({
|
|
|
1803
1982
|
}
|
|
1804
1983
|
);
|
|
1805
1984
|
}
|
|
1806
|
-
function el(tag, className) {
|
|
1807
|
-
return function Element({ node: _node, className: _theirs, ...rest }) {
|
|
1808
|
-
return React7__default.default.createElement(tag, { className, ...rest });
|
|
1809
|
-
};
|
|
1810
|
-
}
|
|
1811
1985
|
function sourceForUrl(url, sources) {
|
|
1812
|
-
return url ? sources.find((
|
|
1986
|
+
return url ? sources.find((source) => source.url === url) : void 0;
|
|
1813
1987
|
}
|
|
1814
1988
|
function citationForLink(label2, href, ctx) {
|
|
1815
1989
|
if (!/^\d+$/.test(label2.trim())) return void 0;
|
|
1816
|
-
return sourceForUrl(href, ctx.sources) ?? ctx.sources.find((
|
|
1817
|
-
}
|
|
1818
|
-
function labelOf(children) {
|
|
1819
|
-
if (typeof children === "string") return children;
|
|
1820
|
-
if (Array.isArray(children) && children.length === 1 && typeof children[0] === "string") {
|
|
1821
|
-
return children[0];
|
|
1822
|
-
}
|
|
1823
|
-
return "";
|
|
1990
|
+
return sourceForUrl(href, ctx.sources) ?? ctx.sources.find((source) => source.index === Number(label2.trim()));
|
|
1824
1991
|
}
|
|
1825
1992
|
function CitationMarker({
|
|
1826
1993
|
source,
|
|
1827
1994
|
className,
|
|
1828
|
-
Link
|
|
1995
|
+
Link: Link2
|
|
1829
1996
|
}) {
|
|
1830
1997
|
const props = {
|
|
1831
1998
|
className: cx("agno-cite", className),
|
|
1832
1999
|
href: source.url ?? `#${source.anchorId}`,
|
|
1833
2000
|
"aria-label": `Source ${source.index}: ${source.title}`
|
|
1834
2001
|
};
|
|
1835
|
-
return /* @__PURE__ */ jsxRuntime.jsx(HoverPreview, { source, className: "agno-cite__wrap", children:
|
|
2002
|
+
return /* @__PURE__ */ jsxRuntime.jsx(HoverPreview, { source, className: "agno-cite__wrap", children: Link2 && source.url ? /* @__PURE__ */ jsxRuntime.jsx(Link2, { ...props, children: source.index }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1836
2003
|
"a",
|
|
1837
2004
|
{
|
|
1838
2005
|
...props,
|
|
@@ -1842,6 +2009,73 @@ function CitationMarker({
|
|
|
1842
2009
|
}
|
|
1843
2010
|
) });
|
|
1844
2011
|
}
|
|
2012
|
+
var THEMES = { light: "github-light", dark: "monokai" };
|
|
2013
|
+
var highlighter;
|
|
2014
|
+
var booting;
|
|
2015
|
+
var loading = /* @__PURE__ */ new Map();
|
|
2016
|
+
var loaded = /* @__PURE__ */ new Set();
|
|
2017
|
+
var unsupported = /* @__PURE__ */ new Set();
|
|
2018
|
+
async function boot() {
|
|
2019
|
+
if (highlighter) return highlighter;
|
|
2020
|
+
booting ?? (booting = (async () => {
|
|
2021
|
+
const [{ createHighlighterCore }, { createJavaScriptRegexEngine }, { bundledThemes }] = await Promise.all([import('shiki/core'), import('shiki/engine/javascript'), import('shiki/themes')]);
|
|
2022
|
+
highlighter = await createHighlighterCore({
|
|
2023
|
+
themes: [bundledThemes[THEMES.light], bundledThemes[THEMES.dark]],
|
|
2024
|
+
langs: [],
|
|
2025
|
+
// No WASM: the JS engine keeps this a plain import. `forgiving` skips
|
|
2026
|
+
// the odd grammar rule it can't translate rather than failing the block.
|
|
2027
|
+
engine: createJavaScriptRegexEngine({ forgiving: true })
|
|
2028
|
+
});
|
|
2029
|
+
return highlighter;
|
|
2030
|
+
})());
|
|
2031
|
+
return booting;
|
|
2032
|
+
}
|
|
2033
|
+
function ensureLanguage(lang) {
|
|
2034
|
+
let pending = loading.get(lang);
|
|
2035
|
+
if (!pending) {
|
|
2036
|
+
pending = (async () => {
|
|
2037
|
+
const [core, { bundledLanguages }] = await Promise.all([boot(), import('shiki/langs')]);
|
|
2038
|
+
const grammar = bundledLanguages[lang];
|
|
2039
|
+
if (!grammar) {
|
|
2040
|
+
unsupported.add(lang);
|
|
2041
|
+
return;
|
|
2042
|
+
}
|
|
2043
|
+
await core.loadLanguage(grammar);
|
|
2044
|
+
loaded.add(lang);
|
|
2045
|
+
})().catch(() => {
|
|
2046
|
+
unsupported.add(lang);
|
|
2047
|
+
});
|
|
2048
|
+
loading.set(lang, pending);
|
|
2049
|
+
}
|
|
2050
|
+
return pending;
|
|
2051
|
+
}
|
|
2052
|
+
function normalizeLanguage(language) {
|
|
2053
|
+
const lang = language?.trim().toLowerCase();
|
|
2054
|
+
return lang || void 0;
|
|
2055
|
+
}
|
|
2056
|
+
function useHighlight(code, language) {
|
|
2057
|
+
const [, rerender] = React8.useReducer((n) => n + 1, 0);
|
|
2058
|
+
const lang = normalizeLanguage(language);
|
|
2059
|
+
const ready = Boolean(lang && loaded.has(lang));
|
|
2060
|
+
React8.useEffect(() => {
|
|
2061
|
+
if (!lang || ready || unsupported.has(lang)) return;
|
|
2062
|
+
let cancelled = false;
|
|
2063
|
+
void ensureLanguage(lang).then(() => {
|
|
2064
|
+
if (!cancelled) rerender();
|
|
2065
|
+
});
|
|
2066
|
+
return () => {
|
|
2067
|
+
cancelled = true;
|
|
2068
|
+
};
|
|
2069
|
+
}, [lang, ready]);
|
|
2070
|
+
return React8.useMemo(() => {
|
|
2071
|
+
if (!lang || !ready || !highlighter) return null;
|
|
2072
|
+
try {
|
|
2073
|
+
return highlighter.codeToTokens(code, { lang, themes: THEMES, defaultColor: false }).tokens;
|
|
2074
|
+
} catch {
|
|
2075
|
+
return null;
|
|
2076
|
+
}
|
|
2077
|
+
}, [code, lang, ready]);
|
|
2078
|
+
}
|
|
1845
2079
|
var COPIED_FOR = 1600;
|
|
1846
2080
|
var CLIPBOARD_TIMEOUT = 400;
|
|
1847
2081
|
async function writeClipboard(text) {
|
|
@@ -1867,25 +2101,26 @@ async function writeClipboard(text) {
|
|
|
1867
2101
|
return false;
|
|
1868
2102
|
}
|
|
1869
2103
|
}
|
|
1870
|
-
function CopyButton({ text, className }) {
|
|
1871
|
-
const [copied, setCopied] =
|
|
1872
|
-
|
|
2104
|
+
function CopyButton({ text, label: label2 = "Copy", size = 14, className }) {
|
|
2105
|
+
const [copied, setCopied] = React8.useState(false);
|
|
2106
|
+
React8.useEffect(() => {
|
|
1873
2107
|
if (!copied) return;
|
|
1874
2108
|
const timer = setTimeout(() => setCopied(false), COPIED_FOR);
|
|
1875
2109
|
return () => clearTimeout(timer);
|
|
1876
2110
|
}, [copied]);
|
|
1877
2111
|
const copy = async () => {
|
|
1878
|
-
if (await writeClipboard(text())) setCopied(true);
|
|
2112
|
+
if (await writeClipboard(typeof text === "function" ? text() : text)) setCopied(true);
|
|
1879
2113
|
};
|
|
2114
|
+
const name = copied ? "Copied" : label2;
|
|
1880
2115
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1881
2116
|
"button",
|
|
1882
2117
|
{
|
|
1883
2118
|
type: "button",
|
|
1884
|
-
className: cx("agno-
|
|
2119
|
+
className: cx("agno-copy", copied && "is-copied", className),
|
|
1885
2120
|
onClick: copy,
|
|
1886
|
-
"aria-label":
|
|
1887
|
-
title:
|
|
1888
|
-
children: copied ? /* @__PURE__ */ jsxRuntime.jsx(Check, { size
|
|
2121
|
+
"aria-label": name,
|
|
2122
|
+
title: name,
|
|
2123
|
+
children: copied ? /* @__PURE__ */ jsxRuntime.jsx(Check, { size }) : /* @__PURE__ */ jsxRuntime.jsx(Copy, { size })
|
|
1889
2124
|
}
|
|
1890
2125
|
);
|
|
1891
2126
|
}
|
|
@@ -1893,15 +2128,20 @@ function textOf(children) {
|
|
|
1893
2128
|
if (typeof children === "string") return children;
|
|
1894
2129
|
if (typeof children === "number") return String(children);
|
|
1895
2130
|
if (Array.isArray(children)) return children.map(textOf).join("");
|
|
1896
|
-
if (
|
|
2131
|
+
if (React8__default.default.isValidElement(children))
|
|
2132
|
+
return textOf(children.props.children);
|
|
1897
2133
|
return "";
|
|
1898
2134
|
}
|
|
1899
2135
|
function fencedCode(children) {
|
|
1900
2136
|
const child = Array.isArray(children) ? children[0] : children;
|
|
1901
|
-
if (!
|
|
2137
|
+
if (!React8__default.default.isValidElement(
|
|
2138
|
+
child
|
|
2139
|
+
)) {
|
|
1902
2140
|
return { code: textOf(children) };
|
|
1903
2141
|
}
|
|
1904
|
-
const language = /(?:^|\s)language-([^\s]+)/.exec(
|
|
2142
|
+
const language = /(?:^|\s)language-([^\s]+)/.exec(
|
|
2143
|
+
child.props.className ?? ""
|
|
2144
|
+
)?.[1];
|
|
1905
2145
|
return { language, code: textOf(child.props.children).replace(/\n$/, "") };
|
|
1906
2146
|
}
|
|
1907
2147
|
function plainLines(code) {
|
|
@@ -1910,93 +2150,159 @@ function plainLines(code) {
|
|
|
1910
2150
|
function CodeBlock({
|
|
1911
2151
|
children,
|
|
1912
2152
|
copyClass,
|
|
1913
|
-
codeCopy
|
|
2153
|
+
codeCopy,
|
|
2154
|
+
streaming
|
|
1914
2155
|
}) {
|
|
1915
|
-
const { language, code } =
|
|
1916
|
-
const highlighted = useHighlight(code, language);
|
|
1917
|
-
const lines = highlighted ?? plainLines(code);
|
|
2156
|
+
const { language, code } = React8.useMemo(() => fencedCode(children), [children]);
|
|
2157
|
+
const highlighted = useHighlight(streaming ? "" : code, language);
|
|
2158
|
+
const lines = streaming ? plainLines(code) : highlighted ?? plainLines(code);
|
|
1918
2159
|
const label2 = normalizeLanguage(language) ?? "text";
|
|
1919
2160
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-md-code-block", "data-language": label2, children: [
|
|
1920
2161
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-md-code-head", children: [
|
|
1921
2162
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-md-code-lang", children: label2 }),
|
|
1922
|
-
codeCopy && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2163
|
+
codeCopy && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2164
|
+
CopyButton,
|
|
2165
|
+
{
|
|
2166
|
+
className: cx("agno-md-copy", copyClass),
|
|
2167
|
+
text: () => code,
|
|
2168
|
+
label: "Copy code",
|
|
2169
|
+
size: 13
|
|
2170
|
+
}
|
|
2171
|
+
)
|
|
1923
2172
|
] }),
|
|
1924
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
2173
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2174
|
+
"pre",
|
|
2175
|
+
{
|
|
2176
|
+
className: "agno-md-pre",
|
|
2177
|
+
style: {
|
|
2178
|
+
"--agno-code-gutter": `${String(lines.length).length}ch`
|
|
2179
|
+
},
|
|
2180
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: language ? `language-${language}` : void 0, children: lines.map((tokens, i) => /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
|
|
2181
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-md-line", children: tokens.map((token, j) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2182
|
+
"span",
|
|
2183
|
+
{
|
|
2184
|
+
style: token.htmlStyle,
|
|
2185
|
+
children: token.content
|
|
2186
|
+
},
|
|
2187
|
+
j
|
|
2188
|
+
)) }),
|
|
2189
|
+
i < lines.length - 1 && "\n"
|
|
2190
|
+
] }, i)) })
|
|
2191
|
+
}
|
|
2192
|
+
)
|
|
1928
2193
|
] });
|
|
1929
2194
|
}
|
|
1930
|
-
|
|
1931
|
-
|
|
2195
|
+
var InlineRenderContext = React8.createContext({
|
|
2196
|
+
sources: [],
|
|
2197
|
+
canResolve: false,
|
|
2198
|
+
codeCopy: true
|
|
2199
|
+
});
|
|
2200
|
+
function el(tag, className) {
|
|
2201
|
+
return function Element({
|
|
1932
2202
|
node: _node,
|
|
1933
2203
|
className: _theirs,
|
|
1934
|
-
href,
|
|
1935
|
-
children,
|
|
1936
2204
|
...rest
|
|
1937
2205
|
}) {
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
2206
|
+
return React8__default.default.createElement(tag, { className, ...rest });
|
|
2207
|
+
};
|
|
2208
|
+
}
|
|
2209
|
+
function Link({
|
|
2210
|
+
node: _node,
|
|
2211
|
+
className: _theirs,
|
|
2212
|
+
href,
|
|
2213
|
+
children,
|
|
2214
|
+
...rest
|
|
2215
|
+
}) {
|
|
2216
|
+
const ctx = React8.useContext(InlineRenderContext);
|
|
2217
|
+
const cited = citationForLink(textOf(children), href, ctx);
|
|
2218
|
+
if (cited)
|
|
1943
2219
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1944
|
-
|
|
2220
|
+
CitationMarker,
|
|
1945
2221
|
{
|
|
1946
|
-
source:
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
kind: "url",
|
|
1950
|
-
url: href,
|
|
1951
|
-
title: labelOf(children) || sourceHost(href) || href
|
|
1952
|
-
},
|
|
1953
|
-
children: link
|
|
2222
|
+
source: cited,
|
|
2223
|
+
className: ctx.markerClass,
|
|
2224
|
+
Link: ctx.Link
|
|
1954
2225
|
}
|
|
1955
2226
|
);
|
|
1956
|
-
};
|
|
1957
|
-
const
|
|
1958
|
-
|
|
1959
|
-
return
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
sub: el("sub"),
|
|
1972
|
-
sup: el("sup"),
|
|
1973
|
-
h1: el("h2", "agno-md-heading"),
|
|
1974
|
-
h2: el("h3", "agno-md-heading"),
|
|
1975
|
-
h3: el("h4", "agno-md-heading"),
|
|
1976
|
-
h4: el("h5", "agno-md-heading"),
|
|
1977
|
-
h5: el("h6", "agno-md-heading"),
|
|
1978
|
-
h6: el("h6", "agno-md-heading"),
|
|
1979
|
-
ul: el("ul", "agno-md-list"),
|
|
1980
|
-
ol: el("ol", "agno-md-list"),
|
|
1981
|
-
li: el("li"),
|
|
1982
|
-
pre: function Pre({ children }) {
|
|
1983
|
-
return /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { copyClass: ctx.copyClass, codeCopy: ctx.codeCopy, children });
|
|
1984
|
-
},
|
|
1985
|
-
blockquote: el("blockquote", "agno-md-quote"),
|
|
1986
|
-
hr: el("hr", "agno-md-rule"),
|
|
1987
|
-
table: function Table({ node: _node, className: _theirs, ...rest }) {
|
|
1988
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-md-table-wrap", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "agno-md-table", ...rest }) });
|
|
1989
|
-
},
|
|
1990
|
-
thead: el("thead"),
|
|
1991
|
-
tbody: el("tbody"),
|
|
1992
|
-
tr: el("tr"),
|
|
1993
|
-
th: el("th"),
|
|
1994
|
-
td: el("td"),
|
|
1995
|
-
img: function Image({ node: _node, className: _theirs, ...rest }) {
|
|
1996
|
-
return /* @__PURE__ */ jsxRuntime.jsx("img", { className: "agno-md-img", ...rest });
|
|
2227
|
+
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 });
|
|
2228
|
+
const source = sourceForUrl(href, ctx.sources);
|
|
2229
|
+
if (!href || !/^https?:\/\//i.test(href) || !source && !ctx.canResolve)
|
|
2230
|
+
return link;
|
|
2231
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2232
|
+
HoverPreview,
|
|
2233
|
+
{
|
|
2234
|
+
source: source ?? {
|
|
2235
|
+
index: 0,
|
|
2236
|
+
anchorId: "",
|
|
2237
|
+
kind: "url",
|
|
2238
|
+
url: href,
|
|
2239
|
+
title: textOf(children) || sourceHost(href) || href
|
|
2240
|
+
},
|
|
2241
|
+
children: link
|
|
1997
2242
|
}
|
|
1998
|
-
|
|
2243
|
+
);
|
|
2244
|
+
}
|
|
2245
|
+
function Code({ node: _node, className, ...rest }) {
|
|
2246
|
+
const fenced = typeof className === "string" && className.includes("language-");
|
|
2247
|
+
return /* @__PURE__ */ jsxRuntime.jsx("code", { className: fenced ? className : "agno-md-code", ...rest });
|
|
2248
|
+
}
|
|
2249
|
+
function Pre({ children }) {
|
|
2250
|
+
const ctx = React8.useContext(InlineRenderContext);
|
|
2251
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2252
|
+
CodeBlock,
|
|
2253
|
+
{
|
|
2254
|
+
copyClass: ctx.copyClass,
|
|
2255
|
+
codeCopy: ctx.codeCopy,
|
|
2256
|
+
streaming: ctx.streaming,
|
|
2257
|
+
children
|
|
2258
|
+
}
|
|
2259
|
+
);
|
|
1999
2260
|
}
|
|
2261
|
+
function Table({ node: _node, className: _theirs, ...rest }) {
|
|
2262
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-md-table-wrap", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "agno-md-table", ...rest }) });
|
|
2263
|
+
}
|
|
2264
|
+
function Image({ node: _node, className: _theirs, ...rest }) {
|
|
2265
|
+
return /* @__PURE__ */ jsxRuntime.jsx("img", { className: "agno-md-img", ...rest });
|
|
2266
|
+
}
|
|
2267
|
+
var MARKDOWN_COMPONENTS = {
|
|
2268
|
+
a: Link,
|
|
2269
|
+
code: Code,
|
|
2270
|
+
p: el("p", "agno-md-p"),
|
|
2271
|
+
// Streamdown renders `**bold**` as a Tailwind-classed <span>, which is not
|
|
2272
|
+
// bold anywhere Tailwind isn't. These stay real elements, styled by the
|
|
2273
|
+
// browser and read correctly by a screen reader.
|
|
2274
|
+
strong: el("strong"),
|
|
2275
|
+
em: el("em"),
|
|
2276
|
+
del: el("del"),
|
|
2277
|
+
sub: el("sub"),
|
|
2278
|
+
sup: el("sup"),
|
|
2279
|
+
h1: el("h2", "agno-md-heading"),
|
|
2280
|
+
h2: el("h3", "agno-md-heading"),
|
|
2281
|
+
h3: el("h4", "agno-md-heading"),
|
|
2282
|
+
h4: el("h5", "agno-md-heading"),
|
|
2283
|
+
h5: el("h6", "agno-md-heading"),
|
|
2284
|
+
h6: el("h6", "agno-md-heading"),
|
|
2285
|
+
ul: el("ul", "agno-md-list"),
|
|
2286
|
+
ol: el("ol", "agno-md-list"),
|
|
2287
|
+
li: el("li"),
|
|
2288
|
+
pre: Pre,
|
|
2289
|
+
blockquote: el("blockquote", "agno-md-quote"),
|
|
2290
|
+
hr: el("hr", "agno-md-rule"),
|
|
2291
|
+
table: Table,
|
|
2292
|
+
thead: el("thead"),
|
|
2293
|
+
tbody: el("tbody"),
|
|
2294
|
+
tr: el("tr"),
|
|
2295
|
+
th: el("th"),
|
|
2296
|
+
td: el("td"),
|
|
2297
|
+
img: Image
|
|
2298
|
+
};
|
|
2299
|
+
var STREAMING_MOTION = {
|
|
2300
|
+
animation: "fadeIn",
|
|
2301
|
+
duration: 400,
|
|
2302
|
+
easing: "ease-out",
|
|
2303
|
+
sep: "word",
|
|
2304
|
+
stagger: 0
|
|
2305
|
+
};
|
|
2000
2306
|
function Markdown({
|
|
2001
2307
|
content,
|
|
2002
2308
|
className,
|
|
@@ -2013,30 +2319,33 @@ function Markdown({
|
|
|
2013
2319
|
const providerLink = useLinkComponent();
|
|
2014
2320
|
const cited = sources ?? fromMessage;
|
|
2015
2321
|
const copy = codeCopy ?? fromProvider ?? true;
|
|
2016
|
-
const
|
|
2017
|
-
const
|
|
2018
|
-
() =>
|
|
2322
|
+
const Link2 = linkComponent ?? providerLink;
|
|
2323
|
+
const inlineContext = React8.useMemo(
|
|
2324
|
+
() => ({
|
|
2019
2325
|
sources: cited,
|
|
2020
2326
|
canResolve,
|
|
2021
2327
|
markerClass: cn.citationMarker,
|
|
2022
2328
|
copyClass: cn.copyButton,
|
|
2023
2329
|
codeCopy: copy,
|
|
2024
|
-
Link
|
|
2330
|
+
Link: Link2,
|
|
2331
|
+
streaming
|
|
2025
2332
|
}),
|
|
2026
|
-
[cited, canResolve, cn.citationMarker, cn.copyButton, copy,
|
|
2333
|
+
[cited, canResolve, cn.citationMarker, cn.copyButton, copy, Link2, streaming]
|
|
2027
2334
|
);
|
|
2028
|
-
const text =
|
|
2029
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2335
|
+
const text = React8.useMemo(() => linkCitations(content, cited), [content, cited]);
|
|
2336
|
+
return /* @__PURE__ */ jsxRuntime.jsx(InlineRenderContext.Provider, { value: inlineContext, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2030
2337
|
streamdown.Streamdown,
|
|
2031
2338
|
{
|
|
2032
2339
|
className: cx("agno-md", className),
|
|
2033
|
-
components,
|
|
2340
|
+
components: MARKDOWN_COMPONENTS,
|
|
2034
2341
|
mode: streaming ? "streaming" : "static",
|
|
2035
2342
|
parseIncompleteMarkdown: streaming !== false,
|
|
2343
|
+
animated: streaming ? STREAMING_MOTION : false,
|
|
2344
|
+
isAnimating: Boolean(streaming),
|
|
2036
2345
|
...options,
|
|
2037
2346
|
children: text
|
|
2038
2347
|
}
|
|
2039
|
-
);
|
|
2348
|
+
) });
|
|
2040
2349
|
}
|
|
2041
2350
|
function statusOf(tool) {
|
|
2042
2351
|
if (tool.tool_call_error) return { label: "error", cls: "error" };
|
|
@@ -2049,7 +2358,7 @@ function hasDetail(tool) {
|
|
|
2049
2358
|
return Boolean(tool.tool_args && Object.keys(tool.tool_args).length) || tool.result != null;
|
|
2050
2359
|
}
|
|
2051
2360
|
function ToolCalls({ tools }) {
|
|
2052
|
-
const [openIndex, setOpenIndex] =
|
|
2361
|
+
const [openIndex, setOpenIndex] = React8.useState(null);
|
|
2053
2362
|
if (!tools || tools.length === 0) return null;
|
|
2054
2363
|
const open = openIndex != null ? tools[openIndex] : void 0;
|
|
2055
2364
|
const openStatus = open ? statusOf(open) : void 0;
|
|
@@ -2107,7 +2416,7 @@ function isNoiseEvent(e) {
|
|
|
2107
2416
|
}
|
|
2108
2417
|
var isMemoryEvent = (e) => eventName(e).includes("MemoryUpdate");
|
|
2109
2418
|
var isMemoryCompleted = (e) => eventName(e).includes("MemoryUpdateCompleted");
|
|
2110
|
-
var isReasoningEvent = (e) =>
|
|
2419
|
+
var isReasoningEvent = (e) => chunkY34YRC5T_cjs.isReasoningStepEvent(e) || chunkY34YRC5T_cjs.isReasoningCompletedEvent(e) || eventName(e).includes("ReasoningStarted");
|
|
2111
2420
|
function formatDuration(seconds) {
|
|
2112
2421
|
return seconds < 10 ? `${seconds.toFixed(1)}s` : `${Math.round(seconds)}s`;
|
|
2113
2422
|
}
|
|
@@ -2141,14 +2450,14 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
2141
2450
|
if (member) put(`member:${runId}`, { kind: "member", id: `member-${runId}`, member });
|
|
2142
2451
|
continue;
|
|
2143
2452
|
}
|
|
2144
|
-
if (
|
|
2453
|
+
if (chunkY34YRC5T_cjs.isToolEvent(e)) {
|
|
2145
2454
|
if (hideTools) continue;
|
|
2146
|
-
for (const tool of
|
|
2455
|
+
for (const tool of chunkY34YRC5T_cjs.toolsFromEvent(e)) {
|
|
2147
2456
|
const key = `tool:${tool.tool_call_id ?? tool.tool_name}`;
|
|
2148
2457
|
const at = indexOf.get(key);
|
|
2149
2458
|
const previous = at != null ? steps[at].tool : void 0;
|
|
2150
2459
|
const merged = { ...previous, ...tool };
|
|
2151
|
-
if (!
|
|
2460
|
+
if (!chunkY34YRC5T_cjs.isToolCompletedEvent(e) && previous?.result != null) merged.result = previous.result;
|
|
2152
2461
|
put(key, { kind: "tool", id: key, tool: merged });
|
|
2153
2462
|
}
|
|
2154
2463
|
continue;
|
|
@@ -2158,8 +2467,8 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
2158
2467
|
const key = `reasoning:${e.run_id ?? "run"}`;
|
|
2159
2468
|
const at = indexOf.get(key);
|
|
2160
2469
|
const previous = at != null ? steps[at].steps : [];
|
|
2161
|
-
const incoming =
|
|
2162
|
-
const completed =
|
|
2470
|
+
const incoming = chunkY34YRC5T_cjs.reasoningStepsFromEvent(e);
|
|
2471
|
+
const completed = chunkY34YRC5T_cjs.isReasoningCompletedEvent(e);
|
|
2163
2472
|
put(key, {
|
|
2164
2473
|
kind: "reasoning",
|
|
2165
2474
|
id: key,
|
|
@@ -2194,7 +2503,7 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
2194
2503
|
label: "Run Continued",
|
|
2195
2504
|
icon: "continued"
|
|
2196
2505
|
});
|
|
2197
|
-
} else if (
|
|
2506
|
+
} else if (chunkY34YRC5T_cjs.isCompletedEvent(e)) {
|
|
2198
2507
|
put(`completed:${runKey}`, {
|
|
2199
2508
|
kind: "status",
|
|
2200
2509
|
id: `completed-${runKey}`,
|
|
@@ -2202,16 +2511,16 @@ function stepsFromEvents(message, { hideReasoning, hideTools }) {
|
|
|
2202
2511
|
detail: durationOf(e),
|
|
2203
2512
|
icon: "run"
|
|
2204
2513
|
});
|
|
2205
|
-
} else if (
|
|
2514
|
+
} else if (chunkY34YRC5T_cjs.isPausedEvent(e)) {
|
|
2206
2515
|
put(`paused:${runKey}`, { kind: "status", id: `paused-${runKey}`, label: "Run Paused", icon: "run" });
|
|
2207
|
-
} else if (
|
|
2516
|
+
} else if (chunkY34YRC5T_cjs.isCancelledEvent(e)) {
|
|
2208
2517
|
put(`cancelled:${runKey}`, {
|
|
2209
2518
|
kind: "status",
|
|
2210
2519
|
id: `cancelled-${runKey}`,
|
|
2211
2520
|
label: "Run Cancelled",
|
|
2212
2521
|
icon: "run"
|
|
2213
2522
|
});
|
|
2214
|
-
} else if (
|
|
2523
|
+
} else if (chunkY34YRC5T_cjs.isErrorEvent(e)) {
|
|
2215
2524
|
const detail = typeof e.content === "string" ? e.content : e.error;
|
|
2216
2525
|
put(`error:${runKey}`, { kind: "status", id: `error-${runKey}`, label: detail || "Run Error", icon: "run" });
|
|
2217
2526
|
}
|
|
@@ -2259,7 +2568,7 @@ function runDuration(message) {
|
|
|
2259
2568
|
function liveActivity(message) {
|
|
2260
2569
|
const events = message.events ?? [];
|
|
2261
2570
|
for (let i = events.length - 1; i >= 0; i--) {
|
|
2262
|
-
const label2 =
|
|
2571
|
+
const label2 = chunkY34YRC5T_cjs.activityLabel(events[i]);
|
|
2263
2572
|
if (label2) return label2;
|
|
2264
2573
|
}
|
|
2265
2574
|
return message.activity ?? null;
|
|
@@ -2286,7 +2595,7 @@ function Step({
|
|
|
2286
2595
|
busy,
|
|
2287
2596
|
children
|
|
2288
2597
|
}) {
|
|
2289
|
-
const [open, setOpen] =
|
|
2598
|
+
const [open, setOpen] = React8.useState(false);
|
|
2290
2599
|
if (!children) {
|
|
2291
2600
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-bts__step", children: [
|
|
2292
2601
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-bts__step-label", children: label2 }),
|
|
@@ -2331,7 +2640,7 @@ function BehindTheScenes({
|
|
|
2331
2640
|
className,
|
|
2332
2641
|
classNames
|
|
2333
2642
|
}) {
|
|
2334
|
-
const [open, setOpen] =
|
|
2643
|
+
const [open, setOpen] = React8.useState(defaultOpen);
|
|
2335
2644
|
const items = behindTheScenesItems(message, { hideReasoning, hideTools });
|
|
2336
2645
|
if (items.length === 0) return null;
|
|
2337
2646
|
const label2 = behindTheScenesLabel(message, streaming, activity);
|
|
@@ -2434,7 +2743,7 @@ function SourceCard({
|
|
|
2434
2743
|
className
|
|
2435
2744
|
}) {
|
|
2436
2745
|
const cn = useResolvedClassNames();
|
|
2437
|
-
const
|
|
2746
|
+
const Link2 = useLinkComponent();
|
|
2438
2747
|
const { preview } = useLinkPreview(source.url, false);
|
|
2439
2748
|
const body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2440
2749
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2450,8 +2759,8 @@ function SourceCard({
|
|
|
2450
2759
|
source.url && /* @__PURE__ */ jsxRuntime.jsx(LinkIcon, { className: "agno-source__link" })
|
|
2451
2760
|
] });
|
|
2452
2761
|
const classes = cx("agno-source", `agno-source--${source.kind}`, cn.sourceCard, className);
|
|
2453
|
-
if (source.url &&
|
|
2454
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2762
|
+
if (source.url && Link2) {
|
|
2763
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Link2, { id: source.anchorId, className: classes, href: source.url, title: source.url, children: body });
|
|
2455
2764
|
}
|
|
2456
2765
|
return source.url ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2457
2766
|
"a",
|
|
@@ -2468,22 +2777,22 @@ function SourceCard({
|
|
|
2468
2777
|
}
|
|
2469
2778
|
var LIST_WIDTH = 240;
|
|
2470
2779
|
function SourcesOverflow({ sources }) {
|
|
2471
|
-
const [open, setOpen] =
|
|
2472
|
-
const [anchor, setAnchor] =
|
|
2473
|
-
const timer =
|
|
2474
|
-
const id =
|
|
2780
|
+
const [open, setOpen] = React8.useState(false);
|
|
2781
|
+
const [anchor, setAnchor] = React8.useState(null);
|
|
2782
|
+
const timer = React8.useRef(null);
|
|
2783
|
+
const id = React8.useId();
|
|
2475
2784
|
const placement = usePlacement(anchor, open, { width: LIST_WIDTH, align: "start" });
|
|
2476
|
-
const schedule =
|
|
2785
|
+
const schedule = React8.useCallback((next) => {
|
|
2477
2786
|
if (timer.current) clearTimeout(timer.current);
|
|
2478
2787
|
timer.current = setTimeout(() => setOpen(next), next ? OPEN_DELAY : CLOSE_DELAY);
|
|
2479
2788
|
}, []);
|
|
2480
|
-
|
|
2789
|
+
React8.useEffect(
|
|
2481
2790
|
() => () => {
|
|
2482
2791
|
if (timer.current) clearTimeout(timer.current);
|
|
2483
2792
|
},
|
|
2484
2793
|
[]
|
|
2485
2794
|
);
|
|
2486
|
-
|
|
2795
|
+
React8.useEffect(() => {
|
|
2487
2796
|
if (!open) return;
|
|
2488
2797
|
const onKey = (e) => {
|
|
2489
2798
|
if (e.key === "Escape") setOpen(false);
|
|
@@ -2491,8 +2800,8 @@ function SourcesOverflow({ sources }) {
|
|
|
2491
2800
|
document.addEventListener("keydown", onKey);
|
|
2492
2801
|
return () => document.removeEventListener("keydown", onKey);
|
|
2493
2802
|
}, [open]);
|
|
2494
|
-
const [mounted, setMounted] =
|
|
2495
|
-
|
|
2803
|
+
const [mounted, setMounted] = React8.useState(false);
|
|
2804
|
+
React8.useEffect(() => setMounted(true), []);
|
|
2496
2805
|
const light = anchor?.closest(".agno-light") ? "agno-light" : void 0;
|
|
2497
2806
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2498
2807
|
"span",
|
|
@@ -2564,8 +2873,8 @@ function Citations({
|
|
|
2564
2873
|
classNames
|
|
2565
2874
|
}) {
|
|
2566
2875
|
const cn = useResolvedClassNames(classNames);
|
|
2567
|
-
const uid =
|
|
2568
|
-
const sources =
|
|
2876
|
+
const uid = React8.useId();
|
|
2877
|
+
const sources = React8.useMemo(
|
|
2569
2878
|
() => given ?? collectSources(references, citations, uid),
|
|
2570
2879
|
[given, references, citations, uid]
|
|
2571
2880
|
);
|
|
@@ -2581,6 +2890,20 @@ function Citations({
|
|
|
2581
2890
|
] })
|
|
2582
2891
|
] });
|
|
2583
2892
|
}
|
|
2893
|
+
function MessageActions({
|
|
2894
|
+
message,
|
|
2895
|
+
hideCopy,
|
|
2896
|
+
children,
|
|
2897
|
+
className,
|
|
2898
|
+
classNames
|
|
2899
|
+
}) {
|
|
2900
|
+
const cn = useResolvedClassNames(classNames);
|
|
2901
|
+
if (hideCopy && !children) return null;
|
|
2902
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("agno-msg__actions", cn.messageActions, className), role: "toolbar", "aria-label": "Message actions", children: [
|
|
2903
|
+
!hideCopy && /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { className: cx("agno-msg__action", cn.messageCopyButton), text: message.content, label: "Copy message" }),
|
|
2904
|
+
children
|
|
2905
|
+
] });
|
|
2906
|
+
}
|
|
2584
2907
|
function audioSrc(a) {
|
|
2585
2908
|
if (a.url) return a.url;
|
|
2586
2909
|
if (a.base64_audio) return `data:${a.mime_type ?? "audio/mpeg"};base64,${a.base64_audio}`;
|
|
@@ -2621,11 +2944,13 @@ function Message({
|
|
|
2621
2944
|
hideReasoning,
|
|
2622
2945
|
hideTools,
|
|
2623
2946
|
hideSources,
|
|
2947
|
+
hideActions,
|
|
2948
|
+
actions,
|
|
2624
2949
|
onFollowup
|
|
2625
2950
|
}) {
|
|
2626
2951
|
const cn = useResolvedClassNames(classNames);
|
|
2627
|
-
const uid =
|
|
2628
|
-
const sources =
|
|
2952
|
+
const uid = React8.useId();
|
|
2953
|
+
const sources = React8.useMemo(() => {
|
|
2629
2954
|
const cited = collectSources(message.references, message.citations, uid);
|
|
2630
2955
|
return cited.length ? cited : sourcesFromMarkdown(message.content, uid);
|
|
2631
2956
|
}, [message.references, message.citations, message.content, uid]);
|
|
@@ -2633,7 +2958,7 @@ function Message({
|
|
|
2633
2958
|
const isAgent = message.role === "agent";
|
|
2634
2959
|
const hasSources = isAgent && !hideSources && sources.length > 0;
|
|
2635
2960
|
const showSources = hasSources && !message.streaming;
|
|
2636
|
-
const content =
|
|
2961
|
+
const content = React8.useMemo(
|
|
2637
2962
|
() => hasSources && message.content ? withoutSourcesLine(message.content) : message.content,
|
|
2638
2963
|
[message.content, hasSources]
|
|
2639
2964
|
);
|
|
@@ -2668,10 +2993,7 @@ function Message({
|
|
|
2668
2993
|
classNames: cn
|
|
2669
2994
|
}
|
|
2670
2995
|
),
|
|
2671
|
-
content ? /* @__PURE__ */ jsxRuntime.
|
|
2672
|
-
renderMarkdown ? renderMarkdown(content) : /* @__PURE__ */ jsxRuntime.jsx(Markdown, { content, className: cn.markdown, streaming: message.streaming }),
|
|
2673
|
-
message.streaming && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-msg__caret", "aria-hidden": true })
|
|
2674
|
-
] }) : isAgent && message.streaming && hasActivity && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-msg__activity", role: "status", "aria-live": "polite", children: [
|
|
2996
|
+
content ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("agno-msg__content", cn.messageContent), children: renderMarkdown ? renderMarkdown(content) : /* @__PURE__ */ jsxRuntime.jsx(Markdown, { content, className: cn.markdown, streaming: message.streaming }) }) : isAgent && message.streaming && hasActivity && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-msg__activity", role: "status", "aria-live": "polite", children: [
|
|
2675
2997
|
/* @__PURE__ */ jsxRuntime.jsx(GridLoader, {}),
|
|
2676
2998
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-msg__activity-label", children: activity ?? "Working..." })
|
|
2677
2999
|
] }),
|
|
@@ -2687,7 +3009,8 @@ function Message({
|
|
|
2687
3009
|
showSources && /* @__PURE__ */ jsxRuntime.jsx(Citations, { sources, classNames: cn }),
|
|
2688
3010
|
isAgent && onFollowup && !message.streaming && /* @__PURE__ */ jsxRuntime.jsx(Followups, { items: message.followups, onSelect: onFollowup, classNames: cn }),
|
|
2689
3011
|
message.error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "agno-msg__error", children: message.error }),
|
|
2690
|
-
children
|
|
3012
|
+
children,
|
|
3013
|
+
isAgent && !hideActions && !message.streaming && message.content && /* @__PURE__ */ jsxRuntime.jsx(MessageActions, { message, classNames: cn, children: actions })
|
|
2691
3014
|
] }) })
|
|
2692
3015
|
]
|
|
2693
3016
|
}
|
|
@@ -2714,10 +3037,10 @@ function MessageList({
|
|
|
2714
3037
|
const runActivity = activity !== void 0 ? activity : ctx?.chat.activity;
|
|
2715
3038
|
const markdown = renderMarkdown ?? ctx?.renderMarkdown;
|
|
2716
3039
|
const kind = entityType ?? ctx?.chat.entityType;
|
|
2717
|
-
const endRef =
|
|
2718
|
-
const stick =
|
|
2719
|
-
const userScrolled =
|
|
2720
|
-
const containerRef =
|
|
3040
|
+
const endRef = React8.useRef(null);
|
|
3041
|
+
const stick = React8.useRef(true);
|
|
3042
|
+
const userScrolled = React8.useRef(false);
|
|
3043
|
+
const containerRef = React8.useRef(null);
|
|
2721
3044
|
const markUserScroll = () => {
|
|
2722
3045
|
userScrolled.current = true;
|
|
2723
3046
|
};
|
|
@@ -2729,7 +3052,7 @@ function MessageList({
|
|
|
2729
3052
|
else if (userScrolled.current) stick.current = false;
|
|
2730
3053
|
userScrolled.current = false;
|
|
2731
3054
|
};
|
|
2732
|
-
|
|
3055
|
+
React8.useEffect(() => {
|
|
2733
3056
|
if (stick.current) endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
2734
3057
|
}, [items, runActivity, runStatus]);
|
|
2735
3058
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2747,7 +3070,7 @@ function MessageList({
|
|
|
2747
3070
|
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: [
|
|
2748
3071
|
items.map((m) => {
|
|
2749
3072
|
const live = m.streaming && runStatus === "streaming" ? runActivity : void 0;
|
|
2750
|
-
return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3073
|
+
return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: renderMessage(m, live) }, m.id) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2751
3074
|
Message,
|
|
2752
3075
|
{
|
|
2753
3076
|
message: m,
|
|
@@ -3018,10 +3341,10 @@ function EntitySelector({
|
|
|
3018
3341
|
classNames
|
|
3019
3342
|
}) {
|
|
3020
3343
|
const cn = useResolvedClassNames(classNames);
|
|
3021
|
-
const [open, setOpen] =
|
|
3022
|
-
const rootRef =
|
|
3344
|
+
const [open, setOpen] = React8.useState(false);
|
|
3345
|
+
const rootRef = React8.useRef(null);
|
|
3023
3346
|
const key = (e) => `${e.type}:${e.id}`;
|
|
3024
|
-
|
|
3347
|
+
React8.useEffect(() => {
|
|
3025
3348
|
if (!open) return;
|
|
3026
3349
|
const onDocClick = (e) => {
|
|
3027
3350
|
if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(false);
|
|
@@ -3170,14 +3493,14 @@ function SessionList({
|
|
|
3170
3493
|
] });
|
|
3171
3494
|
}
|
|
3172
3495
|
function AgnoChat(props) {
|
|
3173
|
-
const client =
|
|
3174
|
-
() => props.client ?? new
|
|
3496
|
+
const client = React8.useMemo(
|
|
3497
|
+
() => props.client ?? new chunkY34YRC5T_cjs.AgnoClient({ baseUrl: props.baseUrl ?? "", headers: props.headers }),
|
|
3175
3498
|
[props.client, props.baseUrl, props.headers]
|
|
3176
3499
|
);
|
|
3177
|
-
const [discovered, setDiscovered] =
|
|
3178
|
-
const [selected, setSelected] =
|
|
3179
|
-
const [discoveryDone, setDiscoveryDone] =
|
|
3180
|
-
|
|
3500
|
+
const [discovered, setDiscovered] = React8.useState(props.entities ?? []);
|
|
3501
|
+
const [selected, setSelected] = React8.useState(props.defaultEntity ?? null);
|
|
3502
|
+
const [discoveryDone, setDiscoveryDone] = React8.useState(Boolean(props.entity || props.entities));
|
|
3503
|
+
React8.useEffect(() => {
|
|
3181
3504
|
if (props.entity && !props.showEntityPicker || props.entities) return;
|
|
3182
3505
|
let cancelled = false;
|
|
3183
3506
|
setDiscoveryDone(false);
|
|
@@ -3192,12 +3515,12 @@ function AgnoChat(props) {
|
|
|
3192
3515
|
};
|
|
3193
3516
|
}, [client, props.entity, props.entities, props.showEntityPicker]);
|
|
3194
3517
|
const entity = props.entity ?? selected;
|
|
3195
|
-
const chat = useAgnoChat({ client, entity, userId: props.userId });
|
|
3518
|
+
const chat = useAgnoChat({ client, entity, userId: props.userId, streaming: props.streaming });
|
|
3196
3519
|
const { refreshSessions } = chat;
|
|
3197
|
-
|
|
3520
|
+
React8.useEffect(() => {
|
|
3198
3521
|
if (props.showSessions && entity) refreshSessions();
|
|
3199
3522
|
}, [props.showSessions, entity?.type, entity?.id, refreshSessions]);
|
|
3200
|
-
|
|
3523
|
+
React8.useEffect(() => {
|
|
3201
3524
|
if (props.showSessions && entity && chat.status === "completed") refreshSessions();
|
|
3202
3525
|
}, [chat.status]);
|
|
3203
3526
|
const onSelect = (e) => {
|
|
@@ -3212,7 +3535,7 @@ function AgnoChat(props) {
|
|
|
3212
3535
|
const noEntities = !props.entity && discoveryDone && entities.length === 0;
|
|
3213
3536
|
const launcher = props.mode === "launcher";
|
|
3214
3537
|
const fullscreen = props.panel === "fullscreen";
|
|
3215
|
-
const [selfOpen, setSelfOpen] =
|
|
3538
|
+
const [selfOpen, setSelfOpen] = React8.useState(props.defaultOpen ?? false);
|
|
3216
3539
|
const isOpen = props.open ?? selfOpen;
|
|
3217
3540
|
const setOpen = (next) => {
|
|
3218
3541
|
if (props.open === void 0) setSelfOpen(next);
|
|
@@ -3337,7 +3660,7 @@ function Reasoning({
|
|
|
3337
3660
|
steps,
|
|
3338
3661
|
defaultOpen = false
|
|
3339
3662
|
}) {
|
|
3340
|
-
const [open, setOpen] =
|
|
3663
|
+
const [open, setOpen] = React8.useState(defaultOpen);
|
|
3341
3664
|
if (!steps || steps.length === 0) return null;
|
|
3342
3665
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-reasoning", children: [
|
|
3343
3666
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3383,7 +3706,7 @@ function statusDot(status) {
|
|
|
3383
3706
|
return "running";
|
|
3384
3707
|
}
|
|
3385
3708
|
function MemberCard({ member, renderMarkdown }) {
|
|
3386
|
-
const [open, setOpen] =
|
|
3709
|
+
const [open, setOpen] = React8.useState(true);
|
|
3387
3710
|
const label2 = member.kind === "executor" ? "Step executor" : "Member";
|
|
3388
3711
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-member", children: [
|
|
3389
3712
|
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "agno-member__head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
@@ -3415,7 +3738,7 @@ function MemberResponses({
|
|
|
3415
3738
|
] });
|
|
3416
3739
|
}
|
|
3417
3740
|
function StepRow({ step, renderMarkdown }) {
|
|
3418
|
-
const [open, setOpen] =
|
|
3741
|
+
const [open, setOpen] = React8.useState(false);
|
|
3419
3742
|
const hasBody = Boolean(step.content || step.error);
|
|
3420
3743
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `agno-step agno-step--${step.status}`, children: [
|
|
3421
3744
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3476,7 +3799,7 @@ function fold(events) {
|
|
|
3476
3799
|
last.created_at = e.created_at ?? last.created_at;
|
|
3477
3800
|
continue;
|
|
3478
3801
|
}
|
|
3479
|
-
rows.push({ event: name, source, count: 1, created_at: e.created_at, detail:
|
|
3802
|
+
rows.push({ event: name, source, count: 1, created_at: e.created_at, detail: chunkY34YRC5T_cjs.activityLabel(e) });
|
|
3480
3803
|
}
|
|
3481
3804
|
return rows;
|
|
3482
3805
|
}
|
|
@@ -3485,9 +3808,9 @@ function EventLog({
|
|
|
3485
3808
|
autoScroll = true,
|
|
3486
3809
|
maxHeight = 240
|
|
3487
3810
|
}) {
|
|
3488
|
-
const ref =
|
|
3489
|
-
const rows =
|
|
3490
|
-
|
|
3811
|
+
const ref = React8.useRef(null);
|
|
3812
|
+
const rows = React8.useMemo(() => fold(events), [events]);
|
|
3813
|
+
React8.useEffect(() => {
|
|
3491
3814
|
if (autoScroll && ref.current) ref.current.scrollTop = ref.current.scrollHeight;
|
|
3492
3815
|
}, [rows, autoScroll]);
|
|
3493
3816
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "agno-eventlog", ref, style: { maxHeight }, children: [
|
|
@@ -3521,6 +3844,8 @@ exports.ChevronDown = ChevronDown;
|
|
|
3521
3844
|
exports.Citations = Citations;
|
|
3522
3845
|
exports.Close = Close;
|
|
3523
3846
|
exports.Copy = Copy;
|
|
3847
|
+
exports.CopyButton = CopyButton;
|
|
3848
|
+
exports.DEFAULT_STREAMING_OPTIONS = DEFAULT_STREAMING_OPTIONS;
|
|
3524
3849
|
exports.EntityBadge = EntityBadge;
|
|
3525
3850
|
exports.EntitySelector = EntitySelector;
|
|
3526
3851
|
exports.EventLog = EventLog;
|
|
@@ -3541,6 +3866,7 @@ exports.Markdown = Markdown;
|
|
|
3541
3866
|
exports.MemberResponses = MemberResponses;
|
|
3542
3867
|
exports.Memory = Memory;
|
|
3543
3868
|
exports.Message = Message;
|
|
3869
|
+
exports.MessageActions = MessageActions;
|
|
3544
3870
|
exports.MessageList = MessageList;
|
|
3545
3871
|
exports.Multimedia = Multimedia;
|
|
3546
3872
|
exports.Paperclip = Paperclip;
|
|
@@ -3566,6 +3892,7 @@ exports.behindTheScenesLabel = behindTheScenesLabel;
|
|
|
3566
3892
|
exports.collectSources = collectSources;
|
|
3567
3893
|
exports.cx = cx;
|
|
3568
3894
|
exports.displayUrl = displayUrl;
|
|
3895
|
+
exports.faviconFallbacks = faviconFallbacks;
|
|
3569
3896
|
exports.faviconUrl = faviconUrl;
|
|
3570
3897
|
exports.fileAccepted = fileAccepted;
|
|
3571
3898
|
exports.getProviderIcon = getProviderIcon;
|
|
@@ -3586,5 +3913,5 @@ exports.useResolvedClassNames = useResolvedClassNames;
|
|
|
3586
3913
|
exports.useSources = useSources;
|
|
3587
3914
|
exports.withoutSourcesLine = withoutSourcesLine;
|
|
3588
3915
|
exports.writeClipboard = writeClipboard;
|
|
3589
|
-
//# sourceMappingURL=chunk-
|
|
3590
|
-
//# sourceMappingURL=chunk-
|
|
3916
|
+
//# sourceMappingURL=chunk-ESV52ERB.cjs.map
|
|
3917
|
+
//# sourceMappingURL=chunk-ESV52ERB.cjs.map
|