@antipopp/agno-react 0.1.0 → 0.3.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/dist/index.d.mts +343 -49
- package/dist/index.d.ts +343 -49
- package/dist/index.js +741 -174
- package/dist/index.mjs +706 -173
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,17 +17,49 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
21
31
|
var src_exports = {};
|
|
22
32
|
__export(src_exports, {
|
|
23
33
|
AgnoProvider: () => AgnoProvider,
|
|
34
|
+
ComponentRegistry: () => ComponentRegistry,
|
|
35
|
+
GenerativeUIRenderer: () => GenerativeUIRenderer,
|
|
36
|
+
ToolHandlerProvider: () => ToolHandlerProvider,
|
|
37
|
+
createAreaChart: () => createAreaChart,
|
|
38
|
+
createArtifact: () => createArtifact,
|
|
39
|
+
createBarChart: () => createBarChart,
|
|
40
|
+
createCard: () => createCard,
|
|
41
|
+
createCardGrid: () => createCardGrid,
|
|
42
|
+
createColumn: () => createColumn,
|
|
43
|
+
createLineChart: () => createLineChart,
|
|
44
|
+
createMarkdown: () => createMarkdown,
|
|
45
|
+
createPieChart: () => createPieChart,
|
|
46
|
+
createSmartChart: () => createSmartChart,
|
|
47
|
+
createTable: () => createTable,
|
|
48
|
+
createToolResult: () => createToolResult,
|
|
49
|
+
getChartComponent: () => getChartComponent,
|
|
50
|
+
getComponentRegistry: () => getComponentRegistry,
|
|
51
|
+
getCustomRender: () => getCustomRender,
|
|
52
|
+
registerChartComponent: () => registerChartComponent,
|
|
53
|
+
resultWithBarChart: () => resultWithBarChart,
|
|
54
|
+
resultWithCardGrid: () => resultWithCardGrid,
|
|
55
|
+
resultWithSmartChart: () => resultWithSmartChart,
|
|
56
|
+
resultWithTable: () => resultWithTable,
|
|
24
57
|
useAgnoActions: () => useAgnoActions,
|
|
25
58
|
useAgnoChat: () => useAgnoChat,
|
|
26
59
|
useAgnoClient: () => useAgnoClient,
|
|
27
60
|
useAgnoSession: () => useAgnoSession,
|
|
28
|
-
useAgnoToolExecution: () => useAgnoToolExecution
|
|
61
|
+
useAgnoToolExecution: () => useAgnoToolExecution,
|
|
62
|
+
useToolHandlers: () => useToolHandlers
|
|
29
63
|
});
|
|
30
64
|
module.exports = __toCommonJS(src_exports);
|
|
31
65
|
|
|
@@ -51,35 +85,687 @@ function useAgnoClient() {
|
|
|
51
85
|
return client;
|
|
52
86
|
}
|
|
53
87
|
|
|
54
|
-
// src/
|
|
88
|
+
// src/context/ToolHandlerContext.tsx
|
|
55
89
|
var import_react2 = require("react");
|
|
90
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
91
|
+
var ToolHandlerContext = (0, import_react2.createContext)(null);
|
|
92
|
+
function ToolHandlerProvider({ handlers: initialHandlers = {}, children }) {
|
|
93
|
+
const [handlers, setHandlers] = (0, import_react2.useState)(initialHandlers);
|
|
94
|
+
const registerHandler = (0, import_react2.useCallback)((name, handler) => {
|
|
95
|
+
setHandlers((prev) => ({ ...prev, [name]: handler }));
|
|
96
|
+
}, []);
|
|
97
|
+
const unregisterHandler = (0, import_react2.useCallback)((name) => {
|
|
98
|
+
setHandlers((prev) => {
|
|
99
|
+
const { [name]: _, ...rest } = prev;
|
|
100
|
+
return rest;
|
|
101
|
+
});
|
|
102
|
+
}, []);
|
|
103
|
+
const value = {
|
|
104
|
+
handlers,
|
|
105
|
+
registerHandler,
|
|
106
|
+
unregisterHandler
|
|
107
|
+
};
|
|
108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ToolHandlerContext.Provider, { value, children });
|
|
109
|
+
}
|
|
110
|
+
function useToolHandlers() {
|
|
111
|
+
return (0, import_react2.useContext)(ToolHandlerContext);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/components/GenerativeUIRenderer.tsx
|
|
115
|
+
var import_react4 = __toESM(require("react"));
|
|
116
|
+
|
|
117
|
+
// src/utils/component-registry.ts
|
|
118
|
+
var ComponentRegistry = class _ComponentRegistry {
|
|
119
|
+
constructor() {
|
|
120
|
+
this.components = /* @__PURE__ */ new Map();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get the singleton instance
|
|
124
|
+
*/
|
|
125
|
+
static getInstance() {
|
|
126
|
+
if (!_ComponentRegistry.instance) {
|
|
127
|
+
_ComponentRegistry.instance = new _ComponentRegistry();
|
|
128
|
+
}
|
|
129
|
+
return _ComponentRegistry.instance;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Register a component renderer
|
|
133
|
+
*/
|
|
134
|
+
register(type, renderer) {
|
|
135
|
+
this.components.set(type, renderer);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Register multiple components at once
|
|
139
|
+
*/
|
|
140
|
+
registerBatch(components) {
|
|
141
|
+
Object.entries(components).forEach(([type, renderer]) => {
|
|
142
|
+
this.register(type, renderer);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get a registered component renderer
|
|
147
|
+
*/
|
|
148
|
+
get(type) {
|
|
149
|
+
return this.components.get(type);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check if a component is registered
|
|
153
|
+
*/
|
|
154
|
+
has(type) {
|
|
155
|
+
return this.components.has(type);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Unregister a component
|
|
159
|
+
*/
|
|
160
|
+
unregister(type) {
|
|
161
|
+
this.components.delete(type);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get all registered component types
|
|
165
|
+
*/
|
|
166
|
+
getRegisteredTypes() {
|
|
167
|
+
return Array.from(this.components.keys());
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Clear all registered components
|
|
171
|
+
*/
|
|
172
|
+
clear() {
|
|
173
|
+
this.components.clear();
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
function getComponentRegistry() {
|
|
177
|
+
return ComponentRegistry.getInstance();
|
|
178
|
+
}
|
|
179
|
+
function registerChartComponent(name, renderer) {
|
|
180
|
+
getComponentRegistry().register(`chart:${name}`, renderer);
|
|
181
|
+
}
|
|
182
|
+
function getChartComponent(name) {
|
|
183
|
+
return getComponentRegistry().get(`chart:${name}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/hooks/useAgnoToolExecution.ts
|
|
187
|
+
var import_react3 = require("react");
|
|
188
|
+
var customRenderRegistry = /* @__PURE__ */ new Map();
|
|
189
|
+
function registerCustomRender(renderFn) {
|
|
190
|
+
const key = `custom-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
191
|
+
customRenderRegistry.set(key, renderFn);
|
|
192
|
+
return key;
|
|
193
|
+
}
|
|
194
|
+
function getCustomRender(key) {
|
|
195
|
+
return customRenderRegistry.get(key);
|
|
196
|
+
}
|
|
197
|
+
function isToolHandlerResult(value) {
|
|
198
|
+
return value && typeof value === "object" && ("data" in value || "ui" in value);
|
|
199
|
+
}
|
|
200
|
+
function isUIComponentSpec(value) {
|
|
201
|
+
return value && typeof value === "object" && "type" in value;
|
|
202
|
+
}
|
|
203
|
+
function processToolResult(result, _tool) {
|
|
204
|
+
if (isToolHandlerResult(result)) {
|
|
205
|
+
const { data, ui } = result;
|
|
206
|
+
let uiComponent = void 0;
|
|
207
|
+
if (ui) {
|
|
208
|
+
if (ui.type === "custom" && typeof ui.render === "function") {
|
|
209
|
+
const renderKey = registerCustomRender(ui.render);
|
|
210
|
+
uiComponent = {
|
|
211
|
+
...ui,
|
|
212
|
+
renderKey,
|
|
213
|
+
render: void 0
|
|
214
|
+
// Don't store the function itself
|
|
215
|
+
};
|
|
216
|
+
} else {
|
|
217
|
+
uiComponent = ui;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
resultData: typeof data === "string" ? data : JSON.stringify(data),
|
|
222
|
+
uiComponent
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (isUIComponentSpec(result)) {
|
|
226
|
+
let uiComponent;
|
|
227
|
+
if (result.type === "custom" && typeof result.render === "function") {
|
|
228
|
+
const renderKey = registerCustomRender(result.render);
|
|
229
|
+
uiComponent = {
|
|
230
|
+
...result,
|
|
231
|
+
renderKey,
|
|
232
|
+
render: void 0
|
|
233
|
+
};
|
|
234
|
+
} else {
|
|
235
|
+
uiComponent = result;
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
resultData: JSON.stringify(result),
|
|
239
|
+
uiComponent
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
resultData: typeof result === "string" ? result : JSON.stringify(result),
|
|
244
|
+
uiComponent: void 0
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
248
|
+
const client = useAgnoClient();
|
|
249
|
+
const toolHandlerContext = useToolHandlers();
|
|
250
|
+
const mergedHandlers = (0, import_react3.useMemo)(() => {
|
|
251
|
+
const globalHandlers = toolHandlerContext?.handlers || {};
|
|
252
|
+
return { ...globalHandlers, ...handlers };
|
|
253
|
+
}, [toolHandlerContext?.handlers, handlers]);
|
|
254
|
+
const [pendingTools, setPendingTools] = (0, import_react3.useState)([]);
|
|
255
|
+
const [isPaused, setIsPaused] = (0, import_react3.useState)(false);
|
|
256
|
+
const [isExecuting, setIsExecuting] = (0, import_react3.useState)(false);
|
|
257
|
+
const [executionError, setExecutionError] = (0, import_react3.useState)();
|
|
258
|
+
(0, import_react3.useEffect)(() => {
|
|
259
|
+
const handleRunPaused = (event) => {
|
|
260
|
+
setIsPaused(true);
|
|
261
|
+
setPendingTools(event.tools);
|
|
262
|
+
setExecutionError(void 0);
|
|
263
|
+
};
|
|
264
|
+
const handleRunContinued = () => {
|
|
265
|
+
setIsPaused(false);
|
|
266
|
+
setPendingTools([]);
|
|
267
|
+
setIsExecuting(false);
|
|
268
|
+
setExecutionError(void 0);
|
|
269
|
+
};
|
|
270
|
+
client.on("run:paused", handleRunPaused);
|
|
271
|
+
client.on("run:continued", handleRunContinued);
|
|
272
|
+
return () => {
|
|
273
|
+
client.off("run:paused", handleRunPaused);
|
|
274
|
+
client.off("run:continued", handleRunContinued);
|
|
275
|
+
};
|
|
276
|
+
}, [client]);
|
|
277
|
+
const executeAndContinue = (0, import_react3.useCallback)(async () => {
|
|
278
|
+
if (!isPaused || pendingTools.length === 0) {
|
|
279
|
+
console.warn("[useAgnoToolExecution] Cannot execute: no pending tools");
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
setIsExecuting(true);
|
|
283
|
+
setExecutionError(void 0);
|
|
284
|
+
try {
|
|
285
|
+
const updatedTools = await Promise.all(
|
|
286
|
+
pendingTools.map(async (tool) => {
|
|
287
|
+
const handler = mergedHandlers[tool.tool_name];
|
|
288
|
+
if (!handler) {
|
|
289
|
+
return {
|
|
290
|
+
...tool,
|
|
291
|
+
result: JSON.stringify({
|
|
292
|
+
error: `No handler registered for ${tool.tool_name}`
|
|
293
|
+
})
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
const result = await handler(tool.tool_args);
|
|
298
|
+
const { resultData, uiComponent } = processToolResult(result, tool);
|
|
299
|
+
return {
|
|
300
|
+
...tool,
|
|
301
|
+
result: resultData,
|
|
302
|
+
ui_component: uiComponent
|
|
303
|
+
};
|
|
304
|
+
} catch (error) {
|
|
305
|
+
return {
|
|
306
|
+
...tool,
|
|
307
|
+
result: JSON.stringify({
|
|
308
|
+
error: error instanceof Error ? error.message : String(error)
|
|
309
|
+
})
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
);
|
|
314
|
+
const toolsWithUI = updatedTools.filter((t) => t.ui_component);
|
|
315
|
+
if (toolsWithUI.length > 0) {
|
|
316
|
+
client.emit("ui:render", {
|
|
317
|
+
tools: updatedTools,
|
|
318
|
+
runId: client.getState().pausedRunId
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
client.addToolCallsToLastMessage(updatedTools);
|
|
322
|
+
await client.continueRun(updatedTools);
|
|
323
|
+
} catch (error) {
|
|
324
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
325
|
+
setExecutionError(errorMessage);
|
|
326
|
+
setIsExecuting(false);
|
|
327
|
+
throw error;
|
|
328
|
+
}
|
|
329
|
+
}, [client, mergedHandlers, isPaused, pendingTools]);
|
|
330
|
+
(0, import_react3.useEffect)(() => {
|
|
331
|
+
const handleSessionLoaded = async (_sessionId) => {
|
|
332
|
+
const messages = client.getMessages();
|
|
333
|
+
for (const message of messages) {
|
|
334
|
+
if (!message.tool_calls)
|
|
335
|
+
continue;
|
|
336
|
+
for (const tool of message.tool_calls) {
|
|
337
|
+
if (tool.ui_component)
|
|
338
|
+
continue;
|
|
339
|
+
const handler = mergedHandlers[tool.tool_name];
|
|
340
|
+
if (!handler)
|
|
341
|
+
continue;
|
|
342
|
+
try {
|
|
343
|
+
const result = await handler(tool.tool_args);
|
|
344
|
+
const { uiComponent } = processToolResult(result, tool);
|
|
345
|
+
if (uiComponent) {
|
|
346
|
+
client.hydrateToolCallUI(tool.tool_call_id, uiComponent);
|
|
347
|
+
}
|
|
348
|
+
} catch (err) {
|
|
349
|
+
console.error(`Failed to hydrate UI for ${tool.tool_name}:`, err);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
client.on("session:loaded", handleSessionLoaded);
|
|
355
|
+
return () => {
|
|
356
|
+
client.off("session:loaded", handleSessionLoaded);
|
|
357
|
+
};
|
|
358
|
+
}, [client, mergedHandlers]);
|
|
359
|
+
const executeTools = (0, import_react3.useCallback)(
|
|
360
|
+
async (tools) => {
|
|
361
|
+
return Promise.all(
|
|
362
|
+
tools.map(async (tool) => {
|
|
363
|
+
const handler = mergedHandlers[tool.tool_name];
|
|
364
|
+
if (!handler)
|
|
365
|
+
return tool;
|
|
366
|
+
try {
|
|
367
|
+
const result = await handler(tool.tool_args);
|
|
368
|
+
const { resultData, uiComponent } = processToolResult(result, tool);
|
|
369
|
+
return {
|
|
370
|
+
...tool,
|
|
371
|
+
result: resultData,
|
|
372
|
+
ui_component: uiComponent
|
|
373
|
+
};
|
|
374
|
+
} catch (error) {
|
|
375
|
+
return {
|
|
376
|
+
...tool,
|
|
377
|
+
result: JSON.stringify({
|
|
378
|
+
error: error instanceof Error ? error.message : String(error)
|
|
379
|
+
})
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
})
|
|
383
|
+
);
|
|
384
|
+
},
|
|
385
|
+
[mergedHandlers]
|
|
386
|
+
);
|
|
387
|
+
const continueWithResults = (0, import_react3.useCallback)(
|
|
388
|
+
async (tools) => {
|
|
389
|
+
if (!isPaused) {
|
|
390
|
+
throw new Error("No paused run to continue");
|
|
391
|
+
}
|
|
392
|
+
setIsExecuting(true);
|
|
393
|
+
try {
|
|
394
|
+
await client.continueRun(tools);
|
|
395
|
+
} catch (error) {
|
|
396
|
+
setIsExecuting(false);
|
|
397
|
+
throw error;
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
[client, isPaused]
|
|
401
|
+
);
|
|
402
|
+
(0, import_react3.useEffect)(() => {
|
|
403
|
+
if (autoExecute && isPaused && !isExecuting && pendingTools.length > 0) {
|
|
404
|
+
executeAndContinue();
|
|
405
|
+
}
|
|
406
|
+
}, [autoExecute, isPaused, isExecuting, pendingTools.length, executeAndContinue]);
|
|
407
|
+
return {
|
|
408
|
+
/** Whether the run is currently paused awaiting tool execution */
|
|
409
|
+
isPaused,
|
|
410
|
+
/** Whether tools are currently being executed */
|
|
411
|
+
isExecuting,
|
|
412
|
+
/** Tools awaiting execution */
|
|
413
|
+
pendingTools,
|
|
414
|
+
/** Execute all pending tools and continue the run */
|
|
415
|
+
executeAndContinue,
|
|
416
|
+
/** Execute specific tools and return results without continuing */
|
|
417
|
+
executeTools,
|
|
418
|
+
/** Continue the run with manually provided tool results */
|
|
419
|
+
continueWithResults,
|
|
420
|
+
/** Error from tool execution, if any */
|
|
421
|
+
executionError
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// src/components/GenerativeUIRenderer.tsx
|
|
426
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
427
|
+
var UIErrorBoundary = class extends import_react4.default.Component {
|
|
428
|
+
constructor(props) {
|
|
429
|
+
super(props);
|
|
430
|
+
this.state = { hasError: false };
|
|
431
|
+
}
|
|
432
|
+
static getDerivedStateFromError(error) {
|
|
433
|
+
return { hasError: true, error };
|
|
434
|
+
}
|
|
435
|
+
componentDidCatch(error, errorInfo) {
|
|
436
|
+
console.error("[GenerativeUIRenderer] Error rendering component:", error, errorInfo);
|
|
437
|
+
this.props.onError?.(error);
|
|
438
|
+
}
|
|
439
|
+
render() {
|
|
440
|
+
if (this.state.hasError) {
|
|
441
|
+
return this.props.fallback || /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "p-4 border border-red-300 rounded-md bg-red-50 text-red-800", children: [
|
|
442
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "font-semibold", children: "Failed to render UI component" }),
|
|
443
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm mt-1", children: this.state.error?.message || "Unknown error" })
|
|
444
|
+
] });
|
|
445
|
+
}
|
|
446
|
+
return this.props.children;
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
function GenerativeUIRenderer({
|
|
450
|
+
spec,
|
|
451
|
+
className,
|
|
452
|
+
onError
|
|
453
|
+
}) {
|
|
454
|
+
const registry = getComponentRegistry();
|
|
455
|
+
if (spec.type === "custom") {
|
|
456
|
+
const customSpec = spec;
|
|
457
|
+
if (customSpec.renderKey) {
|
|
458
|
+
const renderFn = getCustomRender(customSpec.renderKey);
|
|
459
|
+
if (renderFn) {
|
|
460
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, children: renderFn(customSpec.props || {}) }) });
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `p-4 border border-yellow-300 rounded-md bg-yellow-50 text-yellow-800 ${className || ""}`, children: [
|
|
464
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "font-semibold", children: "Custom component not available" }),
|
|
465
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm mt-1", children: "The custom render function for this component is not available." })
|
|
466
|
+
] });
|
|
467
|
+
}
|
|
468
|
+
if (spec.type === "chart") {
|
|
469
|
+
const chartSpec = spec;
|
|
470
|
+
const chartType = `chart:${chartSpec.component}`;
|
|
471
|
+
if (registry.has(chartType)) {
|
|
472
|
+
const ChartRenderer = registry.get(chartType);
|
|
473
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, children: [
|
|
474
|
+
chartSpec.title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "font-semibold mb-2", children: chartSpec.title }),
|
|
475
|
+
chartSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-600 mb-4", children: chartSpec.description }),
|
|
476
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChartRenderer, { ...chartSpec.props })
|
|
477
|
+
] }) });
|
|
478
|
+
}
|
|
479
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `p-4 border border-gray-300 rounded-md ${className || ""}`, children: [
|
|
480
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "font-semibold mb-2", children: chartSpec.title || "Chart Data" }),
|
|
481
|
+
chartSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-600 mb-2", children: chartSpec.description }),
|
|
482
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("pre", { className: "text-xs bg-gray-100 p-2 rounded overflow-auto", children: JSON.stringify(chartSpec.props.data, null, 2) })
|
|
483
|
+
] });
|
|
484
|
+
}
|
|
485
|
+
if (spec.type === "card-grid") {
|
|
486
|
+
const cardGridSpec = spec;
|
|
487
|
+
if (registry.has("card-grid")) {
|
|
488
|
+
const CardGridRenderer = registry.get("card-grid");
|
|
489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, children: [
|
|
490
|
+
cardGridSpec.title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "font-semibold mb-2", children: cardGridSpec.title }),
|
|
491
|
+
cardGridSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-600 mb-4", children: cardGridSpec.description }),
|
|
492
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CardGridRenderer, { ...cardGridSpec.props })
|
|
493
|
+
] }) });
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (spec.type === "table") {
|
|
497
|
+
const tableSpec = spec;
|
|
498
|
+
if (registry.has("table")) {
|
|
499
|
+
const TableRenderer = registry.get("table");
|
|
500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, children: [
|
|
501
|
+
tableSpec.title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "font-semibold mb-2", children: tableSpec.title }),
|
|
502
|
+
tableSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-600 mb-4", children: tableSpec.description }),
|
|
503
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TableRenderer, { ...tableSpec.props })
|
|
504
|
+
] }) });
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
if (spec.type === "markdown") {
|
|
508
|
+
const markdownSpec = spec;
|
|
509
|
+
if (registry.has("markdown")) {
|
|
510
|
+
const MarkdownRenderer = registry.get("markdown");
|
|
511
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MarkdownRenderer, { ...markdownSpec.props }) }) });
|
|
512
|
+
}
|
|
513
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, children: markdownSpec.props.content });
|
|
514
|
+
}
|
|
515
|
+
if (spec.type === "artifact") {
|
|
516
|
+
const artifactSpec = spec;
|
|
517
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `p-4 border rounded-md ${className || ""}`, children: [
|
|
518
|
+
artifactSpec.title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "font-semibold mb-4", children: artifactSpec.title }),
|
|
519
|
+
artifactSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-600 mb-4", children: artifactSpec.description }),
|
|
520
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "space-y-4", children: artifactSpec.props.content?.map((childSpec, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GenerativeUIRenderer, { spec: childSpec, onError }, index)) })
|
|
521
|
+
] }) });
|
|
522
|
+
}
|
|
523
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `p-4 border border-gray-300 rounded-md ${className || ""}`, children: [
|
|
524
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "font-semibold", children: "Unsupported UI component" }),
|
|
525
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "text-sm text-gray-600 mt-1", children: [
|
|
526
|
+
"Component type: ",
|
|
527
|
+
spec.type
|
|
528
|
+
] })
|
|
529
|
+
] });
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// src/utils/ui-helpers.ts
|
|
533
|
+
function createBarChart(data, xKey, bars, options) {
|
|
534
|
+
return {
|
|
535
|
+
type: "chart",
|
|
536
|
+
component: "BarChart",
|
|
537
|
+
layout: options?.layout,
|
|
538
|
+
title: options?.title,
|
|
539
|
+
description: options?.description,
|
|
540
|
+
props: {
|
|
541
|
+
data,
|
|
542
|
+
xKey,
|
|
543
|
+
bars: bars.map((bar) => ({
|
|
544
|
+
key: bar.key,
|
|
545
|
+
label: bar.label || bar.key,
|
|
546
|
+
color: bar.color
|
|
547
|
+
})),
|
|
548
|
+
showLegend: options?.showLegend ?? true,
|
|
549
|
+
showGrid: options?.showGrid ?? true,
|
|
550
|
+
height: options?.height,
|
|
551
|
+
width: options?.width
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
function createLineChart(data, xKey, lines, options) {
|
|
556
|
+
return {
|
|
557
|
+
type: "chart",
|
|
558
|
+
component: "LineChart",
|
|
559
|
+
layout: options?.layout,
|
|
560
|
+
title: options?.title,
|
|
561
|
+
description: options?.description,
|
|
562
|
+
props: {
|
|
563
|
+
data,
|
|
564
|
+
xKey,
|
|
565
|
+
lines: lines.map((line) => ({
|
|
566
|
+
key: line.key,
|
|
567
|
+
label: line.label || line.key,
|
|
568
|
+
color: line.color
|
|
569
|
+
})),
|
|
570
|
+
showLegend: options?.showLegend ?? true,
|
|
571
|
+
showGrid: options?.showGrid ?? true,
|
|
572
|
+
height: options?.height,
|
|
573
|
+
width: options?.width
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function createPieChart(data, dataKey, nameKey, options) {
|
|
578
|
+
return {
|
|
579
|
+
type: "chart",
|
|
580
|
+
component: "PieChart",
|
|
581
|
+
layout: options?.layout,
|
|
582
|
+
title: options?.title,
|
|
583
|
+
description: options?.description,
|
|
584
|
+
props: {
|
|
585
|
+
data,
|
|
586
|
+
pie: {
|
|
587
|
+
dataKey,
|
|
588
|
+
nameKey,
|
|
589
|
+
label: options?.showLabel ?? true
|
|
590
|
+
},
|
|
591
|
+
showLegend: options?.showLegend ?? true,
|
|
592
|
+
height: options?.height || 400,
|
|
593
|
+
width: options?.width
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function createAreaChart(data, xKey, areas, options) {
|
|
598
|
+
return {
|
|
599
|
+
type: "chart",
|
|
600
|
+
component: "AreaChart",
|
|
601
|
+
layout: options?.layout,
|
|
602
|
+
title: options?.title,
|
|
603
|
+
description: options?.description,
|
|
604
|
+
props: {
|
|
605
|
+
data,
|
|
606
|
+
xKey,
|
|
607
|
+
areas: areas.map((area) => ({
|
|
608
|
+
key: area.key,
|
|
609
|
+
label: area.label || area.key,
|
|
610
|
+
color: area.color
|
|
611
|
+
})),
|
|
612
|
+
showLegend: options?.showLegend ?? true,
|
|
613
|
+
showGrid: options?.showGrid ?? true,
|
|
614
|
+
height: options?.height,
|
|
615
|
+
width: options?.width
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
function createCardGrid(cards, options) {
|
|
620
|
+
return {
|
|
621
|
+
type: "card-grid",
|
|
622
|
+
layout: options?.layout,
|
|
623
|
+
title: options?.title,
|
|
624
|
+
description: options?.description,
|
|
625
|
+
props: {
|
|
626
|
+
cards,
|
|
627
|
+
columns: options?.columns || { default: 1, md: 2, lg: 3 },
|
|
628
|
+
variant: options?.variant || "default"
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function createCard(id, title, description, options) {
|
|
633
|
+
return {
|
|
634
|
+
id,
|
|
635
|
+
title,
|
|
636
|
+
description,
|
|
637
|
+
image: options?.image,
|
|
638
|
+
metadata: options?.metadata,
|
|
639
|
+
actions: options?.actions
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
function createTable(data, columns, options) {
|
|
643
|
+
return {
|
|
644
|
+
type: "table",
|
|
645
|
+
layout: options?.layout,
|
|
646
|
+
title: options?.title,
|
|
647
|
+
description: options?.description,
|
|
648
|
+
props: {
|
|
649
|
+
data,
|
|
650
|
+
columns,
|
|
651
|
+
sortable: options?.sortable ?? true,
|
|
652
|
+
filterable: options?.filterable,
|
|
653
|
+
pagination: options?.pagination,
|
|
654
|
+
density: options?.density || "comfortable"
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
function createColumn(key, header, options) {
|
|
659
|
+
return {
|
|
660
|
+
key,
|
|
661
|
+
header,
|
|
662
|
+
width: options?.width,
|
|
663
|
+
sortable: options?.sortable,
|
|
664
|
+
cellType: options?.cellType || "text",
|
|
665
|
+
format: options?.format
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
function createMarkdown(content, options) {
|
|
669
|
+
return {
|
|
670
|
+
type: "markdown",
|
|
671
|
+
layout: options?.layout,
|
|
672
|
+
title: options?.title,
|
|
673
|
+
description: options?.description,
|
|
674
|
+
props: {
|
|
675
|
+
content,
|
|
676
|
+
syntaxHighlight: options?.syntaxHighlight ?? true
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
function createArtifact(content, options) {
|
|
681
|
+
return {
|
|
682
|
+
type: "artifact",
|
|
683
|
+
title: options?.title,
|
|
684
|
+
description: options?.description,
|
|
685
|
+
props: {
|
|
686
|
+
content,
|
|
687
|
+
variant: options?.variant || "default"
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
function createSmartChart(data, options) {
|
|
692
|
+
if (!data || data.length === 0) {
|
|
693
|
+
return createBarChart([], "", [], options);
|
|
694
|
+
}
|
|
695
|
+
const firstItem = data[0];
|
|
696
|
+
const keys = Object.keys(firstItem);
|
|
697
|
+
const xKey = options?.xKey || keys.find(
|
|
698
|
+
(k) => ["name", "label", "category", "date", "time", "month", "year"].includes(k.toLowerCase())
|
|
699
|
+
) || keys[0];
|
|
700
|
+
const numericKeys = keys.filter((k) => k !== xKey && typeof firstItem[k] === "number");
|
|
701
|
+
const yKeys = options?.yKeys || numericKeys;
|
|
702
|
+
if ((options?.preferredType === "pie" || yKeys.length === 1) && typeof firstItem[xKey] === "string") {
|
|
703
|
+
return createPieChart(data, yKeys[0], xKey, options);
|
|
704
|
+
}
|
|
705
|
+
if (options?.preferredType === "line" || xKey.toLowerCase().includes("date") || xKey.toLowerCase().includes("time") || xKey.toLowerCase().includes("month") || xKey.toLowerCase().includes("year")) {
|
|
706
|
+
return createLineChart(
|
|
707
|
+
data,
|
|
708
|
+
xKey,
|
|
709
|
+
yKeys.map((key) => ({ key })),
|
|
710
|
+
options
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
return createBarChart(
|
|
714
|
+
data,
|
|
715
|
+
xKey,
|
|
716
|
+
yKeys.map((key) => ({ key })),
|
|
717
|
+
options
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
function createToolResult(data, ui) {
|
|
721
|
+
return { data, ui };
|
|
722
|
+
}
|
|
723
|
+
function resultWithBarChart(data, xKey, bars, options) {
|
|
724
|
+
return createToolResult(data, createBarChart(data, xKey, bars, options));
|
|
725
|
+
}
|
|
726
|
+
function resultWithSmartChart(data, options) {
|
|
727
|
+
return createToolResult(data, createSmartChart(data, options));
|
|
728
|
+
}
|
|
729
|
+
function resultWithCardGrid(cards, options) {
|
|
730
|
+
return createToolResult(cards, createCardGrid(cards, options));
|
|
731
|
+
}
|
|
732
|
+
function resultWithTable(data, columns, options) {
|
|
733
|
+
return createToolResult(data, createTable(data, columns, options));
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// src/hooks/useAgnoChat.ts
|
|
737
|
+
var import_react5 = require("react");
|
|
56
738
|
function useAgnoChat() {
|
|
57
739
|
const client = useAgnoClient();
|
|
58
|
-
const [messages, setMessages] = (0,
|
|
59
|
-
const [state, setState] = (0,
|
|
60
|
-
const [error, setError] = (0,
|
|
61
|
-
(0,
|
|
740
|
+
const [messages, setMessages] = (0, import_react5.useState)(client.getMessages());
|
|
741
|
+
const [state, setState] = (0, import_react5.useState)(client.getState());
|
|
742
|
+
const [error, setError] = (0, import_react5.useState)();
|
|
743
|
+
(0, import_react5.useEffect)(() => {
|
|
62
744
|
const handleMessageUpdate = (updatedMessages) => {
|
|
63
|
-
console.log("[useAgnoChat] message:update event received, messages:", updatedMessages.length);
|
|
64
745
|
setMessages(updatedMessages);
|
|
65
746
|
};
|
|
66
747
|
const handleMessageComplete = (updatedMessages) => {
|
|
67
|
-
console.log("[useAgnoChat] message:complete event received, messages:", updatedMessages.length);
|
|
68
748
|
setMessages(updatedMessages);
|
|
69
749
|
};
|
|
70
750
|
const handleMessageError = (errorMessage) => {
|
|
71
|
-
console.log("[useAgnoChat] message:error event received:", errorMessage);
|
|
72
751
|
setError(errorMessage);
|
|
73
752
|
};
|
|
74
753
|
const handleStateChange = (newState) => {
|
|
75
|
-
console.log("[useAgnoChat] state:change event received");
|
|
76
754
|
setState(newState);
|
|
77
755
|
};
|
|
756
|
+
const handleUIRender = (event) => {
|
|
757
|
+
const { tools } = event;
|
|
758
|
+
for (const tool of tools) {
|
|
759
|
+
if (tool.ui_component) {
|
|
760
|
+
client.hydrateToolCallUI(tool.tool_call_id, tool.ui_component);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
};
|
|
78
764
|
client.on("message:update", handleMessageUpdate);
|
|
79
765
|
client.on("message:complete", handleMessageComplete);
|
|
80
766
|
client.on("message:error", handleMessageError);
|
|
81
767
|
client.on("state:change", handleStateChange);
|
|
82
|
-
|
|
768
|
+
client.on("ui:render", handleUIRender);
|
|
83
769
|
setMessages(client.getMessages());
|
|
84
770
|
setState(client.getState());
|
|
85
771
|
return () => {
|
|
@@ -87,9 +773,10 @@ function useAgnoChat() {
|
|
|
87
773
|
client.off("message:complete", handleMessageComplete);
|
|
88
774
|
client.off("message:error", handleMessageError);
|
|
89
775
|
client.off("state:change", handleStateChange);
|
|
776
|
+
client.off("ui:render", handleUIRender);
|
|
90
777
|
};
|
|
91
778
|
}, [client]);
|
|
92
|
-
const sendMessage = (0,
|
|
779
|
+
const sendMessage = (0, import_react5.useCallback)(
|
|
93
780
|
async (message, options) => {
|
|
94
781
|
setError(void 0);
|
|
95
782
|
try {
|
|
@@ -102,7 +789,7 @@ function useAgnoChat() {
|
|
|
102
789
|
},
|
|
103
790
|
[client]
|
|
104
791
|
);
|
|
105
|
-
const clearMessages = (0,
|
|
792
|
+
const clearMessages = (0, import_react5.useCallback)(() => {
|
|
106
793
|
client.clearMessages();
|
|
107
794
|
setMessages([]);
|
|
108
795
|
setError(void 0);
|
|
@@ -119,16 +806,16 @@ function useAgnoChat() {
|
|
|
119
806
|
}
|
|
120
807
|
|
|
121
808
|
// src/hooks/useAgnoSession.ts
|
|
122
|
-
var
|
|
809
|
+
var import_react6 = require("react");
|
|
123
810
|
function useAgnoSession() {
|
|
124
811
|
const client = useAgnoClient();
|
|
125
|
-
const [sessions, setSessions] = (0,
|
|
126
|
-
const [currentSessionId, setCurrentSessionId] = (0,
|
|
812
|
+
const [sessions, setSessions] = (0, import_react6.useState)([]);
|
|
813
|
+
const [currentSessionId, setCurrentSessionId] = (0, import_react6.useState)(
|
|
127
814
|
client.getConfig().sessionId
|
|
128
815
|
);
|
|
129
|
-
const [isLoading, setIsLoading] = (0,
|
|
130
|
-
const [error, setError] = (0,
|
|
131
|
-
(0,
|
|
816
|
+
const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
|
|
817
|
+
const [error, setError] = (0, import_react6.useState)();
|
|
818
|
+
(0, import_react6.useEffect)(() => {
|
|
132
819
|
const handleSessionLoaded = (sessionId) => {
|
|
133
820
|
setCurrentSessionId(sessionId);
|
|
134
821
|
};
|
|
@@ -152,7 +839,7 @@ function useAgnoSession() {
|
|
|
152
839
|
client.off("state:change", handleStateChange);
|
|
153
840
|
};
|
|
154
841
|
}, [client]);
|
|
155
|
-
const loadSession = (0,
|
|
842
|
+
const loadSession = (0, import_react6.useCallback)(
|
|
156
843
|
async (sessionId) => {
|
|
157
844
|
setIsLoading(true);
|
|
158
845
|
setError(void 0);
|
|
@@ -170,7 +857,7 @@ function useAgnoSession() {
|
|
|
170
857
|
},
|
|
171
858
|
[client]
|
|
172
859
|
);
|
|
173
|
-
const fetchSessions = (0,
|
|
860
|
+
const fetchSessions = (0, import_react6.useCallback)(async () => {
|
|
174
861
|
setIsLoading(true);
|
|
175
862
|
setError(void 0);
|
|
176
863
|
try {
|
|
@@ -196,12 +883,12 @@ function useAgnoSession() {
|
|
|
196
883
|
}
|
|
197
884
|
|
|
198
885
|
// src/hooks/useAgnoActions.ts
|
|
199
|
-
var
|
|
886
|
+
var import_react7 = require("react");
|
|
200
887
|
function useAgnoActions() {
|
|
201
888
|
const client = useAgnoClient();
|
|
202
|
-
const [isInitializing, setIsInitializing] = (0,
|
|
203
|
-
const [error, setError] = (0,
|
|
204
|
-
const initialize = (0,
|
|
889
|
+
const [isInitializing, setIsInitializing] = (0, import_react7.useState)(false);
|
|
890
|
+
const [error, setError] = (0, import_react7.useState)();
|
|
891
|
+
const initialize = (0, import_react7.useCallback)(async () => {
|
|
205
892
|
setIsInitializing(true);
|
|
206
893
|
setError(void 0);
|
|
207
894
|
try {
|
|
@@ -215,7 +902,7 @@ function useAgnoActions() {
|
|
|
215
902
|
setIsInitializing(false);
|
|
216
903
|
}
|
|
217
904
|
}, [client]);
|
|
218
|
-
const checkStatus = (0,
|
|
905
|
+
const checkStatus = (0, import_react7.useCallback)(async () => {
|
|
219
906
|
setError(void 0);
|
|
220
907
|
try {
|
|
221
908
|
return await client.checkStatus();
|
|
@@ -225,7 +912,7 @@ function useAgnoActions() {
|
|
|
225
912
|
return false;
|
|
226
913
|
}
|
|
227
914
|
}, [client]);
|
|
228
|
-
const fetchAgents = (0,
|
|
915
|
+
const fetchAgents = (0, import_react7.useCallback)(async () => {
|
|
229
916
|
setError(void 0);
|
|
230
917
|
try {
|
|
231
918
|
return await client.fetchAgents();
|
|
@@ -235,7 +922,7 @@ function useAgnoActions() {
|
|
|
235
922
|
throw err;
|
|
236
923
|
}
|
|
237
924
|
}, [client]);
|
|
238
|
-
const fetchTeams = (0,
|
|
925
|
+
const fetchTeams = (0, import_react7.useCallback)(async () => {
|
|
239
926
|
setError(void 0);
|
|
240
927
|
try {
|
|
241
928
|
return await client.fetchTeams();
|
|
@@ -245,7 +932,7 @@ function useAgnoActions() {
|
|
|
245
932
|
throw err;
|
|
246
933
|
}
|
|
247
934
|
}, [client]);
|
|
248
|
-
const updateConfig = (0,
|
|
935
|
+
const updateConfig = (0, import_react7.useCallback)(
|
|
249
936
|
(updates) => {
|
|
250
937
|
client.updateConfig(updates);
|
|
251
938
|
},
|
|
@@ -261,156 +948,36 @@ function useAgnoActions() {
|
|
|
261
948
|
error
|
|
262
949
|
};
|
|
263
950
|
}
|
|
264
|
-
|
|
265
|
-
// src/hooks/useAgnoToolExecution.ts
|
|
266
|
-
var import_react5 = require("react");
|
|
267
|
-
function useAgnoToolExecution(handlers, autoExecute = true) {
|
|
268
|
-
const client = useAgnoClient();
|
|
269
|
-
const [pendingTools, setPendingTools] = (0, import_react5.useState)([]);
|
|
270
|
-
const [isPaused, setIsPaused] = (0, import_react5.useState)(false);
|
|
271
|
-
const [isExecuting, setIsExecuting] = (0, import_react5.useState)(false);
|
|
272
|
-
const [executionError, setExecutionError] = (0, import_react5.useState)();
|
|
273
|
-
(0, import_react5.useEffect)(() => {
|
|
274
|
-
const handleRunPaused = (event) => {
|
|
275
|
-
console.log("[useAgnoToolExecution] Run paused, tools:", event.tools);
|
|
276
|
-
setIsPaused(true);
|
|
277
|
-
setPendingTools(event.tools);
|
|
278
|
-
setExecutionError(void 0);
|
|
279
|
-
};
|
|
280
|
-
const handleRunContinued = () => {
|
|
281
|
-
console.log("[useAgnoToolExecution] Run continued");
|
|
282
|
-
setIsPaused(false);
|
|
283
|
-
setPendingTools([]);
|
|
284
|
-
setIsExecuting(false);
|
|
285
|
-
setExecutionError(void 0);
|
|
286
|
-
};
|
|
287
|
-
client.on("run:paused", handleRunPaused);
|
|
288
|
-
client.on("run:continued", handleRunContinued);
|
|
289
|
-
return () => {
|
|
290
|
-
client.off("run:paused", handleRunPaused);
|
|
291
|
-
client.off("run:continued", handleRunContinued);
|
|
292
|
-
};
|
|
293
|
-
}, [client]);
|
|
294
|
-
const executeAndContinue = (0, import_react5.useCallback)(async () => {
|
|
295
|
-
if (!isPaused || pendingTools.length === 0) {
|
|
296
|
-
console.warn("[useAgnoToolExecution] Cannot execute: no pending tools");
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
setIsExecuting(true);
|
|
300
|
-
setExecutionError(void 0);
|
|
301
|
-
try {
|
|
302
|
-
console.log("[useAgnoToolExecution] Executing", pendingTools.length, "tools");
|
|
303
|
-
const updatedTools = await Promise.all(
|
|
304
|
-
pendingTools.map(async (tool) => {
|
|
305
|
-
const handler = handlers[tool.tool_name];
|
|
306
|
-
if (!handler) {
|
|
307
|
-
console.warn(`[useAgnoToolExecution] No handler for tool: ${tool.tool_name}`);
|
|
308
|
-
return {
|
|
309
|
-
...tool,
|
|
310
|
-
result: JSON.stringify({
|
|
311
|
-
error: `No handler registered for ${tool.tool_name}`
|
|
312
|
-
})
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
try {
|
|
316
|
-
console.log(`[useAgnoToolExecution] Executing tool: ${tool.tool_name}`, tool.tool_args);
|
|
317
|
-
const result = await handler(tool.tool_args);
|
|
318
|
-
console.log(`[useAgnoToolExecution] Tool result:`, result);
|
|
319
|
-
return {
|
|
320
|
-
...tool,
|
|
321
|
-
result: typeof result === "string" ? result : JSON.stringify(result)
|
|
322
|
-
};
|
|
323
|
-
} catch (error) {
|
|
324
|
-
console.error(`[useAgnoToolExecution] Tool execution error:`, error);
|
|
325
|
-
return {
|
|
326
|
-
...tool,
|
|
327
|
-
result: JSON.stringify({
|
|
328
|
-
error: error instanceof Error ? error.message : String(error)
|
|
329
|
-
})
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
})
|
|
333
|
-
);
|
|
334
|
-
console.log("[useAgnoToolExecution] Continuing run with results");
|
|
335
|
-
await client.continueRun(updatedTools);
|
|
336
|
-
} catch (error) {
|
|
337
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
338
|
-
console.error("[useAgnoToolExecution] Failed to continue run:", errorMessage);
|
|
339
|
-
setExecutionError(errorMessage);
|
|
340
|
-
setIsExecuting(false);
|
|
341
|
-
throw error;
|
|
342
|
-
}
|
|
343
|
-
}, [client, handlers, isPaused, pendingTools]);
|
|
344
|
-
const executeTools = (0, import_react5.useCallback)(
|
|
345
|
-
async (tools) => {
|
|
346
|
-
return Promise.all(
|
|
347
|
-
tools.map(async (tool) => {
|
|
348
|
-
const handler = handlers[tool.tool_name];
|
|
349
|
-
if (!handler)
|
|
350
|
-
return tool;
|
|
351
|
-
try {
|
|
352
|
-
const result = await handler(tool.tool_args);
|
|
353
|
-
return {
|
|
354
|
-
...tool,
|
|
355
|
-
result: typeof result === "string" ? result : JSON.stringify(result)
|
|
356
|
-
};
|
|
357
|
-
} catch (error) {
|
|
358
|
-
return {
|
|
359
|
-
...tool,
|
|
360
|
-
result: JSON.stringify({
|
|
361
|
-
error: error instanceof Error ? error.message : String(error)
|
|
362
|
-
})
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
})
|
|
366
|
-
);
|
|
367
|
-
},
|
|
368
|
-
[handlers]
|
|
369
|
-
);
|
|
370
|
-
const continueWithResults = (0, import_react5.useCallback)(
|
|
371
|
-
async (tools) => {
|
|
372
|
-
if (!isPaused) {
|
|
373
|
-
throw new Error("No paused run to continue");
|
|
374
|
-
}
|
|
375
|
-
setIsExecuting(true);
|
|
376
|
-
try {
|
|
377
|
-
await client.continueRun(tools);
|
|
378
|
-
} catch (error) {
|
|
379
|
-
setIsExecuting(false);
|
|
380
|
-
throw error;
|
|
381
|
-
}
|
|
382
|
-
},
|
|
383
|
-
[client, isPaused]
|
|
384
|
-
);
|
|
385
|
-
(0, import_react5.useEffect)(() => {
|
|
386
|
-
if (autoExecute && isPaused && !isExecuting && pendingTools.length > 0) {
|
|
387
|
-
console.log("[useAgnoToolExecution] Auto-executing tools");
|
|
388
|
-
executeAndContinue();
|
|
389
|
-
}
|
|
390
|
-
}, [autoExecute, isPaused, isExecuting, pendingTools.length, executeAndContinue]);
|
|
391
|
-
return {
|
|
392
|
-
/** Whether the run is currently paused awaiting tool execution */
|
|
393
|
-
isPaused,
|
|
394
|
-
/** Whether tools are currently being executed */
|
|
395
|
-
isExecuting,
|
|
396
|
-
/** Tools awaiting execution */
|
|
397
|
-
pendingTools,
|
|
398
|
-
/** Execute all pending tools and continue the run */
|
|
399
|
-
executeAndContinue,
|
|
400
|
-
/** Execute specific tools and return results without continuing */
|
|
401
|
-
executeTools,
|
|
402
|
-
/** Continue the run with manually provided tool results */
|
|
403
|
-
continueWithResults,
|
|
404
|
-
/** Error from tool execution, if any */
|
|
405
|
-
executionError
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
951
|
// Annotate the CommonJS export names for ESM import in node:
|
|
409
952
|
0 && (module.exports = {
|
|
410
953
|
AgnoProvider,
|
|
954
|
+
ComponentRegistry,
|
|
955
|
+
GenerativeUIRenderer,
|
|
956
|
+
ToolHandlerProvider,
|
|
957
|
+
createAreaChart,
|
|
958
|
+
createArtifact,
|
|
959
|
+
createBarChart,
|
|
960
|
+
createCard,
|
|
961
|
+
createCardGrid,
|
|
962
|
+
createColumn,
|
|
963
|
+
createLineChart,
|
|
964
|
+
createMarkdown,
|
|
965
|
+
createPieChart,
|
|
966
|
+
createSmartChart,
|
|
967
|
+
createTable,
|
|
968
|
+
createToolResult,
|
|
969
|
+
getChartComponent,
|
|
970
|
+
getComponentRegistry,
|
|
971
|
+
getCustomRender,
|
|
972
|
+
registerChartComponent,
|
|
973
|
+
resultWithBarChart,
|
|
974
|
+
resultWithCardGrid,
|
|
975
|
+
resultWithSmartChart,
|
|
976
|
+
resultWithTable,
|
|
411
977
|
useAgnoActions,
|
|
412
978
|
useAgnoChat,
|
|
413
979
|
useAgnoClient,
|
|
414
980
|
useAgnoSession,
|
|
415
|
-
useAgnoToolExecution
|
|
981
|
+
useAgnoToolExecution,
|
|
982
|
+
useToolHandlers
|
|
416
983
|
});
|