@antipopp/agno-react 0.10.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 +22 -34
- package/dist/index.d.ts +22 -34
- package/dist/index.js +276 -204
- package/dist/index.mjs +277 -205
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -98,9 +98,9 @@ var ComponentRegistry = class _ComponentRegistry {
|
|
|
98
98
|
* Register multiple components at once
|
|
99
99
|
*/
|
|
100
100
|
registerBatch(components) {
|
|
101
|
-
|
|
101
|
+
for (const [type, renderer] of Object.entries(components)) {
|
|
102
102
|
this.register(type, renderer);
|
|
103
|
-
}
|
|
103
|
+
}
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
106
|
* Get a registered component renderer
|
|
@@ -213,12 +213,80 @@ function useToolHandlers() {
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
// src/hooks/useAgnoToolExecution.ts
|
|
216
|
+
function isRecord(value) {
|
|
217
|
+
return typeof value === "object" && value !== null;
|
|
218
|
+
}
|
|
219
|
+
function getCustomRenderFunction(value) {
|
|
220
|
+
if (value.type !== "custom") {
|
|
221
|
+
return void 0;
|
|
222
|
+
}
|
|
223
|
+
const maybeRender = value.render;
|
|
224
|
+
return typeof maybeRender === "function" ? maybeRender : void 0;
|
|
225
|
+
}
|
|
216
226
|
var customRenderRegistry = /* @__PURE__ */ new Map();
|
|
217
227
|
function registerCustomRender(renderFn) {
|
|
218
228
|
const key = `custom-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
219
229
|
customRenderRegistry.set(key, renderFn);
|
|
220
230
|
return key;
|
|
221
231
|
}
|
|
232
|
+
function toSerializableUIComponent(spec) {
|
|
233
|
+
const renderFn = getCustomRenderFunction(spec);
|
|
234
|
+
if (!renderFn) {
|
|
235
|
+
return spec;
|
|
236
|
+
}
|
|
237
|
+
const { render: _render, ...uiWithoutRender } = spec;
|
|
238
|
+
return {
|
|
239
|
+
...uiWithoutRender,
|
|
240
|
+
renderKey: registerCustomRender(renderFn)
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
async function executeToolCall(tool, handlers) {
|
|
244
|
+
const handler = handlers[tool.tool_name];
|
|
245
|
+
if (!handler) {
|
|
246
|
+
return {
|
|
247
|
+
...tool,
|
|
248
|
+
result: JSON.stringify({
|
|
249
|
+
error: `No handler registered for ${tool.tool_name}`
|
|
250
|
+
})
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
const result = await handler(tool.tool_args);
|
|
255
|
+
const { resultData, uiComponent } = processToolResult(result, tool);
|
|
256
|
+
return {
|
|
257
|
+
...tool,
|
|
258
|
+
result: resultData,
|
|
259
|
+
ui_component: uiComponent
|
|
260
|
+
};
|
|
261
|
+
} catch (error) {
|
|
262
|
+
return {
|
|
263
|
+
...tool,
|
|
264
|
+
result: JSON.stringify({
|
|
265
|
+
error: error instanceof Error ? error.message : String(error)
|
|
266
|
+
})
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async function hydrateToolUIForSession(tools, handlers, onHydrate) {
|
|
271
|
+
for (const tool of tools) {
|
|
272
|
+
if (tool.ui_component) {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
const handler = handlers[tool.tool_name];
|
|
276
|
+
if (!handler) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
const result = await handler(tool.tool_args);
|
|
281
|
+
const { uiComponent } = processToolResult(result, tool);
|
|
282
|
+
if (uiComponent) {
|
|
283
|
+
onHydrate(tool.tool_call_id, uiComponent);
|
|
284
|
+
}
|
|
285
|
+
} catch (error) {
|
|
286
|
+
console.error(`Failed to hydrate UI for ${tool.tool_name}:`, error);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
222
290
|
function getCustomRender(key) {
|
|
223
291
|
return customRenderRegistry.get(key);
|
|
224
292
|
}
|
|
@@ -226,27 +294,17 @@ function clearCustomRenderRegistry() {
|
|
|
226
294
|
customRenderRegistry.clear();
|
|
227
295
|
}
|
|
228
296
|
function isToolHandlerResult(value) {
|
|
229
|
-
return value &&
|
|
297
|
+
return isRecord(value) && ("data" in value || "ui" in value);
|
|
230
298
|
}
|
|
231
299
|
function isUIComponentSpec(value) {
|
|
232
|
-
return value && typeof value === "
|
|
300
|
+
return isRecord(value) && typeof value.type === "string";
|
|
233
301
|
}
|
|
234
302
|
function processToolResult(result, _tool) {
|
|
235
303
|
if (isToolHandlerResult(result)) {
|
|
236
304
|
const { data, ui } = result;
|
|
237
305
|
let uiComponent;
|
|
238
306
|
if (ui) {
|
|
239
|
-
|
|
240
|
-
const renderKey = registerCustomRender(ui.render);
|
|
241
|
-
uiComponent = {
|
|
242
|
-
...ui,
|
|
243
|
-
renderKey,
|
|
244
|
-
render: void 0
|
|
245
|
-
// Don't store the function itself
|
|
246
|
-
};
|
|
247
|
-
} else {
|
|
248
|
-
uiComponent = ui;
|
|
249
|
-
}
|
|
307
|
+
uiComponent = toSerializableUIComponent(ui);
|
|
250
308
|
}
|
|
251
309
|
return {
|
|
252
310
|
resultData: typeof data === "string" ? data : JSON.stringify(data),
|
|
@@ -254,17 +312,7 @@ function processToolResult(result, _tool) {
|
|
|
254
312
|
};
|
|
255
313
|
}
|
|
256
314
|
if (isUIComponentSpec(result)) {
|
|
257
|
-
|
|
258
|
-
if (result.type === "custom" && typeof result.render === "function") {
|
|
259
|
-
const renderKey = registerCustomRender(result.render);
|
|
260
|
-
uiComponent = {
|
|
261
|
-
...result,
|
|
262
|
-
renderKey,
|
|
263
|
-
render: void 0
|
|
264
|
-
};
|
|
265
|
-
} else {
|
|
266
|
-
uiComponent = result;
|
|
267
|
-
}
|
|
315
|
+
const uiComponent = toSerializableUIComponent(result);
|
|
268
316
|
return {
|
|
269
317
|
resultData: JSON.stringify(result),
|
|
270
318
|
uiComponent
|
|
@@ -325,35 +373,9 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
325
373
|
setExecutionError(void 0);
|
|
326
374
|
try {
|
|
327
375
|
const updatedTools = await Promise.all(
|
|
328
|
-
pendingTools.map(
|
|
329
|
-
const handler = mergedHandlers[tool.tool_name];
|
|
330
|
-
if (!handler) {
|
|
331
|
-
return {
|
|
332
|
-
...tool,
|
|
333
|
-
result: JSON.stringify({
|
|
334
|
-
error: `No handler registered for ${tool.tool_name}`
|
|
335
|
-
})
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
try {
|
|
339
|
-
const result = await handler(tool.tool_args);
|
|
340
|
-
const { resultData, uiComponent } = processToolResult(result, tool);
|
|
341
|
-
return {
|
|
342
|
-
...tool,
|
|
343
|
-
result: resultData,
|
|
344
|
-
ui_component: uiComponent
|
|
345
|
-
};
|
|
346
|
-
} catch (error) {
|
|
347
|
-
return {
|
|
348
|
-
...tool,
|
|
349
|
-
result: JSON.stringify({
|
|
350
|
-
error: error instanceof Error ? error.message : String(error)
|
|
351
|
-
})
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
})
|
|
376
|
+
pendingTools.map((tool) => executeToolCall(tool, mergedHandlers))
|
|
355
377
|
);
|
|
356
|
-
const toolsWithUI = updatedTools.filter((
|
|
378
|
+
const toolsWithUI = updatedTools.filter((tool) => tool.ui_component);
|
|
357
379
|
if (toolsWithUI.length > 0) {
|
|
358
380
|
client.emit("ui:render", {
|
|
359
381
|
tools: updatedTools,
|
|
@@ -370,31 +392,20 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
370
392
|
}
|
|
371
393
|
}, [client, mergedHandlers, isPaused, pendingTools]);
|
|
372
394
|
(0, import_react3.useEffect)(() => {
|
|
373
|
-
const handleSessionLoaded =
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
395
|
+
const handleSessionLoaded = (_sessionId) => {
|
|
396
|
+
const tools = client.getMessages().flatMap((message) => message.tool_calls || []);
|
|
397
|
+
hydrateToolUIForSession(
|
|
398
|
+
tools,
|
|
399
|
+
mergedHandlers,
|
|
400
|
+
(toolCallId, uiComponent) => {
|
|
401
|
+
client.hydrateToolCallUI(toolCallId, uiComponent);
|
|
378
402
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
continue;
|
|
386
|
-
}
|
|
387
|
-
try {
|
|
388
|
-
const result = await handler(tool.tool_args);
|
|
389
|
-
const { uiComponent } = processToolResult(result, tool);
|
|
390
|
-
if (uiComponent) {
|
|
391
|
-
client.hydrateToolCallUI(tool.tool_call_id, uiComponent);
|
|
392
|
-
}
|
|
393
|
-
} catch (err) {
|
|
394
|
-
console.error(`Failed to hydrate UI for ${tool.tool_name}:`, err);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
403
|
+
).catch((error) => {
|
|
404
|
+
console.error(
|
|
405
|
+
"[useAgnoToolExecution] Failed to hydrate session UI:",
|
|
406
|
+
error
|
|
407
|
+
);
|
|
408
|
+
});
|
|
398
409
|
};
|
|
399
410
|
client.on("session:loaded", handleSessionLoaded);
|
|
400
411
|
return () => {
|
|
@@ -402,30 +413,9 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
402
413
|
};
|
|
403
414
|
}, [client, mergedHandlers]);
|
|
404
415
|
const executeTools = (0, import_react3.useCallback)(
|
|
405
|
-
|
|
416
|
+
(tools) => {
|
|
406
417
|
return Promise.all(
|
|
407
|
-
tools.map(
|
|
408
|
-
const handler = mergedHandlers[tool.tool_name];
|
|
409
|
-
if (!handler) {
|
|
410
|
-
return tool;
|
|
411
|
-
}
|
|
412
|
-
try {
|
|
413
|
-
const result = await handler(tool.tool_args);
|
|
414
|
-
const { resultData, uiComponent } = processToolResult(result, tool);
|
|
415
|
-
return {
|
|
416
|
-
...tool,
|
|
417
|
-
result: resultData,
|
|
418
|
-
ui_component: uiComponent
|
|
419
|
-
};
|
|
420
|
-
} catch (error) {
|
|
421
|
-
return {
|
|
422
|
-
...tool,
|
|
423
|
-
result: JSON.stringify({
|
|
424
|
-
error: error instanceof Error ? error.message : String(error)
|
|
425
|
-
})
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
})
|
|
418
|
+
tools.map((tool) => executeToolCall(tool, mergedHandlers))
|
|
429
419
|
);
|
|
430
420
|
},
|
|
431
421
|
[mergedHandlers]
|
|
@@ -446,13 +436,15 @@ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
|
|
|
446
436
|
[client, isPaused]
|
|
447
437
|
);
|
|
448
438
|
(0, import_react3.useEffect)(() => {
|
|
449
|
-
if (autoExecute && isPaused && !isExecuting && pendingTools.length > 0) {
|
|
450
|
-
executeAndContinue()
|
|
439
|
+
if (autoExecute && isPaused && !isExecuting && !executionError && pendingTools.length > 0) {
|
|
440
|
+
executeAndContinue().catch(() => {
|
|
441
|
+
});
|
|
451
442
|
}
|
|
452
443
|
}, [
|
|
453
444
|
autoExecute,
|
|
454
445
|
isPaused,
|
|
455
446
|
isExecuting,
|
|
447
|
+
executionError,
|
|
456
448
|
pendingTools.length,
|
|
457
449
|
executeAndContinue
|
|
458
450
|
]);
|
|
@@ -502,108 +494,183 @@ var UIErrorBoundary = class extends import_react4.default.Component {
|
|
|
502
494
|
return this.props.children;
|
|
503
495
|
}
|
|
504
496
|
};
|
|
505
|
-
function
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
520
|
-
"div",
|
|
521
|
-
{
|
|
522
|
-
className: `rounded-md border border-yellow-300 bg-yellow-50 p-4 text-yellow-800 ${className || ""}`,
|
|
523
|
-
children: [
|
|
524
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "font-semibold", children: "Custom component not available" }),
|
|
525
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mt-1 text-sm", children: "The custom render function for this component is not available." })
|
|
526
|
-
]
|
|
527
|
-
}
|
|
528
|
-
);
|
|
497
|
+
function joinClassNames(...classNames) {
|
|
498
|
+
return classNames.filter(Boolean).join(" ");
|
|
499
|
+
}
|
|
500
|
+
function renderHeader(title, description) {
|
|
501
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
502
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mb-2 font-semibold", children: title }) : null,
|
|
503
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-4 text-gray-600 text-sm", children: description }) : null
|
|
504
|
+
] });
|
|
505
|
+
}
|
|
506
|
+
function renderFromRegistry(renderer, props) {
|
|
507
|
+
if (!renderer) {
|
|
508
|
+
return void 0;
|
|
529
509
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
return
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
{
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("pre", { className: "overflow-auto rounded bg-gray-100 p-2 text-xs", children: JSON.stringify(chartSpec.props.data, null, 2) })
|
|
549
|
-
]
|
|
550
|
-
}
|
|
551
|
-
);
|
|
510
|
+
return renderer(props);
|
|
511
|
+
}
|
|
512
|
+
function getSpecKey(spec) {
|
|
513
|
+
switch (spec.type) {
|
|
514
|
+
case "chart":
|
|
515
|
+
return `${spec.type}-${spec.component}-${spec.title ?? "untitled"}-${spec.props.data.length}`;
|
|
516
|
+
case "card-grid":
|
|
517
|
+
return `${spec.type}-${spec.title ?? "untitled"}-${spec.props.cards.map((card) => card.id).join("|")}`;
|
|
518
|
+
case "table":
|
|
519
|
+
return `${spec.type}-${spec.title ?? "untitled"}-${spec.props.columns.map((column) => column.key).join("|")}`;
|
|
520
|
+
case "markdown":
|
|
521
|
+
return `${spec.type}-${spec.props.content.slice(0, 48)}`;
|
|
522
|
+
case "custom":
|
|
523
|
+
return `${spec.type}-${spec.renderKey}`;
|
|
524
|
+
case "artifact":
|
|
525
|
+
return `${spec.type}-${spec.title ?? "untitled"}-${spec.props.content.length}`;
|
|
526
|
+
default:
|
|
527
|
+
return "unknown-spec";
|
|
552
528
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
cardGridSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-4 text-gray-600 text-sm", children: cardGridSpec.description }),
|
|
560
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CardGridRenderer, { ...cardGridSpec.props })
|
|
561
|
-
] }) });
|
|
562
|
-
}
|
|
529
|
+
}
|
|
530
|
+
function renderCustomSpec(spec, className, onError) {
|
|
531
|
+
const renderFn = getCustomRender(spec.renderKey);
|
|
532
|
+
if (renderFn) {
|
|
533
|
+
const renderedContent = renderFn(spec.props || {});
|
|
534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, children: renderedContent }) });
|
|
563
535
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
537
|
+
"div",
|
|
538
|
+
{
|
|
539
|
+
className: joinClassNames(
|
|
540
|
+
"rounded-md border border-yellow-300 bg-yellow-50 p-4 text-yellow-800",
|
|
541
|
+
className
|
|
542
|
+
),
|
|
543
|
+
children: [
|
|
544
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "font-semibold", children: "Custom component not available" }),
|
|
545
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mt-1 text-sm", children: "The custom render function for this component is not available." })
|
|
546
|
+
]
|
|
573
547
|
}
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
function renderChartSpec(spec, className, onError) {
|
|
551
|
+
const registry = getComponentRegistry();
|
|
552
|
+
const chartType = `chart:${spec.component}`;
|
|
553
|
+
const chartRenderer = registry.get(chartType);
|
|
554
|
+
const renderedChart = renderFromRegistry(
|
|
555
|
+
chartRenderer,
|
|
556
|
+
spec.props
|
|
557
|
+
);
|
|
558
|
+
if (renderedChart) {
|
|
559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, children: [
|
|
560
|
+
renderHeader(spec.title, spec.description),
|
|
561
|
+
renderedChart
|
|
562
|
+
] }) });
|
|
574
563
|
}
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
565
|
+
"div",
|
|
566
|
+
{
|
|
567
|
+
className: joinClassNames(
|
|
568
|
+
"rounded-md border border-gray-300 p-4",
|
|
569
|
+
className
|
|
570
|
+
),
|
|
571
|
+
children: [
|
|
572
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-2 font-semibold", children: spec.title || "Chart Data" }),
|
|
573
|
+
spec.description ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-2 text-gray-600 text-sm", children: spec.description }) : null,
|
|
574
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("pre", { className: "overflow-auto rounded bg-gray-100 p-2 text-xs", children: JSON.stringify(spec.props.data, null, 2) })
|
|
575
|
+
]
|
|
580
576
|
}
|
|
581
|
-
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
function renderCardGridSpec(spec, className, onError) {
|
|
580
|
+
const registry = getComponentRegistry();
|
|
581
|
+
const cardGridRenderer = registry.get("card-grid");
|
|
582
|
+
const renderedGrid = renderFromRegistry(
|
|
583
|
+
cardGridRenderer,
|
|
584
|
+
spec.props
|
|
585
|
+
);
|
|
586
|
+
if (!renderedGrid) {
|
|
587
|
+
return renderUnsupportedSpec(spec, className);
|
|
582
588
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, children: [
|
|
590
|
+
renderHeader(spec.title, spec.description),
|
|
591
|
+
renderedGrid
|
|
592
|
+
] }) });
|
|
593
|
+
}
|
|
594
|
+
function renderTableSpec(spec, className, onError) {
|
|
595
|
+
const registry = getComponentRegistry();
|
|
596
|
+
const tableRenderer = registry.get("table");
|
|
597
|
+
const renderedTable = renderFromRegistry(
|
|
598
|
+
tableRenderer,
|
|
599
|
+
spec.props
|
|
600
|
+
);
|
|
601
|
+
if (!renderedTable) {
|
|
602
|
+
return renderUnsupportedSpec(spec, className);
|
|
603
|
+
}
|
|
604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, children: [
|
|
605
|
+
renderHeader(spec.title, spec.description),
|
|
606
|
+
renderedTable
|
|
607
|
+
] }) });
|
|
608
|
+
}
|
|
609
|
+
function renderMarkdownSpec(spec, className, onError) {
|
|
610
|
+
const registry = getComponentRegistry();
|
|
611
|
+
const markdownRenderer = registry.get("markdown");
|
|
612
|
+
const renderedMarkdown = renderFromRegistry(
|
|
613
|
+
markdownRenderer,
|
|
614
|
+
spec.props
|
|
615
|
+
);
|
|
616
|
+
if (!renderedMarkdown) {
|
|
617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, children: spec.props.content });
|
|
618
|
+
}
|
|
619
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, children: renderedMarkdown }) });
|
|
620
|
+
}
|
|
621
|
+
function renderArtifactSpec(spec, className, onError) {
|
|
622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: joinClassNames("rounded-md border p-4", className), children: [
|
|
623
|
+
spec.title ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mb-4 font-semibold", children: spec.title }) : null,
|
|
624
|
+
spec.description ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-4 text-gray-600 text-sm", children: spec.description }) : null,
|
|
625
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "space-y-4", children: spec.props.content.map((childSpec) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
626
|
+
GenerativeUIRenderer,
|
|
627
|
+
{
|
|
628
|
+
onError,
|
|
629
|
+
spec: childSpec
|
|
630
|
+
},
|
|
631
|
+
getSpecKey(childSpec)
|
|
632
|
+
)) })
|
|
633
|
+
] }) });
|
|
634
|
+
}
|
|
635
|
+
function renderUnsupportedSpec(spec, className) {
|
|
636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
637
|
+
"div",
|
|
638
|
+
{
|
|
639
|
+
className: joinClassNames(
|
|
640
|
+
"rounded-md border border-gray-300 p-4",
|
|
641
|
+
className
|
|
642
|
+
),
|
|
643
|
+
children: [
|
|
644
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "font-semibold", children: "Unsupported UI component" }),
|
|
645
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mt-1 text-gray-600 text-sm", children: [
|
|
646
|
+
"Component type: ",
|
|
647
|
+
spec.type
|
|
648
|
+
] })
|
|
649
|
+
]
|
|
650
|
+
}
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
function GenerativeUIRenderer({
|
|
654
|
+
spec,
|
|
655
|
+
className,
|
|
656
|
+
onError
|
|
657
|
+
}) {
|
|
658
|
+
switch (spec.type) {
|
|
659
|
+
case "custom":
|
|
660
|
+
return renderCustomSpec(spec, className, onError);
|
|
661
|
+
case "chart":
|
|
662
|
+
return renderChartSpec(spec, className, onError);
|
|
663
|
+
case "card-grid":
|
|
664
|
+
return renderCardGridSpec(spec, className, onError);
|
|
665
|
+
case "table":
|
|
666
|
+
return renderTableSpec(spec, className, onError);
|
|
667
|
+
case "markdown":
|
|
668
|
+
return renderMarkdownSpec(spec, className, onError);
|
|
669
|
+
case "artifact":
|
|
670
|
+
return renderArtifactSpec(spec, className, onError);
|
|
671
|
+
default:
|
|
672
|
+
return renderUnsupportedSpec(spec, className);
|
|
599
673
|
}
|
|
600
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `rounded-md border border-gray-300 p-4 ${className || ""}`, children: [
|
|
601
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "font-semibold", children: "Unsupported UI component" }),
|
|
602
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mt-1 text-gray-600 text-sm", children: [
|
|
603
|
-
"Component type: ",
|
|
604
|
-
spec.type
|
|
605
|
-
] })
|
|
606
|
-
] });
|
|
607
674
|
}
|
|
608
675
|
|
|
609
676
|
// src/hooks/useAgnoActions.ts
|
|
@@ -712,10 +779,7 @@ function useAgnoChat() {
|
|
|
712
779
|
const { tools } = event;
|
|
713
780
|
for (const tool of tools) {
|
|
714
781
|
if (tool.ui_component) {
|
|
715
|
-
client.hydrateToolCallUI(
|
|
716
|
-
tool.tool_call_id,
|
|
717
|
-
tool.ui_component
|
|
718
|
-
);
|
|
782
|
+
client.hydrateToolCallUI(tool.tool_call_id, tool.ui_component);
|
|
719
783
|
}
|
|
720
784
|
}
|
|
721
785
|
};
|
|
@@ -1032,6 +1096,7 @@ function createSmartChart(data, options) {
|
|
|
1032
1096
|
(k) => k !== xKey && typeof firstItem[k] === "number"
|
|
1033
1097
|
);
|
|
1034
1098
|
const yKeys = options?.yKeys || numericKeys;
|
|
1099
|
+
const firstValueKey = yKeys[0] ?? numericKeys[0];
|
|
1035
1100
|
if (options?.preferredType) {
|
|
1036
1101
|
switch (options.preferredType) {
|
|
1037
1102
|
case "bar":
|
|
@@ -1056,11 +1121,18 @@ function createSmartChart(data, options) {
|
|
|
1056
1121
|
options
|
|
1057
1122
|
);
|
|
1058
1123
|
case "pie":
|
|
1059
|
-
return createPieChart(data,
|
|
1124
|
+
return createPieChart(data, firstValueKey ?? "value", xKey, options);
|
|
1125
|
+
default:
|
|
1126
|
+
return createBarChart(
|
|
1127
|
+
data,
|
|
1128
|
+
xKey,
|
|
1129
|
+
yKeys.map((key) => ({ key })),
|
|
1130
|
+
options
|
|
1131
|
+
);
|
|
1060
1132
|
}
|
|
1061
1133
|
}
|
|
1062
|
-
if (yKeys.length === 1 && typeof firstItem[xKey] === "string") {
|
|
1063
|
-
return createPieChart(data,
|
|
1134
|
+
if (yKeys.length === 1 && firstValueKey && typeof firstItem[xKey] === "string") {
|
|
1135
|
+
return createPieChart(data, firstValueKey, xKey, options);
|
|
1064
1136
|
}
|
|
1065
1137
|
if (xKey.toLowerCase().includes("date") || xKey.toLowerCase().includes("time") || xKey.toLowerCase().includes("month") || xKey.toLowerCase().includes("year")) {
|
|
1066
1138
|
return createLineChart(
|