@rodrigocoliveira/agno-react 1.4.0 → 2.1.0

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 (61) hide show
  1. package/README.md +32 -46
  2. package/dist/hooks/useAgnoToolExecution.d.ts +7 -11
  3. package/dist/hooks/useAgnoToolExecution.d.ts.map +1 -1
  4. package/dist/index.d.ts +7 -6
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2353 -1043
  7. package/dist/index.js.map +31 -6
  8. package/dist/index.mjs +2371 -1040
  9. package/dist/index.mjs.map +31 -6
  10. package/dist/ui/components/chart.d.ts +63 -0
  11. package/dist/ui/components/chart.d.ts.map +1 -0
  12. package/dist/ui/composed/AgnoMessageItem.d.ts +12 -24
  13. package/dist/ui/composed/AgnoMessageItem.d.ts.map +1 -1
  14. package/dist/ui/composed/agno-chat/agno-chat.d.ts +25 -3
  15. package/dist/ui/composed/agno-chat/agno-chat.d.ts.map +1 -1
  16. package/dist/ui/composed/agno-chat/context.d.ts +4 -3
  17. package/dist/ui/composed/agno-chat/context.d.ts.map +1 -1
  18. package/dist/ui/composed/agno-chat/messages.d.ts +9 -15
  19. package/dist/ui/composed/agno-chat/messages.d.ts.map +1 -1
  20. package/dist/ui/composed/agno-chat/render-tool.d.ts +11 -0
  21. package/dist/ui/composed/agno-chat/render-tool.d.ts.map +1 -0
  22. package/dist/ui/composed/agno-chat/tool-building-blocks.d.ts +7 -0
  23. package/dist/ui/composed/agno-chat/tool-building-blocks.d.ts.map +1 -0
  24. package/dist/ui/composed/agno-message/content.d.ts +2 -0
  25. package/dist/ui/composed/agno-message/content.d.ts.map +1 -0
  26. package/dist/ui/composed/agno-message/context.d.ts +21 -0
  27. package/dist/ui/composed/agno-message/context.d.ts.map +1 -0
  28. package/dist/ui/composed/agno-message/footer.d.ts +6 -0
  29. package/dist/ui/composed/agno-message/footer.d.ts.map +1 -0
  30. package/dist/ui/composed/agno-message/index.d.ts +13 -0
  31. package/dist/ui/composed/agno-message/index.d.ts.map +1 -0
  32. package/dist/ui/composed/agno-message/media.d.ts +2 -0
  33. package/dist/ui/composed/agno-message/media.d.ts.map +1 -0
  34. package/dist/ui/composed/agno-message/message.d.ts +41 -0
  35. package/dist/ui/composed/agno-message/message.d.ts.map +1 -0
  36. package/dist/ui/composed/agno-message/reasoning.d.ts +2 -0
  37. package/dist/ui/composed/agno-message/reasoning.d.ts.map +1 -0
  38. package/dist/ui/composed/agno-message/references.d.ts +2 -0
  39. package/dist/ui/composed/agno-message/references.d.ts.map +1 -0
  40. package/dist/ui/composed/agno-message/tools.d.ts +7 -0
  41. package/dist/ui/composed/agno-message/tools.d.ts.map +1 -0
  42. package/dist/ui/composed/generative-components/card-grid.d.ts +4 -0
  43. package/dist/ui/composed/generative-components/card-grid.d.ts.map +1 -0
  44. package/dist/ui/composed/generative-components/charts.d.ts +7 -0
  45. package/dist/ui/composed/generative-components/charts.d.ts.map +1 -0
  46. package/dist/ui/composed/index.d.ts +10 -0
  47. package/dist/ui/composed/index.d.ts.map +1 -1
  48. package/dist/ui/index.d.ts +12 -0
  49. package/dist/ui/index.d.ts.map +1 -1
  50. package/dist/ui/primitives/badge.d.ts +1 -1
  51. package/dist/ui/primitives/button.d.ts +1 -1
  52. package/dist/ui/primitives/command.d.ts +1 -1
  53. package/dist/ui.js +1305 -640
  54. package/dist/ui.js.map +20 -7
  55. package/dist/ui.mjs +1306 -636
  56. package/dist/ui.mjs.map +20 -7
  57. package/package.json +8 -3
  58. package/dist/components/GenerativeUIRenderer.d.ts +0 -21
  59. package/dist/components/GenerativeUIRenderer.d.ts.map +0 -1
  60. package/dist/utils/component-registry.d.ts +0 -63
  61. package/dist/utils/component-registry.d.ts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,3 +1,11 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
1
9
  // src/context/AgnoContext.tsx
2
10
  import { createContext, useContext, useMemo, useEffect } from "react";
3
11
  import { AgnoClient } from "@rodrigocoliveira/agno-client";
@@ -53,1026 +61,2344 @@ function ToolHandlerProvider({ handlers: initialHandlers = {}, children }) {
53
61
  function useToolHandlers() {
54
62
  return useContext2(ToolHandlerContext);
55
63
  }
56
- // src/components/GenerativeUIRenderer.tsx
57
- import React3 from "react";
58
-
59
- // src/utils/component-registry.ts
60
- class ComponentRegistry {
61
- static instance;
62
- components = new Map;
63
- constructor() {}
64
- static getInstance() {
65
- if (!ComponentRegistry.instance) {
66
- ComponentRegistry.instance = new ComponentRegistry;
67
- }
68
- return ComponentRegistry.instance;
69
- }
70
- register(type, renderer) {
71
- this.components.set(type, renderer);
72
- }
73
- registerBatch(components) {
74
- Object.entries(components).forEach(([type, renderer]) => {
75
- this.register(type, renderer);
76
- });
77
- }
78
- get(type) {
79
- return this.components.get(type);
80
- }
81
- has(type) {
82
- return this.components.has(type);
83
- }
84
- unregister(type) {
85
- this.components.delete(type);
86
- }
87
- getRegisteredTypes() {
88
- return Array.from(this.components.keys());
89
- }
90
- clear() {
91
- this.components.clear();
92
- }
64
+ // src/utils/ui-helpers.ts
65
+ function createBarChart(data, xKey, bars, options) {
66
+ return {
67
+ type: "chart",
68
+ component: "BarChart",
69
+ layout: options?.layout,
70
+ title: options?.title,
71
+ description: options?.description,
72
+ props: {
73
+ data,
74
+ xKey,
75
+ bars: bars.map((bar) => ({
76
+ key: bar.key,
77
+ label: bar.label || bar.key,
78
+ color: bar.color
79
+ })),
80
+ showLegend: options?.showLegend ?? true,
81
+ showGrid: options?.showGrid ?? true,
82
+ height: options?.height,
83
+ width: options?.width
84
+ }
85
+ };
93
86
  }
94
- function getComponentRegistry() {
95
- return ComponentRegistry.getInstance();
87
+ function createLineChart(data, xKey, lines, options) {
88
+ return {
89
+ type: "chart",
90
+ component: "LineChart",
91
+ layout: options?.layout,
92
+ title: options?.title,
93
+ description: options?.description,
94
+ props: {
95
+ data,
96
+ xKey,
97
+ lines: lines.map((line) => ({
98
+ key: line.key,
99
+ label: line.label || line.key,
100
+ color: line.color
101
+ })),
102
+ showLegend: options?.showLegend ?? true,
103
+ showGrid: options?.showGrid ?? true,
104
+ height: options?.height,
105
+ width: options?.width
106
+ }
107
+ };
96
108
  }
97
- function registerChartComponent(name, renderer) {
98
- getComponentRegistry().register(`chart:${name}`, renderer);
109
+ function createPieChart(data, dataKey, nameKey, options) {
110
+ return {
111
+ type: "chart",
112
+ component: "PieChart",
113
+ layout: options?.layout,
114
+ title: options?.title,
115
+ description: options?.description,
116
+ props: {
117
+ data,
118
+ pie: {
119
+ dataKey,
120
+ nameKey,
121
+ label: options?.showLabel ?? true
122
+ },
123
+ showLegend: options?.showLegend ?? true,
124
+ height: options?.height || 400,
125
+ width: options?.width
126
+ }
127
+ };
99
128
  }
100
- function getChartComponent(name) {
101
- return getComponentRegistry().get(`chart:${name}`);
129
+ function createAreaChart(data, xKey, areas, options) {
130
+ return {
131
+ type: "chart",
132
+ component: "AreaChart",
133
+ layout: options?.layout,
134
+ title: options?.title,
135
+ description: options?.description,
136
+ props: {
137
+ data,
138
+ xKey,
139
+ areas: areas.map((area) => ({
140
+ key: area.key,
141
+ label: area.label || area.key,
142
+ color: area.color
143
+ })),
144
+ showLegend: options?.showLegend ?? true,
145
+ showGrid: options?.showGrid ?? true,
146
+ height: options?.height,
147
+ width: options?.width
148
+ }
149
+ };
102
150
  }
103
-
104
- // src/hooks/useAgnoToolExecution.ts
105
- import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2, useMemo as useMemo2 } from "react";
106
- var customRenderRegistry = new Map;
107
- function registerCustomRender(renderFn) {
108
- const key = `custom-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
109
- customRenderRegistry.set(key, renderFn);
110
- return key;
151
+ function createCardGrid(cards, options) {
152
+ return {
153
+ type: "card-grid",
154
+ layout: options?.layout,
155
+ title: options?.title,
156
+ description: options?.description,
157
+ props: {
158
+ cards,
159
+ columns: options?.columns || { default: 1, md: 2, lg: 3 },
160
+ variant: options?.variant || "default"
161
+ }
162
+ };
111
163
  }
112
- function getCustomRender(key) {
113
- return customRenderRegistry.get(key);
164
+ function createCard(id, title, description, options) {
165
+ return {
166
+ id,
167
+ title,
168
+ description,
169
+ image: options?.image,
170
+ metadata: options?.metadata,
171
+ actions: options?.actions
172
+ };
114
173
  }
115
- function isToolHandlerResult(value) {
116
- return value && typeof value === "object" && (("data" in value) || ("ui" in value));
174
+ function createTable(data, columns, options) {
175
+ return {
176
+ type: "table",
177
+ layout: options?.layout,
178
+ title: options?.title,
179
+ description: options?.description,
180
+ props: {
181
+ data,
182
+ columns,
183
+ sortable: options?.sortable ?? true,
184
+ filterable: options?.filterable,
185
+ pagination: options?.pagination,
186
+ density: options?.density || "comfortable"
187
+ }
188
+ };
117
189
  }
118
- function isUIComponentSpec(value) {
119
- return value && typeof value === "object" && "type" in value;
190
+ function createColumn(key, header, options) {
191
+ return {
192
+ key,
193
+ header,
194
+ width: options?.width,
195
+ sortable: options?.sortable,
196
+ cellType: options?.cellType || "text",
197
+ format: options?.format
198
+ };
120
199
  }
121
- function processToolResult(result, _tool) {
122
- if (isToolHandlerResult(result)) {
123
- const { data, ui } = result;
124
- let uiComponent = undefined;
125
- if (ui) {
126
- if (ui.type === "custom" && typeof ui.render === "function") {
127
- const renderKey = registerCustomRender(ui.render);
128
- uiComponent = {
129
- ...ui,
130
- renderKey,
131
- render: undefined
132
- };
133
- } else {
134
- uiComponent = ui;
135
- }
200
+ function createMarkdown(content, options) {
201
+ return {
202
+ type: "markdown",
203
+ layout: options?.layout,
204
+ title: options?.title,
205
+ description: options?.description,
206
+ props: {
207
+ content,
208
+ syntaxHighlight: options?.syntaxHighlight ?? true
136
209
  }
137
- return {
138
- resultData: typeof data === "string" ? data : JSON.stringify(data),
139
- uiComponent
140
- };
210
+ };
211
+ }
212
+ function createArtifact(content, options) {
213
+ return {
214
+ type: "artifact",
215
+ title: options?.title,
216
+ description: options?.description,
217
+ props: {
218
+ content,
219
+ variant: options?.variant || "default"
220
+ }
221
+ };
222
+ }
223
+ function createSmartChart(data, options) {
224
+ if (!data || data.length === 0) {
225
+ return createBarChart([], "", [], options);
141
226
  }
142
- if (isUIComponentSpec(result)) {
143
- let uiComponent;
144
- if (result.type === "custom" && typeof result.render === "function") {
145
- const renderKey = registerCustomRender(result.render);
146
- uiComponent = {
147
- ...result,
148
- renderKey,
149
- render: undefined
150
- };
151
- } else {
152
- uiComponent = result;
227
+ const firstItem = data[0];
228
+ const keys = Object.keys(firstItem);
229
+ const xKey = options?.xKey || keys.find((k) => ["name", "label", "category", "date", "time", "month", "year"].includes(k.toLowerCase())) || keys[0];
230
+ const numericKeys = keys.filter((k) => k !== xKey && typeof firstItem[k] === "number");
231
+ const yKeys = options?.yKeys || numericKeys;
232
+ if (options?.preferredType) {
233
+ switch (options.preferredType) {
234
+ case "bar":
235
+ return createBarChart(data, xKey, yKeys.map((key) => ({ key })), options);
236
+ case "line":
237
+ return createLineChart(data, xKey, yKeys.map((key) => ({ key })), options);
238
+ case "area":
239
+ return createAreaChart(data, xKey, yKeys.map((key) => ({ key })), options);
240
+ case "pie":
241
+ return createPieChart(data, yKeys[0], xKey, options);
153
242
  }
154
- return {
155
- resultData: JSON.stringify(result),
156
- uiComponent
157
- };
158
243
  }
159
- return {
160
- resultData: typeof result === "string" ? result : JSON.stringify(result),
161
- uiComponent: undefined
162
- };
244
+ if (yKeys.length === 1 && typeof firstItem[xKey] === "string") {
245
+ return createPieChart(data, yKeys[0], xKey, options);
246
+ }
247
+ if (xKey.toLowerCase().includes("date") || xKey.toLowerCase().includes("time") || xKey.toLowerCase().includes("month") || xKey.toLowerCase().includes("year")) {
248
+ return createLineChart(data, xKey, yKeys.map((key) => ({ key })), options);
249
+ }
250
+ return createBarChart(data, xKey, yKeys.map((key) => ({ key })), options);
163
251
  }
164
- function useAgnoToolExecution(handlers = {}, autoExecute = true, options) {
252
+ function createToolResult(data, ui) {
253
+ return { data, ui };
254
+ }
255
+ function resultWithBarChart(data, xKey, bars, options) {
256
+ return createToolResult(data, createBarChart(data, xKey, bars, options));
257
+ }
258
+ function resultWithSmartChart(data, options) {
259
+ return createToolResult(data, createSmartChart(data, options));
260
+ }
261
+ function resultWithCardGrid(cards, options) {
262
+ return createToolResult(cards, createCardGrid(cards, options));
263
+ }
264
+ function resultWithTable(data, columns, options) {
265
+ return createToolResult(data, createTable(data, columns, options));
266
+ }
267
+ // src/hooks/useAgnoChat.ts
268
+ import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
269
+ function useAgnoChat() {
165
270
  const client = useAgnoClient();
166
- const toolHandlerContext = useToolHandlers();
167
- const isTeamMode = client.getConfig().mode === "team";
168
- useEffect2(() => {
169
- if (isTeamMode) {
170
- console.warn("[useAgnoToolExecution] HITL (Human-in-the-Loop) frontend tool execution is not supported for teams. " + "Only agents support the continue endpoint. This hook will not function in team mode.");
171
- }
172
- }, [isTeamMode]);
173
- const mergedHandlers = useMemo2(() => {
174
- const globalHandlers = toolHandlerContext?.handlers || {};
175
- return { ...globalHandlers, ...handlers };
176
- }, [toolHandlerContext?.handlers, handlers]);
177
- const [pendingTools, setPendingTools] = useState2([]);
178
- const [isPaused, setIsPaused] = useState2(false);
179
- const [isExecuting, setIsExecuting] = useState2(false);
180
- const [executionError, setExecutionError] = useState2();
271
+ const [messages, setMessages] = useState2(client.getMessages());
272
+ const [state, setState] = useState2(client.getState());
181
273
  useEffect2(() => {
182
- if (isTeamMode) {
183
- return;
184
- }
185
- const handleRunPaused = (event) => {
186
- setIsPaused(true);
187
- setPendingTools(event.tools);
188
- setExecutionError(undefined);
274
+ const handleMessageUpdate = (updatedMessages) => {
275
+ setMessages(updatedMessages);
189
276
  };
190
- const handleRunContinued = () => {
191
- setIsPaused(false);
192
- setPendingTools([]);
193
- setIsExecuting(false);
194
- setExecutionError(undefined);
277
+ const handleMessageComplete = (updatedMessages) => {
278
+ setMessages(updatedMessages);
195
279
  };
196
- client.on("run:paused", handleRunPaused);
197
- client.on("run:continued", handleRunContinued);
198
- return () => {
199
- client.off("run:paused", handleRunPaused);
200
- client.off("run:continued", handleRunContinued);
280
+ const handleMessageRefreshed = (updatedMessages) => {
281
+ setMessages(updatedMessages);
201
282
  };
202
- }, [client, isTeamMode]);
203
- const executeAndContinue = useCallback2(async () => {
204
- if (!isPaused || pendingTools.length === 0) {
205
- console.warn("[useAgnoToolExecution] Cannot execute: no pending tools");
206
- return;
207
- }
208
- setIsExecuting(true);
209
- setExecutionError(undefined);
210
- try {
211
- const updatedTools = await Promise.all(pendingTools.map(async (tool) => {
212
- const handler = mergedHandlers[tool.tool_name];
213
- if (!handler) {
214
- return {
215
- ...tool,
216
- result: JSON.stringify({
217
- error: `No handler registered for ${tool.tool_name}`
218
- })
219
- };
220
- }
221
- try {
222
- const result = await handler(tool.tool_args);
223
- const { resultData, uiComponent } = processToolResult(result, tool);
224
- return {
225
- ...tool,
226
- result: resultData,
227
- ui_component: uiComponent
228
- };
229
- } catch (error) {
230
- return {
231
- ...tool,
232
- result: JSON.stringify({
233
- error: error instanceof Error ? error.message : String(error)
234
- })
235
- };
283
+ const handleStateChange = (newState) => {
284
+ setState(newState);
285
+ };
286
+ const handleUIRender = (event) => {
287
+ const { tools } = event;
288
+ for (const tool of tools) {
289
+ if (tool.ui_component) {
290
+ client.hydrateToolCallUI(tool.tool_call_id, tool.ui_component);
236
291
  }
237
- }));
238
- const toolsWithUI = updatedTools.filter((t) => t.ui_component);
239
- if (toolsWithUI.length > 0) {
240
- client.emit("ui:render", {
241
- tools: updatedTools,
242
- runId: client.getState().pausedRunId
243
- });
244
292
  }
245
- client.addToolCallsToLastMessage(updatedTools);
246
- await client.continueRun(updatedTools);
247
- } catch (error) {
248
- const errorMessage = error instanceof Error ? error.message : String(error);
249
- setExecutionError(errorMessage);
250
- setIsExecuting(false);
251
- throw error;
293
+ };
294
+ const handleRunCancelled = () => {};
295
+ client.on("message:update", handleMessageUpdate);
296
+ client.on("message:complete", handleMessageComplete);
297
+ client.on("message:refreshed", handleMessageRefreshed);
298
+ client.on("state:change", handleStateChange);
299
+ client.on("ui:render", handleUIRender);
300
+ client.on("run:cancelled", handleRunCancelled);
301
+ setMessages(client.getMessages());
302
+ setState(client.getState());
303
+ return () => {
304
+ client.off("message:update", handleMessageUpdate);
305
+ client.off("message:complete", handleMessageComplete);
306
+ client.off("message:refreshed", handleMessageRefreshed);
307
+ client.off("state:change", handleStateChange);
308
+ client.off("ui:render", handleUIRender);
309
+ client.off("run:cancelled", handleRunCancelled);
310
+ };
311
+ }, [client]);
312
+ const sendMessage = useCallback2(async (message, options) => {
313
+ try {
314
+ await client.sendMessage(message, options);
315
+ } catch (err) {
316
+ throw err;
252
317
  }
253
- }, [client, mergedHandlers, isPaused, pendingTools]);
254
- useEffect2(() => {
255
- const handleSessionLoaded = async (_sessionId) => {
256
- const messages = client.getMessages();
257
- for (const message of messages) {
258
- if (!message.tool_calls)
259
- continue;
260
- for (const tool of message.tool_calls) {
261
- if (tool.ui_component)
262
- continue;
263
- if (options?.skipHydration?.includes(tool.tool_name))
264
- continue;
265
- const handler = mergedHandlers[tool.tool_name];
266
- if (!handler)
267
- continue;
268
- try {
269
- const result = await handler(tool.tool_args);
270
- const { uiComponent } = processToolResult(result, tool);
271
- if (uiComponent) {
272
- client.hydrateToolCallUI(tool.tool_call_id, uiComponent);
273
- }
274
- } catch (err) {
275
- console.error(`Failed to hydrate UI for ${tool.tool_name}:`, err);
276
- }
277
- }
278
- }
318
+ }, [client]);
319
+ const clearMessages = useCallback2(() => {
320
+ client.clearMessages();
321
+ setMessages([]);
322
+ }, [client]);
323
+ const cancelRun = useCallback2(async () => {
324
+ await client.cancelRun();
325
+ }, [client]);
326
+ return {
327
+ messages,
328
+ sendMessage,
329
+ clearMessages,
330
+ cancelRun,
331
+ isStreaming: state.isStreaming,
332
+ isRefreshing: state.isRefreshing,
333
+ isPaused: state.isPaused,
334
+ isCancelling: state.isCancelling,
335
+ currentRunId: state.currentRunId,
336
+ error: state.errorMessage,
337
+ state
338
+ };
339
+ }
340
+ // src/hooks/useAgnoSession.ts
341
+ import { useState as useState3, useEffect as useEffect3, useCallback as useCallback3 } from "react";
342
+ function useAgnoSession() {
343
+ const client = useAgnoClient();
344
+ const [sessions, setSessions] = useState3([]);
345
+ const [currentSessionId, setCurrentSessionId] = useState3(client.getConfig().sessionId);
346
+ const [isLoading, setIsLoading] = useState3(false);
347
+ const [error, setError] = useState3();
348
+ useEffect3(() => {
349
+ const handleSessionLoaded = (sessionId) => {
350
+ setCurrentSessionId(sessionId);
351
+ };
352
+ const handleSessionCreated = (session) => {
353
+ setSessions((prev) => [session, ...prev]);
354
+ setCurrentSessionId(session.session_id);
355
+ };
356
+ const handleStateChange = () => {
357
+ const config = client.getConfig();
358
+ setCurrentSessionId(config.sessionId);
359
+ setSessions(client.getState().sessions);
279
360
  };
280
361
  client.on("session:loaded", handleSessionLoaded);
362
+ client.on("session:created", handleSessionCreated);
363
+ client.on("state:change", handleStateChange);
364
+ setSessions(client.getState().sessions);
365
+ setCurrentSessionId(client.getConfig().sessionId);
281
366
  return () => {
282
367
  client.off("session:loaded", handleSessionLoaded);
368
+ client.off("session:created", handleSessionCreated);
369
+ client.off("state:change", handleStateChange);
283
370
  };
284
- }, [client, mergedHandlers]);
285
- const executeTools = useCallback2(async (tools) => {
286
- return Promise.all(tools.map(async (tool) => {
287
- const handler = mergedHandlers[tool.tool_name];
288
- if (!handler)
289
- return tool;
290
- try {
291
- const result = await handler(tool.tool_args);
292
- const { resultData, uiComponent } = processToolResult(result, tool);
293
- return {
294
- ...tool,
295
- result: resultData,
296
- ui_component: uiComponent
297
- };
298
- } catch (error) {
299
- return {
300
- ...tool,
301
- result: JSON.stringify({
302
- error: error instanceof Error ? error.message : String(error)
303
- })
304
- };
305
- }
306
- }));
307
- }, [mergedHandlers]);
308
- const continueWithResults = useCallback2(async (tools, options2) => {
309
- if (!isPaused) {
310
- throw new Error("No paused run to continue");
371
+ }, [client]);
372
+ const loadSession = useCallback3(async (sessionId, options) => {
373
+ setIsLoading(true);
374
+ setError(undefined);
375
+ try {
376
+ const messages = await client.loadSession(sessionId, options);
377
+ setCurrentSessionId(sessionId);
378
+ return messages;
379
+ } catch (err) {
380
+ const errorMessage = err instanceof Error ? err.message : String(err);
381
+ setError(errorMessage);
382
+ throw err;
383
+ } finally {
384
+ setIsLoading(false);
311
385
  }
312
- setIsExecuting(true);
386
+ }, [client]);
387
+ const fetchSessions = useCallback3(async (options) => {
388
+ setIsLoading(true);
389
+ setError(undefined);
313
390
  try {
314
- await client.continueRun(tools, options2);
315
- } catch (error) {
316
- setIsExecuting(false);
317
- throw error;
391
+ const fetchedSessions = await client.fetchSessions(options);
392
+ setSessions(fetchedSessions);
393
+ return fetchedSessions;
394
+ } catch (err) {
395
+ const errorMessage = err instanceof Error ? err.message : String(err);
396
+ setError(errorMessage);
397
+ throw err;
398
+ } finally {
399
+ setIsLoading(false);
318
400
  }
319
- }, [client, isPaused]);
320
- useEffect2(() => {
321
- if (autoExecute && isPaused && !isExecuting && pendingTools.length > 0) {
322
- executeAndContinue();
401
+ }, [client]);
402
+ const getSessionById = useCallback3(async (sessionId, options) => {
403
+ setIsLoading(true);
404
+ setError(undefined);
405
+ try {
406
+ return await client.getSessionById(sessionId, options);
407
+ } catch (err) {
408
+ const errorMessage = err instanceof Error ? err.message : String(err);
409
+ setError(errorMessage);
410
+ throw err;
411
+ } finally {
412
+ setIsLoading(false);
323
413
  }
324
- }, [autoExecute, isPaused, isExecuting, pendingTools.length, executeAndContinue]);
325
- return {
326
- isPaused,
327
- isExecuting,
328
- pendingTools,
329
- executeAndContinue,
330
- executeTools,
331
- continueWithResults,
332
- executionError
333
- };
334
- }
335
-
336
- // src/components/GenerativeUIRenderer.tsx
337
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
338
-
339
- class UIErrorBoundary extends React3.Component {
340
- constructor(props) {
341
- super(props);
342
- this.state = { hasError: false };
343
- }
344
- static getDerivedStateFromError(error) {
345
- return { hasError: true, error };
346
- }
347
- componentDidCatch(error, errorInfo) {
348
- console.error("[GenerativeUIRenderer] Error rendering component:", error, errorInfo);
349
- this.props.onError?.(error);
350
- }
351
- render() {
352
- if (this.state.hasError) {
353
- return this.props.fallback || /* @__PURE__ */ jsxs("div", {
354
- className: "p-4 border border-red-300 rounded-md bg-red-50 text-red-800",
355
- children: [
356
- /* @__PURE__ */ jsx3("p", {
357
- className: "font-semibold",
358
- children: "Failed to render UI component"
359
- }),
360
- /* @__PURE__ */ jsx3("p", {
361
- className: "text-sm mt-1",
362
- children: this.state.error?.message || "Unknown error"
363
- })
364
- ]
365
- });
414
+ }, [client]);
415
+ const getRunById = useCallback3(async (sessionId, runId, options) => {
416
+ setIsLoading(true);
417
+ setError(undefined);
418
+ try {
419
+ return await client.getRunById(sessionId, runId, options);
420
+ } catch (err) {
421
+ const errorMessage = err instanceof Error ? err.message : String(err);
422
+ setError(errorMessage);
423
+ throw err;
424
+ } finally {
425
+ setIsLoading(false);
366
426
  }
367
- return this.props.children;
368
- }
369
- }
370
- function GenerativeUIRenderer({
371
- spec,
372
- className,
373
- onError
374
- }) {
375
- const registry = getComponentRegistry();
376
- if (spec.type === "custom") {
377
- const customSpec = spec;
378
- if (customSpec.renderKey) {
379
- const renderFn = getCustomRender(customSpec.renderKey);
380
- if (renderFn) {
381
- return /* @__PURE__ */ jsx3(UIErrorBoundary, {
382
- onError,
383
- children: /* @__PURE__ */ jsx3("div", {
384
- className,
385
- children: renderFn(customSpec.props || {})
386
- })
387
- });
388
- }
427
+ }, [client]);
428
+ const createSession = useCallback3(async (request, options) => {
429
+ setIsLoading(true);
430
+ setError(undefined);
431
+ try {
432
+ const session = await client.createSession(request, options);
433
+ return session;
434
+ } catch (err) {
435
+ const errorMessage = err instanceof Error ? err.message : String(err);
436
+ setError(errorMessage);
437
+ throw err;
438
+ } finally {
439
+ setIsLoading(false);
389
440
  }
390
- return /* @__PURE__ */ jsxs("div", {
391
- className: `p-4 border border-yellow-300 rounded-md bg-yellow-50 text-yellow-800 ${className || ""}`,
392
- children: [
393
- /* @__PURE__ */ jsx3("p", {
394
- className: "font-semibold",
395
- children: "Custom component not available"
396
- }),
397
- /* @__PURE__ */ jsx3("p", {
398
- className: "text-sm mt-1",
399
- children: "The custom render function for this component is not available."
400
- })
401
- ]
402
- });
403
- }
404
- if (spec.type === "chart") {
405
- const chartSpec = spec;
406
- const chartType = `chart:${chartSpec.component}`;
407
- if (registry.has(chartType)) {
408
- const ChartRenderer = registry.get(chartType);
409
- return /* @__PURE__ */ jsx3(UIErrorBoundary, {
410
- onError,
411
- children: /* @__PURE__ */ jsxs("div", {
412
- className,
413
- children: [
414
- chartSpec.title && /* @__PURE__ */ jsx3("h3", {
415
- className: "font-semibold mb-2",
416
- children: chartSpec.title
417
- }),
418
- chartSpec.description && /* @__PURE__ */ jsx3("p", {
419
- className: "text-sm text-gray-600 mb-4",
420
- children: chartSpec.description
421
- }),
422
- /* @__PURE__ */ jsx3(ChartRenderer, {
423
- ...chartSpec.props
424
- })
425
- ]
426
- })
427
- });
441
+ }, [client]);
442
+ const updateSession = useCallback3(async (sessionId, request, options) => {
443
+ setIsLoading(true);
444
+ setError(undefined);
445
+ try {
446
+ return await client.updateSession(sessionId, request, options);
447
+ } catch (err) {
448
+ const errorMessage = err instanceof Error ? err.message : String(err);
449
+ setError(errorMessage);
450
+ throw err;
451
+ } finally {
452
+ setIsLoading(false);
428
453
  }
429
- return /* @__PURE__ */ jsxs("div", {
430
- className: `p-4 border border-gray-300 rounded-md ${className || ""}`,
431
- children: [
432
- /* @__PURE__ */ jsx3("p", {
433
- className: "font-semibold mb-2",
434
- children: chartSpec.title || "Chart Data"
435
- }),
436
- chartSpec.description && /* @__PURE__ */ jsx3("p", {
437
- className: "text-sm text-gray-600 mb-2",
438
- children: chartSpec.description
439
- }),
440
- /* @__PURE__ */ jsx3("pre", {
441
- className: "text-xs bg-gray-100 p-2 rounded overflow-auto",
442
- children: JSON.stringify(chartSpec.props.data, null, 2)
443
- })
444
- ]
445
- });
446
- }
447
- if (spec.type === "card-grid") {
448
- const cardGridSpec = spec;
449
- if (registry.has("card-grid")) {
450
- const CardGridRenderer = registry.get("card-grid");
451
- return /* @__PURE__ */ jsx3(UIErrorBoundary, {
452
- onError,
453
- children: /* @__PURE__ */ jsxs("div", {
454
- className,
455
- children: [
456
- cardGridSpec.title && /* @__PURE__ */ jsx3("h3", {
457
- className: "font-semibold mb-2",
458
- children: cardGridSpec.title
459
- }),
460
- cardGridSpec.description && /* @__PURE__ */ jsx3("p", {
461
- className: "text-sm text-gray-600 mb-4",
462
- children: cardGridSpec.description
463
- }),
464
- /* @__PURE__ */ jsx3(CardGridRenderer, {
465
- ...cardGridSpec.props
466
- })
467
- ]
468
- })
469
- });
454
+ }, [client]);
455
+ const renameSession = useCallback3(async (sessionId, newName, options) => {
456
+ setIsLoading(true);
457
+ setError(undefined);
458
+ try {
459
+ return await client.renameSession(sessionId, newName, options);
460
+ } catch (err) {
461
+ const errorMessage = err instanceof Error ? err.message : String(err);
462
+ setError(errorMessage);
463
+ throw err;
464
+ } finally {
465
+ setIsLoading(false);
470
466
  }
471
- }
472
- if (spec.type === "table") {
473
- const tableSpec = spec;
474
- if (registry.has("table")) {
475
- const TableRenderer = registry.get("table");
476
- return /* @__PURE__ */ jsx3(UIErrorBoundary, {
477
- onError,
478
- children: /* @__PURE__ */ jsxs("div", {
479
- className,
480
- children: [
481
- tableSpec.title && /* @__PURE__ */ jsx3("h3", {
482
- className: "font-semibold mb-2",
483
- children: tableSpec.title
484
- }),
485
- tableSpec.description && /* @__PURE__ */ jsx3("p", {
486
- className: "text-sm text-gray-600 mb-4",
487
- children: tableSpec.description
488
- }),
489
- /* @__PURE__ */ jsx3(TableRenderer, {
490
- ...tableSpec.props
491
- })
492
- ]
493
- })
494
- });
467
+ }, [client]);
468
+ const deleteSession = useCallback3(async (sessionId, options) => {
469
+ setIsLoading(true);
470
+ setError(undefined);
471
+ try {
472
+ await client.deleteSession(sessionId, options);
473
+ } catch (err) {
474
+ const errorMessage = err instanceof Error ? err.message : String(err);
475
+ setError(errorMessage);
476
+ throw err;
477
+ } finally {
478
+ setIsLoading(false);
495
479
  }
496
- }
497
- if (spec.type === "markdown") {
498
- const markdownSpec = spec;
499
- if (registry.has("markdown")) {
500
- const MarkdownRenderer = registry.get("markdown");
501
- return /* @__PURE__ */ jsx3(UIErrorBoundary, {
502
- onError,
503
- children: /* @__PURE__ */ jsx3("div", {
504
- className,
505
- children: /* @__PURE__ */ jsx3(MarkdownRenderer, {
506
- ...markdownSpec.props
507
- })
508
- })
509
- });
480
+ }, [client]);
481
+ const deleteMultipleSessions = useCallback3(async (sessionIds, options) => {
482
+ setIsLoading(true);
483
+ setError(undefined);
484
+ try {
485
+ await client.deleteMultipleSessions(sessionIds, options);
486
+ } catch (err) {
487
+ const errorMessage = err instanceof Error ? err.message : String(err);
488
+ setError(errorMessage);
489
+ throw err;
490
+ } finally {
491
+ setIsLoading(false);
510
492
  }
511
- return /* @__PURE__ */ jsx3("div", {
512
- className,
513
- children: markdownSpec.props.content
514
- });
515
- }
516
- if (spec.type === "artifact") {
517
- const artifactSpec = spec;
518
- return /* @__PURE__ */ jsx3(UIErrorBoundary, {
519
- onError,
520
- children: /* @__PURE__ */ jsxs("div", {
521
- className: `p-4 border rounded-md ${className || ""}`,
522
- children: [
523
- artifactSpec.title && /* @__PURE__ */ jsx3("h3", {
524
- className: "font-semibold mb-4",
525
- children: artifactSpec.title
526
- }),
527
- artifactSpec.description && /* @__PURE__ */ jsx3("p", {
528
- className: "text-sm text-gray-600 mb-4",
529
- children: artifactSpec.description
530
- }),
531
- /* @__PURE__ */ jsx3("div", {
532
- className: "space-y-4",
533
- children: artifactSpec.props.content?.map((childSpec, index) => /* @__PURE__ */ jsx3(GenerativeUIRenderer, {
534
- spec: childSpec,
535
- onError
536
- }, index))
537
- })
538
- ]
539
- })
540
- });
541
- }
542
- return /* @__PURE__ */ jsxs("div", {
543
- className: `p-4 border border-gray-300 rounded-md ${className || ""}`,
544
- children: [
545
- /* @__PURE__ */ jsx3("p", {
546
- className: "font-semibold",
547
- children: "Unsupported UI component"
548
- }),
549
- /* @__PURE__ */ jsxs("p", {
550
- className: "text-sm text-gray-600 mt-1",
551
- children: [
552
- "Component type: ",
553
- spec.type
554
- ]
555
- })
556
- ]
557
- });
558
- }
559
- // src/utils/ui-helpers.ts
560
- function createBarChart(data, xKey, bars, options) {
493
+ }, [client]);
561
494
  return {
562
- type: "chart",
563
- component: "BarChart",
564
- layout: options?.layout,
565
- title: options?.title,
566
- description: options?.description,
567
- props: {
568
- data,
569
- xKey,
570
- bars: bars.map((bar) => ({
571
- key: bar.key,
572
- label: bar.label || bar.key,
573
- color: bar.color
574
- })),
575
- showLegend: options?.showLegend ?? true,
576
- showGrid: options?.showGrid ?? true,
577
- height: options?.height,
578
- width: options?.width
579
- }
495
+ sessions,
496
+ currentSessionId,
497
+ loadSession,
498
+ fetchSessions,
499
+ getSessionById,
500
+ getRunById,
501
+ createSession,
502
+ updateSession,
503
+ renameSession,
504
+ deleteSession,
505
+ deleteMultipleSessions,
506
+ isLoading,
507
+ error
580
508
  };
581
509
  }
582
- function createLineChart(data, xKey, lines, options) {
583
- return {
584
- type: "chart",
585
- component: "LineChart",
586
- layout: options?.layout,
587
- title: options?.title,
588
- description: options?.description,
589
- props: {
590
- data,
591
- xKey,
592
- lines: lines.map((line) => ({
593
- key: line.key,
594
- label: line.label || line.key,
595
- color: line.color
596
- })),
597
- showLegend: options?.showLegend ?? true,
598
- showGrid: options?.showGrid ?? true,
599
- height: options?.height,
600
- width: options?.width
510
+ // src/hooks/useAgnoActions.ts
511
+ import { useState as useState4, useCallback as useCallback4 } from "react";
512
+ function useAgnoActions() {
513
+ const client = useAgnoClient();
514
+ const [isInitializing, setIsInitializing] = useState4(false);
515
+ const [error, setError] = useState4();
516
+ const initialize = useCallback4(async (options) => {
517
+ setIsInitializing(true);
518
+ setError(undefined);
519
+ try {
520
+ const result = await client.initialize(options);
521
+ return result;
522
+ } catch (err) {
523
+ const errorMessage = err instanceof Error ? err.message : String(err);
524
+ setError(errorMessage);
525
+ throw err;
526
+ } finally {
527
+ setIsInitializing(false);
528
+ }
529
+ }, [client]);
530
+ const checkStatus = useCallback4(async (options) => {
531
+ setError(undefined);
532
+ try {
533
+ return await client.checkStatus(options);
534
+ } catch (err) {
535
+ const errorMessage = err instanceof Error ? err.message : String(err);
536
+ setError(errorMessage);
537
+ return false;
538
+ }
539
+ }, [client]);
540
+ const fetchAgents = useCallback4(async (options) => {
541
+ setError(undefined);
542
+ try {
543
+ return await client.fetchAgents(options);
544
+ } catch (err) {
545
+ const errorMessage = err instanceof Error ? err.message : String(err);
546
+ setError(errorMessage);
547
+ throw err;
548
+ }
549
+ }, [client]);
550
+ const fetchTeams = useCallback4(async (options) => {
551
+ setError(undefined);
552
+ try {
553
+ return await client.fetchTeams(options);
554
+ } catch (err) {
555
+ const errorMessage = err instanceof Error ? err.message : String(err);
556
+ setError(errorMessage);
557
+ throw err;
601
558
  }
559
+ }, [client]);
560
+ const updateConfig = useCallback4((updates) => {
561
+ client.updateConfig(updates);
562
+ }, [client]);
563
+ return {
564
+ initialize,
565
+ checkStatus,
566
+ fetchAgents,
567
+ fetchTeams,
568
+ updateConfig,
569
+ isInitializing,
570
+ error
602
571
  };
603
572
  }
604
- function createPieChart(data, dataKey, nameKey, options) {
573
+ // src/hooks/useAgnoToolExecution.ts
574
+ import { useState as useState5, useEffect as useEffect4, useCallback as useCallback5, useMemo as useMemo2 } from "react";
575
+ function isToolHandlerResult(value) {
576
+ return value && typeof value === "object" && (("data" in value) || ("ui" in value));
577
+ }
578
+ function isUIComponentSpec(value) {
579
+ return value && typeof value === "object" && "type" in value;
580
+ }
581
+ function processToolResult(result, _tool) {
582
+ if (isToolHandlerResult(result)) {
583
+ const { data, ui } = result;
584
+ return {
585
+ resultData: typeof data === "string" ? data : JSON.stringify(data),
586
+ uiComponent: ui
587
+ };
588
+ }
589
+ if (isUIComponentSpec(result)) {
590
+ return {
591
+ resultData: JSON.stringify(result),
592
+ uiComponent: result
593
+ };
594
+ }
605
595
  return {
606
- type: "chart",
607
- component: "PieChart",
608
- layout: options?.layout,
609
- title: options?.title,
610
- description: options?.description,
611
- props: {
612
- data,
613
- pie: {
614
- dataKey,
615
- nameKey,
616
- label: options?.showLabel ?? true
617
- },
618
- showLegend: options?.showLegend ?? true,
619
- height: options?.height || 400,
620
- width: options?.width
621
- }
596
+ resultData: typeof result === "string" ? result : JSON.stringify(result),
597
+ uiComponent: undefined
622
598
  };
623
599
  }
624
- function createAreaChart(data, xKey, areas, options) {
625
- return {
626
- type: "chart",
627
- component: "AreaChart",
628
- layout: options?.layout,
629
- title: options?.title,
630
- description: options?.description,
631
- props: {
632
- data,
633
- xKey,
634
- areas: areas.map((area) => ({
635
- key: area.key,
636
- label: area.label || area.key,
637
- color: area.color
638
- })),
639
- showLegend: options?.showLegend ?? true,
640
- showGrid: options?.showGrid ?? true,
641
- height: options?.height,
642
- width: options?.width
600
+ function useAgnoToolExecution(handlers = {}, autoExecute = true, options) {
601
+ const client = useAgnoClient();
602
+ const toolHandlerContext = useToolHandlers();
603
+ const isTeamMode = client.getConfig().mode === "team";
604
+ useEffect4(() => {
605
+ if (isTeamMode) {
606
+ console.warn("[useAgnoToolExecution] HITL (Human-in-the-Loop) frontend tool execution is not supported for teams. " + "Only agents support the continue endpoint. This hook will not function in team mode.");
607
+ }
608
+ }, [isTeamMode]);
609
+ const mergedHandlers = useMemo2(() => {
610
+ const globalHandlers = toolHandlerContext?.handlers || {};
611
+ return { ...globalHandlers, ...handlers };
612
+ }, [toolHandlerContext?.handlers, handlers]);
613
+ const [pendingTools, setPendingTools] = useState5([]);
614
+ const [isPaused, setIsPaused] = useState5(false);
615
+ const [isExecuting, setIsExecuting] = useState5(false);
616
+ const [executionError, setExecutionError] = useState5();
617
+ useEffect4(() => {
618
+ if (isTeamMode) {
619
+ return;
620
+ }
621
+ const handleRunPaused = (event) => {
622
+ setIsPaused(true);
623
+ setPendingTools(event.tools);
624
+ setExecutionError(undefined);
625
+ };
626
+ const handleRunContinued = () => {
627
+ setIsPaused(false);
628
+ setPendingTools([]);
629
+ setIsExecuting(false);
630
+ setExecutionError(undefined);
631
+ };
632
+ client.on("run:paused", handleRunPaused);
633
+ client.on("run:continued", handleRunContinued);
634
+ return () => {
635
+ client.off("run:paused", handleRunPaused);
636
+ client.off("run:continued", handleRunContinued);
637
+ };
638
+ }, [client, isTeamMode]);
639
+ const executeAndContinue = useCallback5(async () => {
640
+ if (!isPaused || pendingTools.length === 0) {
641
+ console.warn("[useAgnoToolExecution] Cannot execute: no pending tools");
642
+ return;
643
643
  }
644
+ setIsExecuting(true);
645
+ setExecutionError(undefined);
646
+ try {
647
+ const updatedTools = await Promise.all(pendingTools.map(async (tool) => {
648
+ const handler = mergedHandlers[tool.tool_name];
649
+ if (!handler) {
650
+ return {
651
+ ...tool,
652
+ result: JSON.stringify({
653
+ error: `No handler registered for ${tool.tool_name}`
654
+ })
655
+ };
656
+ }
657
+ try {
658
+ const result = await handler(tool.tool_args);
659
+ const { resultData, uiComponent } = processToolResult(result, tool);
660
+ return {
661
+ ...tool,
662
+ result: resultData,
663
+ ui_component: uiComponent
664
+ };
665
+ } catch (error) {
666
+ return {
667
+ ...tool,
668
+ result: JSON.stringify({
669
+ error: error instanceof Error ? error.message : String(error)
670
+ })
671
+ };
672
+ }
673
+ }));
674
+ const toolsWithUI = updatedTools.filter((t) => t.ui_component);
675
+ if (toolsWithUI.length > 0) {
676
+ client.emit("ui:render", {
677
+ tools: updatedTools,
678
+ runId: client.getState().pausedRunId
679
+ });
680
+ }
681
+ client.addToolCallsToLastMessage(updatedTools);
682
+ await client.continueRun(updatedTools);
683
+ } catch (error) {
684
+ const errorMessage = error instanceof Error ? error.message : String(error);
685
+ setExecutionError(errorMessage);
686
+ setIsExecuting(false);
687
+ throw error;
688
+ }
689
+ }, [client, mergedHandlers, isPaused, pendingTools]);
690
+ useEffect4(() => {
691
+ const handleSessionLoaded = async (_sessionId) => {
692
+ const messages = client.getMessages();
693
+ for (const message of messages) {
694
+ if (!message.tool_calls)
695
+ continue;
696
+ for (const tool of message.tool_calls) {
697
+ if (tool.ui_component)
698
+ continue;
699
+ if (options?.skipToolsOnSessionLoad?.includes(tool.tool_name))
700
+ continue;
701
+ const handler = mergedHandlers[tool.tool_name];
702
+ if (!handler)
703
+ continue;
704
+ try {
705
+ const result = await handler(tool.tool_args);
706
+ const { uiComponent } = processToolResult(result, tool);
707
+ if (uiComponent) {
708
+ client.hydrateToolCallUI(tool.tool_call_id, uiComponent);
709
+ }
710
+ } catch (err) {
711
+ console.error(`Failed to hydrate UI for ${tool.tool_name}:`, err);
712
+ }
713
+ }
714
+ }
715
+ };
716
+ client.on("session:loaded", handleSessionLoaded);
717
+ return () => {
718
+ client.off("session:loaded", handleSessionLoaded);
719
+ };
720
+ }, [client, mergedHandlers]);
721
+ const executeTools = useCallback5(async (tools) => {
722
+ return Promise.all(tools.map(async (tool) => {
723
+ const handler = mergedHandlers[tool.tool_name];
724
+ if (!handler)
725
+ return tool;
726
+ try {
727
+ const result = await handler(tool.tool_args);
728
+ const { resultData, uiComponent } = processToolResult(result, tool);
729
+ return {
730
+ ...tool,
731
+ result: resultData,
732
+ ui_component: uiComponent
733
+ };
734
+ } catch (error) {
735
+ return {
736
+ ...tool,
737
+ result: JSON.stringify({
738
+ error: error instanceof Error ? error.message : String(error)
739
+ })
740
+ };
741
+ }
742
+ }));
743
+ }, [mergedHandlers]);
744
+ const continueWithResults = useCallback5(async (tools, options2) => {
745
+ if (!isPaused) {
746
+ throw new Error("No paused run to continue");
747
+ }
748
+ setIsExecuting(true);
749
+ try {
750
+ await client.continueRun(tools, options2);
751
+ } catch (error) {
752
+ setIsExecuting(false);
753
+ throw error;
754
+ }
755
+ }, [client, isPaused]);
756
+ useEffect4(() => {
757
+ if (autoExecute && isPaused && !isExecuting && pendingTools.length > 0) {
758
+ executeAndContinue();
759
+ }
760
+ }, [autoExecute, isPaused, isExecuting, pendingTools.length, executeAndContinue]);
761
+ return {
762
+ isPaused,
763
+ isExecuting,
764
+ pendingTools,
765
+ executeAndContinue,
766
+ executeTools,
767
+ continueWithResults,
768
+ executionError
644
769
  };
645
770
  }
646
- function createCardGrid(cards, options) {
647
- return {
648
- type: "card-grid",
649
- layout: options?.layout,
650
- title: options?.title,
651
- description: options?.description,
652
- props: {
653
- cards,
654
- columns: options?.columns || { default: 1, md: 2, lg: 3 },
655
- variant: options?.variant || "default"
656
- }
771
+ // src/ui/composed/agno-chat/render-tool.ts
772
+ function byToolName(map, fallback) {
773
+ return (tool, args) => {
774
+ if (!Object.prototype.hasOwnProperty.call(map, tool.tool_name)) {
775
+ return fallback ? fallback(tool, args) : args.defaultRender();
776
+ }
777
+ const entry = map[tool.tool_name];
778
+ if (entry === false)
779
+ return null;
780
+ return entry(tool, args);
657
781
  };
658
782
  }
659
- function createCard(id, title, description, options) {
660
- return {
661
- id,
662
- title,
663
- description,
664
- image: options?.image,
665
- metadata: options?.metadata,
666
- actions: options?.actions
783
+ // src/ui/primitives/badge.tsx
784
+ import { cva } from "class-variance-authority";
785
+
786
+ // src/ui/lib/cn.ts
787
+ import { clsx } from "clsx";
788
+ import { twMerge } from "tailwind-merge";
789
+ function cn(...inputs) {
790
+ return twMerge(clsx(inputs));
791
+ }
792
+
793
+ // src/ui/primitives/badge.tsx
794
+ import { jsx as jsx3 } from "react/jsx-runtime";
795
+ var badgeVariants = cva("inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", {
796
+ variants: {
797
+ variant: {
798
+ default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
799
+ secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
800
+ destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
801
+ outline: "text-foreground"
802
+ }
803
+ },
804
+ defaultVariants: {
805
+ variant: "default"
806
+ }
807
+ });
808
+ function Badge({ className, variant, ...props }) {
809
+ return /* @__PURE__ */ jsx3("div", {
810
+ className: cn(badgeVariants({ variant }), className),
811
+ ...props
812
+ });
813
+ }
814
+
815
+ // src/ui/primitives/collapsible.tsx
816
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
817
+ var Collapsible = CollapsiblePrimitive.Root;
818
+ var CollapsibleTrigger2 = CollapsiblePrimitive.CollapsibleTrigger;
819
+ var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
820
+
821
+ // src/ui/components/tool.tsx
822
+ import {
823
+ CheckCircleIcon,
824
+ ChevronDownIcon,
825
+ CircleIcon,
826
+ ClockIcon,
827
+ WrenchIcon,
828
+ XCircleIcon
829
+ } from "lucide-react";
830
+ import { isValidElement } from "react";
831
+
832
+ // src/ui/primitives/button.tsx
833
+ import * as React3 from "react";
834
+ import { Slot } from "@radix-ui/react-slot";
835
+ import { cva as cva2 } from "class-variance-authority";
836
+ import { jsx as jsx4 } from "react/jsx-runtime";
837
+ var buttonVariants = cva2("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", {
838
+ variants: {
839
+ variant: {
840
+ default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
841
+ destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
842
+ outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
843
+ secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
844
+ ghost: "hover:bg-accent hover:text-accent-foreground",
845
+ link: "text-primary underline-offset-4 hover:underline"
846
+ },
847
+ size: {
848
+ default: "h-9 px-4 py-2",
849
+ sm: "h-8 rounded-md px-3 text-xs",
850
+ lg: "h-10 rounded-md px-8",
851
+ icon: "h-9 w-9"
852
+ }
853
+ },
854
+ defaultVariants: {
855
+ variant: "default",
856
+ size: "default"
857
+ }
858
+ });
859
+ var Button = React3.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
860
+ const Comp = asChild ? Slot : "button";
861
+ return /* @__PURE__ */ jsx4(Comp, {
862
+ className: cn(buttonVariants({ variant, size, className })),
863
+ ref,
864
+ ...props
865
+ });
866
+ });
867
+ Button.displayName = "Button";
868
+
869
+ // src/ui/components/code-block.tsx
870
+ import { CheckIcon, CopyIcon } from "lucide-react";
871
+ import {
872
+ createContext as createContext3,
873
+ useContext as useContext3,
874
+ useEffect as useEffect5,
875
+ useRef,
876
+ useState as useState6
877
+ } from "react";
878
+ import { jsx as jsx5, jsxs, Fragment } from "react/jsx-runtime";
879
+ var CodeBlockContext = createContext3({
880
+ code: ""
881
+ });
882
+ async function highlightCode(code, language, showLineNumbers = false) {
883
+ try {
884
+ const shiki = await import("shiki");
885
+ const lineNumberTransformer = showLineNumbers ? [
886
+ {
887
+ name: "line-numbers",
888
+ line(node, line) {
889
+ node.children.unshift({
890
+ type: "element",
891
+ tagName: "span",
892
+ properties: {
893
+ className: ["inline-block", "min-w-10", "mr-4", "text-right", "select-none", "text-muted-foreground"]
894
+ },
895
+ children: [{ type: "text", value: String(line) }]
896
+ });
897
+ }
898
+ }
899
+ ] : [];
900
+ const [light, dark] = await Promise.all([
901
+ shiki.codeToHtml(code, { lang: language, theme: "one-light", transformers: lineNumberTransformer }),
902
+ shiki.codeToHtml(code, { lang: language, theme: "one-dark-pro", transformers: lineNumberTransformer })
903
+ ]);
904
+ return [light, dark];
905
+ } catch {
906
+ return ["", ""];
907
+ }
908
+ }
909
+ var CodeBlock = ({
910
+ code,
911
+ language,
912
+ showLineNumbers = false,
913
+ className,
914
+ children,
915
+ ...props
916
+ }) => {
917
+ const [html, setHtml] = useState6("");
918
+ const [darkHtml, setDarkHtml] = useState6("");
919
+ const effectIdRef = useRef(0);
920
+ useEffect5(() => {
921
+ const id = ++effectIdRef.current;
922
+ highlightCode(code, language, showLineNumbers).then(([light, dark]) => {
923
+ if (id === effectIdRef.current) {
924
+ setHtml(light);
925
+ setDarkHtml(dark);
926
+ }
927
+ });
928
+ }, [code, language, showLineNumbers]);
929
+ const useFallback = !html && !darkHtml;
930
+ return /* @__PURE__ */ jsx5(CodeBlockContext.Provider, {
931
+ value: { code },
932
+ children: /* @__PURE__ */ jsx5("div", {
933
+ className: cn("group relative w-full overflow-hidden rounded-md border bg-background text-foreground", className),
934
+ ...props,
935
+ children: /* @__PURE__ */ jsxs("div", {
936
+ className: "relative",
937
+ children: [
938
+ useFallback ? /* @__PURE__ */ jsx5("pre", {
939
+ className: "m-0 overflow-auto bg-background p-4 text-foreground text-sm",
940
+ children: /* @__PURE__ */ jsx5("code", {
941
+ className: "font-mono text-sm",
942
+ children: code
943
+ })
944
+ }) : /* @__PURE__ */ jsxs(Fragment, {
945
+ children: [
946
+ /* @__PURE__ */ jsx5("div", {
947
+ className: "overflow-hidden dark:hidden [&>pre]:m-0 [&>pre]:bg-background! [&>pre]:p-4 [&>pre]:text-foreground! [&>pre]:text-sm [&_code]:font-mono [&_code]:text-sm",
948
+ dangerouslySetInnerHTML: { __html: html }
949
+ }),
950
+ /* @__PURE__ */ jsx5("div", {
951
+ className: "hidden overflow-hidden dark:block [&>pre]:m-0 [&>pre]:bg-background! [&>pre]:p-4 [&>pre]:text-foreground! [&>pre]:text-sm [&_code]:font-mono [&_code]:text-sm",
952
+ dangerouslySetInnerHTML: { __html: darkHtml }
953
+ })
954
+ ]
955
+ }),
956
+ children && /* @__PURE__ */ jsx5("div", {
957
+ className: "absolute top-2 right-2 flex items-center gap-2",
958
+ children
959
+ })
960
+ ]
961
+ })
962
+ })
963
+ });
964
+ };
965
+
966
+ // src/ui/components/tool.tsx
967
+ import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
968
+ var Tool = ({ className, ...props }) => /* @__PURE__ */ jsx6(Collapsible, {
969
+ className: cn("not-prose mb-4 w-full rounded-md border", className),
970
+ ...props
971
+ });
972
+ var getStatusBadge = (status) => {
973
+ const labels = {
974
+ "input-streaming": "Pending",
975
+ "input-available": "Running",
976
+ "approval-requested": "Awaiting Approval",
977
+ "approval-responded": "Responded",
978
+ "output-available": "Completed",
979
+ "output-error": "Error",
980
+ "output-denied": "Denied"
667
981
  };
982
+ const icons = {
983
+ "input-streaming": /* @__PURE__ */ jsx6(CircleIcon, {
984
+ className: "size-4"
985
+ }),
986
+ "input-available": /* @__PURE__ */ jsx6(ClockIcon, {
987
+ className: "size-4 animate-pulse"
988
+ }),
989
+ "approval-requested": /* @__PURE__ */ jsx6(ClockIcon, {
990
+ className: "size-4 text-yellow-600"
991
+ }),
992
+ "approval-responded": /* @__PURE__ */ jsx6(CheckCircleIcon, {
993
+ className: "size-4 text-blue-600"
994
+ }),
995
+ "output-available": /* @__PURE__ */ jsx6(CheckCircleIcon, {
996
+ className: "size-4 text-green-600"
997
+ }),
998
+ "output-error": /* @__PURE__ */ jsx6(XCircleIcon, {
999
+ className: "size-4 text-red-600"
1000
+ }),
1001
+ "output-denied": /* @__PURE__ */ jsx6(XCircleIcon, {
1002
+ className: "size-4 text-orange-600"
1003
+ })
1004
+ };
1005
+ return /* @__PURE__ */ jsxs2(Badge, {
1006
+ className: "gap-1.5 rounded-full text-xs",
1007
+ variant: "secondary",
1008
+ children: [
1009
+ icons[status],
1010
+ labels[status]
1011
+ ]
1012
+ });
1013
+ };
1014
+ var ToolHeader = ({ className, title, type, state, ...props }) => /* @__PURE__ */ jsxs2(CollapsibleTrigger2, {
1015
+ className: cn("group flex w-full items-center justify-between gap-4 p-3", className),
1016
+ ...props,
1017
+ children: [
1018
+ /* @__PURE__ */ jsxs2("div", {
1019
+ className: "flex items-center gap-2",
1020
+ children: [
1021
+ /* @__PURE__ */ jsx6(WrenchIcon, {
1022
+ className: "size-4 text-muted-foreground"
1023
+ }),
1024
+ /* @__PURE__ */ jsx6("span", {
1025
+ className: "font-medium text-sm",
1026
+ children: title ?? type?.split("-").slice(1).join("-") ?? "Tool"
1027
+ }),
1028
+ getStatusBadge(state)
1029
+ ]
1030
+ }),
1031
+ /* @__PURE__ */ jsx6(ChevronDownIcon, {
1032
+ className: "size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180"
1033
+ })
1034
+ ]
1035
+ });
1036
+ var ToolContent = ({ className, ...props }) => /* @__PURE__ */ jsx6(CollapsibleContent2, {
1037
+ className: cn("data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in", className),
1038
+ ...props
1039
+ });
1040
+ var ToolInput = ({ className, input, ...props }) => /* @__PURE__ */ jsxs2("div", {
1041
+ className: cn("space-y-2 overflow-hidden p-4", className),
1042
+ ...props,
1043
+ children: [
1044
+ /* @__PURE__ */ jsx6("h4", {
1045
+ className: "font-medium text-muted-foreground text-xs uppercase tracking-wide",
1046
+ children: "Parameters"
1047
+ }),
1048
+ /* @__PURE__ */ jsx6("div", {
1049
+ className: "rounded-md bg-muted/50",
1050
+ children: /* @__PURE__ */ jsx6(CodeBlock, {
1051
+ code: JSON.stringify(input, null, 2),
1052
+ language: "json"
1053
+ })
1054
+ })
1055
+ ]
1056
+ });
1057
+ var ToolOutput = ({ className, output, errorText, ...props }) => {
1058
+ if (!(output || errorText)) {
1059
+ return null;
1060
+ }
1061
+ let Output = /* @__PURE__ */ jsx6("div", {
1062
+ children: output
1063
+ });
1064
+ if (typeof output === "object" && !isValidElement(output)) {
1065
+ Output = /* @__PURE__ */ jsx6(CodeBlock, {
1066
+ code: JSON.stringify(output, null, 2),
1067
+ language: "json"
1068
+ });
1069
+ } else if (typeof output === "string") {
1070
+ Output = /* @__PURE__ */ jsx6(CodeBlock, {
1071
+ code: output,
1072
+ language: "json"
1073
+ });
1074
+ }
1075
+ return /* @__PURE__ */ jsxs2("div", {
1076
+ className: cn("space-y-2 p-4", className),
1077
+ ...props,
1078
+ children: [
1079
+ /* @__PURE__ */ jsx6("h4", {
1080
+ className: "font-medium text-muted-foreground text-xs uppercase tracking-wide",
1081
+ children: errorText ? "Error" : "Result"
1082
+ }),
1083
+ /* @__PURE__ */ jsxs2("div", {
1084
+ className: cn("overflow-x-auto rounded-md text-xs [&_table]:w-full", errorText ? "bg-destructive/10 text-destructive" : "bg-muted/50 text-foreground"),
1085
+ children: [
1086
+ errorText && /* @__PURE__ */ jsx6("div", {
1087
+ children: errorText
1088
+ }),
1089
+ Output
1090
+ ]
1091
+ })
1092
+ ]
1093
+ });
1094
+ };
1095
+
1096
+ // src/ui/composed/agno-chat/tool-building-blocks.tsx
1097
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1098
+ var getToolState = (tool) => tool.tool_call_error ? "output-error" : "output-available";
1099
+ function ToolDebugCard({ tool, defaultOpen }) {
1100
+ const output = tool.result ?? tool.content;
1101
+ return /* @__PURE__ */ jsxs3(Tool, {
1102
+ defaultOpen,
1103
+ children: [
1104
+ /* @__PURE__ */ jsx7(ToolHeader, {
1105
+ title: tool.tool_name,
1106
+ type: "tool-use",
1107
+ state: getToolState(tool)
1108
+ }),
1109
+ /* @__PURE__ */ jsxs3(ToolContent, {
1110
+ children: [
1111
+ /* @__PURE__ */ jsx7(ToolInput, {
1112
+ input: tool.tool_args
1113
+ }),
1114
+ output ? /* @__PURE__ */ jsx7(ToolOutput, {
1115
+ output,
1116
+ errorText: tool.tool_call_error ? "Tool execution failed" : undefined
1117
+ }) : null
1118
+ ]
1119
+ })
1120
+ ]
1121
+ });
1122
+ }
1123
+ // src/ui/composed/agno-message/message.tsx
1124
+ import { useMemo as useMemo3, useState as useState8 } from "react";
1125
+ import { AlertCircle as AlertCircle2, FileIcon as FileIcon4, Music as Music2 } from "lucide-react";
1126
+
1127
+ // src/ui/primitives/tooltip.tsx
1128
+ import * as React4 from "react";
1129
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
1130
+ import { jsx as jsx8 } from "react/jsx-runtime";
1131
+ var TooltipProvider = TooltipPrimitive.Provider;
1132
+ var Tooltip = TooltipPrimitive.Root;
1133
+ var TooltipTrigger = TooltipPrimitive.Trigger;
1134
+ var TooltipContent = React4.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx8(TooltipPrimitive.Portal, {
1135
+ children: /* @__PURE__ */ jsx8(TooltipPrimitive.Content, {
1136
+ ref,
1137
+ sideOffset,
1138
+ className: cn("z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-tooltip-content-transform-origin]", className),
1139
+ ...props
1140
+ })
1141
+ }));
1142
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
1143
+
1144
+ // src/ui/lib/format-timestamp.ts
1145
+ function formatSmartTimestamp(date) {
1146
+ const now = new Date;
1147
+ const isToday = date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate();
1148
+ if (isToday) {
1149
+ return new Intl.DateTimeFormat(undefined, {
1150
+ hour: "numeric",
1151
+ minute: "2-digit",
1152
+ hour12: true
1153
+ }).format(date);
1154
+ }
1155
+ const isSameYear = date.getFullYear() === now.getFullYear();
1156
+ if (isSameYear) {
1157
+ return new Intl.DateTimeFormat(undefined, {
1158
+ month: "short",
1159
+ day: "numeric"
1160
+ }).format(date);
1161
+ }
1162
+ return new Intl.DateTimeFormat(undefined, {
1163
+ month: "short",
1164
+ day: "numeric",
1165
+ year: "numeric"
1166
+ }).format(date);
1167
+ }
1168
+ function formatFullTimestamp(date) {
1169
+ return new Intl.DateTimeFormat(undefined, {
1170
+ month: "short",
1171
+ day: "numeric",
1172
+ year: "numeric",
1173
+ hour: "numeric",
1174
+ minute: "2-digit",
1175
+ hour12: true
1176
+ }).format(date);
1177
+ }
1178
+
1179
+ // src/ui/components/smart-timestamp.tsx
1180
+ import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
1181
+ function SmartTimestamp({ date, formatShort, className }) {
1182
+ const shortText = formatShort ? formatShort(date) : formatSmartTimestamp(date);
1183
+ const fullText = formatFullTimestamp(date);
1184
+ return /* @__PURE__ */ jsx9(TooltipProvider, {
1185
+ children: /* @__PURE__ */ jsxs4(Tooltip, {
1186
+ children: [
1187
+ /* @__PURE__ */ jsx9(TooltipTrigger, {
1188
+ asChild: true,
1189
+ children: /* @__PURE__ */ jsx9("span", {
1190
+ className,
1191
+ children: shortText
1192
+ })
1193
+ }),
1194
+ /* @__PURE__ */ jsx9(TooltipContent, {
1195
+ children: /* @__PURE__ */ jsx9("p", {
1196
+ children: fullText
1197
+ })
1198
+ })
1199
+ ]
1200
+ })
1201
+ });
1202
+ }
1203
+
1204
+ // src/ui/lib/file-utils.ts
1205
+ function getFilePreviewType(mimeType) {
1206
+ if (!mimeType)
1207
+ return "none";
1208
+ if (mimeType.startsWith("image/"))
1209
+ return "image";
1210
+ if (mimeType === "application/pdf")
1211
+ return "pdf";
1212
+ if (mimeType.startsWith("text/"))
1213
+ return "text";
1214
+ if (mimeType.startsWith("video/"))
1215
+ return "video";
1216
+ if (mimeType.startsWith("audio/"))
1217
+ return "audio";
1218
+ return "none";
1219
+ }
1220
+ function formatFileSize(bytes) {
1221
+ if (bytes === 0)
1222
+ return "0 B";
1223
+ const units = ["B", "KB", "MB", "GB", "TB"];
1224
+ const k = 1024;
1225
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1226
+ const value = bytes / Math.pow(k, i);
1227
+ return `${value % 1 === 0 ? value : value.toFixed(1)} ${units[i]}`;
1228
+ }
1229
+ function getFileExtension(filename, mimeType) {
1230
+ const lastDot = filename.lastIndexOf(".");
1231
+ if (lastDot !== -1 && lastDot !== 0) {
1232
+ return filename.slice(lastDot + 1).toLowerCase();
1233
+ }
1234
+ if (mimeType) {
1235
+ return extensionFromMime(mimeType);
1236
+ }
1237
+ return "";
1238
+ }
1239
+ var mimeToExt = {
1240
+ "application/pdf": "pdf",
1241
+ "application/zip": "zip",
1242
+ "application/x-rar-compressed": "rar",
1243
+ "application/json": "json",
1244
+ "application/xml": "xml",
1245
+ "application/msword": "doc",
1246
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
1247
+ "application/vnd.ms-excel": "xls",
1248
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
1249
+ "application/vnd.ms-powerpoint": "ppt",
1250
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx",
1251
+ "text/csv": "csv",
1252
+ "text/plain": "txt",
1253
+ "text/html": "html",
1254
+ "text/css": "css",
1255
+ "text/javascript": "js"
1256
+ };
1257
+ function extensionFromMime(mimeType) {
1258
+ if (mimeToExt[mimeType])
1259
+ return mimeToExt[mimeType];
1260
+ const subtype = mimeType.split("/")[1];
1261
+ if (subtype && !subtype.includes(".") && !subtype.includes("+")) {
1262
+ return subtype.toLowerCase();
1263
+ }
1264
+ return "";
1265
+ }
1266
+ function isPreviewable(mimeType) {
1267
+ const type = getFilePreviewType(mimeType);
1268
+ return type === "image" || type === "pdf";
1269
+ }
1270
+
1271
+ // src/ui/components/file-preview-card.tsx
1272
+ import { FileIcon, Search } from "lucide-react";
1273
+ import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
1274
+ function ExtBadge({ ext }) {
1275
+ if (!ext)
1276
+ return null;
1277
+ return /* @__PURE__ */ jsx10("span", {
1278
+ className: "absolute bottom-1.5 left-1.5 rounded px-1 py-0.5 text-[9px] font-semibold uppercase leading-none bg-background/80 text-muted-foreground border border-border/50 backdrop-blur-sm",
1279
+ children: ext
1280
+ });
1281
+ }
1282
+ function FilePreviewCard({ file, onClick, className }) {
1283
+ const previewType = getFilePreviewType(file.type);
1284
+ const isClickable = !!onClick;
1285
+ const ext = getFileExtension(file.name, file.type);
1286
+ const cardBase = cn("group relative flex flex-col overflow-hidden rounded-xl border border-border bg-muted/20 w-28 h-28", isClickable && "cursor-pointer hover:border-foreground/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 transition-colors", className);
1287
+ if (previewType === "image" && file.url) {
1288
+ return /* @__PURE__ */ jsxs5("button", {
1289
+ type: "button",
1290
+ onClick,
1291
+ disabled: !isClickable,
1292
+ className: cardBase,
1293
+ children: [
1294
+ /* @__PURE__ */ jsx10("img", {
1295
+ src: file.url,
1296
+ alt: file.name,
1297
+ className: "w-full h-full object-cover"
1298
+ }),
1299
+ /* @__PURE__ */ jsx10(ExtBadge, {
1300
+ ext
1301
+ }),
1302
+ isClickable && /* @__PURE__ */ jsx10("div", {
1303
+ className: "absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/30 transition-colors",
1304
+ children: /* @__PURE__ */ jsx10(Search, {
1305
+ className: "h-5 w-5 text-white opacity-0 group-hover:opacity-100 transition-opacity"
1306
+ })
1307
+ })
1308
+ ]
1309
+ });
1310
+ }
1311
+ if (previewType === "pdf" && file.url) {
1312
+ return /* @__PURE__ */ jsxs5("button", {
1313
+ type: "button",
1314
+ onClick,
1315
+ disabled: !isClickable,
1316
+ className: cardBase,
1317
+ children: [
1318
+ /* @__PURE__ */ jsx10("div", {
1319
+ className: "w-full h-full overflow-hidden pointer-events-none",
1320
+ children: /* @__PURE__ */ jsx10("object", {
1321
+ data: `${file.url}#page=1&view=FitH`,
1322
+ type: "application/pdf",
1323
+ className: "w-[200%] h-[200%] origin-top-left scale-50",
1324
+ "aria-label": file.name,
1325
+ children: /* @__PURE__ */ jsx10("div", {
1326
+ className: "flex items-center justify-center w-full h-full",
1327
+ children: /* @__PURE__ */ jsx10(FileIcon, {
1328
+ className: "h-8 w-8 text-muted-foreground/40"
1329
+ })
1330
+ })
1331
+ })
1332
+ }),
1333
+ /* @__PURE__ */ jsx10(ExtBadge, {
1334
+ ext
1335
+ }),
1336
+ isClickable && /* @__PURE__ */ jsx10("div", {
1337
+ className: "absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/10 transition-colors",
1338
+ children: /* @__PURE__ */ jsx10(Search, {
1339
+ className: "h-5 w-5 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity"
1340
+ })
1341
+ })
1342
+ ]
1343
+ });
1344
+ }
1345
+ return /* @__PURE__ */ jsxs5("button", {
1346
+ type: "button",
1347
+ onClick,
1348
+ disabled: !isClickable,
1349
+ className: cardBase,
1350
+ children: [
1351
+ /* @__PURE__ */ jsx10("div", {
1352
+ className: "flex-1 flex items-center justify-center",
1353
+ children: /* @__PURE__ */ jsx10(FileIcon, {
1354
+ className: "h-8 w-8 text-muted-foreground/40"
1355
+ })
1356
+ }),
1357
+ /* @__PURE__ */ jsxs5("div", {
1358
+ className: "w-full text-center min-w-0 px-2 pb-2 space-y-0.5",
1359
+ children: [
1360
+ /* @__PURE__ */ jsx10("p", {
1361
+ className: "text-[10px] text-foreground truncate leading-tight",
1362
+ title: file.name,
1363
+ children: file.name
1364
+ }),
1365
+ file.size != null && file.size > 0 && /* @__PURE__ */ jsx10("p", {
1366
+ className: "text-[9px] text-muted-foreground leading-tight",
1367
+ children: formatFileSize(file.size)
1368
+ })
1369
+ ]
1370
+ }),
1371
+ /* @__PURE__ */ jsx10(ExtBadge, {
1372
+ ext
1373
+ })
1374
+ ]
1375
+ });
1376
+ }
1377
+
1378
+ // src/ui/primitives/dialog.tsx
1379
+ import * as React5 from "react";
1380
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
1381
+ import { cva as cva3 } from "class-variance-authority";
1382
+ import { X } from "lucide-react";
1383
+ import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
1384
+ var Dialog = DialogPrimitive.Root;
1385
+ var DialogPortal = DialogPrimitive.Portal;
1386
+ var DialogOverlay = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(DialogPrimitive.Overlay, {
1387
+ ref,
1388
+ className: cn("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className),
1389
+ ...props
1390
+ }));
1391
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
1392
+ var dialogContentVariants = cva3("fixed left-[50%] top-[50%] z-50 grid translate-x-[-50%] translate-y-[-50%] gap-4 border shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg", {
1393
+ variants: {
1394
+ variant: {
1395
+ default: "w-full max-w-lg bg-background p-6",
1396
+ lightbox: "max-w-[90vw] max-h-[90vh] bg-background/95 backdrop-blur-sm p-2"
1397
+ }
1398
+ },
1399
+ defaultVariants: {
1400
+ variant: "default"
1401
+ }
1402
+ });
1403
+ var DialogContent = React5.forwardRef(({ className, variant, children, ...props }, ref) => /* @__PURE__ */ jsxs6(DialogPortal, {
1404
+ children: [
1405
+ /* @__PURE__ */ jsx11(DialogOverlay, {}),
1406
+ /* @__PURE__ */ jsxs6(DialogPrimitive.Content, {
1407
+ ref,
1408
+ className: cn(dialogContentVariants({ variant }), className),
1409
+ ...props,
1410
+ children: [
1411
+ children,
1412
+ /* @__PURE__ */ jsxs6(DialogPrimitive.Close, {
1413
+ className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
1414
+ children: [
1415
+ /* @__PURE__ */ jsx11(X, {
1416
+ className: "h-4 w-4"
1417
+ }),
1418
+ /* @__PURE__ */ jsx11("span", {
1419
+ className: "sr-only",
1420
+ children: "Close"
1421
+ })
1422
+ ]
1423
+ })
1424
+ ]
1425
+ })
1426
+ ]
1427
+ }));
1428
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
1429
+ var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx11("div", {
1430
+ className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className),
1431
+ ...props
1432
+ });
1433
+ DialogHeader.displayName = "DialogHeader";
1434
+ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx11("div", {
1435
+ className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
1436
+ ...props
1437
+ });
1438
+ DialogFooter.displayName = "DialogFooter";
1439
+ var DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(DialogPrimitive.Title, {
1440
+ ref,
1441
+ className: cn("text-lg font-semibold leading-none tracking-tight", className),
1442
+ ...props
1443
+ }));
1444
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
1445
+ var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(DialogPrimitive.Description, {
1446
+ ref,
1447
+ className: cn("text-sm text-muted-foreground", className),
1448
+ ...props
1449
+ }));
1450
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
1451
+
1452
+ // src/ui/components/file-preview-modal.tsx
1453
+ import { Download, FileIcon as FileIcon2 } from "lucide-react";
1454
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
1455
+ function FilePreviewModal({ open, onOpenChange, file }) {
1456
+ if (!file)
1457
+ return null;
1458
+ const previewType = getFilePreviewType(file.type);
1459
+ const canPreview = isPreviewable(file.type) && !!file.url;
1460
+ return /* @__PURE__ */ jsx12(Dialog, {
1461
+ open,
1462
+ onOpenChange,
1463
+ children: previewType === "image" && file.url ? /* @__PURE__ */ jsxs7(DialogContent, {
1464
+ variant: "lightbox",
1465
+ "aria-describedby": undefined,
1466
+ children: [
1467
+ /* @__PURE__ */ jsx12(DialogTitle, {
1468
+ className: "sr-only",
1469
+ children: file.name
1470
+ }),
1471
+ /* @__PURE__ */ jsx12("img", {
1472
+ src: file.url,
1473
+ alt: file.name,
1474
+ className: "max-h-[85vh] max-w-full object-contain rounded-md"
1475
+ })
1476
+ ]
1477
+ }) : previewType === "pdf" && file.url ? /* @__PURE__ */ jsxs7(DialogContent, {
1478
+ variant: "lightbox",
1479
+ className: "w-[80vw] h-[85vh]",
1480
+ "aria-describedby": undefined,
1481
+ children: [
1482
+ /* @__PURE__ */ jsx12(DialogTitle, {
1483
+ className: "sr-only",
1484
+ children: file.name
1485
+ }),
1486
+ /* @__PURE__ */ jsx12("object", {
1487
+ data: file.url,
1488
+ type: "application/pdf",
1489
+ className: "w-full h-full rounded-md",
1490
+ children: /* @__PURE__ */ jsxs7("div", {
1491
+ className: "flex flex-col items-center justify-center h-full gap-3 text-muted-foreground",
1492
+ children: [
1493
+ /* @__PURE__ */ jsx12("p", {
1494
+ className: "text-sm",
1495
+ children: "Unable to display PDF"
1496
+ }),
1497
+ /* @__PURE__ */ jsxs7("a", {
1498
+ href: file.url,
1499
+ target: "_blank",
1500
+ rel: "noopener noreferrer",
1501
+ className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline",
1502
+ children: [
1503
+ /* @__PURE__ */ jsx12(Download, {
1504
+ className: "h-4 w-4"
1505
+ }),
1506
+ "Download ",
1507
+ file.name
1508
+ ]
1509
+ })
1510
+ ]
1511
+ })
1512
+ })
1513
+ ]
1514
+ }) : /* @__PURE__ */ jsxs7(DialogContent, {
1515
+ children: [
1516
+ /* @__PURE__ */ jsxs7(DialogHeader, {
1517
+ children: [
1518
+ /* @__PURE__ */ jsxs7(DialogTitle, {
1519
+ className: "flex items-center gap-2",
1520
+ children: [
1521
+ /* @__PURE__ */ jsx12(FileIcon2, {
1522
+ className: "h-5 w-5 text-muted-foreground"
1523
+ }),
1524
+ file.name
1525
+ ]
1526
+ }),
1527
+ /* @__PURE__ */ jsxs7(DialogDescription, {
1528
+ children: [
1529
+ file.size != null && file.size > 0 && /* @__PURE__ */ jsx12("span", {
1530
+ children: formatFileSize(file.size)
1531
+ }),
1532
+ !canPreview && /* @__PURE__ */ jsx12("span", {
1533
+ children: " · Preview not available for this file type"
1534
+ })
1535
+ ]
1536
+ })
1537
+ ]
1538
+ }),
1539
+ /* @__PURE__ */ jsxs7("div", {
1540
+ className: "flex flex-col items-center justify-center py-8 text-muted-foreground gap-3",
1541
+ children: [
1542
+ /* @__PURE__ */ jsx12(FileIcon2, {
1543
+ className: "h-12 w-12"
1544
+ }),
1545
+ /* @__PURE__ */ jsx12("p", {
1546
+ className: "text-sm",
1547
+ children: "Preview not available"
1548
+ }),
1549
+ file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsxs7("a", {
1550
+ href: file.url,
1551
+ target: "_blank",
1552
+ rel: "noopener noreferrer",
1553
+ className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline",
1554
+ children: [
1555
+ /* @__PURE__ */ jsx12(Download, {
1556
+ className: "h-4 w-4"
1557
+ }),
1558
+ "Download file"
1559
+ ]
1560
+ })
1561
+ ]
1562
+ })
1563
+ ]
1564
+ })
1565
+ });
668
1566
  }
669
- function createTable(data, columns, options) {
670
- return {
671
- type: "table",
672
- layout: options?.layout,
673
- title: options?.title,
674
- description: options?.description,
675
- props: {
676
- data,
677
- columns,
678
- sortable: options?.sortable ?? true,
679
- filterable: options?.filterable,
680
- pagination: options?.pagination,
681
- density: options?.density || "comfortable"
682
- }
683
- };
1567
+
1568
+ // src/ui/components/image-lightbox.tsx
1569
+ import { useState as useState7, useEffect as useEffect6, useCallback as useCallback6 } from "react";
1570
+ import { ChevronLeft, ChevronRight } from "lucide-react";
1571
+ import { jsx as jsx13, jsxs as jsxs8, Fragment as Fragment2 } from "react/jsx-runtime";
1572
+ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
1573
+ const [currentIndex, setCurrentIndex] = useState7(initialIndex);
1574
+ const hasMultiple = images.length > 1;
1575
+ useEffect6(() => {
1576
+ if (open)
1577
+ setCurrentIndex(initialIndex);
1578
+ }, [open, initialIndex]);
1579
+ const goNext = useCallback6(() => {
1580
+ setCurrentIndex((i) => (i + 1) % images.length);
1581
+ }, [images.length]);
1582
+ const goPrev = useCallback6(() => {
1583
+ setCurrentIndex((i) => (i - 1 + images.length) % images.length);
1584
+ }, [images.length]);
1585
+ useEffect6(() => {
1586
+ if (!open || !hasMultiple)
1587
+ return;
1588
+ const handler = (e) => {
1589
+ if (e.key === "ArrowRight")
1590
+ goNext();
1591
+ if (e.key === "ArrowLeft")
1592
+ goPrev();
1593
+ };
1594
+ window.addEventListener("keydown", handler);
1595
+ return () => window.removeEventListener("keydown", handler);
1596
+ }, [open, hasMultiple, goNext, goPrev]);
1597
+ if (images.length === 0)
1598
+ return null;
1599
+ const current = images[currentIndex];
1600
+ if (!current)
1601
+ return null;
1602
+ return /* @__PURE__ */ jsx13(Dialog, {
1603
+ open,
1604
+ onOpenChange,
1605
+ children: /* @__PURE__ */ jsxs8(DialogContent, {
1606
+ variant: "lightbox",
1607
+ "aria-describedby": undefined,
1608
+ children: [
1609
+ /* @__PURE__ */ jsx13(DialogTitle, {
1610
+ className: "sr-only",
1611
+ children: current.alt || `Image ${currentIndex + 1} of ${images.length}`
1612
+ }),
1613
+ /* @__PURE__ */ jsxs8("div", {
1614
+ className: "relative flex items-center justify-center",
1615
+ children: [
1616
+ /* @__PURE__ */ jsx13("img", {
1617
+ src: current.url,
1618
+ alt: current.alt || "Image preview",
1619
+ className: "max-h-[85vh] max-w-full object-contain rounded-md"
1620
+ }),
1621
+ hasMultiple && /* @__PURE__ */ jsxs8(Fragment2, {
1622
+ children: [
1623
+ /* @__PURE__ */ jsxs8("button", {
1624
+ type: "button",
1625
+ onClick: goPrev,
1626
+ className: cn("absolute left-2 top-1/2 -translate-y-1/2 rounded-full bg-black/50 p-2 text-white", "hover:bg-black/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring transition-colors"),
1627
+ children: [
1628
+ /* @__PURE__ */ jsx13(ChevronLeft, {
1629
+ className: "h-5 w-5"
1630
+ }),
1631
+ /* @__PURE__ */ jsx13("span", {
1632
+ className: "sr-only",
1633
+ children: "Previous image"
1634
+ })
1635
+ ]
1636
+ }),
1637
+ /* @__PURE__ */ jsxs8("button", {
1638
+ type: "button",
1639
+ onClick: goNext,
1640
+ className: cn("absolute right-2 top-1/2 -translate-y-1/2 rounded-full bg-black/50 p-2 text-white", "hover:bg-black/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring transition-colors"),
1641
+ children: [
1642
+ /* @__PURE__ */ jsx13(ChevronRight, {
1643
+ className: "h-5 w-5"
1644
+ }),
1645
+ /* @__PURE__ */ jsx13("span", {
1646
+ className: "sr-only",
1647
+ children: "Next image"
1648
+ })
1649
+ ]
1650
+ }),
1651
+ /* @__PURE__ */ jsxs8("div", {
1652
+ className: "absolute bottom-2 left-1/2 -translate-x-1/2 rounded-full bg-black/50 px-3 py-1 text-xs text-white",
1653
+ children: [
1654
+ currentIndex + 1,
1655
+ " / ",
1656
+ images.length
1657
+ ]
1658
+ })
1659
+ ]
1660
+ })
1661
+ ]
1662
+ })
1663
+ ]
1664
+ })
1665
+ });
684
1666
  }
685
- function createColumn(key, header, options) {
686
- return {
687
- key,
688
- header,
689
- width: options?.width,
690
- sortable: options?.sortable,
691
- cellType: options?.cellType || "text",
692
- format: options?.format
693
- };
1667
+
1668
+ // src/ui/composed/agno-message/context.ts
1669
+ import { createContext as createContext4, useContext as useContext4 } from "react";
1670
+ var AgnoMessageContext = createContext4(null);
1671
+ function useAgnoMessageContext() {
1672
+ const ctx = useContext4(AgnoMessageContext);
1673
+ if (!ctx) {
1674
+ throw new Error("useAgnoMessageContext must be used within an <AgnoMessage> provider. " + "Wrap your slots with <AgnoMessage message={...}>.");
1675
+ }
1676
+ return ctx;
694
1677
  }
695
- function createMarkdown(content, options) {
696
- return {
697
- type: "markdown",
698
- layout: options?.layout,
699
- title: options?.title,
700
- description: options?.description,
701
- props: {
702
- content,
703
- syntaxHighlight: options?.syntaxHighlight ?? true
704
- }
705
- };
1678
+
1679
+ // src/ui/composed/agno-message/reasoning.tsx
1680
+ import { Lightbulb } from "lucide-react";
1681
+
1682
+ // src/ui/primitives/accordion.tsx
1683
+ import * as React6 from "react";
1684
+ import * as AccordionPrimitive from "@radix-ui/react-accordion";
1685
+ import { ChevronDown } from "lucide-react";
1686
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
1687
+ var Accordion = AccordionPrimitive.Root;
1688
+ var AccordionItem = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14(AccordionPrimitive.Item, {
1689
+ ref,
1690
+ className: cn("border-b", className),
1691
+ ...props
1692
+ }));
1693
+ AccordionItem.displayName = "AccordionItem";
1694
+ var AccordionTrigger = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx14(AccordionPrimitive.Header, {
1695
+ className: "flex",
1696
+ children: /* @__PURE__ */ jsxs9(AccordionPrimitive.Trigger, {
1697
+ ref,
1698
+ className: cn("flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline text-left [&[data-state=open]>svg]:rotate-180", className),
1699
+ ...props,
1700
+ children: [
1701
+ children,
1702
+ /* @__PURE__ */ jsx14(ChevronDown, {
1703
+ className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200"
1704
+ })
1705
+ ]
1706
+ })
1707
+ }));
1708
+ AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
1709
+ var AccordionContent = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx14(AccordionPrimitive.Content, {
1710
+ ref,
1711
+ className: "overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
1712
+ ...props,
1713
+ children: /* @__PURE__ */ jsx14("div", {
1714
+ className: cn("pb-4 pt-0", className),
1715
+ children
1716
+ })
1717
+ }));
1718
+ AccordionContent.displayName = AccordionPrimitive.Content.displayName;
1719
+
1720
+ // src/ui/composed/agno-message/reasoning.tsx
1721
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
1722
+ function AgnoMessageReasoning() {
1723
+ const { message, classNames } = useAgnoMessageContext();
1724
+ const steps = message.extra_data?.reasoning_steps;
1725
+ if (!steps || steps.length === 0)
1726
+ return null;
1727
+ return /* @__PURE__ */ jsxs10("div", {
1728
+ className: cn("space-y-2 pt-1", classNames?.assistant?.reasoning),
1729
+ children: [
1730
+ /* @__PURE__ */ jsxs10("div", {
1731
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
1732
+ children: [
1733
+ /* @__PURE__ */ jsx15(Lightbulb, {
1734
+ className: "h-3.5 w-3.5"
1735
+ }),
1736
+ "Reasoning (",
1737
+ steps.length,
1738
+ " steps)"
1739
+ ]
1740
+ }),
1741
+ /* @__PURE__ */ jsx15(Accordion, {
1742
+ type: "multiple",
1743
+ className: "w-full",
1744
+ children: steps.map((step, idx) => /* @__PURE__ */ jsxs10(AccordionItem, {
1745
+ value: `reasoning-${idx}`,
1746
+ className: "border-muted",
1747
+ children: [
1748
+ /* @__PURE__ */ jsx15(AccordionTrigger, {
1749
+ className: "text-xs py-1.5 hover:no-underline",
1750
+ children: step.title || `Step ${idx + 1}`
1751
+ }),
1752
+ /* @__PURE__ */ jsxs10(AccordionContent, {
1753
+ className: "space-y-1.5 text-xs text-muted-foreground",
1754
+ children: [
1755
+ step.action && /* @__PURE__ */ jsxs10("div", {
1756
+ children: [
1757
+ /* @__PURE__ */ jsx15("span", {
1758
+ className: "font-medium text-foreground",
1759
+ children: "Action:"
1760
+ }),
1761
+ " ",
1762
+ step.action
1763
+ ]
1764
+ }),
1765
+ step.reasoning && /* @__PURE__ */ jsxs10("div", {
1766
+ children: [
1767
+ /* @__PURE__ */ jsx15("span", {
1768
+ className: "font-medium text-foreground",
1769
+ children: "Reasoning:"
1770
+ }),
1771
+ " ",
1772
+ step.reasoning
1773
+ ]
1774
+ }),
1775
+ step.result && /* @__PURE__ */ jsxs10("div", {
1776
+ children: [
1777
+ /* @__PURE__ */ jsx15("span", {
1778
+ className: "font-medium text-foreground",
1779
+ children: "Result:"
1780
+ }),
1781
+ " ",
1782
+ step.result
1783
+ ]
1784
+ }),
1785
+ step.confidence !== undefined && /* @__PURE__ */ jsxs10("div", {
1786
+ children: [
1787
+ /* @__PURE__ */ jsx15("span", {
1788
+ className: "font-medium text-foreground",
1789
+ children: "Confidence:"
1790
+ }),
1791
+ " ",
1792
+ (step.confidence * 100).toFixed(1),
1793
+ "%"
1794
+ ]
1795
+ })
1796
+ ]
1797
+ })
1798
+ ]
1799
+ }, idx))
1800
+ })
1801
+ ]
1802
+ });
706
1803
  }
707
- function createArtifact(content, options) {
708
- return {
709
- type: "artifact",
710
- title: options?.title,
711
- description: options?.description,
712
- props: {
713
- content,
714
- variant: options?.variant || "default"
715
- }
716
- };
1804
+
1805
+ // src/ui/composed/agno-message/media.tsx
1806
+ import { FileIcon as FileIcon3, Image as ImageIcon, Music, Paperclip, Video } from "lucide-react";
1807
+ import { jsx as jsx16, jsxs as jsxs11, Fragment as Fragment3 } from "react/jsx-runtime";
1808
+ function AgnoMessageMedia() {
1809
+ const {
1810
+ message,
1811
+ classNames,
1812
+ showImageLightbox,
1813
+ showFilePreview,
1814
+ openImageLightbox,
1815
+ openFilePreview
1816
+ } = useAgnoMessageContext();
1817
+ const mediaClassName = classNames?.assistant?.media;
1818
+ const hasImages = !!message.images && message.images.length > 0;
1819
+ const hasVideos = !!message.videos && message.videos.length > 0;
1820
+ const hasAudio = !!message.audio && message.audio.length > 0;
1821
+ const hasFiles = !!message.files && message.files.length > 0;
1822
+ const hasResponseAudio = !!message.response_audio;
1823
+ if (!hasImages && !hasVideos && !hasAudio && !hasFiles && !hasResponseAudio)
1824
+ return null;
1825
+ return /* @__PURE__ */ jsxs11(Fragment3, {
1826
+ children: [
1827
+ hasImages && /* @__PURE__ */ jsxs11("div", {
1828
+ className: cn("space-y-2 pt-1", mediaClassName),
1829
+ children: [
1830
+ /* @__PURE__ */ jsxs11("div", {
1831
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
1832
+ children: [
1833
+ /* @__PURE__ */ jsx16(ImageIcon, {
1834
+ className: "h-3.5 w-3.5"
1835
+ }),
1836
+ "Images (",
1837
+ message.images.length,
1838
+ ")"
1839
+ ]
1840
+ }),
1841
+ /* @__PURE__ */ jsx16("div", {
1842
+ className: "grid grid-cols-2 gap-2",
1843
+ children: message.images.map((img, idx) => /* @__PURE__ */ jsxs11("div", {
1844
+ className: "space-y-1",
1845
+ children: [
1846
+ showImageLightbox ? /* @__PURE__ */ jsx16("button", {
1847
+ type: "button",
1848
+ onClick: () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx),
1849
+ className: "group relative w-full overflow-hidden rounded-lg border border-border cursor-pointer hover:border-primary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring transition-colors",
1850
+ children: /* @__PURE__ */ jsx16("img", {
1851
+ src: img.url,
1852
+ alt: img.revised_prompt || "Generated image",
1853
+ className: "w-full rounded-lg"
1854
+ })
1855
+ }) : /* @__PURE__ */ jsx16("img", {
1856
+ src: img.url,
1857
+ alt: img.revised_prompt || "Generated image",
1858
+ className: "w-full rounded-lg border border-border"
1859
+ }),
1860
+ img.revised_prompt && /* @__PURE__ */ jsx16("p", {
1861
+ className: "text-[11px] text-muted-foreground italic px-0.5",
1862
+ children: img.revised_prompt
1863
+ })
1864
+ ]
1865
+ }, idx))
1866
+ })
1867
+ ]
1868
+ }),
1869
+ hasVideos && /* @__PURE__ */ jsxs11("div", {
1870
+ className: cn("space-y-2 pt-1", mediaClassName),
1871
+ children: [
1872
+ /* @__PURE__ */ jsxs11("div", {
1873
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
1874
+ children: [
1875
+ /* @__PURE__ */ jsx16(Video, {
1876
+ className: "h-3.5 w-3.5"
1877
+ }),
1878
+ "Videos (",
1879
+ message.videos.length,
1880
+ ")"
1881
+ ]
1882
+ }),
1883
+ /* @__PURE__ */ jsx16("div", {
1884
+ className: "space-y-2",
1885
+ children: message.videos.map((video, idx) => /* @__PURE__ */ jsx16("div", {
1886
+ children: video.url ? /* @__PURE__ */ jsx16("video", {
1887
+ src: video.url,
1888
+ controls: true,
1889
+ className: "w-full rounded-lg border border-border"
1890
+ }) : /* @__PURE__ */ jsxs11("div", {
1891
+ className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
1892
+ children: [
1893
+ "Video ID: ",
1894
+ video.id,
1895
+ " (ETA: ",
1896
+ video.eta,
1897
+ "s)"
1898
+ ]
1899
+ })
1900
+ }, idx))
1901
+ })
1902
+ ]
1903
+ }),
1904
+ hasAudio && /* @__PURE__ */ jsxs11("div", {
1905
+ className: cn("space-y-2 pt-1", mediaClassName),
1906
+ children: [
1907
+ /* @__PURE__ */ jsxs11("div", {
1908
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
1909
+ children: [
1910
+ /* @__PURE__ */ jsx16(Music, {
1911
+ className: "h-3.5 w-3.5"
1912
+ }),
1913
+ "Audio (",
1914
+ message.audio.length,
1915
+ ")"
1916
+ ]
1917
+ }),
1918
+ /* @__PURE__ */ jsx16("div", {
1919
+ className: "space-y-2",
1920
+ children: message.audio.map((audio, idx) => /* @__PURE__ */ jsx16("div", {
1921
+ children: audio.url ? /* @__PURE__ */ jsx16("audio", {
1922
+ src: audio.url,
1923
+ controls: true,
1924
+ className: "w-full"
1925
+ }) : audio.base64_audio ? /* @__PURE__ */ jsx16("audio", {
1926
+ src: `data:${audio.mime_type || "audio/wav"};base64,${audio.base64_audio}`,
1927
+ controls: true,
1928
+ className: "w-full"
1929
+ }) : /* @__PURE__ */ jsx16("div", {
1930
+ className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
1931
+ children: "Audio data unavailable"
1932
+ })
1933
+ }, idx))
1934
+ })
1935
+ ]
1936
+ }),
1937
+ hasFiles && /* @__PURE__ */ jsxs11("div", {
1938
+ className: cn("space-y-2 pt-1", mediaClassName),
1939
+ children: [
1940
+ /* @__PURE__ */ jsxs11("div", {
1941
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
1942
+ children: [
1943
+ /* @__PURE__ */ jsx16(Paperclip, {
1944
+ className: "h-3.5 w-3.5"
1945
+ }),
1946
+ "Files (",
1947
+ message.files.length,
1948
+ ")"
1949
+ ]
1950
+ }),
1951
+ /* @__PURE__ */ jsx16("div", {
1952
+ className: "flex flex-wrap gap-2",
1953
+ children: message.files.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx16(FilePreviewCard, {
1954
+ file: { name: file.name, type: file.type, url: file.url, size: file.size },
1955
+ onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
1956
+ }, idx) : /* @__PURE__ */ jsxs11("div", {
1957
+ className: "flex items-center gap-2 rounded-lg border border-border px-3 py-2 text-xs bg-muted/30 hover:bg-muted/50 transition-colors",
1958
+ children: [
1959
+ /* @__PURE__ */ jsx16(FileIcon3, {
1960
+ className: "h-3.5 w-3.5 shrink-0 text-muted-foreground"
1961
+ }),
1962
+ /* @__PURE__ */ jsx16("span", {
1963
+ className: "truncate max-w-[180px]",
1964
+ children: file.name
1965
+ }),
1966
+ file.size && /* @__PURE__ */ jsxs11("span", {
1967
+ className: "text-muted-foreground/70",
1968
+ children: [
1969
+ "(",
1970
+ (file.size / 1024).toFixed(1),
1971
+ "KB)"
1972
+ ]
1973
+ }),
1974
+ file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsx16("a", {
1975
+ href: file.url,
1976
+ target: "_blank",
1977
+ rel: "noopener noreferrer",
1978
+ className: "text-primary hover:underline font-medium",
1979
+ children: "View"
1980
+ })
1981
+ ]
1982
+ }, idx))
1983
+ })
1984
+ ]
1985
+ }),
1986
+ hasResponseAudio && message.response_audio && /* @__PURE__ */ jsxs11("div", {
1987
+ className: cn("space-y-2 pt-1", mediaClassName),
1988
+ children: [
1989
+ /* @__PURE__ */ jsxs11("div", {
1990
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
1991
+ children: [
1992
+ /* @__PURE__ */ jsx16(Music, {
1993
+ className: "h-3.5 w-3.5"
1994
+ }),
1995
+ "Response Audio"
1996
+ ]
1997
+ }),
1998
+ message.response_audio.transcript && /* @__PURE__ */ jsxs11("div", {
1999
+ className: "text-xs italic bg-muted/50 border border-border p-2.5 rounded-lg text-muted-foreground",
2000
+ children: [
2001
+ '"',
2002
+ message.response_audio.transcript,
2003
+ '"'
2004
+ ]
2005
+ }),
2006
+ message.response_audio.content && /* @__PURE__ */ jsx16("audio", {
2007
+ src: `data:audio/wav;base64,${message.response_audio.content}`,
2008
+ controls: true,
2009
+ className: "w-full"
2010
+ })
2011
+ ]
2012
+ })
2013
+ ]
2014
+ });
717
2015
  }
718
- function createSmartChart(data, options) {
719
- if (!data || data.length === 0) {
720
- return createBarChart([], "", [], options);
721
- }
722
- const firstItem = data[0];
723
- const keys = Object.keys(firstItem);
724
- const xKey = options?.xKey || keys.find((k) => ["name", "label", "category", "date", "time", "month", "year"].includes(k.toLowerCase())) || keys[0];
725
- const numericKeys = keys.filter((k) => k !== xKey && typeof firstItem[k] === "number");
726
- const yKeys = options?.yKeys || numericKeys;
727
- if (options?.preferredType) {
728
- switch (options.preferredType) {
729
- case "bar":
730
- return createBarChart(data, xKey, yKeys.map((key) => ({ key })), options);
731
- case "line":
732
- return createLineChart(data, xKey, yKeys.map((key) => ({ key })), options);
733
- case "area":
734
- return createAreaChart(data, xKey, yKeys.map((key) => ({ key })), options);
735
- case "pie":
736
- return createPieChart(data, yKeys[0], xKey, options);
737
- }
738
- }
739
- if (yKeys.length === 1 && typeof firstItem[xKey] === "string") {
740
- return createPieChart(data, yKeys[0], xKey, options);
741
- }
742
- if (xKey.toLowerCase().includes("date") || xKey.toLowerCase().includes("time") || xKey.toLowerCase().includes("month") || xKey.toLowerCase().includes("year")) {
743
- return createLineChart(data, xKey, yKeys.map((key) => ({ key })), options);
2016
+
2017
+ // src/ui/composed/agno-chat/context.ts
2018
+ import { createContext as createContext5, useContext as useContext5 } from "react";
2019
+ var AgnoChatContext = createContext5(null);
2020
+ function useAgnoChatContext() {
2021
+ const ctx = useContext5(AgnoChatContext);
2022
+ if (!ctx) {
2023
+ throw new Error("useAgnoChatContext must be used within an <AgnoChat> provider. " + "Wrap your component tree with <AgnoChat>.");
744
2024
  }
745
- return createBarChart(data, xKey, yKeys.map((key) => ({ key })), options);
746
- }
747
- function createToolResult(data, ui) {
748
- return { data, ui };
2025
+ return ctx;
749
2026
  }
750
- function resultWithBarChart(data, xKey, bars, options) {
751
- return createToolResult(data, createBarChart(data, xKey, bars, options));
2027
+
2028
+ // src/ui/composed/agno-message/tools.tsx
2029
+ import { jsx as jsx17 } from "react/jsx-runtime";
2030
+ function AgnoMessageTools({ renderTool: renderToolProp } = {}) {
2031
+ const { message, classNames, renderTool: ctxMsgRenderTool } = useAgnoMessageContext();
2032
+ const { renderTool: ctxChatRenderTool, isDebug } = useAgnoChatContext();
2033
+ const renderTool = renderToolProp ?? ctxMsgRenderTool ?? ctxChatRenderTool;
2034
+ if (!message.tool_calls || message.tool_calls.length === 0)
2035
+ return null;
2036
+ return /* @__PURE__ */ jsx17("div", {
2037
+ className: cn("space-y-2 pt-1", classNames?.assistant?.toolCalls),
2038
+ children: message.tool_calls.map((tool, idx) => {
2039
+ const defaultRender = () => isDebug ? /* @__PURE__ */ jsx17(ToolDebugCard, {
2040
+ tool,
2041
+ defaultOpen: idx === 0
2042
+ }) : null;
2043
+ const node = renderTool ? renderTool(tool, { index: idx, isDebug, defaultRender }) : defaultRender();
2044
+ if (node === null || node === undefined)
2045
+ return null;
2046
+ return /* @__PURE__ */ jsx17("div", {
2047
+ children: node
2048
+ }, tool.tool_call_id || idx);
2049
+ })
2050
+ });
752
2051
  }
753
- function resultWithSmartChart(data, options) {
754
- return createToolResult(data, createSmartChart(data, options));
2052
+
2053
+ // src/ui/components/response.tsx
2054
+ import { memo } from "react";
2055
+ import { Streamdown } from "streamdown";
2056
+ import { jsx as jsx18 } from "react/jsx-runtime";
2057
+ var Response = memo(({ className, ...props }) => /* @__PURE__ */ jsx18(Streamdown, {
2058
+ className: cn("size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", className),
2059
+ ...props
2060
+ }), (prevProps, nextProps) => prevProps.children === nextProps.children);
2061
+ Response.displayName = "Response";
2062
+
2063
+ // src/ui/composed/agno-message/content.tsx
2064
+ import { jsx as jsx19 } from "react/jsx-runtime";
2065
+ function AgnoMessageContent() {
2066
+ const { message } = useAgnoMessageContext();
2067
+ if (!message.content)
2068
+ return null;
2069
+ return /* @__PURE__ */ jsx19("div", {
2070
+ className: "prose prose-sm dark:prose-invert max-w-none prose-p:leading-relaxed prose-pre:bg-muted prose-pre:border prose-pre:border-border",
2071
+ children: /* @__PURE__ */ jsx19(Response, {
2072
+ children: message.content
2073
+ })
2074
+ });
755
2075
  }
756
- function resultWithCardGrid(cards, options) {
757
- return createToolResult(cards, createCardGrid(cards, options));
2076
+
2077
+ // src/ui/composed/agno-message/references.tsx
2078
+ import { FileText } from "lucide-react";
2079
+ import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
2080
+ function AgnoMessageReferences() {
2081
+ const { message, classNames } = useAgnoMessageContext();
2082
+ const references = message.extra_data?.references;
2083
+ if (!references || references.length === 0)
2084
+ return null;
2085
+ return /* @__PURE__ */ jsxs12("div", {
2086
+ className: cn("space-y-2 pt-1", classNames?.assistant?.references),
2087
+ children: [
2088
+ /* @__PURE__ */ jsxs12("div", {
2089
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2090
+ children: [
2091
+ /* @__PURE__ */ jsx20(FileText, {
2092
+ className: "h-3.5 w-3.5"
2093
+ }),
2094
+ "References (",
2095
+ references.length,
2096
+ ")"
2097
+ ]
2098
+ }),
2099
+ /* @__PURE__ */ jsx20("div", {
2100
+ className: "space-y-2",
2101
+ children: references.map((refData, idx) => /* @__PURE__ */ jsxs12("div", {
2102
+ className: "text-xs space-y-1.5",
2103
+ children: [
2104
+ refData.query && /* @__PURE__ */ jsxs12("div", {
2105
+ className: "font-medium text-foreground",
2106
+ children: [
2107
+ "Query: ",
2108
+ refData.query
2109
+ ]
2110
+ }),
2111
+ refData.references.map((ref, refIdx) => /* @__PURE__ */ jsxs12("div", {
2112
+ className: "bg-muted/50 border border-border p-2.5 rounded-lg",
2113
+ children: [
2114
+ /* @__PURE__ */ jsxs12("div", {
2115
+ className: "italic text-muted-foreground mb-1",
2116
+ children: [
2117
+ '"',
2118
+ ref.content,
2119
+ '"'
2120
+ ]
2121
+ }),
2122
+ /* @__PURE__ */ jsxs12("div", {
2123
+ className: "text-muted-foreground/70",
2124
+ children: [
2125
+ "Source: ",
2126
+ ref.name,
2127
+ " (chunk ",
2128
+ ref.meta_data.chunk,
2129
+ "/",
2130
+ ref.meta_data.chunk_size,
2131
+ ")"
2132
+ ]
2133
+ })
2134
+ ]
2135
+ }, refIdx))
2136
+ ]
2137
+ }, idx))
2138
+ })
2139
+ ]
2140
+ });
758
2141
  }
759
- function resultWithTable(data, columns, options) {
760
- return createToolResult(data, createTable(data, columns, options));
2142
+
2143
+ // src/ui/composed/agno-message/footer.tsx
2144
+ import { AlertCircle } from "lucide-react";
2145
+ import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
2146
+ function AgnoMessageFooter({ showTimestamp = true } = {}) {
2147
+ const { message, classNames, actions, isLastAssistantMessage, formatTimestamp } = useAgnoMessageContext();
2148
+ const hasError = message.streamingError;
2149
+ const isCustomTimestamp = !!formatTimestamp;
2150
+ const resolvedFormatTimestamp = formatTimestamp ?? formatSmartTimestamp;
2151
+ if (!actions?.assistant && !showTimestamp && !hasError)
2152
+ return null;
2153
+ return /* @__PURE__ */ jsxs13("div", {
2154
+ className: "flex items-center gap-2 pt-1",
2155
+ children: [
2156
+ actions?.assistant && (() => {
2157
+ const visibility = actions.visibility ?? "visible";
2158
+ if (visibility === "last-assistant" && !isLastAssistantMessage)
2159
+ return null;
2160
+ const useHover = visibility === "hover" || visibility === "hover-last-visible" && !isLastAssistantMessage;
2161
+ return /* @__PURE__ */ jsx21("div", {
2162
+ className: cn("flex items-center gap-1 transition-opacity", useHover && "opacity-0 group-hover/message:opacity-100", classNames?.assistant?.actions),
2163
+ children: actions.assistant(message)
2164
+ });
2165
+ })(),
2166
+ hasError && /* @__PURE__ */ jsxs13("span", {
2167
+ className: "flex items-center gap-1 text-[11px] text-destructive",
2168
+ children: [
2169
+ /* @__PURE__ */ jsx21(AlertCircle, {
2170
+ className: "h-3 w-3"
2171
+ }),
2172
+ "Error"
2173
+ ]
2174
+ }),
2175
+ showTimestamp && /* @__PURE__ */ jsx21(SmartTimestamp, {
2176
+ date: new Date(message.created_at * 1000),
2177
+ formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
2178
+ className: "text-[11px] text-muted-foreground"
2179
+ })
2180
+ ]
2181
+ });
761
2182
  }
762
- // src/hooks/useAgnoChat.ts
763
- import { useState as useState3, useEffect as useEffect3, useCallback as useCallback3 } from "react";
764
- function useAgnoChat() {
765
- const client = useAgnoClient();
766
- const [messages, setMessages] = useState3(client.getMessages());
767
- const [state, setState] = useState3(client.getState());
768
- useEffect3(() => {
769
- const handleMessageUpdate = (updatedMessages) => {
770
- setMessages(updatedMessages);
771
- };
772
- const handleMessageComplete = (updatedMessages) => {
773
- setMessages(updatedMessages);
774
- };
775
- const handleMessageRefreshed = (updatedMessages) => {
776
- setMessages(updatedMessages);
777
- };
778
- const handleStateChange = (newState) => {
779
- setState(newState);
780
- };
781
- const handleUIRender = (event) => {
782
- const { tools } = event;
783
- for (const tool of tools) {
784
- if (tool.ui_component) {
785
- client.hydrateToolCallUI(tool.tool_call_id, tool.ui_component);
786
- }
787
- }
788
- };
789
- const handleRunCancelled = () => {};
790
- client.on("message:update", handleMessageUpdate);
791
- client.on("message:complete", handleMessageComplete);
792
- client.on("message:refreshed", handleMessageRefreshed);
793
- client.on("state:change", handleStateChange);
794
- client.on("ui:render", handleUIRender);
795
- client.on("run:cancelled", handleRunCancelled);
796
- setMessages(client.getMessages());
797
- setState(client.getState());
798
- return () => {
799
- client.off("message:update", handleMessageUpdate);
800
- client.off("message:complete", handleMessageComplete);
801
- client.off("message:refreshed", handleMessageRefreshed);
802
- client.off("state:change", handleStateChange);
803
- client.off("ui:render", handleUIRender);
804
- client.off("run:cancelled", handleRunCancelled);
805
- };
806
- }, [client]);
807
- const sendMessage = useCallback3(async (message, options) => {
808
- try {
809
- await client.sendMessage(message, options);
810
- } catch (err) {
811
- throw err;
812
- }
813
- }, [client]);
814
- const clearMessages = useCallback3(() => {
815
- client.clearMessages();
816
- setMessages([]);
817
- }, [client]);
818
- const cancelRun = useCallback3(async () => {
819
- await client.cancelRun();
820
- }, [client]);
821
- return {
822
- messages,
823
- sendMessage,
824
- clearMessages,
825
- cancelRun,
826
- isStreaming: state.isStreaming,
827
- isRefreshing: state.isRefreshing,
828
- isPaused: state.isPaused,
829
- isCancelling: state.isCancelling,
830
- currentRunId: state.currentRunId,
831
- error: state.errorMessage,
832
- state
833
- };
2183
+
2184
+ // src/ui/composed/agno-message/message.tsx
2185
+ import { jsx as jsx22, jsxs as jsxs14, Fragment as Fragment4 } from "react/jsx-runtime";
2186
+ function DefaultAssistantComposition({ showTimestamp }) {
2187
+ return /* @__PURE__ */ jsxs14(Fragment4, {
2188
+ children: [
2189
+ /* @__PURE__ */ jsx22(AgnoMessageReasoning, {}),
2190
+ /* @__PURE__ */ jsx22(AgnoMessageMedia, {}),
2191
+ /* @__PURE__ */ jsx22(AgnoMessageTools, {}),
2192
+ /* @__PURE__ */ jsx22(AgnoMessageContent, {}),
2193
+ /* @__PURE__ */ jsx22(AgnoMessageReferences, {}),
2194
+ /* @__PURE__ */ jsx22(AgnoMessageFooter, {
2195
+ showTimestamp
2196
+ })
2197
+ ]
2198
+ });
834
2199
  }
835
- // src/hooks/useAgnoSession.ts
836
- import { useState as useState4, useEffect as useEffect4, useCallback as useCallback4 } from "react";
837
- function useAgnoSession() {
838
- const client = useAgnoClient();
839
- const [sessions, setSessions] = useState4([]);
840
- const [currentSessionId, setCurrentSessionId] = useState4(client.getConfig().sessionId);
841
- const [isLoading, setIsLoading] = useState4(false);
842
- const [error, setError] = useState4();
843
- useEffect4(() => {
844
- const handleSessionLoaded = (sessionId) => {
845
- setCurrentSessionId(sessionId);
846
- };
847
- const handleSessionCreated = (session) => {
848
- setSessions((prev) => [session, ...prev]);
849
- setCurrentSessionId(session.session_id);
850
- };
851
- const handleStateChange = () => {
852
- const config = client.getConfig();
853
- setCurrentSessionId(config.sessionId);
854
- setSessions(client.getState().sessions);
855
- };
856
- client.on("session:loaded", handleSessionLoaded);
857
- client.on("session:created", handleSessionCreated);
858
- client.on("state:change", handleStateChange);
859
- setSessions(client.getState().sessions);
860
- setCurrentSessionId(client.getConfig().sessionId);
861
- return () => {
862
- client.off("session:loaded", handleSessionLoaded);
863
- client.off("session:created", handleSessionCreated);
864
- client.off("state:change", handleStateChange);
865
- };
866
- }, [client]);
867
- const loadSession = useCallback4(async (sessionId, options) => {
868
- setIsLoading(true);
869
- setError(undefined);
870
- try {
871
- const messages = await client.loadSession(sessionId, options);
872
- setCurrentSessionId(sessionId);
873
- return messages;
874
- } catch (err) {
875
- const errorMessage = err instanceof Error ? err.message : String(err);
876
- setError(errorMessage);
877
- throw err;
878
- } finally {
879
- setIsLoading(false);
880
- }
881
- }, [client]);
882
- const fetchSessions = useCallback4(async (options) => {
883
- setIsLoading(true);
884
- setError(undefined);
885
- try {
886
- const fetchedSessions = await client.fetchSessions(options);
887
- setSessions(fetchedSessions);
888
- return fetchedSessions;
889
- } catch (err) {
890
- const errorMessage = err instanceof Error ? err.message : String(err);
891
- setError(errorMessage);
892
- throw err;
893
- } finally {
894
- setIsLoading(false);
895
- }
896
- }, [client]);
897
- const getSessionById = useCallback4(async (sessionId, options) => {
898
- setIsLoading(true);
899
- setError(undefined);
900
- try {
901
- return await client.getSessionById(sessionId, options);
902
- } catch (err) {
903
- const errorMessage = err instanceof Error ? err.message : String(err);
904
- setError(errorMessage);
905
- throw err;
906
- } finally {
907
- setIsLoading(false);
908
- }
909
- }, [client]);
910
- const getRunById = useCallback4(async (sessionId, runId, options) => {
911
- setIsLoading(true);
912
- setError(undefined);
913
- try {
914
- return await client.getRunById(sessionId, runId, options);
915
- } catch (err) {
916
- const errorMessage = err instanceof Error ? err.message : String(err);
917
- setError(errorMessage);
918
- throw err;
919
- } finally {
920
- setIsLoading(false);
921
- }
922
- }, [client]);
923
- const createSession = useCallback4(async (request, options) => {
924
- setIsLoading(true);
925
- setError(undefined);
926
- try {
927
- const session = await client.createSession(request, options);
928
- return session;
929
- } catch (err) {
930
- const errorMessage = err instanceof Error ? err.message : String(err);
931
- setError(errorMessage);
932
- throw err;
933
- } finally {
934
- setIsLoading(false);
935
- }
936
- }, [client]);
937
- const updateSession = useCallback4(async (sessionId, request, options) => {
938
- setIsLoading(true);
939
- setError(undefined);
940
- try {
941
- return await client.updateSession(sessionId, request, options);
942
- } catch (err) {
943
- const errorMessage = err instanceof Error ? err.message : String(err);
944
- setError(errorMessage);
945
- throw err;
946
- } finally {
947
- setIsLoading(false);
948
- }
949
- }, [client]);
950
- const renameSession = useCallback4(async (sessionId, newName, options) => {
951
- setIsLoading(true);
952
- setError(undefined);
953
- try {
954
- return await client.renameSession(sessionId, newName, options);
955
- } catch (err) {
956
- const errorMessage = err instanceof Error ? err.message : String(err);
957
- setError(errorMessage);
958
- throw err;
959
- } finally {
960
- setIsLoading(false);
961
- }
962
- }, [client]);
963
- const deleteSession = useCallback4(async (sessionId, options) => {
964
- setIsLoading(true);
965
- setError(undefined);
966
- try {
967
- await client.deleteSession(sessionId, options);
968
- } catch (err) {
969
- const errorMessage = err instanceof Error ? err.message : String(err);
970
- setError(errorMessage);
971
- throw err;
972
- } finally {
973
- setIsLoading(false);
974
- }
975
- }, [client]);
976
- const deleteMultipleSessions = useCallback4(async (sessionIds, options) => {
977
- setIsLoading(true);
978
- setError(undefined);
979
- try {
980
- await client.deleteMultipleSessions(sessionIds, options);
981
- } catch (err) {
982
- const errorMessage = err instanceof Error ? err.message : String(err);
983
- setError(errorMessage);
984
- throw err;
985
- } finally {
986
- setIsLoading(false);
987
- }
988
- }, [client]);
989
- return {
990
- sessions,
991
- currentSessionId,
992
- loadSession,
993
- fetchSessions,
994
- getSessionById,
995
- getRunById,
996
- createSession,
997
- updateSession,
998
- renameSession,
999
- deleteSession,
1000
- deleteMultipleSessions,
1001
- isLoading,
1002
- error
1003
- };
2200
+ function AgnoMessage({
2201
+ message,
2202
+ className,
2203
+ classNames,
2204
+ avatars,
2205
+ actions,
2206
+ isLastAssistantMessage = false,
2207
+ showFilePreview = true,
2208
+ showImageLightbox = true,
2209
+ showTimestamp = true,
2210
+ formatTimestamp,
2211
+ renderTool,
2212
+ children
2213
+ }) {
2214
+ const isUser = message.role === "user";
2215
+ const hasError = message.streamingError;
2216
+ const [preview, setPreview] = useState8(null);
2217
+ const isCustomTimestamp = !!formatTimestamp;
2218
+ const resolvedFormatTimestamp = formatTimestamp ?? formatSmartTimestamp;
2219
+ const ctx = useMemo3(() => ({
2220
+ message,
2221
+ isLastAssistantMessage,
2222
+ classNames,
2223
+ actions,
2224
+ avatars,
2225
+ formatTimestamp,
2226
+ showFilePreview,
2227
+ showImageLightbox,
2228
+ openImageLightbox: (images, index) => {
2229
+ if (!showImageLightbox)
2230
+ return;
2231
+ setPreview({ type: "image", images, initialIndex: index });
2232
+ },
2233
+ openFilePreview: (file) => {
2234
+ if (!showFilePreview)
2235
+ return;
2236
+ setPreview({ type: "file", file });
2237
+ },
2238
+ renderTool
2239
+ }), [
2240
+ message,
2241
+ isLastAssistantMessage,
2242
+ classNames,
2243
+ actions,
2244
+ avatars,
2245
+ formatTimestamp,
2246
+ showFilePreview,
2247
+ showImageLightbox,
2248
+ renderTool
2249
+ ]);
2250
+ const closePreview = () => setPreview(null);
2251
+ return /* @__PURE__ */ jsx22(AgnoMessageContext.Provider, {
2252
+ value: ctx,
2253
+ children: /* @__PURE__ */ jsxs14("div", {
2254
+ className: cn("py-5 first:pt-2", isUser ? "flex justify-end" : "", classNames?.root, className),
2255
+ children: [
2256
+ isUser ? /* @__PURE__ */ jsx22(UserMessageLayout, {
2257
+ message,
2258
+ classNames,
2259
+ avatars,
2260
+ actions,
2261
+ isCustomTimestamp,
2262
+ resolvedFormatTimestamp,
2263
+ showTimestamp,
2264
+ showImageLightbox,
2265
+ showFilePreview,
2266
+ openImageLightbox: ctx.openImageLightbox,
2267
+ openFilePreview: ctx.openFilePreview,
2268
+ hasError
2269
+ }) : /* @__PURE__ */ jsxs14("div", {
2270
+ className: "flex items-start gap-3 group/message",
2271
+ children: [
2272
+ avatars?.assistant,
2273
+ /* @__PURE__ */ jsx22("div", {
2274
+ className: cn("flex-1 min-w-0 space-y-3", classNames?.assistant?.container),
2275
+ children: children ?? /* @__PURE__ */ jsx22(DefaultAssistantComposition, {
2276
+ showTimestamp
2277
+ })
2278
+ })
2279
+ ]
2280
+ }),
2281
+ preview?.type === "image" && /* @__PURE__ */ jsx22(ImageLightbox, {
2282
+ open: true,
2283
+ onOpenChange: (open) => {
2284
+ if (!open)
2285
+ closePreview();
2286
+ },
2287
+ images: preview.images,
2288
+ initialIndex: preview.initialIndex
2289
+ }),
2290
+ preview?.type === "file" && /* @__PURE__ */ jsx22(FilePreviewModal, {
2291
+ open: true,
2292
+ onOpenChange: (open) => {
2293
+ if (!open)
2294
+ closePreview();
2295
+ },
2296
+ file: preview.file
2297
+ })
2298
+ ]
2299
+ })
2300
+ });
1004
2301
  }
1005
- // src/hooks/useAgnoActions.ts
1006
- import { useState as useState5, useCallback as useCallback5 } from "react";
1007
- function useAgnoActions() {
1008
- const client = useAgnoClient();
1009
- const [isInitializing, setIsInitializing] = useState5(false);
1010
- const [error, setError] = useState5();
1011
- const initialize = useCallback5(async (options) => {
1012
- setIsInitializing(true);
1013
- setError(undefined);
1014
- try {
1015
- const result = await client.initialize(options);
1016
- return result;
1017
- } catch (err) {
1018
- const errorMessage = err instanceof Error ? err.message : String(err);
1019
- setError(errorMessage);
1020
- throw err;
1021
- } finally {
1022
- setIsInitializing(false);
1023
- }
1024
- }, [client]);
1025
- const checkStatus = useCallback5(async (options) => {
1026
- setError(undefined);
1027
- try {
1028
- return await client.checkStatus(options);
1029
- } catch (err) {
1030
- const errorMessage = err instanceof Error ? err.message : String(err);
1031
- setError(errorMessage);
1032
- return false;
1033
- }
1034
- }, [client]);
1035
- const fetchAgents = useCallback5(async (options) => {
1036
- setError(undefined);
1037
- try {
1038
- return await client.fetchAgents(options);
1039
- } catch (err) {
1040
- const errorMessage = err instanceof Error ? err.message : String(err);
1041
- setError(errorMessage);
1042
- throw err;
1043
- }
1044
- }, [client]);
1045
- const fetchTeams = useCallback5(async (options) => {
1046
- setError(undefined);
1047
- try {
1048
- return await client.fetchTeams(options);
1049
- } catch (err) {
1050
- const errorMessage = err instanceof Error ? err.message : String(err);
1051
- setError(errorMessage);
1052
- throw err;
1053
- }
1054
- }, [client]);
1055
- const updateConfig = useCallback5((updates) => {
1056
- client.updateConfig(updates);
1057
- }, [client]);
1058
- return {
1059
- initialize,
1060
- checkStatus,
1061
- fetchAgents,
1062
- fetchTeams,
1063
- updateConfig,
1064
- isInitializing,
1065
- error
1066
- };
2302
+ AgnoMessage.Reasoning = AgnoMessageReasoning;
2303
+ AgnoMessage.Media = AgnoMessageMedia;
2304
+ AgnoMessage.Tools = AgnoMessageTools;
2305
+ AgnoMessage.Content = AgnoMessageContent;
2306
+ AgnoMessage.References = AgnoMessageReferences;
2307
+ AgnoMessage.Footer = AgnoMessageFooter;
2308
+ function UserMessageLayout({
2309
+ message,
2310
+ classNames,
2311
+ avatars,
2312
+ actions,
2313
+ isCustomTimestamp,
2314
+ resolvedFormatTimestamp,
2315
+ showTimestamp,
2316
+ showImageLightbox,
2317
+ showFilePreview,
2318
+ openImageLightbox,
2319
+ openFilePreview,
2320
+ hasError
2321
+ }) {
2322
+ return /* @__PURE__ */ jsxs14("div", {
2323
+ className: "flex items-start gap-2.5 max-w-[80%] flex-row-reverse",
2324
+ children: [
2325
+ avatars?.user,
2326
+ /* @__PURE__ */ jsxs14("div", {
2327
+ className: "space-y-1.5 flex flex-col items-end min-w-0",
2328
+ children: [
2329
+ (message.images && message.images.length > 0 || message.audio && message.audio.length > 0 || message.files && message.files.length > 0) && /* @__PURE__ */ jsxs14("div", {
2330
+ className: "flex flex-wrap gap-2 justify-end",
2331
+ children: [
2332
+ message.images?.map((img, idx) => /* @__PURE__ */ jsx22(FilePreviewCard, {
2333
+ file: { name: img.revised_prompt || `Image ${idx + 1}`, type: "image/png", url: img.url },
2334
+ onClick: showImageLightbox ? () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx) : undefined
2335
+ }, `img-${idx}`)),
2336
+ message.audio?.map((audio, idx) => /* @__PURE__ */ jsxs14("div", {
2337
+ className: "flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground self-end",
2338
+ children: [
2339
+ /* @__PURE__ */ jsx22(Music2, {
2340
+ className: "h-3.5 w-3.5 text-muted-foreground"
2341
+ }),
2342
+ /* @__PURE__ */ jsx22("span", {
2343
+ className: "truncate max-w-[150px]",
2344
+ children: audio.id || `Audio ${idx + 1}`
2345
+ })
2346
+ ]
2347
+ }, `audio-${idx}`)),
2348
+ message.files?.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx22(FilePreviewCard, {
2349
+ file: { name: file.name, type: file.type, url: file.url, size: file.size },
2350
+ onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
2351
+ }, `file-${idx}`) : /* @__PURE__ */ jsxs14("div", {
2352
+ className: "flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground self-end",
2353
+ children: [
2354
+ /* @__PURE__ */ jsx22(FileIcon4, {
2355
+ className: "h-3.5 w-3.5 text-muted-foreground"
2356
+ }),
2357
+ /* @__PURE__ */ jsx22("span", {
2358
+ className: "truncate max-w-[150px]",
2359
+ children: file.name
2360
+ })
2361
+ ]
2362
+ }, `file-${idx}`))
2363
+ ]
2364
+ }),
2365
+ message.content && /* @__PURE__ */ jsx22("div", {
2366
+ className: cn("rounded-2xl rounded-br-md px-4 py-2.5", classNames?.user?.bubble ?? "bg-primary text-primary-foreground", hasError && "opacity-70"),
2367
+ children: /* @__PURE__ */ jsx22("p", {
2368
+ className: "text-sm whitespace-pre-wrap",
2369
+ children: message.content
2370
+ })
2371
+ }),
2372
+ (showTimestamp || actions?.user) && /* @__PURE__ */ jsxs14("div", {
2373
+ className: "flex items-center justify-end gap-1.5 px-1",
2374
+ children: [
2375
+ actions?.user && /* @__PURE__ */ jsx22("div", {
2376
+ className: "flex items-center gap-1",
2377
+ children: actions.user(message)
2378
+ }),
2379
+ /* @__PURE__ */ jsx22(SmartTimestamp, {
2380
+ date: new Date(message.created_at * 1000),
2381
+ formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
2382
+ className: "text-[11px] text-muted-foreground"
2383
+ }),
2384
+ hasError && /* @__PURE__ */ jsx22(AlertCircle2, {
2385
+ className: "h-3 w-3 text-destructive"
2386
+ })
2387
+ ]
2388
+ })
2389
+ ]
2390
+ })
2391
+ ]
2392
+ });
1067
2393
  }
1068
2394
  // src/hooks/useAgnoCustomEvents.ts
1069
- import { useState as useState6, useEffect as useEffect5, useCallback as useCallback6, useRef } from "react";
2395
+ import { useState as useState9, useEffect as useEffect7, useCallback as useCallback7, useRef as useRef2 } from "react";
1070
2396
  function useAgnoCustomEvents(handler) {
1071
2397
  const client = useAgnoClient();
1072
- const [events, setEvents] = useState6([]);
1073
- const handlerRef = useRef(handler);
2398
+ const [events, setEvents] = useState9([]);
2399
+ const handlerRef = useRef2(handler);
1074
2400
  handlerRef.current = handler;
1075
- useEffect5(() => {
2401
+ useEffect7(() => {
1076
2402
  const handleCustomEvent = (event) => {
1077
2403
  setEvents((prev) => [...prev, event]);
1078
2404
  handlerRef.current?.(event);
@@ -1082,20 +2408,20 @@ function useAgnoCustomEvents(handler) {
1082
2408
  client.off("custom:event", handleCustomEvent);
1083
2409
  };
1084
2410
  }, [client]);
1085
- const clearEvents = useCallback6(() => {
2411
+ const clearEvents = useCallback7(() => {
1086
2412
  setEvents([]);
1087
2413
  }, []);
1088
2414
  return { events, clearEvents };
1089
2415
  }
1090
2416
  // src/hooks/useAgnoMemory.ts
1091
- import { useState as useState7, useEffect as useEffect6, useCallback as useCallback7 } from "react";
2417
+ import { useState as useState10, useEffect as useEffect8, useCallback as useCallback8 } from "react";
1092
2418
  function useAgnoMemory() {
1093
2419
  const client = useAgnoClient();
1094
- const [memories, setMemories] = useState7([]);
1095
- const [topics, setTopics] = useState7([]);
1096
- const [isLoading, setIsLoading] = useState7(false);
1097
- const [error, setError] = useState7();
1098
- useEffect6(() => {
2420
+ const [memories, setMemories] = useState10([]);
2421
+ const [topics, setTopics] = useState10([]);
2422
+ const [isLoading, setIsLoading] = useState10(false);
2423
+ const [error, setError] = useState10();
2424
+ useEffect8(() => {
1099
2425
  const handleMemoryCreated = (memory) => {
1100
2426
  setMemories((prev) => [memory, ...prev]);
1101
2427
  };
@@ -1130,7 +2456,7 @@ function useAgnoMemory() {
1130
2456
  client.off("state:change", handleStateChange);
1131
2457
  };
1132
2458
  }, [client]);
1133
- const fetchMemories = useCallback7(async (queryParams, options) => {
2459
+ const fetchMemories = useCallback8(async (queryParams, options) => {
1134
2460
  setIsLoading(true);
1135
2461
  setError(undefined);
1136
2462
  try {
@@ -1145,7 +2471,7 @@ function useAgnoMemory() {
1145
2471
  setIsLoading(false);
1146
2472
  }
1147
2473
  }, [client]);
1148
- const getMemoryById = useCallback7(async (memoryId, options) => {
2474
+ const getMemoryById = useCallback8(async (memoryId, options) => {
1149
2475
  setIsLoading(true);
1150
2476
  setError(undefined);
1151
2477
  try {
@@ -1158,7 +2484,7 @@ function useAgnoMemory() {
1158
2484
  setIsLoading(false);
1159
2485
  }
1160
2486
  }, [client]);
1161
- const getMemoryTopics = useCallback7(async (options) => {
2487
+ const getMemoryTopics = useCallback8(async (options) => {
1162
2488
  setIsLoading(true);
1163
2489
  setError(undefined);
1164
2490
  try {
@@ -1173,7 +2499,7 @@ function useAgnoMemory() {
1173
2499
  setIsLoading(false);
1174
2500
  }
1175
2501
  }, [client]);
1176
- const getUserMemoryStats = useCallback7(async (queryParams, options) => {
2502
+ const getUserMemoryStats = useCallback8(async (queryParams, options) => {
1177
2503
  setIsLoading(true);
1178
2504
  setError(undefined);
1179
2505
  try {
@@ -1186,7 +2512,7 @@ function useAgnoMemory() {
1186
2512
  setIsLoading(false);
1187
2513
  }
1188
2514
  }, [client]);
1189
- const createMemory = useCallback7(async (request, options) => {
2515
+ const createMemory = useCallback8(async (request, options) => {
1190
2516
  setIsLoading(true);
1191
2517
  setError(undefined);
1192
2518
  try {
@@ -1199,7 +2525,7 @@ function useAgnoMemory() {
1199
2525
  setIsLoading(false);
1200
2526
  }
1201
2527
  }, [client]);
1202
- const updateMemory = useCallback7(async (memoryId, request, options) => {
2528
+ const updateMemory = useCallback8(async (memoryId, request, options) => {
1203
2529
  setIsLoading(true);
1204
2530
  setError(undefined);
1205
2531
  try {
@@ -1212,7 +2538,7 @@ function useAgnoMemory() {
1212
2538
  setIsLoading(false);
1213
2539
  }
1214
2540
  }, [client]);
1215
- const deleteMemory = useCallback7(async (memoryId, options) => {
2541
+ const deleteMemory = useCallback8(async (memoryId, options) => {
1216
2542
  setIsLoading(true);
1217
2543
  setError(undefined);
1218
2544
  try {
@@ -1225,7 +2551,7 @@ function useAgnoMemory() {
1225
2551
  setIsLoading(false);
1226
2552
  }
1227
2553
  }, [client]);
1228
- const deleteMultipleMemories = useCallback7(async (memoryIds, options) => {
2554
+ const deleteMultipleMemories = useCallback8(async (memoryIds, options) => {
1229
2555
  setIsLoading(true);
1230
2556
  setError(undefined);
1231
2557
  try {
@@ -1254,12 +2580,12 @@ function useAgnoMemory() {
1254
2580
  };
1255
2581
  }
1256
2582
  // src/hooks/useAgnoSessionState.ts
1257
- import { useCallback as useCallback8, useEffect as useEffect7, useState as useState8 } from "react";
2583
+ import { useCallback as useCallback9, useEffect as useEffect9, useState as useState11 } from "react";
1258
2584
  function useAgnoSessionState() {
1259
2585
  const client = useAgnoClient();
1260
- const [sessionState, setLocalSessionState] = useState8(() => client.getSessionState());
1261
- const [isRefreshing, setIsRefreshing] = useState8(() => client.getState().isSessionStateRefreshing ?? false);
1262
- useEffect7(() => {
2586
+ const [sessionState, setLocalSessionState] = useState11(() => client.getSessionState());
2587
+ const [isRefreshing, setIsRefreshing] = useState11(() => client.getState().isSessionStateRefreshing ?? false);
2588
+ useEffect9(() => {
1263
2589
  const handleStateChange = (state) => {
1264
2590
  setLocalSessionState(state);
1265
2591
  };
@@ -1276,16 +2602,16 @@ function useAgnoSessionState() {
1276
2602
  client.off("session-state:refresh:end", handleRefreshEnd);
1277
2603
  };
1278
2604
  }, [client]);
1279
- const setSessionState = useCallback8(async (next) => {
2605
+ const setSessionState = useCallback9(async (next) => {
1280
2606
  const resolved = typeof next === "function" ? next(client.getSessionState()) : next;
1281
2607
  await client.setSessionState(resolved);
1282
2608
  }, [client]);
1283
- const mergeSessionState = useCallback8(async (partial) => {
2609
+ const mergeSessionState = useCallback9(async (partial) => {
1284
2610
  const current = client.getSessionState() ?? {};
1285
2611
  const merged = { ...current, ...partial };
1286
2612
  await client.setSessionState(merged);
1287
2613
  }, [client]);
1288
- const refreshSessionState = useCallback8(async () => {
2614
+ const refreshSessionState = useCallback9(async () => {
1289
2615
  const result = await client.refreshSessionState();
1290
2616
  return result ?? null;
1291
2617
  }, [client]);
@@ -1298,14 +2624,14 @@ function useAgnoSessionState() {
1298
2624
  };
1299
2625
  }
1300
2626
  // src/hooks/useAgnoKnowledge.ts
1301
- import { useState as useState9, useCallback as useCallback9 } from "react";
2627
+ import { useState as useState12, useCallback as useCallback10 } from "react";
1302
2628
  function useAgnoKnowledge() {
1303
2629
  const client = useAgnoClient();
1304
- const [isLoading, setIsLoading] = useState9(false);
1305
- const [error, setError] = useState9();
1306
- const [config, setConfig] = useState9();
1307
- const [content, setContent] = useState9([]);
1308
- const getConfig = useCallback9(async (options) => {
2630
+ const [isLoading, setIsLoading] = useState12(false);
2631
+ const [error, setError] = useState12();
2632
+ const [config, setConfig] = useState12();
2633
+ const [content, setContent] = useState12([]);
2634
+ const getConfig = useCallback10(async (options) => {
1309
2635
  setIsLoading(true);
1310
2636
  setError(undefined);
1311
2637
  try {
@@ -1320,7 +2646,7 @@ function useAgnoKnowledge() {
1320
2646
  setIsLoading(false);
1321
2647
  }
1322
2648
  }, [client]);
1323
- const listContent = useCallback9(async (listOptions, options) => {
2649
+ const listContent = useCallback10(async (listOptions, options) => {
1324
2650
  setIsLoading(true);
1325
2651
  setError(undefined);
1326
2652
  try {
@@ -1335,7 +2661,7 @@ function useAgnoKnowledge() {
1335
2661
  setIsLoading(false);
1336
2662
  }
1337
2663
  }, [client]);
1338
- const getContent = useCallback9(async (contentId, options) => {
2664
+ const getContent = useCallback10(async (contentId, options) => {
1339
2665
  setIsLoading(true);
1340
2666
  setError(undefined);
1341
2667
  try {
@@ -1348,7 +2674,7 @@ function useAgnoKnowledge() {
1348
2674
  setIsLoading(false);
1349
2675
  }
1350
2676
  }, [client]);
1351
- const getContentStatus = useCallback9(async (contentId, options) => {
2677
+ const getContentStatus = useCallback10(async (contentId, options) => {
1352
2678
  setIsLoading(true);
1353
2679
  setError(undefined);
1354
2680
  try {
@@ -1361,7 +2687,7 @@ function useAgnoKnowledge() {
1361
2687
  setIsLoading(false);
1362
2688
  }
1363
2689
  }, [client]);
1364
- const search = useCallback9(async (request, options) => {
2690
+ const search = useCallback10(async (request, options) => {
1365
2691
  setIsLoading(true);
1366
2692
  setError(undefined);
1367
2693
  try {
@@ -1374,7 +2700,7 @@ function useAgnoKnowledge() {
1374
2700
  setIsLoading(false);
1375
2701
  }
1376
2702
  }, [client]);
1377
- const uploadContent = useCallback9(async (data, options) => {
2703
+ const uploadContent = useCallback10(async (data, options) => {
1378
2704
  setIsLoading(true);
1379
2705
  setError(undefined);
1380
2706
  try {
@@ -1389,7 +2715,7 @@ function useAgnoKnowledge() {
1389
2715
  setIsLoading(false);
1390
2716
  }
1391
2717
  }, [client]);
1392
- const updateContent = useCallback9(async (contentId, request, options) => {
2718
+ const updateContent = useCallback10(async (contentId, request, options) => {
1393
2719
  setIsLoading(true);
1394
2720
  setError(undefined);
1395
2721
  try {
@@ -1404,7 +2730,7 @@ function useAgnoKnowledge() {
1404
2730
  setIsLoading(false);
1405
2731
  }
1406
2732
  }, [client]);
1407
- const deleteAllContent = useCallback9(async (options) => {
2733
+ const deleteAllContent = useCallback10(async (options) => {
1408
2734
  setIsLoading(true);
1409
2735
  setError(undefined);
1410
2736
  try {
@@ -1418,7 +2744,7 @@ function useAgnoKnowledge() {
1418
2744
  setIsLoading(false);
1419
2745
  }
1420
2746
  }, [client]);
1421
- const deleteContent = useCallback9(async (contentId, options) => {
2747
+ const deleteContent = useCallback10(async (contentId, options) => {
1422
2748
  setIsLoading(true);
1423
2749
  setError(undefined);
1424
2750
  try {
@@ -1450,14 +2776,14 @@ function useAgnoKnowledge() {
1450
2776
  };
1451
2777
  }
1452
2778
  // src/hooks/useAgnoMetrics.ts
1453
- import { useState as useState10, useCallback as useCallback10 } from "react";
2779
+ import { useState as useState13, useCallback as useCallback11 } from "react";
1454
2780
  function useAgnoMetrics() {
1455
2781
  const client = useAgnoClient();
1456
- const [isLoading, setIsLoading] = useState10(false);
1457
- const [isRefreshing, setIsRefreshing] = useState10(false);
1458
- const [error, setError] = useState10();
1459
- const [metrics, setMetrics] = useState10();
1460
- const fetchMetrics = useCallback10(async (options) => {
2782
+ const [isLoading, setIsLoading] = useState13(false);
2783
+ const [isRefreshing, setIsRefreshing] = useState13(false);
2784
+ const [error, setError] = useState13();
2785
+ const [metrics, setMetrics] = useState13();
2786
+ const fetchMetrics = useCallback11(async (options) => {
1461
2787
  setIsLoading(true);
1462
2788
  setError(undefined);
1463
2789
  try {
@@ -1472,7 +2798,7 @@ function useAgnoMetrics() {
1472
2798
  setIsLoading(false);
1473
2799
  }
1474
2800
  }, [client]);
1475
- const refreshMetrics = useCallback10(async (options) => {
2801
+ const refreshMetrics = useCallback11(async (options) => {
1476
2802
  setIsRefreshing(true);
1477
2803
  setError(undefined);
1478
2804
  try {
@@ -1486,7 +2812,7 @@ function useAgnoMetrics() {
1486
2812
  setIsRefreshing(false);
1487
2813
  }
1488
2814
  }, [client]);
1489
- const clearMetrics = useCallback10(() => {
2815
+ const clearMetrics = useCallback11(() => {
1490
2816
  setMetrics(undefined);
1491
2817
  setError(undefined);
1492
2818
  }, []);
@@ -1501,14 +2827,14 @@ function useAgnoMetrics() {
1501
2827
  };
1502
2828
  }
1503
2829
  // src/hooks/useAgnoEvals.ts
1504
- import { useState as useState11, useCallback as useCallback11 } from "react";
2830
+ import { useState as useState14, useCallback as useCallback12 } from "react";
1505
2831
  function useAgnoEvals() {
1506
2832
  const client = useAgnoClient();
1507
- const [evalRuns, setEvalRuns] = useState11([]);
1508
- const [pagination, setPagination] = useState11();
1509
- const [isLoading, setIsLoading] = useState11(false);
1510
- const [error, setError] = useState11();
1511
- const listEvalRuns = useCallback11(async (listParams = {}, options) => {
2833
+ const [evalRuns, setEvalRuns] = useState14([]);
2834
+ const [pagination, setPagination] = useState14();
2835
+ const [isLoading, setIsLoading] = useState14(false);
2836
+ const [error, setError] = useState14();
2837
+ const listEvalRuns = useCallback12(async (listParams = {}, options) => {
1512
2838
  setIsLoading(true);
1513
2839
  setError(undefined);
1514
2840
  try {
@@ -1524,7 +2850,7 @@ function useAgnoEvals() {
1524
2850
  setIsLoading(false);
1525
2851
  }
1526
2852
  }, [client]);
1527
- const getEvalRun = useCallback11(async (evalRunId, options) => {
2853
+ const getEvalRun = useCallback12(async (evalRunId, options) => {
1528
2854
  setIsLoading(true);
1529
2855
  setError(undefined);
1530
2856
  try {
@@ -1537,7 +2863,7 @@ function useAgnoEvals() {
1537
2863
  setIsLoading(false);
1538
2864
  }
1539
2865
  }, [client]);
1540
- const executeEval = useCallback11(async (request, options) => {
2866
+ const executeEval = useCallback12(async (request, options) => {
1541
2867
  setIsLoading(true);
1542
2868
  setError(undefined);
1543
2869
  try {
@@ -1552,7 +2878,7 @@ function useAgnoEvals() {
1552
2878
  setIsLoading(false);
1553
2879
  }
1554
2880
  }, [client]);
1555
- const updateEvalRun = useCallback11(async (evalRunId, request, options) => {
2881
+ const updateEvalRun = useCallback12(async (evalRunId, request, options) => {
1556
2882
  setIsLoading(true);
1557
2883
  setError(undefined);
1558
2884
  try {
@@ -1567,7 +2893,7 @@ function useAgnoEvals() {
1567
2893
  setIsLoading(false);
1568
2894
  }
1569
2895
  }, [client]);
1570
- const deleteEvalRuns = useCallback11(async (evalRunIds, options) => {
2896
+ const deleteEvalRuns = useCallback12(async (evalRunIds, options) => {
1571
2897
  setIsLoading(true);
1572
2898
  setError(undefined);
1573
2899
  try {
@@ -1582,7 +2908,7 @@ function useAgnoEvals() {
1582
2908
  setIsLoading(false);
1583
2909
  }
1584
2910
  }, [client]);
1585
- const renameEvalRun = useCallback11(async (evalRunId, newName, options) => {
2911
+ const renameEvalRun = useCallback12(async (evalRunId, newName, options) => {
1586
2912
  return updateEvalRun(evalRunId, { name: newName }, options);
1587
2913
  }, [updateEvalRun]);
1588
2914
  return {
@@ -1599,14 +2925,14 @@ function useAgnoEvals() {
1599
2925
  };
1600
2926
  }
1601
2927
  // src/hooks/useAgnoTraces.ts
1602
- import { useState as useState12, useEffect as useEffect8, useCallback as useCallback12 } from "react";
2928
+ import { useState as useState15, useEffect as useEffect10, useCallback as useCallback13 } from "react";
1603
2929
  function useAgnoTraces() {
1604
2930
  const client = useAgnoClient();
1605
- const [traces, setTraces] = useState12([]);
1606
- const [traceSessionStats, setTraceSessionStats] = useState12([]);
1607
- const [isLoading, setIsLoading] = useState12(false);
1608
- const [error, setError] = useState12();
1609
- useEffect8(() => {
2931
+ const [traces, setTraces] = useState15([]);
2932
+ const [traceSessionStats, setTraceSessionStats] = useState15([]);
2933
+ const [isLoading, setIsLoading] = useState15(false);
2934
+ const [error, setError] = useState15();
2935
+ useEffect10(() => {
1610
2936
  const handleStateChange = () => {
1611
2937
  const state2 = client.getState();
1612
2938
  setTraces(state2.traces);
@@ -1620,7 +2946,7 @@ function useAgnoTraces() {
1620
2946
  client.off("state:change", handleStateChange);
1621
2947
  };
1622
2948
  }, [client]);
1623
- const fetchTraces = useCallback12(async (options = {}, requestOptions) => {
2949
+ const fetchTraces = useCallback13(async (options = {}, requestOptions) => {
1624
2950
  setIsLoading(true);
1625
2951
  setError(undefined);
1626
2952
  try {
@@ -1635,7 +2961,7 @@ function useAgnoTraces() {
1635
2961
  setIsLoading(false);
1636
2962
  }
1637
2963
  }, [client]);
1638
- const getTraceDetail = useCallback12(async (traceId, options = {}, requestOptions) => {
2964
+ const getTraceDetail = useCallback13(async (traceId, options = {}, requestOptions) => {
1639
2965
  setIsLoading(true);
1640
2966
  setError(undefined);
1641
2967
  try {
@@ -1648,7 +2974,7 @@ function useAgnoTraces() {
1648
2974
  setIsLoading(false);
1649
2975
  }
1650
2976
  }, [client]);
1651
- const fetchTraceSessionStats = useCallback12(async (options = {}, requestOptions) => {
2977
+ const fetchTraceSessionStats = useCallback13(async (options = {}, requestOptions) => {
1652
2978
  setIsLoading(true);
1653
2979
  setError(undefined);
1654
2980
  try {
@@ -1674,13 +3000,13 @@ function useAgnoTraces() {
1674
3000
  };
1675
3001
  }
1676
3002
  // src/hooks/useAgnoComponents.ts
1677
- import { useState as useState13, useEffect as useEffect9, useCallback as useCallback13 } from "react";
3003
+ import { useState as useState16, useEffect as useEffect11, useCallback as useCallback14 } from "react";
1678
3004
  function useAgnoComponents() {
1679
3005
  const client = useAgnoClient();
1680
- const [components, setComponents] = useState13([]);
1681
- const [isLoading, setIsLoading] = useState13(false);
1682
- const [error, setError] = useState13();
1683
- useEffect9(() => {
3006
+ const [components, setComponents] = useState16([]);
3007
+ const [isLoading, setIsLoading] = useState16(false);
3008
+ const [error, setError] = useState16();
3009
+ useEffect11(() => {
1684
3010
  const handleComponentCreated = (component) => {
1685
3011
  setComponents((prev) => [component, ...prev]);
1686
3012
  };
@@ -1705,7 +3031,7 @@ function useAgnoComponents() {
1705
3031
  client.off("state:change", handleStateChange);
1706
3032
  };
1707
3033
  }, [client]);
1708
- const fetchComponents = useCallback13(async (queryParams, options) => {
3034
+ const fetchComponents = useCallback14(async (queryParams, options) => {
1709
3035
  setIsLoading(true);
1710
3036
  setError(undefined);
1711
3037
  try {
@@ -1720,7 +3046,7 @@ function useAgnoComponents() {
1720
3046
  setIsLoading(false);
1721
3047
  }
1722
3048
  }, [client]);
1723
- const getComponentById = useCallback13(async (componentId, options) => {
3049
+ const getComponentById = useCallback14(async (componentId, options) => {
1724
3050
  setIsLoading(true);
1725
3051
  setError(undefined);
1726
3052
  try {
@@ -1733,7 +3059,7 @@ function useAgnoComponents() {
1733
3059
  setIsLoading(false);
1734
3060
  }
1735
3061
  }, [client]);
1736
- const createComponent = useCallback13(async (request, options) => {
3062
+ const createComponent = useCallback14(async (request, options) => {
1737
3063
  setIsLoading(true);
1738
3064
  setError(undefined);
1739
3065
  try {
@@ -1746,7 +3072,7 @@ function useAgnoComponents() {
1746
3072
  setIsLoading(false);
1747
3073
  }
1748
3074
  }, [client]);
1749
- const updateComponent = useCallback13(async (componentId, request, options) => {
3075
+ const updateComponent = useCallback14(async (componentId, request, options) => {
1750
3076
  setIsLoading(true);
1751
3077
  setError(undefined);
1752
3078
  try {
@@ -1759,7 +3085,7 @@ function useAgnoComponents() {
1759
3085
  setIsLoading(false);
1760
3086
  }
1761
3087
  }, [client]);
1762
- const deleteComponent = useCallback13(async (componentId, options) => {
3088
+ const deleteComponent = useCallback14(async (componentId, options) => {
1763
3089
  setIsLoading(true);
1764
3090
  setError(undefined);
1765
3091
  try {
@@ -1772,7 +3098,7 @@ function useAgnoComponents() {
1772
3098
  setIsLoading(false);
1773
3099
  }
1774
3100
  }, [client]);
1775
- const fetchComponentConfigs = useCallback13(async (componentId, options) => {
3101
+ const fetchComponentConfigs = useCallback14(async (componentId, options) => {
1776
3102
  setIsLoading(true);
1777
3103
  setError(undefined);
1778
3104
  try {
@@ -1785,7 +3111,7 @@ function useAgnoComponents() {
1785
3111
  setIsLoading(false);
1786
3112
  }
1787
3113
  }, [client]);
1788
- const createComponentConfig = useCallback13(async (componentId, request, options) => {
3114
+ const createComponentConfig = useCallback14(async (componentId, request, options) => {
1789
3115
  setIsLoading(true);
1790
3116
  setError(undefined);
1791
3117
  try {
@@ -1798,7 +3124,7 @@ function useAgnoComponents() {
1798
3124
  setIsLoading(false);
1799
3125
  }
1800
3126
  }, [client]);
1801
- const getCurrentComponentConfig = useCallback13(async (componentId, options) => {
3127
+ const getCurrentComponentConfig = useCallback14(async (componentId, options) => {
1802
3128
  setIsLoading(true);
1803
3129
  setError(undefined);
1804
3130
  try {
@@ -1811,7 +3137,7 @@ function useAgnoComponents() {
1811
3137
  setIsLoading(false);
1812
3138
  }
1813
3139
  }, [client]);
1814
- const getComponentConfigByVersion = useCallback13(async (componentId, version, options) => {
3140
+ const getComponentConfigByVersion = useCallback14(async (componentId, version, options) => {
1815
3141
  setIsLoading(true);
1816
3142
  setError(undefined);
1817
3143
  try {
@@ -1824,7 +3150,7 @@ function useAgnoComponents() {
1824
3150
  setIsLoading(false);
1825
3151
  }
1826
3152
  }, [client]);
1827
- const updateComponentConfig = useCallback13(async (componentId, version, request, options) => {
3153
+ const updateComponentConfig = useCallback14(async (componentId, version, request, options) => {
1828
3154
  setIsLoading(true);
1829
3155
  setError(undefined);
1830
3156
  try {
@@ -1837,7 +3163,7 @@ function useAgnoComponents() {
1837
3163
  setIsLoading(false);
1838
3164
  }
1839
3165
  }, [client]);
1840
- const deleteComponentConfig = useCallback13(async (componentId, version, options) => {
3166
+ const deleteComponentConfig = useCallback14(async (componentId, version, options) => {
1841
3167
  setIsLoading(true);
1842
3168
  setError(undefined);
1843
3169
  try {
@@ -1850,7 +3176,7 @@ function useAgnoComponents() {
1850
3176
  setIsLoading(false);
1851
3177
  }
1852
3178
  }, [client]);
1853
- const setCurrentComponentConfig = useCallback13(async (componentId, version, options) => {
3179
+ const setCurrentComponentConfig = useCallback14(async (componentId, version, options) => {
1854
3180
  setIsLoading(true);
1855
3181
  setError(undefined);
1856
3182
  try {
@@ -1888,6 +3214,7 @@ export {
1888
3214
  useAgnoSessionState,
1889
3215
  useAgnoSession,
1890
3216
  useAgnoMetrics,
3217
+ useAgnoMessageContext,
1891
3218
  useAgnoMemory,
1892
3219
  useAgnoKnowledge,
1893
3220
  useAgnoEvals,
@@ -1900,10 +3227,6 @@ export {
1900
3227
  resultWithSmartChart,
1901
3228
  resultWithCardGrid,
1902
3229
  resultWithBarChart,
1903
- registerChartComponent,
1904
- getCustomRender,
1905
- getComponentRegistry,
1906
- getChartComponent,
1907
3230
  createToolResult,
1908
3231
  createTable,
1909
3232
  createSmartChart,
@@ -1916,10 +3239,18 @@ export {
1916
3239
  createBarChart,
1917
3240
  createArtifact,
1918
3241
  createAreaChart,
3242
+ byToolName,
1919
3243
  ToolHandlerProvider,
1920
- GenerativeUIRenderer,
1921
- ComponentRegistry,
1922
- AgnoProvider
3244
+ ToolDebugCard,
3245
+ AgnoProvider,
3246
+ AgnoMessageTools,
3247
+ AgnoMessageReferences,
3248
+ AgnoMessageReasoning,
3249
+ AgnoMessageMedia,
3250
+ AgnoMessageFooter,
3251
+ AgnoMessageContext,
3252
+ AgnoMessageContent,
3253
+ AgnoMessage
1923
3254
  };
1924
3255
 
1925
- //# debugId=001BF048D0CD48E164756E2164756E21
3256
+ //# debugId=D4A0A1768653051B64756E2164756E21