@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/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
- Object.entries(components).forEach(([type, renderer]) => {
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 && typeof value === "object" && ("data" in value || "ui" in value);
297
+ return isRecord(value) && ("data" in value || "ui" in value);
230
298
  }
231
299
  function isUIComponentSpec(value) {
232
- return value && typeof value === "object" && "type" in 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
- if (ui.type === "custom" && typeof ui.render === "function") {
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
- let uiComponent;
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(async (tool) => {
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((t) => t.ui_component);
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 = async (_sessionId) => {
374
- const messages = client.getMessages();
375
- for (const message of messages) {
376
- if (!message.tool_calls) {
377
- continue;
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
- for (const tool of message.tool_calls) {
380
- if (tool.ui_component) {
381
- continue;
382
- }
383
- const handler = mergedHandlers[tool.tool_name];
384
- if (!handler) {
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
- async (tools) => {
416
+ (tools) => {
406
417
  return Promise.all(
407
- tools.map(async (tool) => {
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 GenerativeUIRenderer({
506
- spec,
507
- className,
508
- onError
509
- }) {
510
- const registry = getComponentRegistry();
511
- if (spec.type === "custom") {
512
- const customSpec = spec;
513
- if (customSpec.renderKey) {
514
- const renderFn = getCustomRender(customSpec.renderKey);
515
- if (renderFn) {
516
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, children: renderFn(customSpec.props || {}) }) });
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
- if (spec.type === "chart") {
531
- const chartSpec = spec;
532
- const chartType = `chart:${chartSpec.component}`;
533
- if (registry.has(chartType)) {
534
- const ChartRenderer = registry.get(chartType);
535
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, children: [
536
- chartSpec.title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mb-2 font-semibold", children: chartSpec.title }),
537
- chartSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-4 text-gray-600 text-sm", children: chartSpec.description }),
538
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChartRenderer, { ...chartSpec.props })
539
- ] }) });
540
- }
541
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
542
- "div",
543
- {
544
- className: `rounded-md border border-gray-300 p-4 ${className || ""}`,
545
- children: [
546
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-2 font-semibold", children: chartSpec.title || "Chart Data" }),
547
- chartSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-2 text-gray-600 text-sm", children: chartSpec.description }),
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
- if (spec.type === "card-grid") {
554
- const cardGridSpec = spec;
555
- if (registry.has("card-grid")) {
556
- const CardGridRenderer = registry.get("card-grid");
557
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, children: [
558
- cardGridSpec.title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mb-2 font-semibold", children: cardGridSpec.title }),
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
- if (spec.type === "table") {
565
- const tableSpec = spec;
566
- if (registry.has("table")) {
567
- const TableRenderer = registry.get("table");
568
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, children: [
569
- tableSpec.title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mb-2 font-semibold", children: tableSpec.title }),
570
- tableSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-4 text-gray-600 text-sm", children: tableSpec.description }),
571
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TableRenderer, { ...tableSpec.props })
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
- if (spec.type === "markdown") {
576
- const markdownSpec = spec;
577
- if (registry.has("markdown")) {
578
- const MarkdownRenderer = registry.get("markdown");
579
- 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 }) }) });
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
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, children: markdownSpec.props.content });
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
- if (spec.type === "artifact") {
584
- const artifactSpec = spec;
585
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIErrorBoundary, { onError, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `rounded-md border p-4 ${className || ""}`, children: [
586
- artifactSpec.title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mb-4 font-semibold", children: artifactSpec.title }),
587
- artifactSpec.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mb-4 text-gray-600 text-sm", children: artifactSpec.description }),
588
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "space-y-4", children: artifactSpec.props.content?.map(
589
- (childSpec, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
590
- GenerativeUIRenderer,
591
- {
592
- onError,
593
- spec: childSpec
594
- },
595
- index
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, yKeys[0], xKey, options);
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, yKeys[0], xKey, options);
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(