@rodrigocoliveira/agno-react 1.3.1 → 2.0.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.
Files changed (53) hide show
  1. package/README.md +32 -46
  2. package/dist/index.d.ts +6 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1738 -87
  5. package/dist/index.js.map +31 -3
  6. package/dist/index.mjs +1759 -87
  7. package/dist/index.mjs.map +31 -3
  8. package/dist/ui/components/conversation.d.ts +5 -2
  9. package/dist/ui/components/conversation.d.ts.map +1 -1
  10. package/dist/ui/composed/AgnoMessageItem.d.ts +12 -24
  11. package/dist/ui/composed/AgnoMessageItem.d.ts.map +1 -1
  12. package/dist/ui/composed/agno-chat/agno-chat.d.ts +23 -3
  13. package/dist/ui/composed/agno-chat/agno-chat.d.ts.map +1 -1
  14. package/dist/ui/composed/agno-chat/context.d.ts +4 -3
  15. package/dist/ui/composed/agno-chat/context.d.ts.map +1 -1
  16. package/dist/ui/composed/agno-chat/messages.d.ts +33 -16
  17. package/dist/ui/composed/agno-chat/messages.d.ts.map +1 -1
  18. package/dist/ui/composed/agno-chat/render-tool.d.ts +11 -0
  19. package/dist/ui/composed/agno-chat/render-tool.d.ts.map +1 -0
  20. package/dist/ui/composed/agno-chat/tool-building-blocks.d.ts +11 -0
  21. package/dist/ui/composed/agno-chat/tool-building-blocks.d.ts.map +1 -0
  22. package/dist/ui/composed/agno-message/content.d.ts +2 -0
  23. package/dist/ui/composed/agno-message/content.d.ts.map +1 -0
  24. package/dist/ui/composed/agno-message/context.d.ts +21 -0
  25. package/dist/ui/composed/agno-message/context.d.ts.map +1 -0
  26. package/dist/ui/composed/agno-message/footer.d.ts +6 -0
  27. package/dist/ui/composed/agno-message/footer.d.ts.map +1 -0
  28. package/dist/ui/composed/agno-message/index.d.ts +13 -0
  29. package/dist/ui/composed/agno-message/index.d.ts.map +1 -0
  30. package/dist/ui/composed/agno-message/media.d.ts +2 -0
  31. package/dist/ui/composed/agno-message/media.d.ts.map +1 -0
  32. package/dist/ui/composed/agno-message/message.d.ts +41 -0
  33. package/dist/ui/composed/agno-message/message.d.ts.map +1 -0
  34. package/dist/ui/composed/agno-message/reasoning.d.ts +2 -0
  35. package/dist/ui/composed/agno-message/reasoning.d.ts.map +1 -0
  36. package/dist/ui/composed/agno-message/references.d.ts +2 -0
  37. package/dist/ui/composed/agno-message/references.d.ts.map +1 -0
  38. package/dist/ui/composed/agno-message/tools.d.ts +7 -0
  39. package/dist/ui/composed/agno-message/tools.d.ts.map +1 -0
  40. package/dist/ui/composed/index.d.ts +6 -0
  41. package/dist/ui/composed/index.d.ts.map +1 -1
  42. package/dist/ui/index.d.ts +7 -1
  43. package/dist/ui/index.d.ts.map +1 -1
  44. package/dist/ui/primitives/badge.d.ts +1 -1
  45. package/dist/ui/primitives/button.d.ts +1 -1
  46. package/dist/ui/primitives/command.d.ts +1 -1
  47. package/dist/ui/types.d.ts +26 -0
  48. package/dist/ui/types.d.ts.map +1 -1
  49. package/dist/ui.js +1176 -647
  50. package/dist/ui.js.map +23 -8
  51. package/dist/ui.mjs +1170 -650
  52. package/dist/ui.mjs.map +23 -8
  53. package/package.json +3 -3
package/dist/ui.mjs CHANGED
@@ -749,12 +749,20 @@ import { useCallback } from "react";
749
749
  import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
750
750
  import { useStickToBottomContext as useStickToBottomContext2 } from "use-stick-to-bottom";
751
751
  import { jsx as jsx13, jsxs as jsxs7, Fragment } from "react/jsx-runtime";
752
- var Conversation = ({ className, ...props }) => /* @__PURE__ */ jsx13(StickToBottom, {
753
- className: cn("relative flex-1 overflow-y-auto", className),
754
- initial: "smooth",
755
- role: "log",
756
- ...props
757
- });
752
+ var Conversation = ({ className, scrollBehavior, ...props }) => {
753
+ const initial = scrollBehavior?.initial ?? "smooth";
754
+ const resize = scrollBehavior?.resize ?? "instant";
755
+ return /* @__PURE__ */ jsx13(StickToBottom, {
756
+ className: cn("relative flex-1 overflow-y-auto", className),
757
+ initial,
758
+ resize,
759
+ ...scrollBehavior?.damping !== undefined && { damping: scrollBehavior.damping },
760
+ ...scrollBehavior?.stiffness !== undefined && { stiffness: scrollBehavior.stiffness },
761
+ ...scrollBehavior?.mass !== undefined && { mass: scrollBehavior.mass },
762
+ role: "log",
763
+ ...props
764
+ });
765
+ };
758
766
  var ConversationContent = ({ className, ...props }) => /* @__PURE__ */ jsx13(StickToBottom.Content, {
759
767
  className: cn("p-4", className),
760
768
  ...props
@@ -2684,582 +2692,1066 @@ var PromptInputCommandSeparator = ({ className, ...props }) => /* @__PURE__ */ j
2684
2692
  className: cn(className),
2685
2693
  ...props
2686
2694
  });
2687
- // src/ui/composed/AgnoMessageItem.tsx
2688
- import { useState as useState8 } from "react";
2689
- import { GenerativeUIRenderer } from "@rodrigocoliveira/agno-react";
2690
- import {
2691
- AlertCircle,
2692
- FileIcon as FileIcon3,
2693
- FileText,
2694
- Image as ImageIcon2,
2695
- Lightbulb,
2696
- Music,
2697
- Paperclip,
2698
- Video
2699
- } from "lucide-react";
2700
- import { jsx as jsx35, jsxs as jsxs20, Fragment as Fragment5 } from "react/jsx-runtime";
2701
- var defaultFormatTimestamp = formatSmartTimestamp;
2702
- var getToolState = (tool) => {
2703
- return tool.tool_call_error ? "output-error" : "output-available";
2704
- };
2705
- function AgnoMessageItem({
2695
+ // src/ui/composed/agno-message/message.tsx
2696
+ import { useMemo as useMemo5, useState as useState10 } from "react";
2697
+ import { AlertCircle as AlertCircle2, FileIcon as FileIcon4, Music as Music2 } from "lucide-react";
2698
+
2699
+ // src/ui/composed/agno-message/context.ts
2700
+ import { createContext as createContext3, useContext as useContext3 } from "react";
2701
+ var AgnoMessageContext = createContext3(null);
2702
+ function useAgnoMessageContext() {
2703
+ const ctx = useContext3(AgnoMessageContext);
2704
+ if (!ctx) {
2705
+ throw new Error("useAgnoMessageContext must be used within an <AgnoMessage> provider. " + "Wrap your slots with <AgnoMessage message={...}>.");
2706
+ }
2707
+ return ctx;
2708
+ }
2709
+
2710
+ // src/ui/composed/agno-message/reasoning.tsx
2711
+ import { Lightbulb } from "lucide-react";
2712
+ import { jsx as jsx35, jsxs as jsxs20 } from "react/jsx-runtime";
2713
+ function AgnoMessageReasoning() {
2714
+ const { message, classNames } = useAgnoMessageContext();
2715
+ const steps = message.extra_data?.reasoning_steps;
2716
+ if (!steps || steps.length === 0)
2717
+ return null;
2718
+ return /* @__PURE__ */ jsxs20("div", {
2719
+ className: cn("space-y-2 pt-1", classNames?.assistant?.reasoning),
2720
+ children: [
2721
+ /* @__PURE__ */ jsxs20("div", {
2722
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2723
+ children: [
2724
+ /* @__PURE__ */ jsx35(Lightbulb, {
2725
+ className: "h-3.5 w-3.5"
2726
+ }),
2727
+ "Reasoning (",
2728
+ steps.length,
2729
+ " steps)"
2730
+ ]
2731
+ }),
2732
+ /* @__PURE__ */ jsx35(Accordion, {
2733
+ type: "multiple",
2734
+ className: "w-full",
2735
+ children: steps.map((step, idx) => /* @__PURE__ */ jsxs20(AccordionItem, {
2736
+ value: `reasoning-${idx}`,
2737
+ className: "border-muted",
2738
+ children: [
2739
+ /* @__PURE__ */ jsx35(AccordionTrigger, {
2740
+ className: "text-xs py-1.5 hover:no-underline",
2741
+ children: step.title || `Step ${idx + 1}`
2742
+ }),
2743
+ /* @__PURE__ */ jsxs20(AccordionContent, {
2744
+ className: "space-y-1.5 text-xs text-muted-foreground",
2745
+ children: [
2746
+ step.action && /* @__PURE__ */ jsxs20("div", {
2747
+ children: [
2748
+ /* @__PURE__ */ jsx35("span", {
2749
+ className: "font-medium text-foreground",
2750
+ children: "Action:"
2751
+ }),
2752
+ " ",
2753
+ step.action
2754
+ ]
2755
+ }),
2756
+ step.reasoning && /* @__PURE__ */ jsxs20("div", {
2757
+ children: [
2758
+ /* @__PURE__ */ jsx35("span", {
2759
+ className: "font-medium text-foreground",
2760
+ children: "Reasoning:"
2761
+ }),
2762
+ " ",
2763
+ step.reasoning
2764
+ ]
2765
+ }),
2766
+ step.result && /* @__PURE__ */ jsxs20("div", {
2767
+ children: [
2768
+ /* @__PURE__ */ jsx35("span", {
2769
+ className: "font-medium text-foreground",
2770
+ children: "Result:"
2771
+ }),
2772
+ " ",
2773
+ step.result
2774
+ ]
2775
+ }),
2776
+ step.confidence !== undefined && /* @__PURE__ */ jsxs20("div", {
2777
+ children: [
2778
+ /* @__PURE__ */ jsx35("span", {
2779
+ className: "font-medium text-foreground",
2780
+ children: "Confidence:"
2781
+ }),
2782
+ " ",
2783
+ (step.confidence * 100).toFixed(1),
2784
+ "%"
2785
+ ]
2786
+ })
2787
+ ]
2788
+ })
2789
+ ]
2790
+ }, idx))
2791
+ })
2792
+ ]
2793
+ });
2794
+ }
2795
+
2796
+ // src/ui/composed/agno-message/media.tsx
2797
+ import { FileIcon as FileIcon3, Image as ImageIcon2, Music, Paperclip, Video } from "lucide-react";
2798
+ import { jsx as jsx36, jsxs as jsxs21, Fragment as Fragment5 } from "react/jsx-runtime";
2799
+ function AgnoMessageMedia() {
2800
+ const {
2801
+ message,
2802
+ classNames,
2803
+ showImageLightbox,
2804
+ showFilePreview,
2805
+ openImageLightbox,
2806
+ openFilePreview
2807
+ } = useAgnoMessageContext();
2808
+ const mediaClassName = classNames?.assistant?.media;
2809
+ const hasImages = !!message.images && message.images.length > 0;
2810
+ const hasVideos = !!message.videos && message.videos.length > 0;
2811
+ const hasAudio = !!message.audio && message.audio.length > 0;
2812
+ const hasFiles = !!message.files && message.files.length > 0;
2813
+ const hasResponseAudio = !!message.response_audio;
2814
+ if (!hasImages && !hasVideos && !hasAudio && !hasFiles && !hasResponseAudio)
2815
+ return null;
2816
+ return /* @__PURE__ */ jsxs21(Fragment5, {
2817
+ children: [
2818
+ hasImages && /* @__PURE__ */ jsxs21("div", {
2819
+ className: cn("space-y-2 pt-1", mediaClassName),
2820
+ children: [
2821
+ /* @__PURE__ */ jsxs21("div", {
2822
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2823
+ children: [
2824
+ /* @__PURE__ */ jsx36(ImageIcon2, {
2825
+ className: "h-3.5 w-3.5"
2826
+ }),
2827
+ "Images (",
2828
+ message.images.length,
2829
+ ")"
2830
+ ]
2831
+ }),
2832
+ /* @__PURE__ */ jsx36("div", {
2833
+ className: "grid grid-cols-2 gap-2",
2834
+ children: message.images.map((img, idx) => /* @__PURE__ */ jsxs21("div", {
2835
+ className: "space-y-1",
2836
+ children: [
2837
+ showImageLightbox ? /* @__PURE__ */ jsx36("button", {
2838
+ type: "button",
2839
+ onClick: () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx),
2840
+ className: "group relative w-full overflow-hidden rounded-lg border border-border cursor-pointer hover:border-primary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring transition-colors",
2841
+ children: /* @__PURE__ */ jsx36("img", {
2842
+ src: img.url,
2843
+ alt: img.revised_prompt || "Generated image",
2844
+ className: "w-full rounded-lg"
2845
+ })
2846
+ }) : /* @__PURE__ */ jsx36("img", {
2847
+ src: img.url,
2848
+ alt: img.revised_prompt || "Generated image",
2849
+ className: "w-full rounded-lg border border-border"
2850
+ }),
2851
+ img.revised_prompt && /* @__PURE__ */ jsx36("p", {
2852
+ className: "text-[11px] text-muted-foreground italic px-0.5",
2853
+ children: img.revised_prompt
2854
+ })
2855
+ ]
2856
+ }, idx))
2857
+ })
2858
+ ]
2859
+ }),
2860
+ hasVideos && /* @__PURE__ */ jsxs21("div", {
2861
+ className: cn("space-y-2 pt-1", mediaClassName),
2862
+ children: [
2863
+ /* @__PURE__ */ jsxs21("div", {
2864
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2865
+ children: [
2866
+ /* @__PURE__ */ jsx36(Video, {
2867
+ className: "h-3.5 w-3.5"
2868
+ }),
2869
+ "Videos (",
2870
+ message.videos.length,
2871
+ ")"
2872
+ ]
2873
+ }),
2874
+ /* @__PURE__ */ jsx36("div", {
2875
+ className: "space-y-2",
2876
+ children: message.videos.map((video, idx) => /* @__PURE__ */ jsx36("div", {
2877
+ children: video.url ? /* @__PURE__ */ jsx36("video", {
2878
+ src: video.url,
2879
+ controls: true,
2880
+ className: "w-full rounded-lg border border-border"
2881
+ }) : /* @__PURE__ */ jsxs21("div", {
2882
+ className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
2883
+ children: [
2884
+ "Video ID: ",
2885
+ video.id,
2886
+ " (ETA: ",
2887
+ video.eta,
2888
+ "s)"
2889
+ ]
2890
+ })
2891
+ }, idx))
2892
+ })
2893
+ ]
2894
+ }),
2895
+ hasAudio && /* @__PURE__ */ jsxs21("div", {
2896
+ className: cn("space-y-2 pt-1", mediaClassName),
2897
+ children: [
2898
+ /* @__PURE__ */ jsxs21("div", {
2899
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2900
+ children: [
2901
+ /* @__PURE__ */ jsx36(Music, {
2902
+ className: "h-3.5 w-3.5"
2903
+ }),
2904
+ "Audio (",
2905
+ message.audio.length,
2906
+ ")"
2907
+ ]
2908
+ }),
2909
+ /* @__PURE__ */ jsx36("div", {
2910
+ className: "space-y-2",
2911
+ children: message.audio.map((audio, idx) => /* @__PURE__ */ jsx36("div", {
2912
+ children: audio.url ? /* @__PURE__ */ jsx36("audio", {
2913
+ src: audio.url,
2914
+ controls: true,
2915
+ className: "w-full"
2916
+ }) : audio.base64_audio ? /* @__PURE__ */ jsx36("audio", {
2917
+ src: `data:${audio.mime_type || "audio/wav"};base64,${audio.base64_audio}`,
2918
+ controls: true,
2919
+ className: "w-full"
2920
+ }) : /* @__PURE__ */ jsx36("div", {
2921
+ className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
2922
+ children: "Audio data unavailable"
2923
+ })
2924
+ }, idx))
2925
+ })
2926
+ ]
2927
+ }),
2928
+ hasFiles && /* @__PURE__ */ jsxs21("div", {
2929
+ className: cn("space-y-2 pt-1", mediaClassName),
2930
+ children: [
2931
+ /* @__PURE__ */ jsxs21("div", {
2932
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2933
+ children: [
2934
+ /* @__PURE__ */ jsx36(Paperclip, {
2935
+ className: "h-3.5 w-3.5"
2936
+ }),
2937
+ "Files (",
2938
+ message.files.length,
2939
+ ")"
2940
+ ]
2941
+ }),
2942
+ /* @__PURE__ */ jsx36("div", {
2943
+ className: "flex flex-wrap gap-2",
2944
+ children: message.files.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx36(FilePreviewCard, {
2945
+ file: { name: file.name, type: file.type, url: file.url, size: file.size },
2946
+ onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
2947
+ }, idx) : /* @__PURE__ */ jsxs21("div", {
2948
+ className: "flex items-center gap-2 rounded-lg border border-border px-3 py-2 text-xs bg-muted/30 hover:bg-muted/50 transition-colors",
2949
+ children: [
2950
+ /* @__PURE__ */ jsx36(FileIcon3, {
2951
+ className: "h-3.5 w-3.5 shrink-0 text-muted-foreground"
2952
+ }),
2953
+ /* @__PURE__ */ jsx36("span", {
2954
+ className: "truncate max-w-[180px]",
2955
+ children: file.name
2956
+ }),
2957
+ file.size && /* @__PURE__ */ jsxs21("span", {
2958
+ className: "text-muted-foreground/70",
2959
+ children: [
2960
+ "(",
2961
+ (file.size / 1024).toFixed(1),
2962
+ "KB)"
2963
+ ]
2964
+ }),
2965
+ file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsx36("a", {
2966
+ href: file.url,
2967
+ target: "_blank",
2968
+ rel: "noopener noreferrer",
2969
+ className: "text-primary hover:underline font-medium",
2970
+ children: "View"
2971
+ })
2972
+ ]
2973
+ }, idx))
2974
+ })
2975
+ ]
2976
+ }),
2977
+ hasResponseAudio && message.response_audio && /* @__PURE__ */ jsxs21("div", {
2978
+ className: cn("space-y-2 pt-1", mediaClassName),
2979
+ children: [
2980
+ /* @__PURE__ */ jsxs21("div", {
2981
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2982
+ children: [
2983
+ /* @__PURE__ */ jsx36(Music, {
2984
+ className: "h-3.5 w-3.5"
2985
+ }),
2986
+ "Response Audio"
2987
+ ]
2988
+ }),
2989
+ message.response_audio.transcript && /* @__PURE__ */ jsxs21("div", {
2990
+ className: "text-xs italic bg-muted/50 border border-border p-2.5 rounded-lg text-muted-foreground",
2991
+ children: [
2992
+ '"',
2993
+ message.response_audio.transcript,
2994
+ '"'
2995
+ ]
2996
+ }),
2997
+ message.response_audio.content && /* @__PURE__ */ jsx36("audio", {
2998
+ src: `data:audio/wav;base64,${message.response_audio.content}`,
2999
+ controls: true,
3000
+ className: "w-full"
3001
+ })
3002
+ ]
3003
+ })
3004
+ ]
3005
+ });
3006
+ }
3007
+
3008
+ // src/ui/composed/agno-chat/context.ts
3009
+ import { createContext as createContext4, useContext as useContext4 } from "react";
3010
+ var AgnoChatContext = createContext4(null);
3011
+ function useAgnoChatContext() {
3012
+ const ctx = useContext4(AgnoChatContext);
3013
+ if (!ctx) {
3014
+ throw new Error("useAgnoChatContext must be used within an <AgnoChat> provider. " + "Wrap your component tree with <AgnoChat>.");
3015
+ }
3016
+ return ctx;
3017
+ }
3018
+
3019
+ // src/components/GenerativeUIRenderer.tsx
3020
+ import React13 from "react";
3021
+
3022
+ // src/utils/component-registry.ts
3023
+ class ComponentRegistry {
3024
+ static instance;
3025
+ components = new Map;
3026
+ constructor() {}
3027
+ static getInstance() {
3028
+ if (!ComponentRegistry.instance) {
3029
+ ComponentRegistry.instance = new ComponentRegistry;
3030
+ }
3031
+ return ComponentRegistry.instance;
3032
+ }
3033
+ register(type, renderer) {
3034
+ this.components.set(type, renderer);
3035
+ }
3036
+ registerBatch(components) {
3037
+ Object.entries(components).forEach(([type, renderer]) => {
3038
+ this.register(type, renderer);
3039
+ });
3040
+ }
3041
+ get(type) {
3042
+ return this.components.get(type);
3043
+ }
3044
+ has(type) {
3045
+ return this.components.has(type);
3046
+ }
3047
+ unregister(type) {
3048
+ this.components.delete(type);
3049
+ }
3050
+ getRegisteredTypes() {
3051
+ return Array.from(this.components.keys());
3052
+ }
3053
+ clear() {
3054
+ this.components.clear();
3055
+ }
3056
+ }
3057
+ function getComponentRegistry() {
3058
+ return ComponentRegistry.getInstance();
3059
+ }
3060
+
3061
+ // src/hooks/useAgnoToolExecution.ts
3062
+ import { useState as useState9, useEffect as useEffect7, useCallback as useCallback8, useMemo as useMemo4 } from "react";
3063
+
3064
+ // src/context/AgnoContext.tsx
3065
+ import { createContext as createContext5, useContext as useContext5, useMemo as useMemo3, useEffect as useEffect6 } from "react";
3066
+ import { AgnoClient } from "@rodrigocoliveira/agno-client";
3067
+ import { jsx as jsx37 } from "react/jsx-runtime";
3068
+ var AgnoContext = createContext5(null);
3069
+
3070
+ // src/context/ToolHandlerContext.tsx
3071
+ import { createContext as createContext6, useContext as useContext6, useState as useState8, useCallback as useCallback7 } from "react";
3072
+ import { jsx as jsx38 } from "react/jsx-runtime";
3073
+ var ToolHandlerContext = createContext6(null);
3074
+
3075
+ // src/hooks/useAgnoToolExecution.ts
3076
+ var customRenderRegistry = new Map;
3077
+ function getCustomRender(key) {
3078
+ return customRenderRegistry.get(key);
3079
+ }
3080
+
3081
+ // src/components/GenerativeUIRenderer.tsx
3082
+ import { jsx as jsx39, jsxs as jsxs22 } from "react/jsx-runtime";
3083
+
3084
+ class UIErrorBoundary extends React13.Component {
3085
+ constructor(props) {
3086
+ super(props);
3087
+ this.state = { hasError: false };
3088
+ }
3089
+ static getDerivedStateFromError(error) {
3090
+ return { hasError: true, error };
3091
+ }
3092
+ componentDidCatch(error, errorInfo) {
3093
+ console.error("[GenerativeUIRenderer] Error rendering component:", error, errorInfo);
3094
+ this.props.onError?.(error);
3095
+ }
3096
+ render() {
3097
+ if (this.state.hasError) {
3098
+ return this.props.fallback || /* @__PURE__ */ jsxs22("div", {
3099
+ className: "p-4 border border-red-300 rounded-md bg-red-50 text-red-800",
3100
+ children: [
3101
+ /* @__PURE__ */ jsx39("p", {
3102
+ className: "font-semibold",
3103
+ children: "Failed to render UI component"
3104
+ }),
3105
+ /* @__PURE__ */ jsx39("p", {
3106
+ className: "text-sm mt-1",
3107
+ children: this.state.error?.message || "Unknown error"
3108
+ })
3109
+ ]
3110
+ });
3111
+ }
3112
+ return this.props.children;
3113
+ }
3114
+ }
3115
+ function GenerativeUIRenderer({
3116
+ spec,
3117
+ className,
3118
+ onError
3119
+ }) {
3120
+ const registry = getComponentRegistry();
3121
+ if (spec.type === "custom") {
3122
+ const customSpec = spec;
3123
+ if (customSpec.renderKey) {
3124
+ const renderFn = getCustomRender(customSpec.renderKey);
3125
+ if (renderFn) {
3126
+ return /* @__PURE__ */ jsx39(UIErrorBoundary, {
3127
+ onError,
3128
+ children: /* @__PURE__ */ jsx39("div", {
3129
+ className,
3130
+ children: renderFn(customSpec.props || {})
3131
+ })
3132
+ });
3133
+ }
3134
+ }
3135
+ return /* @__PURE__ */ jsxs22("div", {
3136
+ className: `p-4 border border-yellow-300 rounded-md bg-yellow-50 text-yellow-800 ${className || ""}`,
3137
+ children: [
3138
+ /* @__PURE__ */ jsx39("p", {
3139
+ className: "font-semibold",
3140
+ children: "Custom component not available"
3141
+ }),
3142
+ /* @__PURE__ */ jsx39("p", {
3143
+ className: "text-sm mt-1",
3144
+ children: "The custom render function for this component is not available."
3145
+ })
3146
+ ]
3147
+ });
3148
+ }
3149
+ if (spec.type === "chart") {
3150
+ const chartSpec = spec;
3151
+ const chartType = `chart:${chartSpec.component}`;
3152
+ if (registry.has(chartType)) {
3153
+ const ChartRenderer = registry.get(chartType);
3154
+ return /* @__PURE__ */ jsx39(UIErrorBoundary, {
3155
+ onError,
3156
+ children: /* @__PURE__ */ jsxs22("div", {
3157
+ className,
3158
+ children: [
3159
+ chartSpec.title && /* @__PURE__ */ jsx39("h3", {
3160
+ className: "font-semibold mb-2",
3161
+ children: chartSpec.title
3162
+ }),
3163
+ chartSpec.description && /* @__PURE__ */ jsx39("p", {
3164
+ className: "text-sm text-gray-600 mb-4",
3165
+ children: chartSpec.description
3166
+ }),
3167
+ /* @__PURE__ */ jsx39(ChartRenderer, {
3168
+ ...chartSpec.props
3169
+ })
3170
+ ]
3171
+ })
3172
+ });
3173
+ }
3174
+ return /* @__PURE__ */ jsxs22("div", {
3175
+ className: `p-4 border border-gray-300 rounded-md ${className || ""}`,
3176
+ children: [
3177
+ /* @__PURE__ */ jsx39("p", {
3178
+ className: "font-semibold mb-2",
3179
+ children: chartSpec.title || "Chart Data"
3180
+ }),
3181
+ chartSpec.description && /* @__PURE__ */ jsx39("p", {
3182
+ className: "text-sm text-gray-600 mb-2",
3183
+ children: chartSpec.description
3184
+ }),
3185
+ /* @__PURE__ */ jsx39("pre", {
3186
+ className: "text-xs bg-gray-100 p-2 rounded overflow-auto",
3187
+ children: JSON.stringify(chartSpec.props.data, null, 2)
3188
+ })
3189
+ ]
3190
+ });
3191
+ }
3192
+ if (spec.type === "card-grid") {
3193
+ const cardGridSpec = spec;
3194
+ if (registry.has("card-grid")) {
3195
+ const CardGridRenderer = registry.get("card-grid");
3196
+ return /* @__PURE__ */ jsx39(UIErrorBoundary, {
3197
+ onError,
3198
+ children: /* @__PURE__ */ jsxs22("div", {
3199
+ className,
3200
+ children: [
3201
+ cardGridSpec.title && /* @__PURE__ */ jsx39("h3", {
3202
+ className: "font-semibold mb-2",
3203
+ children: cardGridSpec.title
3204
+ }),
3205
+ cardGridSpec.description && /* @__PURE__ */ jsx39("p", {
3206
+ className: "text-sm text-gray-600 mb-4",
3207
+ children: cardGridSpec.description
3208
+ }),
3209
+ /* @__PURE__ */ jsx39(CardGridRenderer, {
3210
+ ...cardGridSpec.props
3211
+ })
3212
+ ]
3213
+ })
3214
+ });
3215
+ }
3216
+ }
3217
+ if (spec.type === "table") {
3218
+ const tableSpec = spec;
3219
+ if (registry.has("table")) {
3220
+ const TableRenderer = registry.get("table");
3221
+ return /* @__PURE__ */ jsx39(UIErrorBoundary, {
3222
+ onError,
3223
+ children: /* @__PURE__ */ jsxs22("div", {
3224
+ className,
3225
+ children: [
3226
+ tableSpec.title && /* @__PURE__ */ jsx39("h3", {
3227
+ className: "font-semibold mb-2",
3228
+ children: tableSpec.title
3229
+ }),
3230
+ tableSpec.description && /* @__PURE__ */ jsx39("p", {
3231
+ className: "text-sm text-gray-600 mb-4",
3232
+ children: tableSpec.description
3233
+ }),
3234
+ /* @__PURE__ */ jsx39(TableRenderer, {
3235
+ ...tableSpec.props
3236
+ })
3237
+ ]
3238
+ })
3239
+ });
3240
+ }
3241
+ }
3242
+ if (spec.type === "markdown") {
3243
+ const markdownSpec = spec;
3244
+ if (registry.has("markdown")) {
3245
+ const MarkdownRenderer = registry.get("markdown");
3246
+ return /* @__PURE__ */ jsx39(UIErrorBoundary, {
3247
+ onError,
3248
+ children: /* @__PURE__ */ jsx39("div", {
3249
+ className,
3250
+ children: /* @__PURE__ */ jsx39(MarkdownRenderer, {
3251
+ ...markdownSpec.props
3252
+ })
3253
+ })
3254
+ });
3255
+ }
3256
+ return /* @__PURE__ */ jsx39("div", {
3257
+ className,
3258
+ children: markdownSpec.props.content
3259
+ });
3260
+ }
3261
+ if (spec.type === "artifact") {
3262
+ const artifactSpec = spec;
3263
+ return /* @__PURE__ */ jsx39(UIErrorBoundary, {
3264
+ onError,
3265
+ children: /* @__PURE__ */ jsxs22("div", {
3266
+ className: `p-4 border rounded-md ${className || ""}`,
3267
+ children: [
3268
+ artifactSpec.title && /* @__PURE__ */ jsx39("h3", {
3269
+ className: "font-semibold mb-4",
3270
+ children: artifactSpec.title
3271
+ }),
3272
+ artifactSpec.description && /* @__PURE__ */ jsx39("p", {
3273
+ className: "text-sm text-gray-600 mb-4",
3274
+ children: artifactSpec.description
3275
+ }),
3276
+ /* @__PURE__ */ jsx39("div", {
3277
+ className: "space-y-4",
3278
+ children: artifactSpec.props.content?.map((childSpec, index) => /* @__PURE__ */ jsx39(GenerativeUIRenderer, {
3279
+ spec: childSpec,
3280
+ onError
3281
+ }, index))
3282
+ })
3283
+ ]
3284
+ })
3285
+ });
3286
+ }
3287
+ return /* @__PURE__ */ jsxs22("div", {
3288
+ className: `p-4 border border-gray-300 rounded-md ${className || ""}`,
3289
+ children: [
3290
+ /* @__PURE__ */ jsx39("p", {
3291
+ className: "font-semibold",
3292
+ children: "Unsupported UI component"
3293
+ }),
3294
+ /* @__PURE__ */ jsxs22("p", {
3295
+ className: "text-sm text-gray-600 mt-1",
3296
+ children: [
3297
+ "Component type: ",
3298
+ spec.type
3299
+ ]
3300
+ })
3301
+ ]
3302
+ });
3303
+ }
3304
+
3305
+ // src/ui/composed/agno-chat/tool-building-blocks.tsx
3306
+ import { jsx as jsx40, jsxs as jsxs23 } from "react/jsx-runtime";
3307
+ var getToolState = (tool) => tool.tool_call_error ? "output-error" : "output-available";
3308
+ function ToolDebugCard({ tool, defaultOpen }) {
3309
+ const output = tool.result ?? tool.content;
3310
+ return /* @__PURE__ */ jsxs23(Tool, {
3311
+ defaultOpen,
3312
+ children: [
3313
+ /* @__PURE__ */ jsx40(ToolHeader, {
3314
+ title: tool.tool_name,
3315
+ type: "tool-use",
3316
+ state: getToolState(tool)
3317
+ }),
3318
+ /* @__PURE__ */ jsxs23(ToolContent, {
3319
+ children: [
3320
+ /* @__PURE__ */ jsx40(ToolInput, {
3321
+ input: tool.tool_args
3322
+ }),
3323
+ output ? /* @__PURE__ */ jsx40(ToolOutput, {
3324
+ output,
3325
+ errorText: tool.tool_call_error ? "Tool execution failed" : undefined
3326
+ }) : null
3327
+ ]
3328
+ })
3329
+ ]
3330
+ });
3331
+ }
3332
+ function ToolGenerativeUI({ tool }) {
3333
+ const uiComponent = tool.ui_component;
3334
+ if (!uiComponent)
3335
+ return null;
3336
+ return uiComponent.layout === "artifact" ? /* @__PURE__ */ jsx40(Artifact, {
3337
+ children: /* @__PURE__ */ jsx40(GenerativeUIRenderer, {
3338
+ spec: uiComponent,
3339
+ className: "w-full p-2"
3340
+ })
3341
+ }) : /* @__PURE__ */ jsx40(GenerativeUIRenderer, {
3342
+ spec: uiComponent,
3343
+ className: "w-full"
3344
+ });
3345
+ }
3346
+
3347
+ // src/ui/composed/agno-message/tools.tsx
3348
+ import { jsx as jsx41, jsxs as jsxs24, Fragment as Fragment6 } from "react/jsx-runtime";
3349
+ function AgnoMessageTools({ renderTool: renderToolProp } = {}) {
3350
+ const { message, classNames, renderTool: ctxMsgRenderTool } = useAgnoMessageContext();
3351
+ const { renderTool: ctxChatRenderTool, isDebug } = useAgnoChatContext();
3352
+ const renderTool = renderToolProp ?? ctxMsgRenderTool ?? ctxChatRenderTool;
3353
+ if (!message.tool_calls || message.tool_calls.length === 0)
3354
+ return null;
3355
+ return /* @__PURE__ */ jsx41("div", {
3356
+ className: cn("space-y-2 pt-1", classNames?.assistant?.toolCalls),
3357
+ children: message.tool_calls.map((tool, idx) => {
3358
+ const defaultRender = () => /* @__PURE__ */ jsxs24(Fragment6, {
3359
+ children: [
3360
+ /* @__PURE__ */ jsx41(ToolGenerativeUI, {
3361
+ tool
3362
+ }),
3363
+ isDebug ? /* @__PURE__ */ jsx41(ToolDebugCard, {
3364
+ tool,
3365
+ defaultOpen: idx === 0
3366
+ }) : null
3367
+ ]
3368
+ });
3369
+ const node = renderTool ? renderTool(tool, { index: idx, isDebug, defaultRender }) : defaultRender();
3370
+ if (node === null || node === undefined)
3371
+ return null;
3372
+ return /* @__PURE__ */ jsx41("div", {
3373
+ children: node
3374
+ }, tool.tool_call_id || idx);
3375
+ })
3376
+ });
3377
+ }
3378
+
3379
+ // src/ui/composed/agno-message/content.tsx
3380
+ import { jsx as jsx42 } from "react/jsx-runtime";
3381
+ function AgnoMessageContent() {
3382
+ const { message } = useAgnoMessageContext();
3383
+ if (!message.content)
3384
+ return null;
3385
+ return /* @__PURE__ */ jsx42("div", {
3386
+ className: "prose prose-sm dark:prose-invert max-w-none prose-p:leading-relaxed prose-pre:bg-muted prose-pre:border prose-pre:border-border",
3387
+ children: /* @__PURE__ */ jsx42(Response, {
3388
+ children: message.content
3389
+ })
3390
+ });
3391
+ }
3392
+
3393
+ // src/ui/composed/agno-message/references.tsx
3394
+ import { FileText } from "lucide-react";
3395
+ import { jsx as jsx43, jsxs as jsxs25 } from "react/jsx-runtime";
3396
+ function AgnoMessageReferences() {
3397
+ const { message, classNames } = useAgnoMessageContext();
3398
+ const references = message.extra_data?.references;
3399
+ if (!references || references.length === 0)
3400
+ return null;
3401
+ return /* @__PURE__ */ jsxs25("div", {
3402
+ className: cn("space-y-2 pt-1", classNames?.assistant?.references),
3403
+ children: [
3404
+ /* @__PURE__ */ jsxs25("div", {
3405
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3406
+ children: [
3407
+ /* @__PURE__ */ jsx43(FileText, {
3408
+ className: "h-3.5 w-3.5"
3409
+ }),
3410
+ "References (",
3411
+ references.length,
3412
+ ")"
3413
+ ]
3414
+ }),
3415
+ /* @__PURE__ */ jsx43("div", {
3416
+ className: "space-y-2",
3417
+ children: references.map((refData, idx) => /* @__PURE__ */ jsxs25("div", {
3418
+ className: "text-xs space-y-1.5",
3419
+ children: [
3420
+ refData.query && /* @__PURE__ */ jsxs25("div", {
3421
+ className: "font-medium text-foreground",
3422
+ children: [
3423
+ "Query: ",
3424
+ refData.query
3425
+ ]
3426
+ }),
3427
+ refData.references.map((ref, refIdx) => /* @__PURE__ */ jsxs25("div", {
3428
+ className: "bg-muted/50 border border-border p-2.5 rounded-lg",
3429
+ children: [
3430
+ /* @__PURE__ */ jsxs25("div", {
3431
+ className: "italic text-muted-foreground mb-1",
3432
+ children: [
3433
+ '"',
3434
+ ref.content,
3435
+ '"'
3436
+ ]
3437
+ }),
3438
+ /* @__PURE__ */ jsxs25("div", {
3439
+ className: "text-muted-foreground/70",
3440
+ children: [
3441
+ "Source: ",
3442
+ ref.name,
3443
+ " (chunk ",
3444
+ ref.meta_data.chunk,
3445
+ "/",
3446
+ ref.meta_data.chunk_size,
3447
+ ")"
3448
+ ]
3449
+ })
3450
+ ]
3451
+ }, refIdx))
3452
+ ]
3453
+ }, idx))
3454
+ })
3455
+ ]
3456
+ });
3457
+ }
3458
+
3459
+ // src/ui/composed/agno-message/footer.tsx
3460
+ import { AlertCircle } from "lucide-react";
3461
+ import { jsx as jsx44, jsxs as jsxs26 } from "react/jsx-runtime";
3462
+ function AgnoMessageFooter({ showTimestamp = true } = {}) {
3463
+ const { message, classNames, actions, isLastAssistantMessage, formatTimestamp } = useAgnoMessageContext();
3464
+ const hasError = message.streamingError;
3465
+ const isCustomTimestamp = !!formatTimestamp;
3466
+ const resolvedFormatTimestamp = formatTimestamp ?? formatSmartTimestamp;
3467
+ if (!actions?.assistant && !showTimestamp && !hasError)
3468
+ return null;
3469
+ return /* @__PURE__ */ jsxs26("div", {
3470
+ className: "flex items-center gap-2 pt-1",
3471
+ children: [
3472
+ actions?.assistant && (() => {
3473
+ const visibility = actions.visibility ?? "visible";
3474
+ if (visibility === "last-assistant" && !isLastAssistantMessage)
3475
+ return null;
3476
+ const useHover = visibility === "hover" || visibility === "hover-last-visible" && !isLastAssistantMessage;
3477
+ return /* @__PURE__ */ jsx44("div", {
3478
+ className: cn("flex items-center gap-1 transition-opacity", useHover && "opacity-0 group-hover/message:opacity-100", classNames?.assistant?.actions),
3479
+ children: actions.assistant(message)
3480
+ });
3481
+ })(),
3482
+ hasError && /* @__PURE__ */ jsxs26("span", {
3483
+ className: "flex items-center gap-1 text-[11px] text-destructive",
3484
+ children: [
3485
+ /* @__PURE__ */ jsx44(AlertCircle, {
3486
+ className: "h-3 w-3"
3487
+ }),
3488
+ "Error"
3489
+ ]
3490
+ }),
3491
+ showTimestamp && /* @__PURE__ */ jsx44(SmartTimestamp, {
3492
+ date: new Date(message.created_at * 1000),
3493
+ formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
3494
+ className: "text-[11px] text-muted-foreground"
3495
+ })
3496
+ ]
3497
+ });
3498
+ }
3499
+
3500
+ // src/ui/composed/agno-message/message.tsx
3501
+ import { jsx as jsx45, jsxs as jsxs27, Fragment as Fragment7 } from "react/jsx-runtime";
3502
+ function DefaultAssistantComposition({ showTimestamp }) {
3503
+ return /* @__PURE__ */ jsxs27(Fragment7, {
3504
+ children: [
3505
+ /* @__PURE__ */ jsx45(AgnoMessageReasoning, {}),
3506
+ /* @__PURE__ */ jsx45(AgnoMessageMedia, {}),
3507
+ /* @__PURE__ */ jsx45(AgnoMessageTools, {}),
3508
+ /* @__PURE__ */ jsx45(AgnoMessageContent, {}),
3509
+ /* @__PURE__ */ jsx45(AgnoMessageReferences, {}),
3510
+ /* @__PURE__ */ jsx45(AgnoMessageFooter, {
3511
+ showTimestamp
3512
+ })
3513
+ ]
3514
+ });
3515
+ }
3516
+ function AgnoMessage({
2706
3517
  message,
2707
3518
  className,
2708
3519
  classNames,
2709
- renderContent,
2710
- renderToolCall,
2711
- renderMedia,
2712
3520
  avatars,
2713
3521
  actions,
2714
3522
  isLastAssistantMessage = false,
2715
- showReasoning = true,
2716
- showReferences = true,
2717
- showTimestamp = true,
2718
- showGenerativeUI = true,
2719
- showToolCalls = true,
2720
3523
  showFilePreview = true,
2721
3524
  showImageLightbox = true,
3525
+ showTimestamp = true,
2722
3526
  formatTimestamp,
2723
- toolResultRenderers
3527
+ renderTool,
3528
+ children
2724
3529
  }) {
2725
3530
  const isUser = message.role === "user";
2726
3531
  const hasError = message.streamingError;
2727
- const toolsWithUI = message.tool_calls?.filter((tool) => tool.ui_component) || [];
2728
- const [preview, setPreview] = useState8(null);
3532
+ const [preview, setPreview] = useState10(null);
2729
3533
  const isCustomTimestamp = !!formatTimestamp;
2730
- const resolvedFormatTimestamp = formatTimestamp ?? defaultFormatTimestamp;
2731
- const openImageLightbox = (images, index) => {
2732
- if (!showImageLightbox)
2733
- return;
2734
- setPreview({ type: "image", images, initialIndex: index });
2735
- };
2736
- const openFilePreview = (file) => {
2737
- if (!showFilePreview)
2738
- return;
2739
- setPreview({ type: "file", file });
2740
- };
3534
+ const resolvedFormatTimestamp = formatTimestamp ?? formatSmartTimestamp;
3535
+ const ctx = useMemo5(() => ({
3536
+ message,
3537
+ isLastAssistantMessage,
3538
+ classNames,
3539
+ actions,
3540
+ avatars,
3541
+ formatTimestamp,
3542
+ showFilePreview,
3543
+ showImageLightbox,
3544
+ openImageLightbox: (images, index) => {
3545
+ if (!showImageLightbox)
3546
+ return;
3547
+ setPreview({ type: "image", images, initialIndex: index });
3548
+ },
3549
+ openFilePreview: (file) => {
3550
+ if (!showFilePreview)
3551
+ return;
3552
+ setPreview({ type: "file", file });
3553
+ },
3554
+ renderTool
3555
+ }), [
3556
+ message,
3557
+ isLastAssistantMessage,
3558
+ classNames,
3559
+ actions,
3560
+ avatars,
3561
+ formatTimestamp,
3562
+ showFilePreview,
3563
+ showImageLightbox,
3564
+ renderTool
3565
+ ]);
2741
3566
  const closePreview = () => setPreview(null);
2742
- return /* @__PURE__ */ jsxs20("div", {
2743
- className: cn("py-5 first:pt-2", isUser ? "flex justify-end" : "", classNames?.root, className),
3567
+ return /* @__PURE__ */ jsx45(AgnoMessageContext.Provider, {
3568
+ value: ctx,
3569
+ children: /* @__PURE__ */ jsxs27("div", {
3570
+ className: cn("py-5 first:pt-2", isUser ? "flex justify-end" : "", classNames?.root, className),
3571
+ children: [
3572
+ isUser ? /* @__PURE__ */ jsx45(UserMessageLayout, {
3573
+ message,
3574
+ classNames,
3575
+ avatars,
3576
+ actions,
3577
+ isCustomTimestamp,
3578
+ resolvedFormatTimestamp,
3579
+ showTimestamp,
3580
+ showImageLightbox,
3581
+ showFilePreview,
3582
+ openImageLightbox: ctx.openImageLightbox,
3583
+ openFilePreview: ctx.openFilePreview,
3584
+ hasError
3585
+ }) : /* @__PURE__ */ jsxs27("div", {
3586
+ className: "flex items-start gap-3 group/message",
3587
+ children: [
3588
+ avatars?.assistant,
3589
+ /* @__PURE__ */ jsx45("div", {
3590
+ className: cn("flex-1 min-w-0 space-y-3", classNames?.assistant?.container),
3591
+ children: children ?? /* @__PURE__ */ jsx45(DefaultAssistantComposition, {
3592
+ showTimestamp
3593
+ })
3594
+ })
3595
+ ]
3596
+ }),
3597
+ preview?.type === "image" && /* @__PURE__ */ jsx45(ImageLightbox, {
3598
+ open: true,
3599
+ onOpenChange: (open) => {
3600
+ if (!open)
3601
+ closePreview();
3602
+ },
3603
+ images: preview.images,
3604
+ initialIndex: preview.initialIndex
3605
+ }),
3606
+ preview?.type === "file" && /* @__PURE__ */ jsx45(FilePreviewModal, {
3607
+ open: true,
3608
+ onOpenChange: (open) => {
3609
+ if (!open)
3610
+ closePreview();
3611
+ },
3612
+ file: preview.file
3613
+ })
3614
+ ]
3615
+ })
3616
+ });
3617
+ }
3618
+ AgnoMessage.Reasoning = AgnoMessageReasoning;
3619
+ AgnoMessage.Media = AgnoMessageMedia;
3620
+ AgnoMessage.Tools = AgnoMessageTools;
3621
+ AgnoMessage.Content = AgnoMessageContent;
3622
+ AgnoMessage.References = AgnoMessageReferences;
3623
+ AgnoMessage.Footer = AgnoMessageFooter;
3624
+ function UserMessageLayout({
3625
+ message,
3626
+ classNames,
3627
+ avatars,
3628
+ actions,
3629
+ isCustomTimestamp,
3630
+ resolvedFormatTimestamp,
3631
+ showTimestamp,
3632
+ showImageLightbox,
3633
+ showFilePreview,
3634
+ openImageLightbox,
3635
+ openFilePreview,
3636
+ hasError
3637
+ }) {
3638
+ return /* @__PURE__ */ jsxs27("div", {
3639
+ className: "flex items-start gap-2.5 max-w-[80%] flex-row-reverse",
2744
3640
  children: [
2745
- isUser ? /* @__PURE__ */ jsxs20("div", {
2746
- className: "flex items-start gap-2.5 max-w-[80%] flex-row-reverse",
3641
+ avatars?.user,
3642
+ /* @__PURE__ */ jsxs27("div", {
3643
+ className: "space-y-1.5 flex flex-col items-end min-w-0",
2747
3644
  children: [
2748
- avatars?.user,
2749
- /* @__PURE__ */ jsxs20("div", {
2750
- className: "space-y-1.5 flex flex-col items-end min-w-0",
3645
+ (message.images && message.images.length > 0 || message.audio && message.audio.length > 0 || message.files && message.files.length > 0) && /* @__PURE__ */ jsxs27("div", {
3646
+ className: "flex flex-wrap gap-2 justify-end",
2751
3647
  children: [
2752
- (message.images && message.images.length > 0 || message.audio && message.audio.length > 0 || message.files && message.files.length > 0) && /* @__PURE__ */ jsxs20("div", {
2753
- className: "flex flex-wrap gap-2 justify-end",
3648
+ message.images?.map((img, idx) => /* @__PURE__ */ jsx45(FilePreviewCard, {
3649
+ file: { name: img.revised_prompt || `Image ${idx + 1}`, type: "image/png", url: img.url },
3650
+ onClick: showImageLightbox ? () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx) : undefined
3651
+ }, `img-${idx}`)),
3652
+ message.audio?.map((audio, idx) => /* @__PURE__ */ jsxs27("div", {
3653
+ className: "flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground self-end",
2754
3654
  children: [
2755
- message.images?.map((img, idx) => /* @__PURE__ */ jsx35(FilePreviewCard, {
2756
- file: { name: img.revised_prompt || `Image ${idx + 1}`, type: "image/png", url: img.url },
2757
- onClick: showImageLightbox ? () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx) : undefined
2758
- }, `img-${idx}`)),
2759
- message.audio?.map((audio, idx) => /* @__PURE__ */ jsxs20("div", {
2760
- className: "flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground self-end",
2761
- children: [
2762
- /* @__PURE__ */ jsx35(Music, {
2763
- className: "h-3.5 w-3.5 text-muted-foreground"
2764
- }),
2765
- /* @__PURE__ */ jsx35("span", {
2766
- className: "truncate max-w-[150px]",
2767
- children: audio.id || `Audio ${idx + 1}`
2768
- })
2769
- ]
2770
- }, `audio-${idx}`)),
2771
- message.files?.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx35(FilePreviewCard, {
2772
- file: { name: file.name, type: file.type, url: file.url, size: file.size },
2773
- onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
2774
- }, `file-${idx}`) : /* @__PURE__ */ jsxs20("div", {
2775
- className: "flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground self-end",
2776
- children: [
2777
- /* @__PURE__ */ jsx35(FileIcon3, {
2778
- className: "h-3.5 w-3.5 text-muted-foreground"
2779
- }),
2780
- /* @__PURE__ */ jsx35("span", {
2781
- className: "truncate max-w-[150px]",
2782
- children: file.name
2783
- })
2784
- ]
2785
- }, `file-${idx}`))
2786
- ]
2787
- }),
2788
- message.content && /* @__PURE__ */ jsx35("div", {
2789
- className: cn("rounded-2xl rounded-br-md px-4 py-2.5", classNames?.user?.bubble ?? "bg-primary text-primary-foreground", hasError && "opacity-70"),
2790
- children: /* @__PURE__ */ jsx35("p", {
2791
- className: "text-sm whitespace-pre-wrap",
2792
- children: message.content
2793
- })
2794
- }),
2795
- (showTimestamp || actions?.user) && /* @__PURE__ */ jsxs20("div", {
2796
- className: "flex items-center justify-end gap-1.5 px-1",
2797
- children: [
2798
- actions?.user && /* @__PURE__ */ jsx35("div", {
2799
- className: "flex items-center gap-1",
2800
- children: actions.user(message)
3655
+ /* @__PURE__ */ jsx45(Music2, {
3656
+ className: "h-3.5 w-3.5 text-muted-foreground"
2801
3657
  }),
2802
- /* @__PURE__ */ jsx35(SmartTimestamp, {
2803
- date: new Date(message.created_at * 1000),
2804
- formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
2805
- className: "text-[11px] text-muted-foreground"
2806
- }),
2807
- hasError && /* @__PURE__ */ jsx35(AlertCircle, {
2808
- className: "h-3 w-3 text-destructive"
3658
+ /* @__PURE__ */ jsx45("span", {
3659
+ className: "truncate max-w-[150px]",
3660
+ children: audio.id || `Audio ${idx + 1}`
2809
3661
  })
2810
3662
  ]
2811
- })
2812
- ]
2813
- })
2814
- ]
2815
- }) : /* @__PURE__ */ jsxs20("div", {
2816
- className: "flex items-start gap-3 group/message",
2817
- children: [
2818
- avatars?.assistant,
2819
- /* @__PURE__ */ jsxs20("div", {
2820
- className: cn("flex-1 min-w-0 space-y-3", classNames?.assistant?.container),
2821
- children: [
2822
- renderContent ? renderContent(message) : /* @__PURE__ */ jsxs20(Fragment5, {
3663
+ }, `audio-${idx}`)),
3664
+ message.files?.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx45(FilePreviewCard, {
3665
+ file: { name: file.name, type: file.type, url: file.url, size: file.size },
3666
+ onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
3667
+ }, `file-${idx}`) : /* @__PURE__ */ jsxs27("div", {
3668
+ className: "flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground self-end",
2823
3669
  children: [
2824
- showReasoning && message.extra_data?.reasoning_steps && message.extra_data.reasoning_steps.length > 0 && /* @__PURE__ */ jsxs20("div", {
2825
- className: cn("space-y-2 pt-1", classNames?.assistant?.reasoning),
2826
- children: [
2827
- /* @__PURE__ */ jsxs20("div", {
2828
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2829
- children: [
2830
- /* @__PURE__ */ jsx35(Lightbulb, {
2831
- className: "h-3.5 w-3.5"
2832
- }),
2833
- "Reasoning (",
2834
- message.extra_data.reasoning_steps.length,
2835
- " steps)"
2836
- ]
2837
- }),
2838
- /* @__PURE__ */ jsx35(Accordion, {
2839
- type: "multiple",
2840
- className: "w-full",
2841
- children: message.extra_data.reasoning_steps.map((step, idx) => /* @__PURE__ */ jsxs20(AccordionItem, {
2842
- value: `reasoning-${idx}`,
2843
- className: "border-muted",
2844
- children: [
2845
- /* @__PURE__ */ jsx35(AccordionTrigger, {
2846
- className: "text-xs py-1.5 hover:no-underline",
2847
- children: step.title || `Step ${idx + 1}`
2848
- }),
2849
- /* @__PURE__ */ jsxs20(AccordionContent, {
2850
- className: "space-y-1.5 text-xs text-muted-foreground",
2851
- children: [
2852
- step.action && /* @__PURE__ */ jsxs20("div", {
2853
- children: [
2854
- /* @__PURE__ */ jsx35("span", {
2855
- className: "font-medium text-foreground",
2856
- children: "Action:"
2857
- }),
2858
- " ",
2859
- step.action
2860
- ]
2861
- }),
2862
- step.reasoning && /* @__PURE__ */ jsxs20("div", {
2863
- children: [
2864
- /* @__PURE__ */ jsx35("span", {
2865
- className: "font-medium text-foreground",
2866
- children: "Reasoning:"
2867
- }),
2868
- " ",
2869
- step.reasoning
2870
- ]
2871
- }),
2872
- step.result && /* @__PURE__ */ jsxs20("div", {
2873
- children: [
2874
- /* @__PURE__ */ jsx35("span", {
2875
- className: "font-medium text-foreground",
2876
- children: "Result:"
2877
- }),
2878
- " ",
2879
- step.result
2880
- ]
2881
- }),
2882
- step.confidence !== undefined && /* @__PURE__ */ jsxs20("div", {
2883
- children: [
2884
- /* @__PURE__ */ jsx35("span", {
2885
- className: "font-medium text-foreground",
2886
- children: "Confidence:"
2887
- }),
2888
- " ",
2889
- (step.confidence * 100).toFixed(1),
2890
- "%"
2891
- ]
2892
- })
2893
- ]
2894
- })
2895
- ]
2896
- }, idx))
2897
- })
2898
- ]
2899
- }),
2900
- message.content && /* @__PURE__ */ jsx35("div", {
2901
- className: "prose prose-sm dark:prose-invert max-w-none prose-p:leading-relaxed prose-pre:bg-muted prose-pre:border prose-pre:border-border",
2902
- children: /* @__PURE__ */ jsx35(Response, {
2903
- children: message.content
2904
- })
2905
- }),
2906
- showGenerativeUI && toolsWithUI.length > 0 && /* @__PURE__ */ jsx35("div", {
2907
- className: "space-y-3",
2908
- children: toolsWithUI.map((tool) => {
2909
- const uiComponent = tool.ui_component;
2910
- return /* @__PURE__ */ jsx35("div", {
2911
- children: uiComponent.layout === "artifact" ? /* @__PURE__ */ jsx35(Artifact, {
2912
- children: /* @__PURE__ */ jsx35(GenerativeUIRenderer, {
2913
- spec: uiComponent,
2914
- className: "w-full p-2"
2915
- })
2916
- }) : /* @__PURE__ */ jsx35(GenerativeUIRenderer, {
2917
- spec: uiComponent,
2918
- className: "w-full"
2919
- })
2920
- }, tool.tool_call_id);
2921
- })
2922
- }),
2923
- toolResultRenderers && message.tool_calls?.map((tool) => {
2924
- const renderer = toolResultRenderers[tool.tool_name];
2925
- const content = tool.result ?? tool.content;
2926
- if (!renderer || !content)
2927
- return null;
2928
- return /* @__PURE__ */ jsx35("div", {
2929
- children: renderer(tool.tool_args, content)
2930
- }, `result-${tool.tool_call_id}`);
3670
+ /* @__PURE__ */ jsx45(FileIcon4, {
3671
+ className: "h-3.5 w-3.5 text-muted-foreground"
2931
3672
  }),
2932
- renderMedia ? renderMedia(message) : (() => {
2933
- const mediaClassName = classNames?.assistant?.media;
2934
- return /* @__PURE__ */ jsxs20(Fragment5, {
2935
- children: [
2936
- message.images && message.images.length > 0 && /* @__PURE__ */ jsxs20("div", {
2937
- className: cn("space-y-2 pt-1", mediaClassName),
2938
- children: [
2939
- /* @__PURE__ */ jsxs20("div", {
2940
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2941
- children: [
2942
- /* @__PURE__ */ jsx35(ImageIcon2, {
2943
- className: "h-3.5 w-3.5"
2944
- }),
2945
- "Images (",
2946
- message.images.length,
2947
- ")"
2948
- ]
2949
- }),
2950
- /* @__PURE__ */ jsx35("div", {
2951
- className: "grid grid-cols-2 gap-2",
2952
- children: message.images.map((img, idx) => /* @__PURE__ */ jsxs20("div", {
2953
- className: "space-y-1",
2954
- children: [
2955
- showImageLightbox ? /* @__PURE__ */ jsx35("button", {
2956
- type: "button",
2957
- onClick: () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx),
2958
- className: "group relative w-full overflow-hidden rounded-lg border border-border cursor-pointer hover:border-primary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring transition-colors",
2959
- children: /* @__PURE__ */ jsx35("img", {
2960
- src: img.url,
2961
- alt: img.revised_prompt || "Generated image",
2962
- className: "w-full rounded-lg"
2963
- })
2964
- }) : /* @__PURE__ */ jsx35("img", {
2965
- src: img.url,
2966
- alt: img.revised_prompt || "Generated image",
2967
- className: "w-full rounded-lg border border-border"
2968
- }),
2969
- img.revised_prompt && /* @__PURE__ */ jsx35("p", {
2970
- className: "text-[11px] text-muted-foreground italic px-0.5",
2971
- children: img.revised_prompt
2972
- })
2973
- ]
2974
- }, idx))
2975
- })
2976
- ]
2977
- }),
2978
- message.videos && message.videos.length > 0 && /* @__PURE__ */ jsxs20("div", {
2979
- className: cn("space-y-2 pt-1", mediaClassName),
2980
- children: [
2981
- /* @__PURE__ */ jsxs20("div", {
2982
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2983
- children: [
2984
- /* @__PURE__ */ jsx35(Video, {
2985
- className: "h-3.5 w-3.5"
2986
- }),
2987
- "Videos (",
2988
- message.videos.length,
2989
- ")"
2990
- ]
2991
- }),
2992
- /* @__PURE__ */ jsx35("div", {
2993
- className: "space-y-2",
2994
- children: message.videos.map((video, idx) => /* @__PURE__ */ jsx35("div", {
2995
- children: video.url ? /* @__PURE__ */ jsx35("video", {
2996
- src: video.url,
2997
- controls: true,
2998
- className: "w-full rounded-lg border border-border"
2999
- }) : /* @__PURE__ */ jsxs20("div", {
3000
- className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3001
- children: [
3002
- "Video ID: ",
3003
- video.id,
3004
- " (ETA: ",
3005
- video.eta,
3006
- "s)"
3007
- ]
3008
- })
3009
- }, idx))
3010
- })
3011
- ]
3012
- }),
3013
- message.audio && message.audio.length > 0 && /* @__PURE__ */ jsxs20("div", {
3014
- className: cn("space-y-2 pt-1", mediaClassName),
3015
- children: [
3016
- /* @__PURE__ */ jsxs20("div", {
3017
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3018
- children: [
3019
- /* @__PURE__ */ jsx35(Music, {
3020
- className: "h-3.5 w-3.5"
3021
- }),
3022
- "Audio (",
3023
- message.audio.length,
3024
- ")"
3025
- ]
3026
- }),
3027
- /* @__PURE__ */ jsx35("div", {
3028
- className: "space-y-2",
3029
- children: message.audio.map((audio, idx) => /* @__PURE__ */ jsx35("div", {
3030
- children: audio.url ? /* @__PURE__ */ jsx35("audio", {
3031
- src: audio.url,
3032
- controls: true,
3033
- className: "w-full"
3034
- }) : audio.base64_audio ? /* @__PURE__ */ jsx35("audio", {
3035
- src: `data:${audio.mime_type || "audio/wav"};base64,${audio.base64_audio}`,
3036
- controls: true,
3037
- className: "w-full"
3038
- }) : /* @__PURE__ */ jsx35("div", {
3039
- className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3040
- children: "Audio data unavailable"
3041
- })
3042
- }, idx))
3043
- })
3044
- ]
3045
- }),
3046
- message.files && message.files.length > 0 && /* @__PURE__ */ jsxs20("div", {
3047
- className: cn("space-y-2 pt-1", mediaClassName),
3048
- children: [
3049
- /* @__PURE__ */ jsxs20("div", {
3050
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3051
- children: [
3052
- /* @__PURE__ */ jsx35(Paperclip, {
3053
- className: "h-3.5 w-3.5"
3054
- }),
3055
- "Files (",
3056
- message.files.length,
3057
- ")"
3058
- ]
3059
- }),
3060
- /* @__PURE__ */ jsx35("div", {
3061
- className: "flex flex-wrap gap-2",
3062
- children: message.files.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx35(FilePreviewCard, {
3063
- file: { name: file.name, type: file.type, url: file.url, size: file.size },
3064
- onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
3065
- }, idx) : /* @__PURE__ */ jsxs20("div", {
3066
- className: "flex items-center gap-2 rounded-lg border border-border px-3 py-2 text-xs bg-muted/30 hover:bg-muted/50 transition-colors",
3067
- children: [
3068
- /* @__PURE__ */ jsx35(FileIcon3, {
3069
- className: "h-3.5 w-3.5 shrink-0 text-muted-foreground"
3070
- }),
3071
- /* @__PURE__ */ jsx35("span", {
3072
- className: "truncate max-w-[180px]",
3073
- children: file.name
3074
- }),
3075
- file.size && /* @__PURE__ */ jsxs20("span", {
3076
- className: "text-muted-foreground/70",
3077
- children: [
3078
- "(",
3079
- (file.size / 1024).toFixed(1),
3080
- "KB)"
3081
- ]
3082
- }),
3083
- file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsx35("a", {
3084
- href: file.url,
3085
- target: "_blank",
3086
- rel: "noopener noreferrer",
3087
- className: "text-primary hover:underline font-medium",
3088
- children: "View"
3089
- })
3090
- ]
3091
- }, idx))
3092
- })
3093
- ]
3094
- }),
3095
- message.response_audio && /* @__PURE__ */ jsxs20("div", {
3096
- className: cn("space-y-2 pt-1", mediaClassName),
3097
- children: [
3098
- /* @__PURE__ */ jsxs20("div", {
3099
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3100
- children: [
3101
- /* @__PURE__ */ jsx35(Music, {
3102
- className: "h-3.5 w-3.5"
3103
- }),
3104
- "Response Audio"
3105
- ]
3106
- }),
3107
- message.response_audio.transcript && /* @__PURE__ */ jsxs20("div", {
3108
- className: "text-xs italic bg-muted/50 border border-border p-2.5 rounded-lg text-muted-foreground",
3109
- children: [
3110
- '"',
3111
- message.response_audio.transcript,
3112
- '"'
3113
- ]
3114
- }),
3115
- message.response_audio.content && /* @__PURE__ */ jsx35("audio", {
3116
- src: `data:audio/wav;base64,${message.response_audio.content}`,
3117
- controls: true,
3118
- className: "w-full"
3119
- })
3120
- ]
3121
- })
3122
- ]
3123
- });
3124
- })(),
3125
- showToolCalls && message.tool_calls && message.tool_calls.length > 0 && /* @__PURE__ */ jsx35("div", {
3126
- className: cn("space-y-2 pt-1", classNames?.assistant?.toolCalls),
3127
- children: message.tool_calls.map((tool, idx) => renderToolCall ? renderToolCall(tool, idx) : /* @__PURE__ */ jsxs20(Tool, {
3128
- defaultOpen: idx === 0,
3129
- children: [
3130
- /* @__PURE__ */ jsx35(ToolHeader, {
3131
- title: tool.tool_name,
3132
- type: "tool-use",
3133
- state: getToolState(tool)
3134
- }),
3135
- /* @__PURE__ */ jsxs20(ToolContent, {
3136
- children: [
3137
- /* @__PURE__ */ jsx35(ToolInput, {
3138
- input: tool.tool_args
3139
- }),
3140
- tool.content && /* @__PURE__ */ jsx35(ToolOutput, {
3141
- output: tool.content,
3142
- errorText: tool.tool_call_error ? "Tool execution failed" : undefined
3143
- })
3144
- ]
3145
- })
3146
- ]
3147
- }, tool.tool_call_id || idx))
3148
- }),
3149
- showReferences && message.extra_data?.references && message.extra_data.references.length > 0 && /* @__PURE__ */ jsxs20("div", {
3150
- className: cn("space-y-2 pt-1", classNames?.assistant?.references),
3151
- children: [
3152
- /* @__PURE__ */ jsxs20("div", {
3153
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3154
- children: [
3155
- /* @__PURE__ */ jsx35(FileText, {
3156
- className: "h-3.5 w-3.5"
3157
- }),
3158
- "References (",
3159
- message.extra_data.references.length,
3160
- ")"
3161
- ]
3162
- }),
3163
- /* @__PURE__ */ jsx35("div", {
3164
- className: "space-y-2",
3165
- children: message.extra_data.references.map((refData, idx) => /* @__PURE__ */ jsxs20("div", {
3166
- className: "text-xs space-y-1.5",
3167
- children: [
3168
- refData.query && /* @__PURE__ */ jsxs20("div", {
3169
- className: "font-medium text-foreground",
3170
- children: [
3171
- "Query: ",
3172
- refData.query
3173
- ]
3174
- }),
3175
- refData.references.map((ref, refIdx) => /* @__PURE__ */ jsxs20("div", {
3176
- className: "bg-muted/50 border border-border p-2.5 rounded-lg",
3177
- children: [
3178
- /* @__PURE__ */ jsxs20("div", {
3179
- className: "italic text-muted-foreground mb-1",
3180
- children: [
3181
- '"',
3182
- ref.content,
3183
- '"'
3184
- ]
3185
- }),
3186
- /* @__PURE__ */ jsxs20("div", {
3187
- className: "text-muted-foreground/70",
3188
- children: [
3189
- "Source: ",
3190
- ref.name,
3191
- " (chunk ",
3192
- ref.meta_data.chunk,
3193
- "/",
3194
- ref.meta_data.chunk_size,
3195
- ")"
3196
- ]
3197
- })
3198
- ]
3199
- }, refIdx))
3200
- ]
3201
- }, idx))
3202
- })
3203
- ]
3673
+ /* @__PURE__ */ jsx45("span", {
3674
+ className: "truncate max-w-[150px]",
3675
+ children: file.name
3204
3676
  })
3205
3677
  ]
3678
+ }, `file-${idx}`))
3679
+ ]
3680
+ }),
3681
+ message.content && /* @__PURE__ */ jsx45("div", {
3682
+ className: cn("rounded-2xl rounded-br-md px-4 py-2.5", classNames?.user?.bubble ?? "bg-primary text-primary-foreground", hasError && "opacity-70"),
3683
+ children: /* @__PURE__ */ jsx45("p", {
3684
+ className: "text-sm whitespace-pre-wrap",
3685
+ children: message.content
3686
+ })
3687
+ }),
3688
+ (showTimestamp || actions?.user) && /* @__PURE__ */ jsxs27("div", {
3689
+ className: "flex items-center justify-end gap-1.5 px-1",
3690
+ children: [
3691
+ actions?.user && /* @__PURE__ */ jsx45("div", {
3692
+ className: "flex items-center gap-1",
3693
+ children: actions.user(message)
3206
3694
  }),
3207
- (actions?.assistant || showTimestamp || hasError) && /* @__PURE__ */ jsxs20("div", {
3208
- className: "flex items-center gap-2 pt-1",
3209
- children: [
3210
- actions?.assistant && (() => {
3211
- const visibility = actions.visibility ?? "visible";
3212
- if (visibility === "last-assistant" && !isLastAssistantMessage)
3213
- return null;
3214
- const useHover = visibility === "hover" || visibility === "hover-last-visible" && !isLastAssistantMessage;
3215
- return /* @__PURE__ */ jsx35("div", {
3216
- className: cn("flex items-center gap-1 transition-opacity", useHover && "opacity-0 group-hover/message:opacity-100", classNames?.assistant?.actions),
3217
- children: actions.assistant(message)
3218
- });
3219
- })(),
3220
- hasError && /* @__PURE__ */ jsxs20("span", {
3221
- className: "flex items-center gap-1 text-[11px] text-destructive",
3222
- children: [
3223
- /* @__PURE__ */ jsx35(AlertCircle, {
3224
- className: "h-3 w-3"
3225
- }),
3226
- "Error"
3227
- ]
3228
- }),
3229
- showTimestamp && /* @__PURE__ */ jsx35(SmartTimestamp, {
3230
- date: new Date(message.created_at * 1000),
3231
- formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
3232
- className: "text-[11px] text-muted-foreground"
3233
- })
3234
- ]
3695
+ /* @__PURE__ */ jsx45(SmartTimestamp, {
3696
+ date: new Date(message.created_at * 1000),
3697
+ formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
3698
+ className: "text-[11px] text-muted-foreground"
3699
+ }),
3700
+ hasError && /* @__PURE__ */ jsx45(AlertCircle2, {
3701
+ className: "h-3 w-3 text-destructive"
3235
3702
  })
3236
3703
  ]
3237
3704
  })
3238
3705
  ]
3239
- }),
3240
- preview?.type === "image" && /* @__PURE__ */ jsx35(ImageLightbox, {
3241
- open: true,
3242
- onOpenChange: (open) => {
3243
- if (!open)
3244
- closePreview();
3245
- },
3246
- images: preview.images,
3247
- initialIndex: preview.initialIndex
3248
- }),
3249
- preview?.type === "file" && /* @__PURE__ */ jsx35(FilePreviewModal, {
3250
- open: true,
3251
- onOpenChange: (open) => {
3252
- if (!open)
3253
- closePreview();
3254
- },
3255
- file: preview.file
3706
+ })
3707
+ ]
3708
+ });
3709
+ }
3710
+
3711
+ // src/ui/composed/AgnoMessageItem.tsx
3712
+ import { jsx as jsx46, jsxs as jsxs28 } from "react/jsx-runtime";
3713
+ function AgnoMessageItem({
3714
+ message,
3715
+ className,
3716
+ classNames,
3717
+ avatars,
3718
+ actions,
3719
+ isLastAssistantMessage = false,
3720
+ showReasoning = true,
3721
+ showReferences = true,
3722
+ showTimestamp = true,
3723
+ showFilePreview = true,
3724
+ showImageLightbox = true,
3725
+ formatTimestamp,
3726
+ renderTool
3727
+ }) {
3728
+ return /* @__PURE__ */ jsxs28(AgnoMessage, {
3729
+ message,
3730
+ className,
3731
+ classNames,
3732
+ avatars,
3733
+ actions,
3734
+ isLastAssistantMessage,
3735
+ showTimestamp,
3736
+ showFilePreview,
3737
+ showImageLightbox,
3738
+ formatTimestamp,
3739
+ renderTool,
3740
+ children: [
3741
+ showReasoning && /* @__PURE__ */ jsx46(AgnoMessage.Reasoning, {}),
3742
+ /* @__PURE__ */ jsx46(AgnoMessage.Media, {}),
3743
+ /* @__PURE__ */ jsx46(AgnoMessage.Tools, {}),
3744
+ /* @__PURE__ */ jsx46(AgnoMessage.Content, {}),
3745
+ showReferences && /* @__PURE__ */ jsx46(AgnoMessage.References, {}),
3746
+ /* @__PURE__ */ jsx46(AgnoMessage.Footer, {
3747
+ showTimestamp
3256
3748
  })
3257
3749
  ]
3258
3750
  });
3259
3751
  }
3260
3752
  // src/ui/composed/AgnoChatInput.tsx
3261
3753
  import { CircleStop } from "lucide-react";
3262
- import { jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
3754
+ import { jsx as jsx47, jsxs as jsxs29 } from "react/jsx-runtime";
3263
3755
  var DEFAULT_ACCEPTED_FILE_TYPES = "image/*,audio/*,.pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.ppt,.pptx,.md,.json,.xml";
3264
3756
  function normalizeAudio(audio) {
3265
3757
  if (audio === true)
@@ -3279,14 +3771,14 @@ function dataUrlToBlob(dataUrl) {
3279
3771
  return new Blob([buf], { type: mime });
3280
3772
  }
3281
3773
  function CancelButton({ onCancel }) {
3282
- return /* @__PURE__ */ jsx36(Button, {
3774
+ return /* @__PURE__ */ jsx47(Button, {
3283
3775
  type: "button",
3284
3776
  variant: "destructive",
3285
3777
  size: "icon",
3286
3778
  className: "h-8 w-8 rounded-lg",
3287
3779
  onClick: onCancel,
3288
3780
  "aria-label": "Stop",
3289
- children: /* @__PURE__ */ jsx36(CircleStop, {
3781
+ children: /* @__PURE__ */ jsx47(CircleStop, {
3290
3782
  className: "size-4"
3291
3783
  })
3292
3784
  });
@@ -3294,7 +3786,7 @@ function CancelButton({ onCancel }) {
3294
3786
  function SubmitButton({ disabled, status }) {
3295
3787
  const { textInput } = usePromptInputController();
3296
3788
  const hasText = textInput.value.trim().length > 0;
3297
- return /* @__PURE__ */ jsx36(PromptInputSubmit, {
3789
+ return /* @__PURE__ */ jsx47(PromptInputSubmit, {
3298
3790
  disabled: disabled || !hasText,
3299
3791
  status
3300
3792
  });
@@ -3303,9 +3795,9 @@ function AttachmentHeader() {
3303
3795
  const { files } = usePromptInputAttachments();
3304
3796
  if (files.length === 0)
3305
3797
  return null;
3306
- return /* @__PURE__ */ jsx36(PromptInputHeader, {
3307
- children: /* @__PURE__ */ jsx36(PromptInputAttachments, {
3308
- children: (attachment) => /* @__PURE__ */ jsx36(PromptInputAttachment, {
3798
+ return /* @__PURE__ */ jsx47(PromptInputHeader, {
3799
+ children: /* @__PURE__ */ jsx47(PromptInputAttachments, {
3800
+ children: (attachment) => /* @__PURE__ */ jsx47(PromptInputAttachment, {
3309
3801
  data: attachment
3310
3802
  })
3311
3803
  })
@@ -3320,7 +3812,7 @@ function TranscribeAudioRecorder({
3320
3812
  labels
3321
3813
  }) {
3322
3814
  const { textInput } = usePromptInputController();
3323
- return /* @__PURE__ */ jsx36(AudioRecorder, {
3815
+ return /* @__PURE__ */ jsx47(AudioRecorder, {
3324
3816
  mode: "transcribe",
3325
3817
  transcriptionEndpoint: endpoint,
3326
3818
  transcriptionHeaders: headers,
@@ -3384,8 +3876,8 @@ function AgnoChatInput({
3384
3876
  };
3385
3877
  const computedStatus = status ?? (disabled ? "submitted" : undefined);
3386
3878
  const showCancelButton = allowCancelRun && isStreaming && onCancel;
3387
- return /* @__PURE__ */ jsx36(PromptInputProvider, {
3388
- children: /* @__PURE__ */ jsxs21(PromptInput, {
3879
+ return /* @__PURE__ */ jsx47(PromptInputProvider, {
3880
+ children: /* @__PURE__ */ jsxs29(PromptInput, {
3389
3881
  onSubmit: handleSubmit,
3390
3882
  accept: fileUpload?.accept ?? DEFAULT_ACCEPTED_FILE_TYPES,
3391
3883
  multiple: fileUpload?.multiple ?? true,
@@ -3395,35 +3887,35 @@ function AgnoChatInput({
3395
3887
  dragListenerTarget: dropZoneContainerRef,
3396
3888
  className: cn("w-full", className),
3397
3889
  children: [
3398
- /* @__PURE__ */ jsx36(AttachmentHeader, {}),
3399
- /* @__PURE__ */ jsx36(PromptInputBody, {
3400
- children: /* @__PURE__ */ jsx36(PromptInputTextarea, {
3890
+ /* @__PURE__ */ jsx47(AttachmentHeader, {}),
3891
+ /* @__PURE__ */ jsx47(PromptInputBody, {
3892
+ children: /* @__PURE__ */ jsx47(PromptInputTextarea, {
3401
3893
  placeholder: placeholder || "Type your message... (Enter to send, Shift+Enter for new line)",
3402
3894
  disabled
3403
3895
  })
3404
3896
  }),
3405
- /* @__PURE__ */ jsxs21(PromptInputFooter, {
3897
+ /* @__PURE__ */ jsxs29(PromptInputFooter, {
3406
3898
  children: [
3407
- /* @__PURE__ */ jsxs21(PromptInputTools, {
3899
+ /* @__PURE__ */ jsxs29(PromptInputTools, {
3408
3900
  children: [
3409
- showAttachments && /* @__PURE__ */ jsxs21(PromptInputActionMenu, {
3901
+ showAttachments && /* @__PURE__ */ jsxs29(PromptInputActionMenu, {
3410
3902
  children: [
3411
- /* @__PURE__ */ jsx36(PromptInputActionMenuTrigger, {}),
3412
- /* @__PURE__ */ jsx36(PromptInputActionMenuContent, {
3413
- children: /* @__PURE__ */ jsx36(PromptInputActionAddAttachments, {
3903
+ /* @__PURE__ */ jsx47(PromptInputActionMenuTrigger, {}),
3904
+ /* @__PURE__ */ jsx47(PromptInputActionMenuContent, {
3905
+ children: /* @__PURE__ */ jsx47(PromptInputActionAddAttachments, {
3414
3906
  label: "Add files"
3415
3907
  })
3416
3908
  })
3417
3909
  ]
3418
3910
  }),
3419
- audioEnabled && (audioMode === "transcribe" && resolvedAudio?.endpoint ? /* @__PURE__ */ jsx36(TranscribeAudioRecorder, {
3911
+ audioEnabled && (audioMode === "transcribe" && resolvedAudio?.endpoint ? /* @__PURE__ */ jsx47(TranscribeAudioRecorder, {
3420
3912
  endpoint: resolvedAudio.endpoint,
3421
3913
  headers: resolvedAudio.headers,
3422
3914
  disabled,
3423
3915
  parseResponse: resolvedAudio.parseResponse,
3424
3916
  onRequestPermission: resolvedAudio.requestPermission,
3425
3917
  labels: resolvedAudio.labels
3426
- }) : /* @__PURE__ */ jsx36(AudioRecorder, {
3918
+ }) : /* @__PURE__ */ jsx47(AudioRecorder, {
3427
3919
  onRecordingComplete: handleAudioRecording,
3428
3920
  disabled,
3429
3921
  onRequestPermission: resolvedAudio?.requestPermission,
@@ -3432,15 +3924,15 @@ function AgnoChatInput({
3432
3924
  extraTools
3433
3925
  ]
3434
3926
  }),
3435
- showCancelButton ? /* @__PURE__ */ jsx36(CancelButton, {
3927
+ showCancelButton ? /* @__PURE__ */ jsx47(CancelButton, {
3436
3928
  onCancel
3437
- }) : /* @__PURE__ */ jsx36(SubmitButton, {
3929
+ }) : /* @__PURE__ */ jsx47(SubmitButton, {
3438
3930
  disabled,
3439
3931
  status: computedStatus
3440
3932
  })
3441
3933
  ]
3442
3934
  }),
3443
- showAttachments && /* @__PURE__ */ jsx36(PromptInputDropZone, {
3935
+ showAttachments && /* @__PURE__ */ jsx47(PromptInputDropZone, {
3444
3936
  ...dropZoneProps,
3445
3937
  container: dropZoneContainerRef
3446
3938
  })
@@ -3448,39 +3940,46 @@ function AgnoChatInput({
3448
3940
  })
3449
3941
  });
3450
3942
  }
3943
+ // src/ui/composed/agno-chat/render-tool.ts
3944
+ function byToolName(map, fallback) {
3945
+ return (tool, args) => {
3946
+ if (!Object.prototype.hasOwnProperty.call(map, tool.tool_name)) {
3947
+ return fallback ? fallback(tool, args) : args.defaultRender();
3948
+ }
3949
+ const entry = map[tool.tool_name];
3950
+ if (entry === false)
3951
+ return null;
3952
+ return entry(tool, args);
3953
+ };
3954
+ }
3451
3955
  // src/ui/composed/agno-chat/agno-chat.tsx
3452
- import { useCallback as useCallback7, useMemo as useMemo3, useRef as useRef6 } from "react";
3956
+ import { useCallback as useCallback9, useMemo as useMemo6, useRef as useRef6 } from "react";
3453
3957
  import { useAgnoChat, useAgnoToolExecution } from "@rodrigocoliveira/agno-react";
3454
-
3455
- // src/ui/composed/agno-chat/context.ts
3456
- import { createContext as createContext3, useContext as useContext3 } from "react";
3457
- var AgnoChatContext = createContext3(null);
3458
- function useAgnoChatContext() {
3459
- const ctx = useContext3(AgnoChatContext);
3460
- if (!ctx) {
3461
- throw new Error("useAgnoChatContext must be used within an <AgnoChat> provider. " + "Wrap your component tree with <AgnoChat>.");
3462
- }
3463
- return ctx;
3958
+ import { jsx as jsx48 } from "react/jsx-runtime";
3959
+ function resolveDebug(debug) {
3960
+ if (typeof debug === "boolean")
3961
+ return debug;
3962
+ return typeof process !== "undefined" && process.env?.NODE_ENV === "development";
3464
3963
  }
3465
-
3466
- // src/ui/composed/agno-chat/agno-chat.tsx
3467
- import { jsx as jsx37 } from "react/jsx-runtime";
3468
3964
  function AgnoChatRoot({
3469
3965
  children,
3470
3966
  toolHandlers = {},
3471
3967
  autoExecuteTools = true,
3472
- toolResultRenderers,
3968
+ renderTool,
3969
+ debug,
3970
+ skipHydration,
3473
3971
  className,
3474
3972
  ...divProps
3475
3973
  }) {
3476
3974
  const chat = useAgnoChat();
3477
3975
  const toolExec = useAgnoToolExecution(toolHandlers, autoExecuteTools, {
3478
- skipHydration: toolResultRenderers ? Object.keys(toolResultRenderers) : undefined
3976
+ skipHydration
3479
3977
  });
3480
3978
  const containerRef = useRef6(null);
3979
+ const isDebug = resolveDebug(debug);
3481
3980
  const sendRef = useRef6(chat.sendMessage);
3482
3981
  sendRef.current = chat.sendMessage;
3483
- const handleSend = useCallback7(async (message) => {
3982
+ const handleSend = useCallback9(async (message) => {
3484
3983
  try {
3485
3984
  await sendRef.current(message);
3486
3985
  } catch {}
@@ -3506,7 +4005,7 @@ function AgnoChatRoot({
3506
4005
  continueWithResults,
3507
4006
  executionError
3508
4007
  } = toolExec;
3509
- const contextValue = useMemo3(() => ({
4008
+ const contextValue = useMemo6(() => ({
3510
4009
  messages,
3511
4010
  sendMessage,
3512
4011
  clearMessages,
@@ -3527,7 +4026,8 @@ function AgnoChatRoot({
3527
4026
  handleSend,
3528
4027
  inputDisabled: isStreaming || isPaused,
3529
4028
  dropZoneContainerRef: containerRef,
3530
- toolResultRenderers
4029
+ renderTool,
4030
+ isDebug
3531
4031
  }), [
3532
4032
  messages,
3533
4033
  sendMessage,
@@ -3547,11 +4047,12 @@ function AgnoChatRoot({
3547
4047
  continueWithResults,
3548
4048
  executionError,
3549
4049
  handleSend,
3550
- toolResultRenderers
4050
+ renderTool,
4051
+ isDebug
3551
4052
  ]);
3552
- return /* @__PURE__ */ jsx37(AgnoChatContext.Provider, {
4053
+ return /* @__PURE__ */ jsx48(AgnoChatContext.Provider, {
3553
4054
  value: contextValue,
3554
- children: /* @__PURE__ */ jsx37("div", {
4055
+ children: /* @__PURE__ */ jsx48("div", {
3555
4056
  ref: containerRef,
3556
4057
  className: cn("relative h-full flex flex-col", className),
3557
4058
  ...divProps,
@@ -3561,25 +4062,25 @@ function AgnoChatRoot({
3561
4062
  }
3562
4063
 
3563
4064
  // src/ui/composed/agno-chat/messages.tsx
3564
- import { useEffect as useEffect6, useRef as useRef7 } from "react";
4065
+ import { isValidElement as isValidElement2, useEffect as useEffect8, useRef as useRef7 } from "react";
3565
4066
 
3566
4067
  // src/ui/composed/agno-chat/suggested-prompts.tsx
3567
- import { jsx as jsx38, jsxs as jsxs22 } from "react/jsx-runtime";
4068
+ import { jsx as jsx49, jsxs as jsxs30 } from "react/jsx-runtime";
3568
4069
  function AgnoChatSuggestedPrompts({ className, prompts }) {
3569
4070
  const { handleSend } = useAgnoChatContext();
3570
4071
  if (prompts.length === 0)
3571
4072
  return null;
3572
- return /* @__PURE__ */ jsx38("div", {
4073
+ return /* @__PURE__ */ jsx49("div", {
3573
4074
  className: cn("grid grid-cols-2 gap-2 w-full max-w-md", className),
3574
- children: prompts.map((prompt, idx) => /* @__PURE__ */ jsxs22("button", {
4075
+ children: prompts.map((prompt, idx) => /* @__PURE__ */ jsxs30("button", {
3575
4076
  onClick: () => handleSend(prompt.text),
3576
4077
  className: "flex items-center gap-2 px-3 py-2.5 rounded-xl border border-border bg-card hover:bg-accent/50 hover:border-primary/20 transition-all duration-200 text-left text-sm group",
3577
4078
  children: [
3578
- prompt.icon && /* @__PURE__ */ jsx38("span", {
4079
+ prompt.icon && /* @__PURE__ */ jsx49("span", {
3579
4080
  className: "text-muted-foreground group-hover:text-primary transition-colors",
3580
4081
  children: prompt.icon
3581
4082
  }),
3582
- /* @__PURE__ */ jsx38("span", {
4083
+ /* @__PURE__ */ jsx49("span", {
3583
4084
  className: "text-muted-foreground group-hover:text-foreground transition-colors text-xs leading-snug",
3584
4085
  children: prompt.text
3585
4086
  })
@@ -3590,11 +4091,11 @@ function AgnoChatSuggestedPrompts({ className, prompts }) {
3590
4091
 
3591
4092
  // src/ui/composed/agno-chat/messages.tsx
3592
4093
  import { Bot as Bot2 } from "lucide-react";
3593
- import { jsx as jsx39, jsxs as jsxs23 } from "react/jsx-runtime";
4094
+ import { jsx as jsx50, jsxs as jsxs31 } from "react/jsx-runtime";
3594
4095
  function ScrollOnNewUserMessage({ messageCount }) {
3595
4096
  const { scrollToBottom } = useStickToBottomContext2();
3596
4097
  const prevCount = useRef7(messageCount);
3597
- useEffect6(() => {
4098
+ useEffect8(() => {
3598
4099
  if (messageCount > prevCount.current) {
3599
4100
  scrollToBottom("smooth");
3600
4101
  }
@@ -3614,13 +4115,8 @@ function AgnoChatMessages({
3614
4115
  showReasoning,
3615
4116
  showReferences,
3616
4117
  showTimestamp,
3617
- showGenerativeUI,
3618
- showToolCalls,
3619
4118
  showFilePreview,
3620
4119
  showImageLightbox,
3621
- renderToolCall,
3622
- renderContent,
3623
- renderMedia,
3624
4120
  formatTimestamp,
3625
4121
  messageClassNames,
3626
4122
  emptyState,
@@ -3628,12 +4124,28 @@ function AgnoChatMessages({
3628
4124
  children,
3629
4125
  showThinkingIndicator = true,
3630
4126
  renderThinkingIndicator,
3631
- toolResultRenderers: propToolResultRenderers
4127
+ renderTool: propRenderTool,
4128
+ scrollBehavior,
4129
+ scrollToBottomButton
3632
4130
  }) {
3633
- const { messages, isStreaming, toolResultRenderers: contextToolResultRenderers } = useAgnoChatContext();
3634
- const toolResultRenderers = propToolResultRenderers ?? contextToolResultRenderers;
4131
+ const { messages, isStreaming } = useAgnoChatContext();
3635
4132
  const lastMessage = messages[messages.length - 1];
3636
4133
  const isThinking = showThinkingIndicator && isStreaming && (!lastMessage || lastMessage.role !== "user") && !lastMessage?.content;
4134
+ const resolvedScrollButton = (() => {
4135
+ if (scrollToBottomButton === false)
4136
+ return null;
4137
+ if (scrollToBottomButton === undefined || scrollToBottomButton === true) {
4138
+ return /* @__PURE__ */ jsx50(ConversationScrollButton, {});
4139
+ }
4140
+ if (isValidElement2(scrollToBottomButton))
4141
+ return scrollToBottomButton;
4142
+ if (typeof scrollToBottomButton === "object" && scrollToBottomButton !== null && "className" in scrollToBottomButton) {
4143
+ return /* @__PURE__ */ jsx50(ConversationScrollButton, {
4144
+ className: scrollToBottomButton.className
4145
+ });
4146
+ }
4147
+ return scrollToBottomButton;
4148
+ })();
3637
4149
  let lastAssistantIndex = -1;
3638
4150
  for (let i = messages.length - 1;i >= 0; i--) {
3639
4151
  if (messages[i].role !== "user") {
@@ -3645,70 +4157,66 @@ function AgnoChatMessages({
3645
4157
  ...showReasoning !== undefined && { showReasoning },
3646
4158
  ...showReferences !== undefined && { showReferences },
3647
4159
  ...showTimestamp !== undefined && { showTimestamp },
3648
- ...showGenerativeUI !== undefined && { showGenerativeUI },
3649
- ...showToolCalls !== undefined && { showToolCalls },
3650
4160
  ...showFilePreview !== undefined && { showFilePreview },
3651
4161
  ...showImageLightbox !== undefined && { showImageLightbox },
3652
- ...renderToolCall !== undefined && { renderToolCall },
3653
- ...renderContent !== undefined && { renderContent },
3654
- ...renderMedia !== undefined && { renderMedia },
3655
4162
  ...formatTimestamp !== undefined && { formatTimestamp },
3656
4163
  ...messageClassNames !== undefined && { classNames: messageClassNames },
3657
- ...toolResultRenderers !== undefined && { toolResultRenderers }
4164
+ ...propRenderTool !== undefined && { renderTool: propRenderTool }
3658
4165
  };
3659
- const resolvedEmptyState = children ?? emptyState ?? /* @__PURE__ */ jsxs23("div", {
4166
+ const resolvedEmptyState = children ?? emptyState ?? /* @__PURE__ */ jsxs31("div", {
3660
4167
  className: "flex flex-col items-center gap-6",
3661
4168
  children: [
3662
- /* @__PURE__ */ jsxs23("div", {
4169
+ /* @__PURE__ */ jsxs31("div", {
3663
4170
  className: "relative",
3664
4171
  children: [
3665
- /* @__PURE__ */ jsx39("div", {
4172
+ /* @__PURE__ */ jsx50("div", {
3666
4173
  className: "h-16 w-16 rounded-2xl bg-primary/10 flex items-center justify-center",
3667
- children: /* @__PURE__ */ jsx39(Bot2, {
4174
+ children: /* @__PURE__ */ jsx50(Bot2, {
3668
4175
  className: "h-8 w-8 text-primary"
3669
4176
  })
3670
4177
  }),
3671
- /* @__PURE__ */ jsx39("div", {
4178
+ /* @__PURE__ */ jsx50("div", {
3672
4179
  className: "absolute -bottom-1 -right-1 h-5 w-5 rounded-full bg-green-500 border-2 border-background flex items-center justify-center",
3673
- children: /* @__PURE__ */ jsx39("span", {
4180
+ children: /* @__PURE__ */ jsx50("span", {
3674
4181
  className: "h-2 w-2 rounded-full bg-white animate-pulse"
3675
4182
  })
3676
4183
  })
3677
4184
  ]
3678
4185
  }),
3679
- /* @__PURE__ */ jsxs23("div", {
4186
+ /* @__PURE__ */ jsxs31("div", {
3680
4187
  className: "space-y-2 text-center",
3681
4188
  children: [
3682
- /* @__PURE__ */ jsx39("h3", {
4189
+ /* @__PURE__ */ jsx50("h3", {
3683
4190
  className: "text-xl font-semibold tracking-tight",
3684
4191
  children: "Welcome to Agno Chat"
3685
4192
  }),
3686
- /* @__PURE__ */ jsx39("p", {
4193
+ /* @__PURE__ */ jsx50("p", {
3687
4194
  className: "text-muted-foreground text-sm max-w-sm",
3688
4195
  children: "Start a conversation with your AI agent. Ask questions, explore ideas, or run tools."
3689
4196
  })
3690
4197
  ]
3691
4198
  }),
3692
- suggestedPrompts.length > 0 && /* @__PURE__ */ jsx39(AgnoChatSuggestedPrompts, {
4199
+ suggestedPrompts.length > 0 && /* @__PURE__ */ jsx50(AgnoChatSuggestedPrompts, {
3693
4200
  prompts: suggestedPrompts
3694
4201
  })
3695
4202
  ]
3696
4203
  });
3697
- return /* @__PURE__ */ jsxs23(Conversation, {
4204
+ return /* @__PURE__ */ jsxs31(Conversation, {
3698
4205
  className: cn("relative flex-1 w-full", className),
4206
+ scrollBehavior,
3699
4207
  children: [
3700
- /* @__PURE__ */ jsx39(ScrollOnNewUserMessage, {
4208
+ /* @__PURE__ */ jsx50(ScrollOnNewUserMessage, {
3701
4209
  messageCount: messages.length
3702
4210
  }),
3703
- /* @__PURE__ */ jsxs23(ConversationContent, {
4211
+ /* @__PURE__ */ jsxs31(ConversationContent, {
3704
4212
  className: "max-w-3xl mx-auto",
3705
4213
  children: [
3706
- messages.length === 0 ? /* @__PURE__ */ jsx39(ConversationEmptyState, {
4214
+ messages.length === 0 ? /* @__PURE__ */ jsx50(ConversationEmptyState, {
3707
4215
  children: resolvedEmptyState
3708
4216
  }) : messages.map((message, index) => {
3709
4217
  if (isThinking && index === messages.length - 1 && message === lastMessage)
3710
4218
  return null;
3711
- return renderMessage ? renderMessage(message, index) : /* @__PURE__ */ jsx39(AgnoMessageItem, {
4219
+ return renderMessage ? renderMessage(message, index) : /* @__PURE__ */ jsx50(AgnoMessageItem, {
3712
4220
  message,
3713
4221
  avatars,
3714
4222
  actions,
@@ -3716,23 +4224,23 @@ function AgnoChatMessages({
3716
4224
  ...messageItemProps
3717
4225
  }, `msg-${index}-${message.created_at}`);
3718
4226
  }),
3719
- isThinking && /* @__PURE__ */ jsx39("div", {
4227
+ isThinking && /* @__PURE__ */ jsx50("div", {
3720
4228
  className: "py-2",
3721
- children: renderThinkingIndicator ?? /* @__PURE__ */ jsx39(StreamingIndicator, {
4229
+ children: renderThinkingIndicator ?? /* @__PURE__ */ jsx50(StreamingIndicator, {
3722
4230
  avatar: avatars?.assistant
3723
4231
  })
3724
4232
  })
3725
4233
  ]
3726
4234
  }),
3727
- /* @__PURE__ */ jsx39(ConversationScrollButton, {})
4235
+ resolvedScrollButton
3728
4236
  ]
3729
4237
  });
3730
4238
  }
3731
4239
 
3732
4240
  // src/ui/composed/agno-chat/empty-state.tsx
3733
- import { jsx as jsx40 } from "react/jsx-runtime";
4241
+ import { jsx as jsx51 } from "react/jsx-runtime";
3734
4242
  function AgnoChatEmptyState({ children, className, ...props }) {
3735
- return /* @__PURE__ */ jsx40("div", {
4243
+ return /* @__PURE__ */ jsx51("div", {
3736
4244
  className: cn("flex flex-col items-center gap-6", className),
3737
4245
  ...props,
3738
4246
  children
@@ -3740,8 +4248,8 @@ function AgnoChatEmptyState({ children, className, ...props }) {
3740
4248
  }
3741
4249
 
3742
4250
  // src/ui/composed/agno-chat/error-bar.tsx
3743
- import { useState as useState9, useEffect as useEffect7, useRef as useRef8 } from "react";
3744
- import { jsx as jsx41, jsxs as jsxs24 } from "react/jsx-runtime";
4251
+ import { useState as useState11, useEffect as useEffect9, useRef as useRef8 } from "react";
4252
+ import { jsx as jsx52, jsxs as jsxs32 } from "react/jsx-runtime";
3745
4253
  function AgnoChatErrorBar({
3746
4254
  className,
3747
4255
  text,
@@ -3751,10 +4259,10 @@ function AgnoChatErrorBar({
3751
4259
  children
3752
4260
  }) {
3753
4261
  const { error, executionError } = useAgnoChatContext();
3754
- const [hidden, setHidden] = useState9(false);
4262
+ const [hidden, setHidden] = useState11(false);
3755
4263
  const timerRef = useRef8(null);
3756
4264
  const rawMessage = error || executionError;
3757
- useEffect7(() => {
4265
+ useEffect9(() => {
3758
4266
  if (!rawMessage)
3759
4267
  return;
3760
4268
  setHidden(false);
@@ -3781,23 +4289,23 @@ function AgnoChatErrorBar({
3781
4289
  if (children) {
3782
4290
  return typeof children === "function" ? children(rawMessage) : children;
3783
4291
  }
3784
- return /* @__PURE__ */ jsxs24("div", {
4292
+ return /* @__PURE__ */ jsxs32("div", {
3785
4293
  className: "flex items-center gap-2 max-w-3xl mx-auto",
3786
4294
  children: [
3787
- icon && /* @__PURE__ */ jsx41("span", {
4295
+ icon && /* @__PURE__ */ jsx52("span", {
3788
4296
  className: "shrink-0",
3789
4297
  children: icon
3790
4298
  }),
3791
- /* @__PURE__ */ jsx41("p", {
4299
+ /* @__PURE__ */ jsx52("p", {
3792
4300
  className: "text-sm text-destructive flex-1",
3793
4301
  children: displayMessage
3794
4302
  }),
3795
- dismissible && /* @__PURE__ */ jsx41("button", {
4303
+ dismissible && /* @__PURE__ */ jsx52("button", {
3796
4304
  type: "button",
3797
4305
  onClick: () => setHidden(true),
3798
4306
  className: "shrink-0 text-destructive/60 hover:text-destructive transition-colors",
3799
4307
  "aria-label": "Dismiss error",
3800
- children: /* @__PURE__ */ jsxs24("svg", {
4308
+ children: /* @__PURE__ */ jsxs32("svg", {
3801
4309
  xmlns: "http://www.w3.org/2000/svg",
3802
4310
  width: "16",
3803
4311
  height: "16",
@@ -3808,10 +4316,10 @@ function AgnoChatErrorBar({
3808
4316
  strokeLinecap: "round",
3809
4317
  strokeLinejoin: "round",
3810
4318
  children: [
3811
- /* @__PURE__ */ jsx41("path", {
4319
+ /* @__PURE__ */ jsx52("path", {
3812
4320
  d: "M18 6 6 18"
3813
4321
  }),
3814
- /* @__PURE__ */ jsx41("path", {
4322
+ /* @__PURE__ */ jsx52("path", {
3815
4323
  d: "m6 6 12 12"
3816
4324
  })
3817
4325
  ]
@@ -3820,14 +4328,14 @@ function AgnoChatErrorBar({
3820
4328
  ]
3821
4329
  });
3822
4330
  };
3823
- return /* @__PURE__ */ jsx41("div", {
4331
+ return /* @__PURE__ */ jsx52("div", {
3824
4332
  className: cn("px-4 py-2.5 bg-destructive/5 border-t border-destructive/20", className),
3825
4333
  children: renderContent()
3826
4334
  });
3827
4335
  }
3828
4336
 
3829
4337
  // src/ui/composed/agno-chat/input.tsx
3830
- import { jsx as jsx42 } from "react/jsx-runtime";
4338
+ import { jsx as jsx53 } from "react/jsx-runtime";
3831
4339
  function AgnoChatInputArea({
3832
4340
  className,
3833
4341
  children,
@@ -3840,11 +4348,11 @@ function AgnoChatInputArea({
3840
4348
  dropZoneProps
3841
4349
  }) {
3842
4350
  const { handleSend, inputDisabled, isStreaming, isPaused, cancelRun, dropZoneContainerRef } = useAgnoChatContext();
3843
- return /* @__PURE__ */ jsx42("div", {
4351
+ return /* @__PURE__ */ jsx53("div", {
3844
4352
  className: cn("border-t border-border bg-background/80 backdrop-blur-sm", className),
3845
- children: /* @__PURE__ */ jsx42("div", {
4353
+ children: /* @__PURE__ */ jsx53("div", {
3846
4354
  className: "mx-auto px-4 py-2",
3847
- children: children ? children({ onSend: handleSend, disabled: inputDisabled, isStreaming, isPaused }) : /* @__PURE__ */ jsx42(AgnoChatInput, {
4355
+ children: children ? children({ onSend: handleSend, disabled: inputDisabled, isStreaming, isPaused }) : /* @__PURE__ */ jsx53(AgnoChatInput, {
3848
4356
  onSend: handleSend,
3849
4357
  disabled: inputDisabled,
3850
4358
  isStreaming,
@@ -3875,6 +4383,7 @@ export {
3875
4383
  usePromptInputDropZone,
3876
4384
  usePromptInputController,
3877
4385
  usePromptInputAttachments,
4386
+ useAgnoMessageContext,
3878
4387
  useAgnoChatContext,
3879
4388
  isPreviewable,
3880
4389
  getFilePreviewType,
@@ -3883,6 +4392,7 @@ export {
3883
4392
  formatFullTimestamp,
3884
4393
  formatFileSize,
3885
4394
  cn,
4395
+ byToolName,
3886
4396
  buttonVariants,
3887
4397
  badgeVariants,
3888
4398
  TooltipTrigger,
@@ -3892,6 +4402,8 @@ export {
3892
4402
  ToolOutput,
3893
4403
  ToolInput,
3894
4404
  ToolHeader,
4405
+ ToolGenerativeUI,
4406
+ ToolDebugCard,
3895
4407
  ToolContent,
3896
4408
  Tool,
3897
4409
  StreamingIndicator,
@@ -4013,7 +4525,15 @@ export {
4013
4525
  ArtifactActions,
4014
4526
  ArtifactAction,
4015
4527
  Artifact,
4528
+ AgnoMessageTools,
4529
+ AgnoMessageReferences,
4530
+ AgnoMessageReasoning,
4531
+ AgnoMessageMedia,
4016
4532
  AgnoMessageItem,
4533
+ AgnoMessageFooter,
4534
+ AgnoMessageContext,
4535
+ AgnoMessageContent,
4536
+ AgnoMessage,
4017
4537
  AgnoChatSuggestedPrompts,
4018
4538
  AgnoChatRoot,
4019
4539
  AgnoChatMessages,
@@ -4028,4 +4548,4 @@ export {
4028
4548
  Accordion
4029
4549
  };
4030
4550
 
4031
- //# debugId=B7CF327D3F6FBB7F64756E2164756E21
4551
+ //# debugId=849670CE2678388A64756E2164756E21