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