@antipopp/agno-react 0.9.0 → 0.11.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.
- package/README.md +18 -1
- package/dist/index.d.mts +124 -121
- package/dist/index.d.ts +124 -121
- package/dist/index.js +704 -534
- package/dist/index.mjs +711 -542
- package/package.json +13 -5
package/dist/index.mjs
CHANGED
|
@@ -1,56 +1,12 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import
|
|
3
|
-
import { AgnoClient } from "@antipopp/agno-client";
|
|
4
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
var AgnoContext = createContext(null);
|
|
6
|
-
function AgnoProvider({ config, children }) {
|
|
7
|
-
const client = useMemo(() => new AgnoClient(config), []);
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
client.updateConfig(config);
|
|
10
|
-
}, [client, config]);
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
return () => {
|
|
13
|
-
client.removeAllListeners();
|
|
14
|
-
};
|
|
15
|
-
}, [client]);
|
|
16
|
-
return /* @__PURE__ */ jsx(AgnoContext.Provider, { value: client, children });
|
|
17
|
-
}
|
|
18
|
-
function useAgnoClient() {
|
|
19
|
-
const client = useContext(AgnoContext);
|
|
20
|
-
if (!client) {
|
|
21
|
-
throw new Error("useAgnoClient must be used within an AgnoProvider");
|
|
22
|
-
}
|
|
23
|
-
return client;
|
|
24
|
-
}
|
|
1
|
+
// src/components/GenerativeUIRenderer.tsx
|
|
2
|
+
import React from "react";
|
|
25
3
|
|
|
26
|
-
// src/
|
|
27
|
-
import {
|
|
28
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
29
|
-
var ToolHandlerContext = createContext2(null);
|
|
30
|
-
function ToolHandlerProvider({ handlers: initialHandlers = {}, children }) {
|
|
31
|
-
const [handlers, setHandlers] = useState(initialHandlers);
|
|
32
|
-
const registerHandler = useCallback((name, handler) => {
|
|
33
|
-
setHandlers((prev) => ({ ...prev, [name]: handler }));
|
|
34
|
-
}, []);
|
|
35
|
-
const unregisterHandler = useCallback((name) => {
|
|
36
|
-
setHandlers((prev) => {
|
|
37
|
-
const { [name]: _, ...rest } = prev;
|
|
38
|
-
return rest;
|
|
39
|
-
});
|
|
40
|
-
}, []);
|
|
41
|
-
const value = {
|
|
42
|
-
handlers,
|
|
43
|
-
registerHandler,
|
|
44
|
-
unregisterHandler
|
|
45
|
-
};
|
|
46
|
-
return /* @__PURE__ */ jsx2(ToolHandlerContext.Provider, { value, children });
|
|
47
|
-
}
|
|
48
|
-
function useToolHandlers() {
|
|
49
|
-
return useContext2(ToolHandlerContext);
|
|
50
|
-
}
|
|
4
|
+
// src/hooks/useAgnoToolExecution.ts
|
|
5
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
|
|
51
6
|
|
|
52
|
-
// src/
|
|
53
|
-
import
|
|
7
|
+
// src/context/AgnoContext.tsx
|
|
8
|
+
import { AgnoClient } from "@antipopp/agno-client";
|
|
9
|
+
import { createContext, useContext, useEffect, useRef } from "react";
|
|
54
10
|
|
|
55
11
|
// src/utils/component-registry.ts
|
|
56
12
|
var ComponentRegistry = class _ComponentRegistry {
|
|
@@ -76,9 +32,9 @@ var ComponentRegistry = class _ComponentRegistry {
|
|
|
76
32
|
* Register multiple components at once
|
|
77
33
|
*/
|
|
78
34
|
registerBatch(components) {
|
|
79
|
-
|
|
35
|
+
for (const [type, renderer] of Object.entries(components)) {
|
|
80
36
|
this.register(type, renderer);
|
|
81
|
-
}
|
|
37
|
+
}
|
|
82
38
|
}
|
|
83
39
|
/**
|
|
84
40
|
* Get a registered component renderer
|
|
@@ -110,6 +66,17 @@ var ComponentRegistry = class _ComponentRegistry {
|
|
|
110
66
|
clear() {
|
|
111
67
|
this.components.clear();
|
|
112
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Reset the singleton instance.
|
|
71
|
+
* Call this during cleanup (e.g., when AgnoProvider unmounts) to prevent memory leaks.
|
|
72
|
+
* After calling this, getInstance() will create a fresh instance.
|
|
73
|
+
*/
|
|
74
|
+
static resetInstance() {
|
|
75
|
+
if (_ComponentRegistry.instance) {
|
|
76
|
+
_ComponentRegistry.instance.clear();
|
|
77
|
+
_ComponentRegistry.instance = void 0;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
113
80
|
};
|
|
114
81
|
function getComponentRegistry() {
|
|
115
82
|
return ComponentRegistry.getInstance();
|
|
@@ -121,39 +88,157 @@ function getChartComponent(name) {
|
|
|
121
88
|
return getComponentRegistry().get(`chart:${name}`);
|
|
122
89
|
}
|
|
123
90
|
|
|
91
|
+
// src/context/AgnoContext.tsx
|
|
92
|
+
import { jsx } from "react/jsx-runtime";
|
|
93
|
+
var AgnoContext = createContext(null);
|
|
94
|
+
function AgnoProvider({ config, children }) {
|
|
95
|
+
const clientRef = useRef(null);
|
|
96
|
+
if (clientRef.current === null) {
|
|
97
|
+
clientRef.current = new AgnoClient(config);
|
|
98
|
+
}
|
|
99
|
+
const client = clientRef.current;
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
client.updateConfig(config);
|
|
102
|
+
}, [client, config]);
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
return () => {
|
|
105
|
+
client.dispose();
|
|
106
|
+
clearCustomRenderRegistry();
|
|
107
|
+
ComponentRegistry.resetInstance();
|
|
108
|
+
};
|
|
109
|
+
}, [client]);
|
|
110
|
+
return /* @__PURE__ */ jsx(AgnoContext.Provider, { value: client, children });
|
|
111
|
+
}
|
|
112
|
+
function useAgnoClient() {
|
|
113
|
+
const client = useContext(AgnoContext);
|
|
114
|
+
if (!client) {
|
|
115
|
+
throw new Error("useAgnoClient must be used within an AgnoProvider");
|
|
116
|
+
}
|
|
117
|
+
return client;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/context/ToolHandlerContext.tsx
|
|
121
|
+
import { createContext as createContext2, useCallback, useContext as useContext2, useState } from "react";
|
|
122
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
123
|
+
var ToolHandlerContext = createContext2(null);
|
|
124
|
+
function ToolHandlerProvider({
|
|
125
|
+
handlers: initialHandlers = {},
|
|
126
|
+
children
|
|
127
|
+
}) {
|
|
128
|
+
const [handlers, setHandlers] = useState(initialHandlers);
|
|
129
|
+
const registerHandler = useCallback((name, handler) => {
|
|
130
|
+
setHandlers((prev) => ({ ...prev, [name]: handler }));
|
|
131
|
+
}, []);
|
|
132
|
+
const unregisterHandler = useCallback((name) => {
|
|
133
|
+
setHandlers((prev) => {
|
|
134
|
+
const { [name]: _, ...rest } = prev;
|
|
135
|
+
return rest;
|
|
136
|
+
});
|
|
137
|
+
}, []);
|
|
138
|
+
const value = {
|
|
139
|
+
handlers,
|
|
140
|
+
registerHandler,
|
|
141
|
+
unregisterHandler
|
|
142
|
+
};
|
|
143
|
+
return /* @__PURE__ */ jsx2(ToolHandlerContext.Provider, { value, children });
|
|
144
|
+
}
|
|
145
|
+
function useToolHandlers() {
|
|
146
|
+
return useContext2(ToolHandlerContext);
|
|
147
|
+
}
|
|
148
|
+
|
|
124
149
|
// src/hooks/useAgnoToolExecution.ts
|
|
125
|
-
|
|
150
|
+
function isRecord(value) {
|
|
151
|
+
return typeof value === "object" && value !== null;
|
|
152
|
+
}
|
|
153
|
+
function getCustomRenderFunction(value) {
|
|
154
|
+
if (value.type !== "custom") {
|
|
155
|
+
return void 0;
|
|
156
|
+
}
|
|
157
|
+
const maybeRender = value.render;
|
|
158
|
+
return typeof maybeRender === "function" ? maybeRender : void 0;
|
|
159
|
+
}
|
|
126
160
|
var customRenderRegistry = /* @__PURE__ */ new Map();
|
|
127
161
|
function registerCustomRender(renderFn) {
|
|
128
162
|
const key = `custom-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
129
163
|
customRenderRegistry.set(key, renderFn);
|
|
130
164
|
return key;
|
|
131
165
|
}
|
|
166
|
+
function toSerializableUIComponent(spec) {
|
|
167
|
+
const renderFn = getCustomRenderFunction(spec);
|
|
168
|
+
if (!renderFn) {
|
|
169
|
+
return spec;
|
|
170
|
+
}
|
|
171
|
+
const { render: _render, ...uiWithoutRender } = spec;
|
|
172
|
+
return {
|
|
173
|
+
...uiWithoutRender,
|
|
174
|
+
renderKey: registerCustomRender(renderFn)
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
async function executeToolCall(tool, handlers) {
|
|
178
|
+
const handler = handlers[tool.tool_name];
|
|
179
|
+
if (!handler) {
|
|
180
|
+
return {
|
|
181
|
+
...tool,
|
|
182
|
+
result: JSON.stringify({
|
|
183
|
+
error: `No handler registered for ${tool.tool_name}`
|
|
184
|
+
})
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
const result = await handler(tool.tool_args);
|
|
189
|
+
const { resultData, uiComponent } = processToolResult(result, tool);
|
|
190
|
+
return {
|
|
191
|
+
...tool,
|
|
192
|
+
result: resultData,
|
|
193
|
+
ui_component: uiComponent
|
|
194
|
+
};
|
|
195
|
+
} catch (error) {
|
|
196
|
+
return {
|
|
197
|
+
...tool,
|
|
198
|
+
result: JSON.stringify({
|
|
199
|
+
error: error instanceof Error ? error.message : String(error)
|
|
200
|
+
})
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async function hydrateToolUIForSession(tools, handlers, onHydrate) {
|
|
205
|
+
for (const tool of tools) {
|
|
206
|
+
if (tool.ui_component) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
const handler = handlers[tool.tool_name];
|
|
210
|
+
if (!handler) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
const result = await handler(tool.tool_args);
|
|
215
|
+
const { uiComponent } = processToolResult(result, tool);
|
|
216
|
+
if (uiComponent) {
|
|
217
|
+
onHydrate(tool.tool_call_id, uiComponent);
|
|
218
|
+
}
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error(`Failed to hydrate UI for ${tool.tool_name}:`, error);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
132
224
|
function getCustomRender(key) {
|
|
133
225
|
return customRenderRegistry.get(key);
|
|
134
226
|
}
|
|
227
|
+
function clearCustomRenderRegistry() {
|
|
228
|
+
customRenderRegistry.clear();
|
|
229
|
+
}
|
|
135
230
|
function isToolHandlerResult(value) {
|
|
136
|
-
return value &&
|
|
231
|
+
return isRecord(value) && ("data" in value || "ui" in value);
|
|
137
232
|
}
|
|
138
233
|
function isUIComponentSpec(value) {
|
|
139
|
-
return value && typeof value === "
|
|
234
|
+
return isRecord(value) && typeof value.type === "string";
|
|
140
235
|
}
|
|
141
236
|
function processToolResult(result, _tool) {
|
|
142
237
|
if (isToolHandlerResult(result)) {
|
|
143
238
|
const { data, ui } = result;
|
|
144
|
-
let uiComponent
|
|
239
|
+
let uiComponent;
|
|
145
240
|
if (ui) {
|
|
146
|
-
|
|
147
|
-
const renderKey = registerCustomRender(ui.render);
|
|
148
|
-
uiComponent = {
|
|
149
|
-
...ui,
|
|
150
|
-
renderKey,
|
|
151
|
-
render: void 0
|
|
152
|
-
// Don't store the function itself
|
|
153
|
-
};
|
|
154
|
-
} else {
|
|
155
|
-
uiComponent = ui;
|
|
156
|
-
}
|
|
241
|
+
uiComponent = toSerializableUIComponent(ui);
|
|
157
242
|
}
|
|
158
243
|
return {
|
|
159
244
|
resultData: typeof data === "string" ? data : JSON.stringify(data),
|
|
@@ -161,17 +246,7 @@ function processToolResult(result, _tool) {
|
|
|
161
246
|
};
|
|
162
247
|
}
|
|
163
248
|
if (isUIComponentSpec(result)) {
|
|
164
|
-
|
|
165
|
-
if (result.type === "custom" && typeof result.render === "function") {
|
|
166
|
-
const renderKey = registerCustomRender(result.render);
|
|
167
|
-
uiComponent = {
|
|
168
|
-
...result,
|
|
169
|
-
renderKey,
|
|
170
|
-
render: void 0
|
|
171
|
-
};
|
|
172
|
-
} else {
|
|
173
|
-
uiComponent = result;
|
|
174
|
-
}
|
|
249
|
+
const uiComponent = toSerializableUIComponent(result);
|
|
175
250
|
return {
|
|
176
251
|
resultData: JSON.stringify(result),
|
|
177
252
|
uiComponent
|
|
@@ -193,7 +268,7 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
193
268
|
);
|
|
194
269
|
}
|
|
195
270
|
}, [isTeamMode]);
|
|
196
|
-
const mergedHandlers =
|
|
271
|
+
const mergedHandlers = useMemo(() => {
|
|
197
272
|
const globalHandlers = toolHandlerContext?.handlers || {};
|
|
198
273
|
return { ...globalHandlers, ...handlers };
|
|
199
274
|
}, [toolHandlerContext?.handlers, handlers]);
|
|
@@ -232,35 +307,9 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
232
307
|
setExecutionError(void 0);
|
|
233
308
|
try {
|
|
234
309
|
const updatedTools = await Promise.all(
|
|
235
|
-
pendingTools.map(
|
|
236
|
-
const handler = mergedHandlers[tool.tool_name];
|
|
237
|
-
if (!handler) {
|
|
238
|
-
return {
|
|
239
|
-
...tool,
|
|
240
|
-
result: JSON.stringify({
|
|
241
|
-
error: `No handler registered for ${tool.tool_name}`
|
|
242
|
-
})
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
try {
|
|
246
|
-
const result = await handler(tool.tool_args);
|
|
247
|
-
const { resultData, uiComponent } = processToolResult(result, tool);
|
|
248
|
-
return {
|
|
249
|
-
...tool,
|
|
250
|
-
result: resultData,
|
|
251
|
-
ui_component: uiComponent
|
|
252
|
-
};
|
|
253
|
-
} catch (error) {
|
|
254
|
-
return {
|
|
255
|
-
...tool,
|
|
256
|
-
result: JSON.stringify({
|
|
257
|
-
error: error instanceof Error ? error.message : String(error)
|
|
258
|
-
})
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
})
|
|
310
|
+
pendingTools.map((tool) => executeToolCall(tool, mergedHandlers))
|
|
262
311
|
);
|
|
263
|
-
const toolsWithUI = updatedTools.filter((
|
|
312
|
+
const toolsWithUI = updatedTools.filter((tool) => tool.ui_component);
|
|
264
313
|
if (toolsWithUI.length > 0) {
|
|
265
314
|
client.emit("ui:render", {
|
|
266
315
|
tools: updatedTools,
|
|
@@ -277,28 +326,20 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
277
326
|
}
|
|
278
327
|
}, [client, mergedHandlers, isPaused, pendingTools]);
|
|
279
328
|
useEffect2(() => {
|
|
280
|
-
const handleSessionLoaded =
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
continue;
|
|
288
|
-
const handler = mergedHandlers[tool.tool_name];
|
|
289
|
-
if (!handler)
|
|
290
|
-
continue;
|
|
291
|
-
try {
|
|
292
|
-
const result = await handler(tool.tool_args);
|
|
293
|
-
const { uiComponent } = processToolResult(result, tool);
|
|
294
|
-
if (uiComponent) {
|
|
295
|
-
client.hydrateToolCallUI(tool.tool_call_id, uiComponent);
|
|
296
|
-
}
|
|
297
|
-
} catch (err) {
|
|
298
|
-
console.error(`Failed to hydrate UI for ${tool.tool_name}:`, err);
|
|
299
|
-
}
|
|
329
|
+
const handleSessionLoaded = (_sessionId) => {
|
|
330
|
+
const tools = client.getMessages().flatMap((message) => message.tool_calls || []);
|
|
331
|
+
hydrateToolUIForSession(
|
|
332
|
+
tools,
|
|
333
|
+
mergedHandlers,
|
|
334
|
+
(toolCallId, uiComponent) => {
|
|
335
|
+
client.hydrateToolCallUI(toolCallId, uiComponent);
|
|
300
336
|
}
|
|
301
|
-
|
|
337
|
+
).catch((error) => {
|
|
338
|
+
console.error(
|
|
339
|
+
"[useAgnoToolExecution] Failed to hydrate session UI:",
|
|
340
|
+
error
|
|
341
|
+
);
|
|
342
|
+
});
|
|
302
343
|
};
|
|
303
344
|
client.on("session:loaded", handleSessionLoaded);
|
|
304
345
|
return () => {
|
|
@@ -306,29 +347,9 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
306
347
|
};
|
|
307
348
|
}, [client, mergedHandlers]);
|
|
308
349
|
const executeTools = useCallback2(
|
|
309
|
-
|
|
350
|
+
(tools) => {
|
|
310
351
|
return Promise.all(
|
|
311
|
-
tools.map(
|
|
312
|
-
const handler = mergedHandlers[tool.tool_name];
|
|
313
|
-
if (!handler)
|
|
314
|
-
return tool;
|
|
315
|
-
try {
|
|
316
|
-
const result = await handler(tool.tool_args);
|
|
317
|
-
const { resultData, uiComponent } = processToolResult(result, tool);
|
|
318
|
-
return {
|
|
319
|
-
...tool,
|
|
320
|
-
result: resultData,
|
|
321
|
-
ui_component: uiComponent
|
|
322
|
-
};
|
|
323
|
-
} catch (error) {
|
|
324
|
-
return {
|
|
325
|
-
...tool,
|
|
326
|
-
result: JSON.stringify({
|
|
327
|
-
error: error instanceof Error ? error.message : String(error)
|
|
328
|
-
})
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
})
|
|
352
|
+
tools.map((tool) => executeToolCall(tool, mergedHandlers))
|
|
332
353
|
);
|
|
333
354
|
},
|
|
334
355
|
[mergedHandlers]
|
|
@@ -349,10 +370,18 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
349
370
|
[client, isPaused]
|
|
350
371
|
);
|
|
351
372
|
useEffect2(() => {
|
|
352
|
-
if (autoExecute && isPaused && !isExecuting && pendingTools.length > 0) {
|
|
353
|
-
executeAndContinue()
|
|
373
|
+
if (autoExecute && isPaused && !isExecuting && !executionError && pendingTools.length > 0) {
|
|
374
|
+
executeAndContinue().catch(() => {
|
|
375
|
+
});
|
|
354
376
|
}
|
|
355
|
-
}, [
|
|
377
|
+
}, [
|
|
378
|
+
autoExecute,
|
|
379
|
+
isPaused,
|
|
380
|
+
isExecuting,
|
|
381
|
+
executionError,
|
|
382
|
+
pendingTools.length,
|
|
383
|
+
executeAndContinue
|
|
384
|
+
]);
|
|
356
385
|
return {
|
|
357
386
|
/** Whether the run is currently paused awaiting tool execution */
|
|
358
387
|
isPaused,
|
|
@@ -372,8 +401,8 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
372
401
|
}
|
|
373
402
|
|
|
374
403
|
// src/components/GenerativeUIRenderer.tsx
|
|
375
|
-
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
376
|
-
var UIErrorBoundary = class extends
|
|
404
|
+
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
405
|
+
var UIErrorBoundary = class extends React.Component {
|
|
377
406
|
constructor(props) {
|
|
378
407
|
super(props);
|
|
379
408
|
this.state = { hasError: false };
|
|
@@ -382,340 +411,288 @@ var UIErrorBoundary = class extends React3.Component {
|
|
|
382
411
|
return { hasError: true, error };
|
|
383
412
|
}
|
|
384
413
|
componentDidCatch(error, errorInfo) {
|
|
385
|
-
console.error(
|
|
414
|
+
console.error(
|
|
415
|
+
"[GenerativeUIRenderer] Error rendering component:",
|
|
416
|
+
error,
|
|
417
|
+
errorInfo
|
|
418
|
+
);
|
|
386
419
|
this.props.onError?.(error);
|
|
387
420
|
}
|
|
388
421
|
render() {
|
|
389
422
|
if (this.state.hasError) {
|
|
390
|
-
return this.props.fallback || /* @__PURE__ */ jsxs("div", { className: "
|
|
423
|
+
return this.props.fallback || /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-red-300 bg-red-50 p-4 text-red-800", children: [
|
|
391
424
|
/* @__PURE__ */ jsx3("p", { className: "font-semibold", children: "Failed to render UI component" }),
|
|
392
|
-
/* @__PURE__ */ jsx3("p", { className: "text-sm
|
|
425
|
+
/* @__PURE__ */ jsx3("p", { className: "mt-1 text-sm", children: this.state.error?.message || "Unknown error" })
|
|
393
426
|
] });
|
|
394
427
|
}
|
|
395
428
|
return this.props.children;
|
|
396
429
|
}
|
|
397
430
|
};
|
|
398
|
-
function
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
return /* @__PURE__ */ jsxs("div", { className: `p-4 border border-yellow-300 rounded-md bg-yellow-50 text-yellow-800 ${className || ""}`, children: [
|
|
413
|
-
/* @__PURE__ */ jsx3("p", { className: "font-semibold", children: "Custom component not available" }),
|
|
414
|
-
/* @__PURE__ */ jsx3("p", { className: "text-sm mt-1", children: "The custom render function for this component is not available." })
|
|
415
|
-
] });
|
|
416
|
-
}
|
|
417
|
-
if (spec.type === "chart") {
|
|
418
|
-
const chartSpec = spec;
|
|
419
|
-
const chartType = `chart:${chartSpec.component}`;
|
|
420
|
-
if (registry.has(chartType)) {
|
|
421
|
-
const ChartRenderer = registry.get(chartType);
|
|
422
|
-
return /* @__PURE__ */ jsx3(UIErrorBoundary, { onError, children: /* @__PURE__ */ jsxs("div", { className, children: [
|
|
423
|
-
chartSpec.title && /* @__PURE__ */ jsx3("h3", { className: "font-semibold mb-2", children: chartSpec.title }),
|
|
424
|
-
chartSpec.description && /* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-600 mb-4", children: chartSpec.description }),
|
|
425
|
-
/* @__PURE__ */ jsx3(ChartRenderer, { ...chartSpec.props })
|
|
426
|
-
] }) });
|
|
427
|
-
}
|
|
428
|
-
return /* @__PURE__ */ jsxs("div", { className: `p-4 border border-gray-300 rounded-md ${className || ""}`, children: [
|
|
429
|
-
/* @__PURE__ */ jsx3("p", { className: "font-semibold mb-2", children: chartSpec.title || "Chart Data" }),
|
|
430
|
-
chartSpec.description && /* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-600 mb-2", children: chartSpec.description }),
|
|
431
|
-
/* @__PURE__ */ jsx3("pre", { className: "text-xs bg-gray-100 p-2 rounded overflow-auto", children: JSON.stringify(chartSpec.props.data, null, 2) })
|
|
432
|
-
] });
|
|
433
|
-
}
|
|
434
|
-
if (spec.type === "card-grid") {
|
|
435
|
-
const cardGridSpec = spec;
|
|
436
|
-
if (registry.has("card-grid")) {
|
|
437
|
-
const CardGridRenderer = registry.get("card-grid");
|
|
438
|
-
return /* @__PURE__ */ jsx3(UIErrorBoundary, { onError, children: /* @__PURE__ */ jsxs("div", { className, children: [
|
|
439
|
-
cardGridSpec.title && /* @__PURE__ */ jsx3("h3", { className: "font-semibold mb-2", children: cardGridSpec.title }),
|
|
440
|
-
cardGridSpec.description && /* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-600 mb-4", children: cardGridSpec.description }),
|
|
441
|
-
/* @__PURE__ */ jsx3(CardGridRenderer, { ...cardGridSpec.props })
|
|
442
|
-
] }) });
|
|
443
|
-
}
|
|
431
|
+
function joinClassNames(...classNames) {
|
|
432
|
+
return classNames.filter(Boolean).join(" ");
|
|
433
|
+
}
|
|
434
|
+
function renderHeader(title, description) {
|
|
435
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
436
|
+
title ? /* @__PURE__ */ jsx3("h3", { className: "mb-2 font-semibold", children: title }) : null,
|
|
437
|
+
description ? /* @__PURE__ */ jsx3("p", { className: "mb-4 text-gray-600 text-sm", children: description }) : null
|
|
438
|
+
] });
|
|
439
|
+
}
|
|
440
|
+
function renderFromRegistry(renderer, props) {
|
|
441
|
+
if (!renderer) {
|
|
442
|
+
return void 0;
|
|
444
443
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
444
|
+
return renderer(props);
|
|
445
|
+
}
|
|
446
|
+
function getSpecKey(spec) {
|
|
447
|
+
switch (spec.type) {
|
|
448
|
+
case "chart":
|
|
449
|
+
return `${spec.type}-${spec.component}-${spec.title ?? "untitled"}-${spec.props.data.length}`;
|
|
450
|
+
case "card-grid":
|
|
451
|
+
return `${spec.type}-${spec.title ?? "untitled"}-${spec.props.cards.map((card) => card.id).join("|")}`;
|
|
452
|
+
case "table":
|
|
453
|
+
return `${spec.type}-${spec.title ?? "untitled"}-${spec.props.columns.map((column) => column.key).join("|")}`;
|
|
454
|
+
case "markdown":
|
|
455
|
+
return `${spec.type}-${spec.props.content.slice(0, 48)}`;
|
|
456
|
+
case "custom":
|
|
457
|
+
return `${spec.type}-${spec.renderKey}`;
|
|
458
|
+
case "artifact":
|
|
459
|
+
return `${spec.type}-${spec.title ?? "untitled"}-${spec.props.content.length}`;
|
|
460
|
+
default:
|
|
461
|
+
return "unknown-spec";
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function renderCustomSpec(spec, className, onError) {
|
|
465
|
+
const renderFn = getCustomRender(spec.renderKey);
|
|
466
|
+
if (renderFn) {
|
|
467
|
+
const renderedContent = renderFn(spec.props || {});
|
|
468
|
+
return /* @__PURE__ */ jsx3(UIErrorBoundary, { onError, children: /* @__PURE__ */ jsx3("div", { className, children: renderedContent }) });
|
|
455
469
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
470
|
+
return /* @__PURE__ */ jsxs(
|
|
471
|
+
"div",
|
|
472
|
+
{
|
|
473
|
+
className: joinClassNames(
|
|
474
|
+
"rounded-md border border-yellow-300 bg-yellow-50 p-4 text-yellow-800",
|
|
475
|
+
className
|
|
476
|
+
),
|
|
477
|
+
children: [
|
|
478
|
+
/* @__PURE__ */ jsx3("p", { className: "font-semibold", children: "Custom component not available" }),
|
|
479
|
+
/* @__PURE__ */ jsx3("p", { className: "mt-1 text-sm", children: "The custom render function for this component is not available." })
|
|
480
|
+
]
|
|
461
481
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
function renderChartSpec(spec, className, onError) {
|
|
485
|
+
const registry = getComponentRegistry();
|
|
486
|
+
const chartType = `chart:${spec.component}`;
|
|
487
|
+
const chartRenderer = registry.get(chartType);
|
|
488
|
+
const renderedChart = renderFromRegistry(
|
|
489
|
+
chartRenderer,
|
|
490
|
+
spec.props
|
|
491
|
+
);
|
|
492
|
+
if (renderedChart) {
|
|
493
|
+
return /* @__PURE__ */ jsx3(UIErrorBoundary, { onError, children: /* @__PURE__ */ jsxs("div", { className, children: [
|
|
494
|
+
renderHeader(spec.title, spec.description),
|
|
495
|
+
renderedChart
|
|
470
496
|
] }) });
|
|
471
497
|
}
|
|
472
|
-
return /* @__PURE__ */ jsxs(
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
type: "chart",
|
|
485
|
-
component: "BarChart",
|
|
486
|
-
layout: options?.layout,
|
|
487
|
-
title: options?.title,
|
|
488
|
-
description: options?.description,
|
|
489
|
-
props: {
|
|
490
|
-
data,
|
|
491
|
-
xKey,
|
|
492
|
-
bars: bars.map((bar) => ({
|
|
493
|
-
key: bar.key,
|
|
494
|
-
label: bar.label || bar.key,
|
|
495
|
-
color: bar.color
|
|
496
|
-
})),
|
|
497
|
-
showLegend: options?.showLegend ?? true,
|
|
498
|
-
showGrid: options?.showGrid ?? true,
|
|
499
|
-
height: options?.height,
|
|
500
|
-
width: options?.width
|
|
498
|
+
return /* @__PURE__ */ jsxs(
|
|
499
|
+
"div",
|
|
500
|
+
{
|
|
501
|
+
className: joinClassNames(
|
|
502
|
+
"rounded-md border border-gray-300 p-4",
|
|
503
|
+
className
|
|
504
|
+
),
|
|
505
|
+
children: [
|
|
506
|
+
/* @__PURE__ */ jsx3("p", { className: "mb-2 font-semibold", children: spec.title || "Chart Data" }),
|
|
507
|
+
spec.description ? /* @__PURE__ */ jsx3("p", { className: "mb-2 text-gray-600 text-sm", children: spec.description }) : null,
|
|
508
|
+
/* @__PURE__ */ jsx3("pre", { className: "overflow-auto rounded bg-gray-100 p-2 text-xs", children: JSON.stringify(spec.props.data, null, 2) })
|
|
509
|
+
]
|
|
501
510
|
}
|
|
502
|
-
|
|
511
|
+
);
|
|
503
512
|
}
|
|
504
|
-
function
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
})),
|
|
519
|
-
showLegend: options?.showLegend ?? true,
|
|
520
|
-
showGrid: options?.showGrid ?? true,
|
|
521
|
-
height: options?.height,
|
|
522
|
-
width: options?.width
|
|
523
|
-
}
|
|
524
|
-
};
|
|
513
|
+
function renderCardGridSpec(spec, className, onError) {
|
|
514
|
+
const registry = getComponentRegistry();
|
|
515
|
+
const cardGridRenderer = registry.get("card-grid");
|
|
516
|
+
const renderedGrid = renderFromRegistry(
|
|
517
|
+
cardGridRenderer,
|
|
518
|
+
spec.props
|
|
519
|
+
);
|
|
520
|
+
if (!renderedGrid) {
|
|
521
|
+
return renderUnsupportedSpec(spec, className);
|
|
522
|
+
}
|
|
523
|
+
return /* @__PURE__ */ jsx3(UIErrorBoundary, { onError, children: /* @__PURE__ */ jsxs("div", { className, children: [
|
|
524
|
+
renderHeader(spec.title, spec.description),
|
|
525
|
+
renderedGrid
|
|
526
|
+
] }) });
|
|
525
527
|
}
|
|
526
|
-
function
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
528
|
+
function renderTableSpec(spec, className, onError) {
|
|
529
|
+
const registry = getComponentRegistry();
|
|
530
|
+
const tableRenderer = registry.get("table");
|
|
531
|
+
const renderedTable = renderFromRegistry(
|
|
532
|
+
tableRenderer,
|
|
533
|
+
spec.props
|
|
534
|
+
);
|
|
535
|
+
if (!renderedTable) {
|
|
536
|
+
return renderUnsupportedSpec(spec, className);
|
|
537
|
+
}
|
|
538
|
+
return /* @__PURE__ */ jsx3(UIErrorBoundary, { onError, children: /* @__PURE__ */ jsxs("div", { className, children: [
|
|
539
|
+
renderHeader(spec.title, spec.description),
|
|
540
|
+
renderedTable
|
|
541
|
+
] }) });
|
|
542
|
+
}
|
|
543
|
+
function renderMarkdownSpec(spec, className, onError) {
|
|
544
|
+
const registry = getComponentRegistry();
|
|
545
|
+
const markdownRenderer = registry.get("markdown");
|
|
546
|
+
const renderedMarkdown = renderFromRegistry(
|
|
547
|
+
markdownRenderer,
|
|
548
|
+
spec.props
|
|
549
|
+
);
|
|
550
|
+
if (!renderedMarkdown) {
|
|
551
|
+
return /* @__PURE__ */ jsx3("div", { className, children: spec.props.content });
|
|
552
|
+
}
|
|
553
|
+
return /* @__PURE__ */ jsx3(UIErrorBoundary, { onError, children: /* @__PURE__ */ jsx3("div", { className, children: renderedMarkdown }) });
|
|
554
|
+
}
|
|
555
|
+
function renderArtifactSpec(spec, className, onError) {
|
|
556
|
+
return /* @__PURE__ */ jsx3(UIErrorBoundary, { onError, children: /* @__PURE__ */ jsxs("div", { className: joinClassNames("rounded-md border p-4", className), children: [
|
|
557
|
+
spec.title ? /* @__PURE__ */ jsx3("h3", { className: "mb-4 font-semibold", children: spec.title }) : null,
|
|
558
|
+
spec.description ? /* @__PURE__ */ jsx3("p", { className: "mb-4 text-gray-600 text-sm", children: spec.description }) : null,
|
|
559
|
+
/* @__PURE__ */ jsx3("div", { className: "space-y-4", children: spec.props.content.map((childSpec) => /* @__PURE__ */ jsx3(
|
|
560
|
+
GenerativeUIRenderer,
|
|
561
|
+
{
|
|
562
|
+
onError,
|
|
563
|
+
spec: childSpec
|
|
539
564
|
},
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}
|
|
544
|
-
};
|
|
565
|
+
getSpecKey(childSpec)
|
|
566
|
+
)) })
|
|
567
|
+
] }) });
|
|
545
568
|
}
|
|
546
|
-
function
|
|
547
|
-
return
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
showLegend: options?.showLegend ?? true,
|
|
562
|
-
showGrid: options?.showGrid ?? true,
|
|
563
|
-
height: options?.height,
|
|
564
|
-
width: options?.width
|
|
569
|
+
function renderUnsupportedSpec(spec, className) {
|
|
570
|
+
return /* @__PURE__ */ jsxs(
|
|
571
|
+
"div",
|
|
572
|
+
{
|
|
573
|
+
className: joinClassNames(
|
|
574
|
+
"rounded-md border border-gray-300 p-4",
|
|
575
|
+
className
|
|
576
|
+
),
|
|
577
|
+
children: [
|
|
578
|
+
/* @__PURE__ */ jsx3("p", { className: "font-semibold", children: "Unsupported UI component" }),
|
|
579
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-1 text-gray-600 text-sm", children: [
|
|
580
|
+
"Component type: ",
|
|
581
|
+
spec.type
|
|
582
|
+
] })
|
|
583
|
+
]
|
|
565
584
|
}
|
|
566
|
-
|
|
585
|
+
);
|
|
567
586
|
}
|
|
568
|
-
function
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
function createTable(data, columns, options) {
|
|
592
|
-
return {
|
|
593
|
-
type: "table",
|
|
594
|
-
layout: options?.layout,
|
|
595
|
-
title: options?.title,
|
|
596
|
-
description: options?.description,
|
|
597
|
-
props: {
|
|
598
|
-
data,
|
|
599
|
-
columns,
|
|
600
|
-
sortable: options?.sortable ?? true,
|
|
601
|
-
filterable: options?.filterable,
|
|
602
|
-
pagination: options?.pagination,
|
|
603
|
-
density: options?.density || "comfortable"
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
}
|
|
607
|
-
function createColumn(key, header, options) {
|
|
608
|
-
return {
|
|
609
|
-
key,
|
|
610
|
-
header,
|
|
611
|
-
width: options?.width,
|
|
612
|
-
sortable: options?.sortable,
|
|
613
|
-
cellType: options?.cellType || "text",
|
|
614
|
-
format: options?.format
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
function createMarkdown(content, options) {
|
|
618
|
-
return {
|
|
619
|
-
type: "markdown",
|
|
620
|
-
layout: options?.layout,
|
|
621
|
-
title: options?.title,
|
|
622
|
-
description: options?.description,
|
|
623
|
-
props: {
|
|
624
|
-
content,
|
|
625
|
-
syntaxHighlight: options?.syntaxHighlight ?? true
|
|
626
|
-
}
|
|
627
|
-
};
|
|
587
|
+
function GenerativeUIRenderer({
|
|
588
|
+
spec,
|
|
589
|
+
className,
|
|
590
|
+
onError
|
|
591
|
+
}) {
|
|
592
|
+
switch (spec.type) {
|
|
593
|
+
case "custom":
|
|
594
|
+
return renderCustomSpec(spec, className, onError);
|
|
595
|
+
case "chart":
|
|
596
|
+
return renderChartSpec(spec, className, onError);
|
|
597
|
+
case "card-grid":
|
|
598
|
+
return renderCardGridSpec(spec, className, onError);
|
|
599
|
+
case "table":
|
|
600
|
+
return renderTableSpec(spec, className, onError);
|
|
601
|
+
case "markdown":
|
|
602
|
+
return renderMarkdownSpec(spec, className, onError);
|
|
603
|
+
case "artifact":
|
|
604
|
+
return renderArtifactSpec(spec, className, onError);
|
|
605
|
+
default:
|
|
606
|
+
return renderUnsupportedSpec(spec, className);
|
|
607
|
+
}
|
|
628
608
|
}
|
|
629
|
-
|
|
609
|
+
|
|
610
|
+
// src/hooks/useAgnoActions.ts
|
|
611
|
+
import { useCallback as useCallback3, useState as useState3 } from "react";
|
|
612
|
+
function useAgnoActions() {
|
|
613
|
+
const client = useAgnoClient();
|
|
614
|
+
const [isInitializing, setIsInitializing] = useState3(false);
|
|
615
|
+
const [error, setError] = useState3();
|
|
616
|
+
const initialize = useCallback3(
|
|
617
|
+
async (options) => {
|
|
618
|
+
setIsInitializing(true);
|
|
619
|
+
setError(void 0);
|
|
620
|
+
try {
|
|
621
|
+
const result = await client.initialize(options);
|
|
622
|
+
return result;
|
|
623
|
+
} catch (err) {
|
|
624
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
625
|
+
setError(errorMessage);
|
|
626
|
+
throw err;
|
|
627
|
+
} finally {
|
|
628
|
+
setIsInitializing(false);
|
|
629
|
+
}
|
|
630
|
+
},
|
|
631
|
+
[client]
|
|
632
|
+
);
|
|
633
|
+
const checkStatus = useCallback3(
|
|
634
|
+
async (options) => {
|
|
635
|
+
setError(void 0);
|
|
636
|
+
try {
|
|
637
|
+
return await client.checkStatus(options);
|
|
638
|
+
} catch (err) {
|
|
639
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
640
|
+
setError(errorMessage);
|
|
641
|
+
return false;
|
|
642
|
+
}
|
|
643
|
+
},
|
|
644
|
+
[client]
|
|
645
|
+
);
|
|
646
|
+
const fetchAgents = useCallback3(
|
|
647
|
+
async (options) => {
|
|
648
|
+
setError(void 0);
|
|
649
|
+
try {
|
|
650
|
+
return await client.fetchAgents(options);
|
|
651
|
+
} catch (err) {
|
|
652
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
653
|
+
setError(errorMessage);
|
|
654
|
+
throw err;
|
|
655
|
+
}
|
|
656
|
+
},
|
|
657
|
+
[client]
|
|
658
|
+
);
|
|
659
|
+
const fetchTeams = useCallback3(
|
|
660
|
+
async (options) => {
|
|
661
|
+
setError(void 0);
|
|
662
|
+
try {
|
|
663
|
+
return await client.fetchTeams(options);
|
|
664
|
+
} catch (err) {
|
|
665
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
666
|
+
setError(errorMessage);
|
|
667
|
+
throw err;
|
|
668
|
+
}
|
|
669
|
+
},
|
|
670
|
+
[client]
|
|
671
|
+
);
|
|
672
|
+
const updateConfig = useCallback3(
|
|
673
|
+
(updates) => {
|
|
674
|
+
client.updateConfig(updates);
|
|
675
|
+
},
|
|
676
|
+
[client]
|
|
677
|
+
);
|
|
630
678
|
return {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
679
|
+
initialize,
|
|
680
|
+
checkStatus,
|
|
681
|
+
fetchAgents,
|
|
682
|
+
fetchTeams,
|
|
683
|
+
updateConfig,
|
|
684
|
+
isInitializing,
|
|
685
|
+
error
|
|
638
686
|
};
|
|
639
687
|
}
|
|
640
|
-
function createSmartChart(data, options) {
|
|
641
|
-
if (!data || data.length === 0) {
|
|
642
|
-
return createBarChart([], "", [], options);
|
|
643
|
-
}
|
|
644
|
-
const firstItem = data[0];
|
|
645
|
-
const keys = Object.keys(firstItem);
|
|
646
|
-
const xKey = options?.xKey || keys.find(
|
|
647
|
-
(k) => ["name", "label", "category", "date", "time", "month", "year"].includes(k.toLowerCase())
|
|
648
|
-
) || keys[0];
|
|
649
|
-
const numericKeys = keys.filter((k) => k !== xKey && typeof firstItem[k] === "number");
|
|
650
|
-
const yKeys = options?.yKeys || numericKeys;
|
|
651
|
-
if (options?.preferredType) {
|
|
652
|
-
switch (options.preferredType) {
|
|
653
|
-
case "bar":
|
|
654
|
-
return createBarChart(
|
|
655
|
-
data,
|
|
656
|
-
xKey,
|
|
657
|
-
yKeys.map((key) => ({ key })),
|
|
658
|
-
options
|
|
659
|
-
);
|
|
660
|
-
case "line":
|
|
661
|
-
return createLineChart(
|
|
662
|
-
data,
|
|
663
|
-
xKey,
|
|
664
|
-
yKeys.map((key) => ({ key })),
|
|
665
|
-
options
|
|
666
|
-
);
|
|
667
|
-
case "area":
|
|
668
|
-
return createAreaChart(
|
|
669
|
-
data,
|
|
670
|
-
xKey,
|
|
671
|
-
yKeys.map((key) => ({ key })),
|
|
672
|
-
options
|
|
673
|
-
);
|
|
674
|
-
case "pie":
|
|
675
|
-
return createPieChart(data, yKeys[0], xKey, options);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
if (yKeys.length === 1 && typeof firstItem[xKey] === "string") {
|
|
679
|
-
return createPieChart(data, yKeys[0], xKey, options);
|
|
680
|
-
}
|
|
681
|
-
if (xKey.toLowerCase().includes("date") || xKey.toLowerCase().includes("time") || xKey.toLowerCase().includes("month") || xKey.toLowerCase().includes("year")) {
|
|
682
|
-
return createLineChart(
|
|
683
|
-
data,
|
|
684
|
-
xKey,
|
|
685
|
-
yKeys.map((key) => ({ key })),
|
|
686
|
-
options
|
|
687
|
-
);
|
|
688
|
-
}
|
|
689
|
-
return createBarChart(
|
|
690
|
-
data,
|
|
691
|
-
xKey,
|
|
692
|
-
yKeys.map((key) => ({ key })),
|
|
693
|
-
options
|
|
694
|
-
);
|
|
695
|
-
}
|
|
696
|
-
function createToolResult(data, ui) {
|
|
697
|
-
return { data, ui };
|
|
698
|
-
}
|
|
699
|
-
function resultWithBarChart(data, xKey, bars, options) {
|
|
700
|
-
return createToolResult(data, createBarChart(data, xKey, bars, options));
|
|
701
|
-
}
|
|
702
|
-
function resultWithSmartChart(data, options) {
|
|
703
|
-
return createToolResult(data, createSmartChart(data, options));
|
|
704
|
-
}
|
|
705
|
-
function resultWithCardGrid(cards, options) {
|
|
706
|
-
return createToolResult(cards, createCardGrid(cards, options));
|
|
707
|
-
}
|
|
708
|
-
function resultWithTable(data, columns, options) {
|
|
709
|
-
return createToolResult(data, createTable(data, columns, options));
|
|
710
|
-
}
|
|
711
688
|
|
|
712
689
|
// src/hooks/useAgnoChat.ts
|
|
713
|
-
import {
|
|
690
|
+
import { useCallback as useCallback4, useEffect as useEffect3, useState as useState4 } from "react";
|
|
714
691
|
function useAgnoChat() {
|
|
715
692
|
const client = useAgnoClient();
|
|
716
|
-
const [messages, setMessages] =
|
|
717
|
-
const [state, setState] =
|
|
718
|
-
const [error, setError] =
|
|
693
|
+
const [messages, setMessages] = useState4(client.getMessages());
|
|
694
|
+
const [state, setState] = useState4(client.getState());
|
|
695
|
+
const [error, setError] = useState4();
|
|
719
696
|
useEffect3(() => {
|
|
720
697
|
const handleMessageUpdate = (updatedMessages) => {
|
|
721
698
|
setMessages(updatedMessages);
|
|
@@ -757,7 +734,7 @@ function useAgnoChat() {
|
|
|
757
734
|
client.off("ui:render", handleUIRender);
|
|
758
735
|
};
|
|
759
736
|
}, [client]);
|
|
760
|
-
const sendMessage =
|
|
737
|
+
const sendMessage = useCallback4(
|
|
761
738
|
async (message, options) => {
|
|
762
739
|
setError(void 0);
|
|
763
740
|
try {
|
|
@@ -770,7 +747,16 @@ function useAgnoChat() {
|
|
|
770
747
|
},
|
|
771
748
|
[client]
|
|
772
749
|
);
|
|
773
|
-
const
|
|
750
|
+
const cancelRun = useCallback4(async () => {
|
|
751
|
+
try {
|
|
752
|
+
await client.cancelRun();
|
|
753
|
+
} catch (err) {
|
|
754
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
755
|
+
setError(errorMessage);
|
|
756
|
+
throw err;
|
|
757
|
+
}
|
|
758
|
+
}, [client]);
|
|
759
|
+
const clearMessages = useCallback4(() => {
|
|
774
760
|
client.clearMessages();
|
|
775
761
|
setMessages([]);
|
|
776
762
|
setError(void 0);
|
|
@@ -779,24 +765,27 @@ function useAgnoChat() {
|
|
|
779
765
|
messages,
|
|
780
766
|
sendMessage,
|
|
781
767
|
clearMessages,
|
|
768
|
+
cancelRun,
|
|
782
769
|
isStreaming: state.isStreaming,
|
|
783
770
|
isRefreshing: state.isRefreshing,
|
|
784
771
|
isPaused: state.isPaused,
|
|
772
|
+
isCancelling: state.isCancelling,
|
|
773
|
+
currentRunId: state.currentRunId,
|
|
785
774
|
error,
|
|
786
775
|
state
|
|
787
776
|
};
|
|
788
777
|
}
|
|
789
778
|
|
|
790
779
|
// src/hooks/useAgnoSession.ts
|
|
791
|
-
import {
|
|
780
|
+
import { useCallback as useCallback5, useEffect as useEffect4, useState as useState5 } from "react";
|
|
792
781
|
function useAgnoSession() {
|
|
793
782
|
const client = useAgnoClient();
|
|
794
|
-
const [sessions, setSessions] =
|
|
795
|
-
const [currentSessionId, setCurrentSessionId] =
|
|
783
|
+
const [sessions, setSessions] = useState5([]);
|
|
784
|
+
const [currentSessionId, setCurrentSessionId] = useState5(
|
|
796
785
|
client.getConfig().sessionId
|
|
797
786
|
);
|
|
798
|
-
const [isLoading, setIsLoading] =
|
|
799
|
-
const [error, setError] =
|
|
787
|
+
const [isLoading, setIsLoading] = useState5(false);
|
|
788
|
+
const [error, setError] = useState5();
|
|
800
789
|
useEffect4(() => {
|
|
801
790
|
const handleSessionLoaded = (sessionId) => {
|
|
802
791
|
setCurrentSessionId(sessionId);
|
|
@@ -821,7 +810,7 @@ function useAgnoSession() {
|
|
|
821
810
|
client.off("state:change", handleStateChange);
|
|
822
811
|
};
|
|
823
812
|
}, [client]);
|
|
824
|
-
const loadSession =
|
|
813
|
+
const loadSession = useCallback5(
|
|
825
814
|
async (sessionId, options) => {
|
|
826
815
|
setIsLoading(true);
|
|
827
816
|
setError(void 0);
|
|
@@ -839,21 +828,24 @@ function useAgnoSession() {
|
|
|
839
828
|
},
|
|
840
829
|
[client]
|
|
841
830
|
);
|
|
842
|
-
const fetchSessions =
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
831
|
+
const fetchSessions = useCallback5(
|
|
832
|
+
async (options) => {
|
|
833
|
+
setIsLoading(true);
|
|
834
|
+
setError(void 0);
|
|
835
|
+
try {
|
|
836
|
+
const fetchedSessions = await client.fetchSessions(options);
|
|
837
|
+
setSessions(fetchedSessions);
|
|
838
|
+
return fetchedSessions;
|
|
839
|
+
} catch (err) {
|
|
840
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
841
|
+
setError(errorMessage);
|
|
842
|
+
throw err;
|
|
843
|
+
} finally {
|
|
844
|
+
setIsLoading(false);
|
|
845
|
+
}
|
|
846
|
+
},
|
|
847
|
+
[client]
|
|
848
|
+
);
|
|
857
849
|
return {
|
|
858
850
|
sessions,
|
|
859
851
|
currentSessionId,
|
|
@@ -864,77 +856,254 @@ function useAgnoSession() {
|
|
|
864
856
|
};
|
|
865
857
|
}
|
|
866
858
|
|
|
867
|
-
// src/
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
859
|
+
// src/utils/ui-helpers.ts
|
|
860
|
+
function createBarChart(data, xKey, bars, options) {
|
|
861
|
+
return {
|
|
862
|
+
type: "chart",
|
|
863
|
+
component: "BarChart",
|
|
864
|
+
layout: options?.layout,
|
|
865
|
+
title: options?.title,
|
|
866
|
+
description: options?.description,
|
|
867
|
+
props: {
|
|
868
|
+
data,
|
|
869
|
+
xKey,
|
|
870
|
+
bars: bars.map((bar) => ({
|
|
871
|
+
key: bar.key,
|
|
872
|
+
label: bar.label || bar.key,
|
|
873
|
+
color: bar.color
|
|
874
|
+
})),
|
|
875
|
+
showLegend: options?.showLegend ?? true,
|
|
876
|
+
showGrid: options?.showGrid ?? true,
|
|
877
|
+
height: options?.height,
|
|
878
|
+
width: options?.width
|
|
885
879
|
}
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
function createLineChart(data, xKey, lines, options) {
|
|
883
|
+
return {
|
|
884
|
+
type: "chart",
|
|
885
|
+
component: "LineChart",
|
|
886
|
+
layout: options?.layout,
|
|
887
|
+
title: options?.title,
|
|
888
|
+
description: options?.description,
|
|
889
|
+
props: {
|
|
890
|
+
data,
|
|
891
|
+
xKey,
|
|
892
|
+
lines: lines.map((line) => ({
|
|
893
|
+
key: line.key,
|
|
894
|
+
label: line.label || line.key,
|
|
895
|
+
color: line.color
|
|
896
|
+
})),
|
|
897
|
+
showLegend: options?.showLegend ?? true,
|
|
898
|
+
showGrid: options?.showGrid ?? true,
|
|
899
|
+
height: options?.height,
|
|
900
|
+
width: options?.width
|
|
895
901
|
}
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
function createPieChart(data, dataKey, nameKey, options) {
|
|
905
|
+
return {
|
|
906
|
+
type: "chart",
|
|
907
|
+
component: "PieChart",
|
|
908
|
+
layout: options?.layout,
|
|
909
|
+
title: options?.title,
|
|
910
|
+
description: options?.description,
|
|
911
|
+
props: {
|
|
912
|
+
data,
|
|
913
|
+
pie: {
|
|
914
|
+
dataKey,
|
|
915
|
+
nameKey,
|
|
916
|
+
label: options?.showLabel ?? true
|
|
917
|
+
},
|
|
918
|
+
showLegend: options?.showLegend ?? true,
|
|
919
|
+
height: options?.height || 400,
|
|
920
|
+
width: options?.width
|
|
905
921
|
}
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
function createAreaChart(data, xKey, areas, options) {
|
|
925
|
+
return {
|
|
926
|
+
type: "chart",
|
|
927
|
+
component: "AreaChart",
|
|
928
|
+
layout: options?.layout,
|
|
929
|
+
title: options?.title,
|
|
930
|
+
description: options?.description,
|
|
931
|
+
props: {
|
|
932
|
+
data,
|
|
933
|
+
xKey,
|
|
934
|
+
areas: areas.map((area) => ({
|
|
935
|
+
key: area.key,
|
|
936
|
+
label: area.label || area.key,
|
|
937
|
+
color: area.color
|
|
938
|
+
})),
|
|
939
|
+
showLegend: options?.showLegend ?? true,
|
|
940
|
+
showGrid: options?.showGrid ?? true,
|
|
941
|
+
height: options?.height,
|
|
942
|
+
width: options?.width
|
|
915
943
|
}
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
client.updateConfig(updates);
|
|
920
|
-
},
|
|
921
|
-
[client]
|
|
922
|
-
);
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
function createCardGrid(cards, options) {
|
|
923
947
|
return {
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
948
|
+
type: "card-grid",
|
|
949
|
+
layout: options?.layout,
|
|
950
|
+
title: options?.title,
|
|
951
|
+
description: options?.description,
|
|
952
|
+
props: {
|
|
953
|
+
cards,
|
|
954
|
+
columns: options?.columns || { default: 1, md: 2, lg: 3 },
|
|
955
|
+
variant: options?.variant || "default"
|
|
956
|
+
}
|
|
931
957
|
};
|
|
932
958
|
}
|
|
959
|
+
function createCard(id, title, description, options) {
|
|
960
|
+
return {
|
|
961
|
+
id,
|
|
962
|
+
title,
|
|
963
|
+
description,
|
|
964
|
+
image: options?.image,
|
|
965
|
+
metadata: options?.metadata,
|
|
966
|
+
actions: options?.actions
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
function createTable(data, columns, options) {
|
|
970
|
+
return {
|
|
971
|
+
type: "table",
|
|
972
|
+
layout: options?.layout,
|
|
973
|
+
title: options?.title,
|
|
974
|
+
description: options?.description,
|
|
975
|
+
props: {
|
|
976
|
+
data,
|
|
977
|
+
columns,
|
|
978
|
+
sortable: options?.sortable ?? true,
|
|
979
|
+
filterable: options?.filterable,
|
|
980
|
+
pagination: options?.pagination,
|
|
981
|
+
density: options?.density || "comfortable"
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
function createColumn(key, header, options) {
|
|
986
|
+
return {
|
|
987
|
+
key,
|
|
988
|
+
header,
|
|
989
|
+
width: options?.width,
|
|
990
|
+
sortable: options?.sortable,
|
|
991
|
+
cellType: options?.cellType || "text",
|
|
992
|
+
format: options?.format
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
function createMarkdown(content, options) {
|
|
996
|
+
return {
|
|
997
|
+
type: "markdown",
|
|
998
|
+
layout: options?.layout,
|
|
999
|
+
title: options?.title,
|
|
1000
|
+
description: options?.description,
|
|
1001
|
+
props: {
|
|
1002
|
+
content,
|
|
1003
|
+
syntaxHighlight: options?.syntaxHighlight ?? true
|
|
1004
|
+
}
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
function createArtifact(content, options) {
|
|
1008
|
+
return {
|
|
1009
|
+
type: "artifact",
|
|
1010
|
+
title: options?.title,
|
|
1011
|
+
description: options?.description,
|
|
1012
|
+
props: {
|
|
1013
|
+
content,
|
|
1014
|
+
variant: options?.variant || "default"
|
|
1015
|
+
}
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
function createSmartChart(data, options) {
|
|
1019
|
+
if (!data || data.length === 0) {
|
|
1020
|
+
return createBarChart([], "", [], options);
|
|
1021
|
+
}
|
|
1022
|
+
const firstItem = data[0];
|
|
1023
|
+
const keys = Object.keys(firstItem);
|
|
1024
|
+
const xKey = options?.xKey || keys.find(
|
|
1025
|
+
(k) => ["name", "label", "category", "date", "time", "month", "year"].includes(
|
|
1026
|
+
k.toLowerCase()
|
|
1027
|
+
)
|
|
1028
|
+
) || keys[0];
|
|
1029
|
+
const numericKeys = keys.filter(
|
|
1030
|
+
(k) => k !== xKey && typeof firstItem[k] === "number"
|
|
1031
|
+
);
|
|
1032
|
+
const yKeys = options?.yKeys || numericKeys;
|
|
1033
|
+
const firstValueKey = yKeys[0] ?? numericKeys[0];
|
|
1034
|
+
if (options?.preferredType) {
|
|
1035
|
+
switch (options.preferredType) {
|
|
1036
|
+
case "bar":
|
|
1037
|
+
return createBarChart(
|
|
1038
|
+
data,
|
|
1039
|
+
xKey,
|
|
1040
|
+
yKeys.map((key) => ({ key })),
|
|
1041
|
+
options
|
|
1042
|
+
);
|
|
1043
|
+
case "line":
|
|
1044
|
+
return createLineChart(
|
|
1045
|
+
data,
|
|
1046
|
+
xKey,
|
|
1047
|
+
yKeys.map((key) => ({ key })),
|
|
1048
|
+
options
|
|
1049
|
+
);
|
|
1050
|
+
case "area":
|
|
1051
|
+
return createAreaChart(
|
|
1052
|
+
data,
|
|
1053
|
+
xKey,
|
|
1054
|
+
yKeys.map((key) => ({ key })),
|
|
1055
|
+
options
|
|
1056
|
+
);
|
|
1057
|
+
case "pie":
|
|
1058
|
+
return createPieChart(data, firstValueKey ?? "value", xKey, options);
|
|
1059
|
+
default:
|
|
1060
|
+
return createBarChart(
|
|
1061
|
+
data,
|
|
1062
|
+
xKey,
|
|
1063
|
+
yKeys.map((key) => ({ key })),
|
|
1064
|
+
options
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
if (yKeys.length === 1 && firstValueKey && typeof firstItem[xKey] === "string") {
|
|
1069
|
+
return createPieChart(data, firstValueKey, xKey, options);
|
|
1070
|
+
}
|
|
1071
|
+
if (xKey.toLowerCase().includes("date") || xKey.toLowerCase().includes("time") || xKey.toLowerCase().includes("month") || xKey.toLowerCase().includes("year")) {
|
|
1072
|
+
return createLineChart(
|
|
1073
|
+
data,
|
|
1074
|
+
xKey,
|
|
1075
|
+
yKeys.map((key) => ({ key })),
|
|
1076
|
+
options
|
|
1077
|
+
);
|
|
1078
|
+
}
|
|
1079
|
+
return createBarChart(
|
|
1080
|
+
data,
|
|
1081
|
+
xKey,
|
|
1082
|
+
yKeys.map((key) => ({ key })),
|
|
1083
|
+
options
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
function createToolResult(data, ui) {
|
|
1087
|
+
return { data, ui };
|
|
1088
|
+
}
|
|
1089
|
+
function resultWithBarChart(data, xKey, bars, options) {
|
|
1090
|
+
return createToolResult(data, createBarChart(data, xKey, bars, options));
|
|
1091
|
+
}
|
|
1092
|
+
function resultWithSmartChart(data, options) {
|
|
1093
|
+
return createToolResult(data, createSmartChart(data, options));
|
|
1094
|
+
}
|
|
1095
|
+
function resultWithCardGrid(cards, options) {
|
|
1096
|
+
return createToolResult(cards, createCardGrid(cards, options));
|
|
1097
|
+
}
|
|
1098
|
+
function resultWithTable(data, columns, options) {
|
|
1099
|
+
return createToolResult(data, createTable(data, columns, options));
|
|
1100
|
+
}
|
|
933
1101
|
export {
|
|
934
1102
|
AgnoProvider,
|
|
935
1103
|
ComponentRegistry,
|
|
936
1104
|
GenerativeUIRenderer,
|
|
937
1105
|
ToolHandlerProvider,
|
|
1106
|
+
clearCustomRenderRegistry,
|
|
938
1107
|
createAreaChart,
|
|
939
1108
|
createArtifact,
|
|
940
1109
|
createBarChart,
|