@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.
Files changed (33) hide show
  1. package/README.md +81 -5
  2. package/dist/chat/index.cjs +99 -83
  3. package/dist/chat/index.d.cts +80 -16
  4. package/dist/chat/index.d.ts +80 -16
  5. package/dist/chat/index.js +2 -2
  6. package/dist/{chunk-RE7ZT73K.js → chunk-5QKU7OPE.js} +2 -2
  7. package/dist/{chunk-RE7ZT73K.js.map → chunk-5QKU7OPE.js.map} +1 -1
  8. package/dist/{chunk-6V2YIPHF.js → chunk-BCVKAMSO.js} +22 -4
  9. package/dist/chunk-BCVKAMSO.js.map +1 -0
  10. package/dist/{chunk-Q73XHL35.cjs → chunk-ESV52ERB.cjs} +771 -444
  11. package/dist/chunk-ESV52ERB.cjs.map +1 -0
  12. package/dist/{chunk-2WM3CCFE.cjs → chunk-HBSF434L.cjs} +2 -2
  13. package/dist/{chunk-2WM3CCFE.cjs.map → chunk-HBSF434L.cjs.map} +1 -1
  14. package/dist/{chunk-XTP3TMEZ.js → chunk-OGDPK4Z3.js} +602 -279
  15. package/dist/chunk-OGDPK4Z3.js.map +1 -0
  16. package/dist/{chunk-55HQJGLP.cjs → chunk-Y34YRC5T.cjs} +22 -3
  17. package/dist/chunk-Y34YRC5T.cjs.map +1 -0
  18. package/dist/{client-DUyVqxU9.d.cts → client-Dwk6ThnW.d.cts} +24 -12
  19. package/dist/{client-DUyVqxU9.d.ts → client-Dwk6ThnW.d.ts} +24 -12
  20. package/dist/core/index.cjs +23 -23
  21. package/dist/core/index.d.cts +2 -2
  22. package/dist/core/index.d.ts +2 -2
  23. package/dist/core/index.js +2 -2
  24. package/dist/index.cjs +122 -106
  25. package/dist/index.d.cts +2 -2
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +3 -3
  28. package/dist/styles.css +79 -34
  29. package/package.json +1 -1
  30. package/dist/chunk-55HQJGLP.cjs.map +0 -1
  31. package/dist/chunk-6V2YIPHF.js.map +0 -1
  32. package/dist/chunk-Q73XHL35.cjs.map +0 -1
  33. package/dist/chunk-XTP3TMEZ.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunk55HQJGLP_cjs = require('./chunk-55HQJGLP.cjs');
4
- var React7 = require('react');
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 React7__default = /*#__PURE__*/_interopDefault(React7);
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 = React7.useMemo(() => {
185
+ const client = React8.useMemo(() => {
20
186
  if (options.client) return options.client;
21
- return new chunk55HQJGLP_cjs.AgnoClient({ baseUrl: options.baseUrl ?? "", headers: options.headers });
187
+ return new chunkY34YRC5T_cjs.AgnoClient({ baseUrl: options.baseUrl ?? "", headers: options.headers });
22
188
  }, [options.client, options.baseUrl, JSON.stringify(options.headers)]);
23
- const [messages, setMessages] = React7.useState(options.initialMessages ?? []);
24
- const [events, setEvents] = React7.useState([]);
25
- const [currentEvent, setCurrentEvent] = React7.useState(null);
26
- const [status, setStatus] = React7.useState("idle");
27
- const [activity, setActivity] = React7.useState(null);
28
- const [error, setError] = React7.useState(null);
29
- const [sessionId, setSessionId] = React7.useState(options.sessionId);
30
- const [sessions, setSessions] = React7.useState([]);
31
- const [sessionsLoading, setSessionsLoading] = React7.useState(false);
32
- const [backgroundRunning, setBackgroundRunning] = React7.useState([]);
33
- const abortRef = React7.useRef(null);
34
- const channelRef = React7.useRef(null);
35
- const backgroundRef = React7.useRef(/* @__PURE__ */ new Map());
36
- const activeMsgIdRef = React7.useRef(null);
37
- const runIdRef = React7.useRef(void 0);
38
- const entityRef = React7.useRef(entity);
39
- const sessionIdRef = React7.useRef(options.sessionId);
40
- const pendingSessionNameRef = React7.useRef(void 0);
41
- const bumpedSessionRef = React7.useRef(void 0);
42
- React7.useEffect(() => {
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
- React7.useEffect(() => {
223
+ React8.useEffect(() => {
46
224
  sessionIdRef.current = sessionId;
47
225
  }, [sessionId]);
48
- const upsertSession = React7.useCallback((id, createdAt) => {
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 viewRef = React7.useRef({ messages, events, status, activity, error });
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 = React7.useCallback((chan, e) => {
74
- const park = chan?.park;
75
- if (park) park.events = [...park.events, e];
76
- else {
77
- setEvents((prev) => [...prev, e]);
78
- setCurrentEvent(e);
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 = React7.useCallback((chan, activity2) => {
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 = React7.useCallback((chan, message) => {
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 = React7.useCallback(
266
+ }, [setError]);
267
+ const patchActive = React8.useCallback(
97
268
  (chan, patch) => {
98
- const id = chan?.park ? chan.park.activeMsgId : activeMsgIdRef.current;
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 = React7.useCallback(
275
+ const applyEvent = React8.useCallback(
105
276
  (chan, e) => {
106
- writeEvents(chan, e);
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 (chunk55HQJGLP_cjs.isSubRunEvent(e)) {
127
- const kind = entityRef.current?.type === "workflow" ? "executor" : "member";
128
- patchActive(chan, (m) => chunk55HQJGLP_cjs.applySubRunEvent(m, e, kind));
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 (chunk55HQJGLP_cjs.isStepEvent(e)) {
132
- patchActive(chan, (m) => chunk55HQJGLP_cjs.applyStepEvent(m, e));
299
+ if (chunkY34YRC5T_cjs.isStepEvent(e)) {
300
+ patchActive(chan, (m) => chunkY34YRC5T_cjs.applyStepEvent(m, e));
133
301
  return;
134
302
  }
135
- if (chunk55HQJGLP_cjs.isStartedEvent(e)) {
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 (chunk55HQJGLP_cjs.isToolEvent(e)) {
145
- const incoming = chunk55HQJGLP_cjs.toolsFromEvent(e);
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 = chunk55HQJGLP_cjs.mergeTool(tool_calls, t);
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 (chunk55HQJGLP_cjs.isContentEvent(e)) {
156
- patchActive(chan, (m) => chunk55HQJGLP_cjs.applyContentEvent(m, e));
323
+ if (chunkY34YRC5T_cjs.isContentEvent(e)) {
324
+ patchActive(chan, (m) => chunkY34YRC5T_cjs.applyContentEvent(m, e));
157
325
  return;
158
326
  }
159
- if (chunk55HQJGLP_cjs.isReasoningStepEvent(e)) {
160
- const incoming = e.reasoning_steps ?? e.extra_data?.reasoning_steps ?? [];
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 (chunk55HQJGLP_cjs.isReasoningCompletedEvent(e)) {
170
- const steps = e.reasoning_steps ?? e.extra_data?.reasoning_steps;
171
- if (steps?.length) patchActive(chan, (m) => ({ ...m, reasoning_steps: 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 (chunk55HQJGLP_cjs.isFollowupsCompletedEvent(e)) {
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 (chunk55HQJGLP_cjs.isPausedEvent(e)) {
347
+ if (chunkY34YRC5T_cjs.isPausedEvent(e)) {
180
348
  const requirements = e.requirements ?? [];
181
- const pausedTools2 = chunk55HQJGLP_cjs.toolsFromEvent(e);
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 = chunk55HQJGLP_cjs.mergeTool(tool_calls, t);
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 (chunk55HQJGLP_cjs.isCompletedEvent(e)) {
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 = chunk55HQJGLP_cjs.toolsFromEvent(e);
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 = chunk55HQJGLP_cjs.mergeTool(tc, t);
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 (chunk55HQJGLP_cjs.isCancelledEvent(e)) {
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 (chunk55HQJGLP_cjs.isErrorEvent(e)) {
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 = React7.useCallback((chan, sessionId2) => {
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 = React7.useCallback((sessionId2) => {
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 = React7.useCallback(() => {
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 = React7.useCallback(
453
+ const drive = React8.useCallback(
289
454
  async (starter) => {
290
455
  const controller = new AbortController();
291
- const chan = { controller, park: null };
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
- setError(null);
295
- setStatus("streaming");
296
- await starter({
297
- signal: controller.signal,
298
- // `chan.park` is read at call time, so events follow the run when the
299
- // user navigates away mid-stream.
300
- onEvent: (e) => applyEvent(chan, e),
301
- onError: (err) => {
302
- patchActive(chan, (m) => ({ ...m, streaming: false, status: "error", error: err.message }));
303
- writeError(chan, err.message);
304
- writeStatus(chan, "error");
305
- },
306
- onComplete: () => {
307
- writeActivity(chan, null);
308
- patchActive(chan, (m) => m.streaming ? { ...m, streaming: false } : m);
309
- const park = chan.park;
310
- if (park) park.status = park.status === "streaming" ? "completed" : park.status;
311
- else setStatus((s) => s === "streaming" ? "completed" : s);
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 = React7.useCallback(
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 = React7.useCallback(
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 = React7.useMemo(
591
+ const activeMessage = React8.useMemo(
392
592
  () => messages.find((m) => m.id === activeMsgIdRef.current) ?? null,
393
593
  [messages]
394
594
  );
395
- const pausedTools = React7.useMemo(
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 = React7.useCallback(
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 = React7.useCallback(
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 = React7.useCallback(async () => {
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
- setStatus("cancelled");
444
- setActivity(null);
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 = React7.useCallback(async () => {
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 loadSession = React7.useCallback(
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
- activeMsgIdRef.current = null;
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(chunk55HQJGLP_cjs.sessionRunsToMessages(runs));
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 = React7.useCallback(
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 = React7.useCallback(() => {
736
+ const reset = React8.useCallback(() => {
515
737
  releaseCurrentRun();
516
- activeMsgIdRef.current = null;
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
- React7.useEffect(() => {
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 = React7.useMemo(
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 = React7.createContext(null);
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 = React7.useMemo(
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 = React7.useContext(ChatContext);
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 React7.useContext(ChatContext);
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 React7.useMemo(() => ({ ...ctx?.classNames, ...explicit }), [ctx?.classNames, explicit]);
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] = React7.useState(defaultOpen);
997
+ const [uncontrolledOpen, setUncontrolledOpen] = React8.useState(defaultOpen);
782
998
  const isOpen = open ?? uncontrolledOpen;
783
- const opened = React7.useRef(isOpen);
999
+ const opened = React8.useRef(isOpen);
784
1000
  if (isOpen) opened.current = true;
785
1001
  const mounted = keepMounted ? opened.current : isOpen;
786
- const setOpen = React7.useCallback(
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
- React7.useEffect(() => {
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
- React7.useEffect(() => {
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] = React7.useState(false);
810
- React7.useEffect(() => setCanPortal(true), []);
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] = React7.useState(null);
867
- React7.useEffect(() => {
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] = React7.useState("");
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] = React7.useState([]);
978
- const filesRef = React7.useRef([]);
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] = React7.useState(null);
984
- const [dragging, setDragging] = React7.useState(false);
985
- const dragDepth = React7.useRef(0);
986
- const fileRef = React7.useRef(null);
987
- const textareaRef = React7.useRef(null);
988
- const setTextareaRef = React7.useCallback(
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 = React7.useCallback(() => {
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
- React7.useEffect(adjustHeight, [value, adjustHeight]);
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 = React7.useMemo(() => buildAsks(message, entityType), [message, entityType]);
1256
- const [choices, setChoices] = React7.useState({});
1257
- const [values, setValues] = React7.useState({});
1258
- const [reasons, setReasons] = React7.useState({});
1259
- const [openArgs, setOpenArgs] = React7.useState({});
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
- if (!url) return void 0;
1644
+ return faviconFallbacks(url)[0];
1645
+ }
1646
+ function faviconFallbacks(url) {
1647
+ if (!url) return [];
1403
1648
  try {
1404
- return new URL("/favicon.ico", url).href;
1649
+ return ["/favicon.ico", "/favicon.svg"].map((path) => new URL(path, url).href);
1405
1650
  } catch {
1406
- return void 0;
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 = React7.createContext([]);
1775
+ var SourcesContext = React8.createContext([]);
1531
1776
  var SourcesProvider = SourcesContext.Provider;
1532
1777
  function useSources() {
1533
- return React7.useContext(SourcesContext);
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" ? React7.useEffect : React7.useLayoutEffect;
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] = React7.useState(cached ?? null);
1620
- const [loading2, setLoading] = React7.useState(false);
1621
- React7.useEffect(() => {
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 src = faviconUrl(url);
1659
- const [failed, setFailed] = React7.useState(false);
1660
- React7.useEffect(() => setFailed(false), [src]);
1661
- if (kind === "document" || !src || failed) {
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: () => setFailed(true),
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] = React7.useState(null);
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] = React7.useState(false);
1735
- const [awake, setAwake] = React7.useState(false);
1736
- const [anchor, setAnchor] = React7.useState(null);
1737
- const timer = React7.useRef(null);
1738
- const id = React7.useId();
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 = React7.useCallback((next) => {
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
- React7.useEffect(
1931
+ React8.useEffect(
1753
1932
  () => () => {
1754
1933
  if (timer.current) clearTimeout(timer.current);
1755
1934
  },
1756
1935
  []
1757
1936
  );
1758
- React7.useEffect(() => {
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] = React7.useState(false);
1767
- React7.useEffect(() => setMounted(true), []);
1945
+ const [mounted, setMounted] = React8.useState(false);
1946
+ React8.useEffect(() => setMounted(true), []);
1768
1947
  if (disabled) return children;
1769
- const trigger = React7.isValidElement(children) ? React7.cloneElement(children, {
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((s) => s.url === url) : void 0;
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((s) => s.index === Number(label2.trim()));
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: Link && source.url ? /* @__PURE__ */ jsxRuntime.jsx(Link, { ...props, children: source.index }) : /* @__PURE__ */ jsxRuntime.jsx(
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] = React7.useState(false);
1872
- React7.useEffect(() => {
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-md-copy", copied && "is-copied", className),
2119
+ className: cx("agno-copy", copied && "is-copied", className),
1885
2120
  onClick: copy,
1886
- "aria-label": copied ? "Copied" : "Copy code",
1887
- title: copied ? "Copied" : "Copy code",
1888
- children: copied ? /* @__PURE__ */ jsxRuntime.jsx(Check, { size: 13 }) : /* @__PURE__ */ jsxRuntime.jsx(Copy, { size: 13 })
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 (React7__default.default.isValidElement(children)) return textOf(children.props.children);
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 (!React7__default.default.isValidElement(child)) {
2137
+ if (!React8__default.default.isValidElement(
2138
+ child
2139
+ )) {
1902
2140
  return { code: textOf(children) };
1903
2141
  }
1904
- const language = /(?:^|\s)language-([^\s]+)/.exec(child.props.className ?? "")?.[1];
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 } = React7.useMemo(() => fencedCode(children), [children]);
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(CopyButton, { className: copyClass, text: () => code })
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("pre", { className: "agno-md-pre", style: { "--agno-code-gutter": `${String(lines.length).length}ch` }, children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: language ? `language-${language}` : void 0, children: lines.map((tokens, i) => /* @__PURE__ */ jsxRuntime.jsxs(React7__default.default.Fragment, { children: [
1925
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "agno-md-line", children: tokens.map((token, j) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: token.htmlStyle, children: token.content }, j)) }),
1926
- i < lines.length - 1 && "\n"
1927
- ] }, i)) }) })
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
- function elementsFor(ctx) {
1931
- const Link = function Link2({
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
- const cited = citationForLink(labelOf(children), href, ctx);
1939
- if (cited) return /* @__PURE__ */ jsxRuntime.jsx(CitationMarker, { source: cited, className: ctx.markerClass, Link: ctx.Link });
1940
- const link = ctx.Link && href ? /* @__PURE__ */ jsxRuntime.jsx(ctx.Link, { href, ...rest, children }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href, target: "_blank", rel: "noreferrer noopener", ...rest, children });
1941
- const source = sourceForUrl(href, ctx.sources);
1942
- if (!href || !/^https?:\/\//i.test(href) || !source && !ctx.canResolve) return link;
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
- HoverPreview,
2220
+ CitationMarker,
1945
2221
  {
1946
- source: source ?? {
1947
- index: 0,
1948
- anchorId: "",
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 Code = function Code2({ node: _node, className, ...rest }) {
1958
- const fenced = typeof className === "string" && className.includes("language-");
1959
- return /* @__PURE__ */ jsxRuntime.jsx("code", { className: fenced ? className : "agno-md-code", ...rest });
1960
- };
1961
- return {
1962
- a: Link,
1963
- code: Code,
1964
- p: el("p", "agno-md-p"),
1965
- // Streamdown renders `**bold**` as a Tailwind-classed <span>, which is not
1966
- // bold anywhere Tailwind isn't. These stay real elements, styled by the
1967
- // browser and read correctly by a screen reader.
1968
- strong: el("strong"),
1969
- em: el("em"),
1970
- del: el("del"),
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 Link = linkComponent ?? providerLink;
2017
- const components = React7.useMemo(
2018
- () => elementsFor({
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, Link]
2333
+ [cited, canResolve, cn.citationMarker, cn.copyButton, copy, Link2, streaming]
2027
2334
  );
2028
- const text = React7.useMemo(() => linkCitations(content, cited), [content, cited]);
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] = React7.useState(null);
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) => chunk55HQJGLP_cjs.isReasoningStepEvent(e) || chunk55HQJGLP_cjs.isReasoningCompletedEvent(e) || eventName(e).includes("ReasoningStarted");
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 (chunk55HQJGLP_cjs.isToolEvent(e)) {
2453
+ if (chunkY34YRC5T_cjs.isToolEvent(e)) {
2145
2454
  if (hideTools) continue;
2146
- for (const tool of chunk55HQJGLP_cjs.toolsFromEvent(e)) {
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 (!chunk55HQJGLP_cjs.isToolCompletedEvent(e) && previous?.result != null) merged.result = previous.result;
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 = e.reasoning_steps ?? e.extra_data?.reasoning_steps ?? [];
2162
- const completed = chunk55HQJGLP_cjs.isReasoningCompletedEvent(e);
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 (chunk55HQJGLP_cjs.isCompletedEvent(e)) {
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 (chunk55HQJGLP_cjs.isPausedEvent(e)) {
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 (chunk55HQJGLP_cjs.isCancelledEvent(e)) {
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 (chunk55HQJGLP_cjs.isErrorEvent(e)) {
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 = chunk55HQJGLP_cjs.activityLabel(events[i]);
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] = React7.useState(false);
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] = React7.useState(defaultOpen);
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 Link = useLinkComponent();
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 && Link) {
2454
- return /* @__PURE__ */ jsxRuntime.jsx(Link, { id: source.anchorId, className: classes, href: source.url, title: source.url, children: body });
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] = React7.useState(false);
2472
- const [anchor, setAnchor] = React7.useState(null);
2473
- const timer = React7.useRef(null);
2474
- const id = React7.useId();
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 = React7.useCallback((next) => {
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
- React7.useEffect(
2789
+ React8.useEffect(
2481
2790
  () => () => {
2482
2791
  if (timer.current) clearTimeout(timer.current);
2483
2792
  },
2484
2793
  []
2485
2794
  );
2486
- React7.useEffect(() => {
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] = React7.useState(false);
2495
- React7.useEffect(() => setMounted(true), []);
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 = React7.useId();
2568
- const sources = React7.useMemo(
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 = React7.useId();
2628
- const sources = React7.useMemo(() => {
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 = React7.useMemo(
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.jsxs("div", { className: cx("agno-msg__content", cn.messageContent), children: [
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 = React7.useRef(null);
2718
- const stick = React7.useRef(true);
2719
- const userScrolled = React7.useRef(false);
2720
- const containerRef = React7.useRef(null);
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
- React7.useEffect(() => {
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(React7__default.default.Fragment, { children: renderMessage(m, live) }, m.id) : /* @__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] = React7.useState(false);
3022
- const rootRef = React7.useRef(null);
3344
+ const [open, setOpen] = React8.useState(false);
3345
+ const rootRef = React8.useRef(null);
3023
3346
  const key = (e) => `${e.type}:${e.id}`;
3024
- React7.useEffect(() => {
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 = React7.useMemo(
3174
- () => props.client ?? new chunk55HQJGLP_cjs.AgnoClient({ baseUrl: props.baseUrl ?? "", headers: props.headers }),
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] = React7.useState(props.entities ?? []);
3178
- const [selected, setSelected] = React7.useState(props.defaultEntity ?? null);
3179
- const [discoveryDone, setDiscoveryDone] = React7.useState(Boolean(props.entity || props.entities));
3180
- React7.useEffect(() => {
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
- React7.useEffect(() => {
3520
+ React8.useEffect(() => {
3198
3521
  if (props.showSessions && entity) refreshSessions();
3199
3522
  }, [props.showSessions, entity?.type, entity?.id, refreshSessions]);
3200
- React7.useEffect(() => {
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] = React7.useState(props.defaultOpen ?? false);
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] = React7.useState(defaultOpen);
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] = React7.useState(true);
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] = React7.useState(false);
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: chunk55HQJGLP_cjs.activityLabel(e) });
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 = React7.useRef(null);
3489
- const rows = React7.useMemo(() => fold(events), [events]);
3490
- React7.useEffect(() => {
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-Q73XHL35.cjs.map
3590
- //# sourceMappingURL=chunk-Q73XHL35.cjs.map
3916
+ //# sourceMappingURL=chunk-ESV52ERB.cjs.map
3917
+ //# sourceMappingURL=chunk-ESV52ERB.cjs.map