@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.js CHANGED
@@ -47,6 +47,7 @@ __export(exports_ui, {
47
47
  usePromptInputDropZone: () => usePromptInputDropZone,
48
48
  usePromptInputController: () => usePromptInputController,
49
49
  usePromptInputAttachments: () => usePromptInputAttachments,
50
+ useAgnoMessageContext: () => useAgnoMessageContext,
50
51
  useAgnoChatContext: () => useAgnoChatContext,
51
52
  isPreviewable: () => isPreviewable,
52
53
  getFilePreviewType: () => getFilePreviewType,
@@ -55,6 +56,7 @@ __export(exports_ui, {
55
56
  formatFullTimestamp: () => formatFullTimestamp,
56
57
  formatFileSize: () => formatFileSize,
57
58
  cn: () => cn,
59
+ byToolName: () => byToolName,
58
60
  buttonVariants: () => buttonVariants,
59
61
  badgeVariants: () => badgeVariants,
60
62
  TooltipTrigger: () => TooltipTrigger,
@@ -64,6 +66,8 @@ __export(exports_ui, {
64
66
  ToolOutput: () => ToolOutput,
65
67
  ToolInput: () => ToolInput,
66
68
  ToolHeader: () => ToolHeader,
69
+ ToolGenerativeUI: () => ToolGenerativeUI,
70
+ ToolDebugCard: () => ToolDebugCard,
67
71
  ToolContent: () => ToolContent,
68
72
  Tool: () => Tool,
69
73
  StreamingIndicator: () => StreamingIndicator,
@@ -185,7 +189,15 @@ __export(exports_ui, {
185
189
  ArtifactActions: () => ArtifactActions,
186
190
  ArtifactAction: () => ArtifactAction,
187
191
  Artifact: () => Artifact,
192
+ AgnoMessageTools: () => AgnoMessageTools,
193
+ AgnoMessageReferences: () => AgnoMessageReferences,
194
+ AgnoMessageReasoning: () => AgnoMessageReasoning,
195
+ AgnoMessageMedia: () => AgnoMessageMedia,
188
196
  AgnoMessageItem: () => AgnoMessageItem,
197
+ AgnoMessageFooter: () => AgnoMessageFooter,
198
+ AgnoMessageContext: () => AgnoMessageContext,
199
+ AgnoMessageContent: () => AgnoMessageContent,
200
+ AgnoMessage: () => AgnoMessage,
189
201
  AgnoChatSuggestedPrompts: () => AgnoChatSuggestedPrompts,
190
202
  AgnoChatRoot: () => AgnoChatRoot,
191
203
  AgnoChatMessages: () => AgnoChatMessages,
@@ -943,12 +955,20 @@ var import_react = require("react");
943
955
  var import_use_stick_to_bottom = require("use-stick-to-bottom");
944
956
  var import_use_stick_to_bottom2 = require("use-stick-to-bottom");
945
957
  var jsx_runtime13 = require("react/jsx-runtime");
946
- var Conversation = ({ className, ...props }) => /* @__PURE__ */ jsx_runtime13.jsx(import_use_stick_to_bottom.StickToBottom, {
947
- className: cn("relative flex-1 overflow-y-auto", className),
948
- initial: "smooth",
949
- role: "log",
950
- ...props
951
- });
958
+ var Conversation = ({ className, scrollBehavior, ...props }) => {
959
+ const initial = scrollBehavior?.initial ?? "smooth";
960
+ const resize = scrollBehavior?.resize ?? "instant";
961
+ return /* @__PURE__ */ jsx_runtime13.jsx(import_use_stick_to_bottom.StickToBottom, {
962
+ className: cn("relative flex-1 overflow-y-auto", className),
963
+ initial,
964
+ resize,
965
+ ...scrollBehavior?.damping !== undefined && { damping: scrollBehavior.damping },
966
+ ...scrollBehavior?.stiffness !== undefined && { stiffness: scrollBehavior.stiffness },
967
+ ...scrollBehavior?.mass !== undefined && { mass: scrollBehavior.mass },
968
+ role: "log",
969
+ ...props
970
+ });
971
+ };
952
972
  var ConversationContent = ({ className, ...props }) => /* @__PURE__ */ jsx_runtime13.jsx(import_use_stick_to_bottom.StickToBottom.Content, {
953
973
  className: cn("p-4", className),
954
974
  ...props
@@ -2865,573 +2885,1066 @@ var PromptInputCommandSeparator = ({ className, ...props }) => /* @__PURE__ */ j
2865
2885
  className: cn(className),
2866
2886
  ...props
2867
2887
  });
2868
- // src/ui/composed/AgnoMessageItem.tsx
2888
+ // src/ui/composed/agno-message/message.tsx
2889
+ var import_react20 = require("react");
2890
+ var import_lucide_react23 = require("lucide-react");
2891
+
2892
+ // src/ui/composed/agno-message/context.ts
2869
2893
  var import_react14 = require("react");
2870
- var import_agno_react = require("@rodrigocoliveira/agno-react");
2894
+ var AgnoMessageContext = import_react14.createContext(null);
2895
+ function useAgnoMessageContext() {
2896
+ const ctx = import_react14.useContext(AgnoMessageContext);
2897
+ if (!ctx) {
2898
+ throw new Error("useAgnoMessageContext must be used within an <AgnoMessage> provider. " + "Wrap your slots with <AgnoMessage message={...}>.");
2899
+ }
2900
+ return ctx;
2901
+ }
2902
+
2903
+ // src/ui/composed/agno-message/reasoning.tsx
2871
2904
  var import_lucide_react19 = require("lucide-react");
2872
2905
  var jsx_runtime35 = require("react/jsx-runtime");
2873
- var defaultFormatTimestamp = formatSmartTimestamp;
2874
- var getToolState = (tool) => {
2875
- return tool.tool_call_error ? "output-error" : "output-available";
2876
- };
2877
- function AgnoMessageItem({
2906
+ function AgnoMessageReasoning() {
2907
+ const { message, classNames } = useAgnoMessageContext();
2908
+ const steps = message.extra_data?.reasoning_steps;
2909
+ if (!steps || steps.length === 0)
2910
+ return null;
2911
+ return /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2912
+ className: cn("space-y-2 pt-1", classNames?.assistant?.reasoning),
2913
+ children: [
2914
+ /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2915
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2916
+ children: [
2917
+ /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Lightbulb, {
2918
+ className: "h-3.5 w-3.5"
2919
+ }),
2920
+ "Reasoning (",
2921
+ steps.length,
2922
+ " steps)"
2923
+ ]
2924
+ }),
2925
+ /* @__PURE__ */ jsx_runtime35.jsx(Accordion, {
2926
+ type: "multiple",
2927
+ className: "w-full",
2928
+ children: steps.map((step, idx) => /* @__PURE__ */ jsx_runtime35.jsxs(AccordionItem, {
2929
+ value: `reasoning-${idx}`,
2930
+ className: "border-muted",
2931
+ children: [
2932
+ /* @__PURE__ */ jsx_runtime35.jsx(AccordionTrigger, {
2933
+ className: "text-xs py-1.5 hover:no-underline",
2934
+ children: step.title || `Step ${idx + 1}`
2935
+ }),
2936
+ /* @__PURE__ */ jsx_runtime35.jsxs(AccordionContent, {
2937
+ className: "space-y-1.5 text-xs text-muted-foreground",
2938
+ children: [
2939
+ step.action && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2940
+ children: [
2941
+ /* @__PURE__ */ jsx_runtime35.jsx("span", {
2942
+ className: "font-medium text-foreground",
2943
+ children: "Action:"
2944
+ }),
2945
+ " ",
2946
+ step.action
2947
+ ]
2948
+ }),
2949
+ step.reasoning && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2950
+ children: [
2951
+ /* @__PURE__ */ jsx_runtime35.jsx("span", {
2952
+ className: "font-medium text-foreground",
2953
+ children: "Reasoning:"
2954
+ }),
2955
+ " ",
2956
+ step.reasoning
2957
+ ]
2958
+ }),
2959
+ step.result && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2960
+ children: [
2961
+ /* @__PURE__ */ jsx_runtime35.jsx("span", {
2962
+ className: "font-medium text-foreground",
2963
+ children: "Result:"
2964
+ }),
2965
+ " ",
2966
+ step.result
2967
+ ]
2968
+ }),
2969
+ step.confidence !== undefined && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2970
+ children: [
2971
+ /* @__PURE__ */ jsx_runtime35.jsx("span", {
2972
+ className: "font-medium text-foreground",
2973
+ children: "Confidence:"
2974
+ }),
2975
+ " ",
2976
+ (step.confidence * 100).toFixed(1),
2977
+ "%"
2978
+ ]
2979
+ })
2980
+ ]
2981
+ })
2982
+ ]
2983
+ }, idx))
2984
+ })
2985
+ ]
2986
+ });
2987
+ }
2988
+
2989
+ // src/ui/composed/agno-message/media.tsx
2990
+ var import_lucide_react20 = require("lucide-react");
2991
+ var jsx_runtime36 = require("react/jsx-runtime");
2992
+ function AgnoMessageMedia() {
2993
+ const {
2994
+ message,
2995
+ classNames,
2996
+ showImageLightbox,
2997
+ showFilePreview,
2998
+ openImageLightbox,
2999
+ openFilePreview
3000
+ } = useAgnoMessageContext();
3001
+ const mediaClassName = classNames?.assistant?.media;
3002
+ const hasImages = !!message.images && message.images.length > 0;
3003
+ const hasVideos = !!message.videos && message.videos.length > 0;
3004
+ const hasAudio = !!message.audio && message.audio.length > 0;
3005
+ const hasFiles = !!message.files && message.files.length > 0;
3006
+ const hasResponseAudio = !!message.response_audio;
3007
+ if (!hasImages && !hasVideos && !hasAudio && !hasFiles && !hasResponseAudio)
3008
+ return null;
3009
+ return /* @__PURE__ */ jsx_runtime36.jsxs(jsx_runtime36.Fragment, {
3010
+ children: [
3011
+ hasImages && /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3012
+ className: cn("space-y-2 pt-1", mediaClassName),
3013
+ children: [
3014
+ /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3015
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3016
+ children: [
3017
+ /* @__PURE__ */ jsx_runtime36.jsx(import_lucide_react20.Image, {
3018
+ className: "h-3.5 w-3.5"
3019
+ }),
3020
+ "Images (",
3021
+ message.images.length,
3022
+ ")"
3023
+ ]
3024
+ }),
3025
+ /* @__PURE__ */ jsx_runtime36.jsx("div", {
3026
+ className: "grid grid-cols-2 gap-2",
3027
+ children: message.images.map((img, idx) => /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3028
+ className: "space-y-1",
3029
+ children: [
3030
+ showImageLightbox ? /* @__PURE__ */ jsx_runtime36.jsx("button", {
3031
+ type: "button",
3032
+ onClick: () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx),
3033
+ 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",
3034
+ children: /* @__PURE__ */ jsx_runtime36.jsx("img", {
3035
+ src: img.url,
3036
+ alt: img.revised_prompt || "Generated image",
3037
+ className: "w-full rounded-lg"
3038
+ })
3039
+ }) : /* @__PURE__ */ jsx_runtime36.jsx("img", {
3040
+ src: img.url,
3041
+ alt: img.revised_prompt || "Generated image",
3042
+ className: "w-full rounded-lg border border-border"
3043
+ }),
3044
+ img.revised_prompt && /* @__PURE__ */ jsx_runtime36.jsx("p", {
3045
+ className: "text-[11px] text-muted-foreground italic px-0.5",
3046
+ children: img.revised_prompt
3047
+ })
3048
+ ]
3049
+ }, idx))
3050
+ })
3051
+ ]
3052
+ }),
3053
+ hasVideos && /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3054
+ className: cn("space-y-2 pt-1", mediaClassName),
3055
+ children: [
3056
+ /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3057
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3058
+ children: [
3059
+ /* @__PURE__ */ jsx_runtime36.jsx(import_lucide_react20.Video, {
3060
+ className: "h-3.5 w-3.5"
3061
+ }),
3062
+ "Videos (",
3063
+ message.videos.length,
3064
+ ")"
3065
+ ]
3066
+ }),
3067
+ /* @__PURE__ */ jsx_runtime36.jsx("div", {
3068
+ className: "space-y-2",
3069
+ children: message.videos.map((video, idx) => /* @__PURE__ */ jsx_runtime36.jsx("div", {
3070
+ children: video.url ? /* @__PURE__ */ jsx_runtime36.jsx("video", {
3071
+ src: video.url,
3072
+ controls: true,
3073
+ className: "w-full rounded-lg border border-border"
3074
+ }) : /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3075
+ className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3076
+ children: [
3077
+ "Video ID: ",
3078
+ video.id,
3079
+ " (ETA: ",
3080
+ video.eta,
3081
+ "s)"
3082
+ ]
3083
+ })
3084
+ }, idx))
3085
+ })
3086
+ ]
3087
+ }),
3088
+ hasAudio && /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3089
+ className: cn("space-y-2 pt-1", mediaClassName),
3090
+ children: [
3091
+ /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3092
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3093
+ children: [
3094
+ /* @__PURE__ */ jsx_runtime36.jsx(import_lucide_react20.Music, {
3095
+ className: "h-3.5 w-3.5"
3096
+ }),
3097
+ "Audio (",
3098
+ message.audio.length,
3099
+ ")"
3100
+ ]
3101
+ }),
3102
+ /* @__PURE__ */ jsx_runtime36.jsx("div", {
3103
+ className: "space-y-2",
3104
+ children: message.audio.map((audio, idx) => /* @__PURE__ */ jsx_runtime36.jsx("div", {
3105
+ children: audio.url ? /* @__PURE__ */ jsx_runtime36.jsx("audio", {
3106
+ src: audio.url,
3107
+ controls: true,
3108
+ className: "w-full"
3109
+ }) : audio.base64_audio ? /* @__PURE__ */ jsx_runtime36.jsx("audio", {
3110
+ src: `data:${audio.mime_type || "audio/wav"};base64,${audio.base64_audio}`,
3111
+ controls: true,
3112
+ className: "w-full"
3113
+ }) : /* @__PURE__ */ jsx_runtime36.jsx("div", {
3114
+ className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3115
+ children: "Audio data unavailable"
3116
+ })
3117
+ }, idx))
3118
+ })
3119
+ ]
3120
+ }),
3121
+ hasFiles && /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3122
+ className: cn("space-y-2 pt-1", mediaClassName),
3123
+ children: [
3124
+ /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3125
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3126
+ children: [
3127
+ /* @__PURE__ */ jsx_runtime36.jsx(import_lucide_react20.Paperclip, {
3128
+ className: "h-3.5 w-3.5"
3129
+ }),
3130
+ "Files (",
3131
+ message.files.length,
3132
+ ")"
3133
+ ]
3134
+ }),
3135
+ /* @__PURE__ */ jsx_runtime36.jsx("div", {
3136
+ className: "flex flex-wrap gap-2",
3137
+ children: message.files.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx_runtime36.jsx(FilePreviewCard, {
3138
+ file: { name: file.name, type: file.type, url: file.url, size: file.size },
3139
+ onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
3140
+ }, idx) : /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3141
+ 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",
3142
+ children: [
3143
+ /* @__PURE__ */ jsx_runtime36.jsx(import_lucide_react20.FileIcon, {
3144
+ className: "h-3.5 w-3.5 shrink-0 text-muted-foreground"
3145
+ }),
3146
+ /* @__PURE__ */ jsx_runtime36.jsx("span", {
3147
+ className: "truncate max-w-[180px]",
3148
+ children: file.name
3149
+ }),
3150
+ file.size && /* @__PURE__ */ jsx_runtime36.jsxs("span", {
3151
+ className: "text-muted-foreground/70",
3152
+ children: [
3153
+ "(",
3154
+ (file.size / 1024).toFixed(1),
3155
+ "KB)"
3156
+ ]
3157
+ }),
3158
+ file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsx_runtime36.jsx("a", {
3159
+ href: file.url,
3160
+ target: "_blank",
3161
+ rel: "noopener noreferrer",
3162
+ className: "text-primary hover:underline font-medium",
3163
+ children: "View"
3164
+ })
3165
+ ]
3166
+ }, idx))
3167
+ })
3168
+ ]
3169
+ }),
3170
+ hasResponseAudio && message.response_audio && /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3171
+ className: cn("space-y-2 pt-1", mediaClassName),
3172
+ children: [
3173
+ /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3174
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3175
+ children: [
3176
+ /* @__PURE__ */ jsx_runtime36.jsx(import_lucide_react20.Music, {
3177
+ className: "h-3.5 w-3.5"
3178
+ }),
3179
+ "Response Audio"
3180
+ ]
3181
+ }),
3182
+ message.response_audio.transcript && /* @__PURE__ */ jsx_runtime36.jsxs("div", {
3183
+ className: "text-xs italic bg-muted/50 border border-border p-2.5 rounded-lg text-muted-foreground",
3184
+ children: [
3185
+ '"',
3186
+ message.response_audio.transcript,
3187
+ '"'
3188
+ ]
3189
+ }),
3190
+ message.response_audio.content && /* @__PURE__ */ jsx_runtime36.jsx("audio", {
3191
+ src: `data:audio/wav;base64,${message.response_audio.content}`,
3192
+ controls: true,
3193
+ className: "w-full"
3194
+ })
3195
+ ]
3196
+ })
3197
+ ]
3198
+ });
3199
+ }
3200
+
3201
+ // src/ui/composed/agno-chat/context.ts
3202
+ var import_react15 = require("react");
3203
+ var AgnoChatContext = import_react15.createContext(null);
3204
+ function useAgnoChatContext() {
3205
+ const ctx = import_react15.useContext(AgnoChatContext);
3206
+ if (!ctx) {
3207
+ throw new Error("useAgnoChatContext must be used within an <AgnoChat> provider. " + "Wrap your component tree with <AgnoChat>.");
3208
+ }
3209
+ return ctx;
3210
+ }
3211
+
3212
+ // src/components/GenerativeUIRenderer.tsx
3213
+ var import_react19 = __toESM(require("react"));
3214
+
3215
+ // src/utils/component-registry.ts
3216
+ class ComponentRegistry {
3217
+ static instance;
3218
+ components = new Map;
3219
+ constructor() {}
3220
+ static getInstance() {
3221
+ if (!ComponentRegistry.instance) {
3222
+ ComponentRegistry.instance = new ComponentRegistry;
3223
+ }
3224
+ return ComponentRegistry.instance;
3225
+ }
3226
+ register(type, renderer) {
3227
+ this.components.set(type, renderer);
3228
+ }
3229
+ registerBatch(components) {
3230
+ Object.entries(components).forEach(([type, renderer]) => {
3231
+ this.register(type, renderer);
3232
+ });
3233
+ }
3234
+ get(type) {
3235
+ return this.components.get(type);
3236
+ }
3237
+ has(type) {
3238
+ return this.components.has(type);
3239
+ }
3240
+ unregister(type) {
3241
+ this.components.delete(type);
3242
+ }
3243
+ getRegisteredTypes() {
3244
+ return Array.from(this.components.keys());
3245
+ }
3246
+ clear() {
3247
+ this.components.clear();
3248
+ }
3249
+ }
3250
+ function getComponentRegistry() {
3251
+ return ComponentRegistry.getInstance();
3252
+ }
3253
+
3254
+ // src/hooks/useAgnoToolExecution.ts
3255
+ var import_react18 = require("react");
3256
+
3257
+ // src/context/AgnoContext.tsx
3258
+ var import_react16 = require("react");
3259
+ var import_agno_client = require("@rodrigocoliveira/agno-client");
3260
+ var jsx_runtime37 = require("react/jsx-runtime");
3261
+ var AgnoContext = import_react16.createContext(null);
3262
+
3263
+ // src/context/ToolHandlerContext.tsx
3264
+ var import_react17 = require("react");
3265
+ var jsx_runtime38 = require("react/jsx-runtime");
3266
+ var ToolHandlerContext = import_react17.createContext(null);
3267
+
3268
+ // src/hooks/useAgnoToolExecution.ts
3269
+ var customRenderRegistry = new Map;
3270
+ function getCustomRender(key) {
3271
+ return customRenderRegistry.get(key);
3272
+ }
3273
+
3274
+ // src/components/GenerativeUIRenderer.tsx
3275
+ var jsx_runtime39 = require("react/jsx-runtime");
3276
+
3277
+ class UIErrorBoundary extends import_react19.default.Component {
3278
+ constructor(props) {
3279
+ super(props);
3280
+ this.state = { hasError: false };
3281
+ }
3282
+ static getDerivedStateFromError(error) {
3283
+ return { hasError: true, error };
3284
+ }
3285
+ componentDidCatch(error, errorInfo) {
3286
+ console.error("[GenerativeUIRenderer] Error rendering component:", error, errorInfo);
3287
+ this.props.onError?.(error);
3288
+ }
3289
+ render() {
3290
+ if (this.state.hasError) {
3291
+ return this.props.fallback || /* @__PURE__ */ jsx_runtime39.jsxs("div", {
3292
+ className: "p-4 border border-red-300 rounded-md bg-red-50 text-red-800",
3293
+ children: [
3294
+ /* @__PURE__ */ jsx_runtime39.jsx("p", {
3295
+ className: "font-semibold",
3296
+ children: "Failed to render UI component"
3297
+ }),
3298
+ /* @__PURE__ */ jsx_runtime39.jsx("p", {
3299
+ className: "text-sm mt-1",
3300
+ children: this.state.error?.message || "Unknown error"
3301
+ })
3302
+ ]
3303
+ });
3304
+ }
3305
+ return this.props.children;
3306
+ }
3307
+ }
3308
+ function GenerativeUIRenderer({
3309
+ spec,
3310
+ className,
3311
+ onError
3312
+ }) {
3313
+ const registry = getComponentRegistry();
3314
+ if (spec.type === "custom") {
3315
+ const customSpec = spec;
3316
+ if (customSpec.renderKey) {
3317
+ const renderFn = getCustomRender(customSpec.renderKey);
3318
+ if (renderFn) {
3319
+ return /* @__PURE__ */ jsx_runtime39.jsx(UIErrorBoundary, {
3320
+ onError,
3321
+ children: /* @__PURE__ */ jsx_runtime39.jsx("div", {
3322
+ className,
3323
+ children: renderFn(customSpec.props || {})
3324
+ })
3325
+ });
3326
+ }
3327
+ }
3328
+ return /* @__PURE__ */ jsx_runtime39.jsxs("div", {
3329
+ className: `p-4 border border-yellow-300 rounded-md bg-yellow-50 text-yellow-800 ${className || ""}`,
3330
+ children: [
3331
+ /* @__PURE__ */ jsx_runtime39.jsx("p", {
3332
+ className: "font-semibold",
3333
+ children: "Custom component not available"
3334
+ }),
3335
+ /* @__PURE__ */ jsx_runtime39.jsx("p", {
3336
+ className: "text-sm mt-1",
3337
+ children: "The custom render function for this component is not available."
3338
+ })
3339
+ ]
3340
+ });
3341
+ }
3342
+ if (spec.type === "chart") {
3343
+ const chartSpec = spec;
3344
+ const chartType = `chart:${chartSpec.component}`;
3345
+ if (registry.has(chartType)) {
3346
+ const ChartRenderer = registry.get(chartType);
3347
+ return /* @__PURE__ */ jsx_runtime39.jsx(UIErrorBoundary, {
3348
+ onError,
3349
+ children: /* @__PURE__ */ jsx_runtime39.jsxs("div", {
3350
+ className,
3351
+ children: [
3352
+ chartSpec.title && /* @__PURE__ */ jsx_runtime39.jsx("h3", {
3353
+ className: "font-semibold mb-2",
3354
+ children: chartSpec.title
3355
+ }),
3356
+ chartSpec.description && /* @__PURE__ */ jsx_runtime39.jsx("p", {
3357
+ className: "text-sm text-gray-600 mb-4",
3358
+ children: chartSpec.description
3359
+ }),
3360
+ /* @__PURE__ */ jsx_runtime39.jsx(ChartRenderer, {
3361
+ ...chartSpec.props
3362
+ })
3363
+ ]
3364
+ })
3365
+ });
3366
+ }
3367
+ return /* @__PURE__ */ jsx_runtime39.jsxs("div", {
3368
+ className: `p-4 border border-gray-300 rounded-md ${className || ""}`,
3369
+ children: [
3370
+ /* @__PURE__ */ jsx_runtime39.jsx("p", {
3371
+ className: "font-semibold mb-2",
3372
+ children: chartSpec.title || "Chart Data"
3373
+ }),
3374
+ chartSpec.description && /* @__PURE__ */ jsx_runtime39.jsx("p", {
3375
+ className: "text-sm text-gray-600 mb-2",
3376
+ children: chartSpec.description
3377
+ }),
3378
+ /* @__PURE__ */ jsx_runtime39.jsx("pre", {
3379
+ className: "text-xs bg-gray-100 p-2 rounded overflow-auto",
3380
+ children: JSON.stringify(chartSpec.props.data, null, 2)
3381
+ })
3382
+ ]
3383
+ });
3384
+ }
3385
+ if (spec.type === "card-grid") {
3386
+ const cardGridSpec = spec;
3387
+ if (registry.has("card-grid")) {
3388
+ const CardGridRenderer = registry.get("card-grid");
3389
+ return /* @__PURE__ */ jsx_runtime39.jsx(UIErrorBoundary, {
3390
+ onError,
3391
+ children: /* @__PURE__ */ jsx_runtime39.jsxs("div", {
3392
+ className,
3393
+ children: [
3394
+ cardGridSpec.title && /* @__PURE__ */ jsx_runtime39.jsx("h3", {
3395
+ className: "font-semibold mb-2",
3396
+ children: cardGridSpec.title
3397
+ }),
3398
+ cardGridSpec.description && /* @__PURE__ */ jsx_runtime39.jsx("p", {
3399
+ className: "text-sm text-gray-600 mb-4",
3400
+ children: cardGridSpec.description
3401
+ }),
3402
+ /* @__PURE__ */ jsx_runtime39.jsx(CardGridRenderer, {
3403
+ ...cardGridSpec.props
3404
+ })
3405
+ ]
3406
+ })
3407
+ });
3408
+ }
3409
+ }
3410
+ if (spec.type === "table") {
3411
+ const tableSpec = spec;
3412
+ if (registry.has("table")) {
3413
+ const TableRenderer = registry.get("table");
3414
+ return /* @__PURE__ */ jsx_runtime39.jsx(UIErrorBoundary, {
3415
+ onError,
3416
+ children: /* @__PURE__ */ jsx_runtime39.jsxs("div", {
3417
+ className,
3418
+ children: [
3419
+ tableSpec.title && /* @__PURE__ */ jsx_runtime39.jsx("h3", {
3420
+ className: "font-semibold mb-2",
3421
+ children: tableSpec.title
3422
+ }),
3423
+ tableSpec.description && /* @__PURE__ */ jsx_runtime39.jsx("p", {
3424
+ className: "text-sm text-gray-600 mb-4",
3425
+ children: tableSpec.description
3426
+ }),
3427
+ /* @__PURE__ */ jsx_runtime39.jsx(TableRenderer, {
3428
+ ...tableSpec.props
3429
+ })
3430
+ ]
3431
+ })
3432
+ });
3433
+ }
3434
+ }
3435
+ if (spec.type === "markdown") {
3436
+ const markdownSpec = spec;
3437
+ if (registry.has("markdown")) {
3438
+ const MarkdownRenderer = registry.get("markdown");
3439
+ return /* @__PURE__ */ jsx_runtime39.jsx(UIErrorBoundary, {
3440
+ onError,
3441
+ children: /* @__PURE__ */ jsx_runtime39.jsx("div", {
3442
+ className,
3443
+ children: /* @__PURE__ */ jsx_runtime39.jsx(MarkdownRenderer, {
3444
+ ...markdownSpec.props
3445
+ })
3446
+ })
3447
+ });
3448
+ }
3449
+ return /* @__PURE__ */ jsx_runtime39.jsx("div", {
3450
+ className,
3451
+ children: markdownSpec.props.content
3452
+ });
3453
+ }
3454
+ if (spec.type === "artifact") {
3455
+ const artifactSpec = spec;
3456
+ return /* @__PURE__ */ jsx_runtime39.jsx(UIErrorBoundary, {
3457
+ onError,
3458
+ children: /* @__PURE__ */ jsx_runtime39.jsxs("div", {
3459
+ className: `p-4 border rounded-md ${className || ""}`,
3460
+ children: [
3461
+ artifactSpec.title && /* @__PURE__ */ jsx_runtime39.jsx("h3", {
3462
+ className: "font-semibold mb-4",
3463
+ children: artifactSpec.title
3464
+ }),
3465
+ artifactSpec.description && /* @__PURE__ */ jsx_runtime39.jsx("p", {
3466
+ className: "text-sm text-gray-600 mb-4",
3467
+ children: artifactSpec.description
3468
+ }),
3469
+ /* @__PURE__ */ jsx_runtime39.jsx("div", {
3470
+ className: "space-y-4",
3471
+ children: artifactSpec.props.content?.map((childSpec, index) => /* @__PURE__ */ jsx_runtime39.jsx(GenerativeUIRenderer, {
3472
+ spec: childSpec,
3473
+ onError
3474
+ }, index))
3475
+ })
3476
+ ]
3477
+ })
3478
+ });
3479
+ }
3480
+ return /* @__PURE__ */ jsx_runtime39.jsxs("div", {
3481
+ className: `p-4 border border-gray-300 rounded-md ${className || ""}`,
3482
+ children: [
3483
+ /* @__PURE__ */ jsx_runtime39.jsx("p", {
3484
+ className: "font-semibold",
3485
+ children: "Unsupported UI component"
3486
+ }),
3487
+ /* @__PURE__ */ jsx_runtime39.jsxs("p", {
3488
+ className: "text-sm text-gray-600 mt-1",
3489
+ children: [
3490
+ "Component type: ",
3491
+ spec.type
3492
+ ]
3493
+ })
3494
+ ]
3495
+ });
3496
+ }
3497
+
3498
+ // src/ui/composed/agno-chat/tool-building-blocks.tsx
3499
+ var jsx_runtime40 = require("react/jsx-runtime");
3500
+ var getToolState = (tool) => tool.tool_call_error ? "output-error" : "output-available";
3501
+ function ToolDebugCard({ tool, defaultOpen }) {
3502
+ const output = tool.result ?? tool.content;
3503
+ return /* @__PURE__ */ jsx_runtime40.jsxs(Tool, {
3504
+ defaultOpen,
3505
+ children: [
3506
+ /* @__PURE__ */ jsx_runtime40.jsx(ToolHeader, {
3507
+ title: tool.tool_name,
3508
+ type: "tool-use",
3509
+ state: getToolState(tool)
3510
+ }),
3511
+ /* @__PURE__ */ jsx_runtime40.jsxs(ToolContent, {
3512
+ children: [
3513
+ /* @__PURE__ */ jsx_runtime40.jsx(ToolInput, {
3514
+ input: tool.tool_args
3515
+ }),
3516
+ output ? /* @__PURE__ */ jsx_runtime40.jsx(ToolOutput, {
3517
+ output,
3518
+ errorText: tool.tool_call_error ? "Tool execution failed" : undefined
3519
+ }) : null
3520
+ ]
3521
+ })
3522
+ ]
3523
+ });
3524
+ }
3525
+ function ToolGenerativeUI({ tool }) {
3526
+ const uiComponent = tool.ui_component;
3527
+ if (!uiComponent)
3528
+ return null;
3529
+ return uiComponent.layout === "artifact" ? /* @__PURE__ */ jsx_runtime40.jsx(Artifact, {
3530
+ children: /* @__PURE__ */ jsx_runtime40.jsx(GenerativeUIRenderer, {
3531
+ spec: uiComponent,
3532
+ className: "w-full p-2"
3533
+ })
3534
+ }) : /* @__PURE__ */ jsx_runtime40.jsx(GenerativeUIRenderer, {
3535
+ spec: uiComponent,
3536
+ className: "w-full"
3537
+ });
3538
+ }
3539
+
3540
+ // src/ui/composed/agno-message/tools.tsx
3541
+ var jsx_runtime41 = require("react/jsx-runtime");
3542
+ function AgnoMessageTools({ renderTool: renderToolProp } = {}) {
3543
+ const { message, classNames, renderTool: ctxMsgRenderTool } = useAgnoMessageContext();
3544
+ const { renderTool: ctxChatRenderTool, isDebug } = useAgnoChatContext();
3545
+ const renderTool = renderToolProp ?? ctxMsgRenderTool ?? ctxChatRenderTool;
3546
+ if (!message.tool_calls || message.tool_calls.length === 0)
3547
+ return null;
3548
+ return /* @__PURE__ */ jsx_runtime41.jsx("div", {
3549
+ className: cn("space-y-2 pt-1", classNames?.assistant?.toolCalls),
3550
+ children: message.tool_calls.map((tool, idx) => {
3551
+ const defaultRender = () => /* @__PURE__ */ jsx_runtime41.jsxs(jsx_runtime41.Fragment, {
3552
+ children: [
3553
+ /* @__PURE__ */ jsx_runtime41.jsx(ToolGenerativeUI, {
3554
+ tool
3555
+ }),
3556
+ isDebug ? /* @__PURE__ */ jsx_runtime41.jsx(ToolDebugCard, {
3557
+ tool,
3558
+ defaultOpen: idx === 0
3559
+ }) : null
3560
+ ]
3561
+ });
3562
+ const node = renderTool ? renderTool(tool, { index: idx, isDebug, defaultRender }) : defaultRender();
3563
+ if (node === null || node === undefined)
3564
+ return null;
3565
+ return /* @__PURE__ */ jsx_runtime41.jsx("div", {
3566
+ children: node
3567
+ }, tool.tool_call_id || idx);
3568
+ })
3569
+ });
3570
+ }
3571
+
3572
+ // src/ui/composed/agno-message/content.tsx
3573
+ var jsx_runtime42 = require("react/jsx-runtime");
3574
+ function AgnoMessageContent() {
3575
+ const { message } = useAgnoMessageContext();
3576
+ if (!message.content)
3577
+ return null;
3578
+ return /* @__PURE__ */ jsx_runtime42.jsx("div", {
3579
+ 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",
3580
+ children: /* @__PURE__ */ jsx_runtime42.jsx(Response, {
3581
+ children: message.content
3582
+ })
3583
+ });
3584
+ }
3585
+
3586
+ // src/ui/composed/agno-message/references.tsx
3587
+ var import_lucide_react21 = require("lucide-react");
3588
+ var jsx_runtime43 = require("react/jsx-runtime");
3589
+ function AgnoMessageReferences() {
3590
+ const { message, classNames } = useAgnoMessageContext();
3591
+ const references = message.extra_data?.references;
3592
+ if (!references || references.length === 0)
3593
+ return null;
3594
+ return /* @__PURE__ */ jsx_runtime43.jsxs("div", {
3595
+ className: cn("space-y-2 pt-1", classNames?.assistant?.references),
3596
+ children: [
3597
+ /* @__PURE__ */ jsx_runtime43.jsxs("div", {
3598
+ className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3599
+ children: [
3600
+ /* @__PURE__ */ jsx_runtime43.jsx(import_lucide_react21.FileText, {
3601
+ className: "h-3.5 w-3.5"
3602
+ }),
3603
+ "References (",
3604
+ references.length,
3605
+ ")"
3606
+ ]
3607
+ }),
3608
+ /* @__PURE__ */ jsx_runtime43.jsx("div", {
3609
+ className: "space-y-2",
3610
+ children: references.map((refData, idx) => /* @__PURE__ */ jsx_runtime43.jsxs("div", {
3611
+ className: "text-xs space-y-1.5",
3612
+ children: [
3613
+ refData.query && /* @__PURE__ */ jsx_runtime43.jsxs("div", {
3614
+ className: "font-medium text-foreground",
3615
+ children: [
3616
+ "Query: ",
3617
+ refData.query
3618
+ ]
3619
+ }),
3620
+ refData.references.map((ref, refIdx) => /* @__PURE__ */ jsx_runtime43.jsxs("div", {
3621
+ className: "bg-muted/50 border border-border p-2.5 rounded-lg",
3622
+ children: [
3623
+ /* @__PURE__ */ jsx_runtime43.jsxs("div", {
3624
+ className: "italic text-muted-foreground mb-1",
3625
+ children: [
3626
+ '"',
3627
+ ref.content,
3628
+ '"'
3629
+ ]
3630
+ }),
3631
+ /* @__PURE__ */ jsx_runtime43.jsxs("div", {
3632
+ className: "text-muted-foreground/70",
3633
+ children: [
3634
+ "Source: ",
3635
+ ref.name,
3636
+ " (chunk ",
3637
+ ref.meta_data.chunk,
3638
+ "/",
3639
+ ref.meta_data.chunk_size,
3640
+ ")"
3641
+ ]
3642
+ })
3643
+ ]
3644
+ }, refIdx))
3645
+ ]
3646
+ }, idx))
3647
+ })
3648
+ ]
3649
+ });
3650
+ }
3651
+
3652
+ // src/ui/composed/agno-message/footer.tsx
3653
+ var import_lucide_react22 = require("lucide-react");
3654
+ var jsx_runtime44 = require("react/jsx-runtime");
3655
+ function AgnoMessageFooter({ showTimestamp = true } = {}) {
3656
+ const { message, classNames, actions, isLastAssistantMessage, formatTimestamp } = useAgnoMessageContext();
3657
+ const hasError = message.streamingError;
3658
+ const isCustomTimestamp = !!formatTimestamp;
3659
+ const resolvedFormatTimestamp = formatTimestamp ?? formatSmartTimestamp;
3660
+ if (!actions?.assistant && !showTimestamp && !hasError)
3661
+ return null;
3662
+ return /* @__PURE__ */ jsx_runtime44.jsxs("div", {
3663
+ className: "flex items-center gap-2 pt-1",
3664
+ children: [
3665
+ actions?.assistant && (() => {
3666
+ const visibility = actions.visibility ?? "visible";
3667
+ if (visibility === "last-assistant" && !isLastAssistantMessage)
3668
+ return null;
3669
+ const useHover = visibility === "hover" || visibility === "hover-last-visible" && !isLastAssistantMessage;
3670
+ return /* @__PURE__ */ jsx_runtime44.jsx("div", {
3671
+ className: cn("flex items-center gap-1 transition-opacity", useHover && "opacity-0 group-hover/message:opacity-100", classNames?.assistant?.actions),
3672
+ children: actions.assistant(message)
3673
+ });
3674
+ })(),
3675
+ hasError && /* @__PURE__ */ jsx_runtime44.jsxs("span", {
3676
+ className: "flex items-center gap-1 text-[11px] text-destructive",
3677
+ children: [
3678
+ /* @__PURE__ */ jsx_runtime44.jsx(import_lucide_react22.AlertCircle, {
3679
+ className: "h-3 w-3"
3680
+ }),
3681
+ "Error"
3682
+ ]
3683
+ }),
3684
+ showTimestamp && /* @__PURE__ */ jsx_runtime44.jsx(SmartTimestamp, {
3685
+ date: new Date(message.created_at * 1000),
3686
+ formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
3687
+ className: "text-[11px] text-muted-foreground"
3688
+ })
3689
+ ]
3690
+ });
3691
+ }
3692
+
3693
+ // src/ui/composed/agno-message/message.tsx
3694
+ var jsx_runtime45 = require("react/jsx-runtime");
3695
+ function DefaultAssistantComposition({ showTimestamp }) {
3696
+ return /* @__PURE__ */ jsx_runtime45.jsxs(jsx_runtime45.Fragment, {
3697
+ children: [
3698
+ /* @__PURE__ */ jsx_runtime45.jsx(AgnoMessageReasoning, {}),
3699
+ /* @__PURE__ */ jsx_runtime45.jsx(AgnoMessageMedia, {}),
3700
+ /* @__PURE__ */ jsx_runtime45.jsx(AgnoMessageTools, {}),
3701
+ /* @__PURE__ */ jsx_runtime45.jsx(AgnoMessageContent, {}),
3702
+ /* @__PURE__ */ jsx_runtime45.jsx(AgnoMessageReferences, {}),
3703
+ /* @__PURE__ */ jsx_runtime45.jsx(AgnoMessageFooter, {
3704
+ showTimestamp
3705
+ })
3706
+ ]
3707
+ });
3708
+ }
3709
+ function AgnoMessage({
2878
3710
  message,
2879
3711
  className,
2880
3712
  classNames,
2881
- renderContent,
2882
- renderToolCall,
2883
- renderMedia,
2884
3713
  avatars,
2885
3714
  actions,
2886
3715
  isLastAssistantMessage = false,
2887
- showReasoning = true,
2888
- showReferences = true,
2889
- showTimestamp = true,
2890
- showGenerativeUI = true,
2891
- showToolCalls = true,
2892
3716
  showFilePreview = true,
2893
3717
  showImageLightbox = true,
3718
+ showTimestamp = true,
2894
3719
  formatTimestamp,
2895
- toolResultRenderers
3720
+ renderTool,
3721
+ children
2896
3722
  }) {
2897
3723
  const isUser = message.role === "user";
2898
3724
  const hasError = message.streamingError;
2899
- const toolsWithUI = message.tool_calls?.filter((tool) => tool.ui_component) || [];
2900
- const [preview, setPreview] = import_react14.useState(null);
3725
+ const [preview, setPreview] = import_react20.useState(null);
2901
3726
  const isCustomTimestamp = !!formatTimestamp;
2902
- const resolvedFormatTimestamp = formatTimestamp ?? defaultFormatTimestamp;
2903
- const openImageLightbox = (images, index) => {
2904
- if (!showImageLightbox)
2905
- return;
2906
- setPreview({ type: "image", images, initialIndex: index });
2907
- };
2908
- const openFilePreview = (file) => {
2909
- if (!showFilePreview)
2910
- return;
2911
- setPreview({ type: "file", file });
2912
- };
3727
+ const resolvedFormatTimestamp = formatTimestamp ?? formatSmartTimestamp;
3728
+ const ctx = import_react20.useMemo(() => ({
3729
+ message,
3730
+ isLastAssistantMessage,
3731
+ classNames,
3732
+ actions,
3733
+ avatars,
3734
+ formatTimestamp,
3735
+ showFilePreview,
3736
+ showImageLightbox,
3737
+ openImageLightbox: (images, index) => {
3738
+ if (!showImageLightbox)
3739
+ return;
3740
+ setPreview({ type: "image", images, initialIndex: index });
3741
+ },
3742
+ openFilePreview: (file) => {
3743
+ if (!showFilePreview)
3744
+ return;
3745
+ setPreview({ type: "file", file });
3746
+ },
3747
+ renderTool
3748
+ }), [
3749
+ message,
3750
+ isLastAssistantMessage,
3751
+ classNames,
3752
+ actions,
3753
+ avatars,
3754
+ formatTimestamp,
3755
+ showFilePreview,
3756
+ showImageLightbox,
3757
+ renderTool
3758
+ ]);
2913
3759
  const closePreview = () => setPreview(null);
2914
- return /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2915
- className: cn("py-5 first:pt-2", isUser ? "flex justify-end" : "", classNames?.root, className),
3760
+ return /* @__PURE__ */ jsx_runtime45.jsx(AgnoMessageContext.Provider, {
3761
+ value: ctx,
3762
+ children: /* @__PURE__ */ jsx_runtime45.jsxs("div", {
3763
+ className: cn("py-5 first:pt-2", isUser ? "flex justify-end" : "", classNames?.root, className),
3764
+ children: [
3765
+ isUser ? /* @__PURE__ */ jsx_runtime45.jsx(UserMessageLayout, {
3766
+ message,
3767
+ classNames,
3768
+ avatars,
3769
+ actions,
3770
+ isCustomTimestamp,
3771
+ resolvedFormatTimestamp,
3772
+ showTimestamp,
3773
+ showImageLightbox,
3774
+ showFilePreview,
3775
+ openImageLightbox: ctx.openImageLightbox,
3776
+ openFilePreview: ctx.openFilePreview,
3777
+ hasError
3778
+ }) : /* @__PURE__ */ jsx_runtime45.jsxs("div", {
3779
+ className: "flex items-start gap-3 group/message",
3780
+ children: [
3781
+ avatars?.assistant,
3782
+ /* @__PURE__ */ jsx_runtime45.jsx("div", {
3783
+ className: cn("flex-1 min-w-0 space-y-3", classNames?.assistant?.container),
3784
+ children: children ?? /* @__PURE__ */ jsx_runtime45.jsx(DefaultAssistantComposition, {
3785
+ showTimestamp
3786
+ })
3787
+ })
3788
+ ]
3789
+ }),
3790
+ preview?.type === "image" && /* @__PURE__ */ jsx_runtime45.jsx(ImageLightbox, {
3791
+ open: true,
3792
+ onOpenChange: (open) => {
3793
+ if (!open)
3794
+ closePreview();
3795
+ },
3796
+ images: preview.images,
3797
+ initialIndex: preview.initialIndex
3798
+ }),
3799
+ preview?.type === "file" && /* @__PURE__ */ jsx_runtime45.jsx(FilePreviewModal, {
3800
+ open: true,
3801
+ onOpenChange: (open) => {
3802
+ if (!open)
3803
+ closePreview();
3804
+ },
3805
+ file: preview.file
3806
+ })
3807
+ ]
3808
+ })
3809
+ });
3810
+ }
3811
+ AgnoMessage.Reasoning = AgnoMessageReasoning;
3812
+ AgnoMessage.Media = AgnoMessageMedia;
3813
+ AgnoMessage.Tools = AgnoMessageTools;
3814
+ AgnoMessage.Content = AgnoMessageContent;
3815
+ AgnoMessage.References = AgnoMessageReferences;
3816
+ AgnoMessage.Footer = AgnoMessageFooter;
3817
+ function UserMessageLayout({
3818
+ message,
3819
+ classNames,
3820
+ avatars,
3821
+ actions,
3822
+ isCustomTimestamp,
3823
+ resolvedFormatTimestamp,
3824
+ showTimestamp,
3825
+ showImageLightbox,
3826
+ showFilePreview,
3827
+ openImageLightbox,
3828
+ openFilePreview,
3829
+ hasError
3830
+ }) {
3831
+ return /* @__PURE__ */ jsx_runtime45.jsxs("div", {
3832
+ className: "flex items-start gap-2.5 max-w-[80%] flex-row-reverse",
2916
3833
  children: [
2917
- isUser ? /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2918
- className: "flex items-start gap-2.5 max-w-[80%] flex-row-reverse",
3834
+ avatars?.user,
3835
+ /* @__PURE__ */ jsx_runtime45.jsxs("div", {
3836
+ className: "space-y-1.5 flex flex-col items-end min-w-0",
2919
3837
  children: [
2920
- avatars?.user,
2921
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2922
- className: "space-y-1.5 flex flex-col items-end min-w-0",
3838
+ (message.images && message.images.length > 0 || message.audio && message.audio.length > 0 || message.files && message.files.length > 0) && /* @__PURE__ */ jsx_runtime45.jsxs("div", {
3839
+ className: "flex flex-wrap gap-2 justify-end",
2923
3840
  children: [
2924
- (message.images && message.images.length > 0 || message.audio && message.audio.length > 0 || message.files && message.files.length > 0) && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2925
- className: "flex flex-wrap gap-2 justify-end",
2926
- children: [
2927
- message.images?.map((img, idx) => /* @__PURE__ */ jsx_runtime35.jsx(FilePreviewCard, {
2928
- file: { name: img.revised_prompt || `Image ${idx + 1}`, type: "image/png", url: img.url },
2929
- onClick: showImageLightbox ? () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx) : undefined
2930
- }, `img-${idx}`)),
2931
- message.audio?.map((audio, idx) => /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2932
- 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",
2933
- children: [
2934
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Music, {
2935
- className: "h-3.5 w-3.5 text-muted-foreground"
2936
- }),
2937
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
2938
- className: "truncate max-w-[150px]",
2939
- children: audio.id || `Audio ${idx + 1}`
2940
- })
2941
- ]
2942
- }, `audio-${idx}`)),
2943
- message.files?.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx_runtime35.jsx(FilePreviewCard, {
2944
- file: { name: file.name, type: file.type, url: file.url, size: file.size },
2945
- onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
2946
- }, `file-${idx}`) : /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2947
- 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",
2948
- children: [
2949
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.FileIcon, {
2950
- className: "h-3.5 w-3.5 text-muted-foreground"
2951
- }),
2952
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
2953
- className: "truncate max-w-[150px]",
2954
- children: file.name
2955
- })
2956
- ]
2957
- }, `file-${idx}`))
2958
- ]
2959
- }),
2960
- message.content && /* @__PURE__ */ jsx_runtime35.jsx("div", {
2961
- className: cn("rounded-2xl rounded-br-md px-4 py-2.5", classNames?.user?.bubble ?? "bg-primary text-primary-foreground", hasError && "opacity-70"),
2962
- children: /* @__PURE__ */ jsx_runtime35.jsx("p", {
2963
- className: "text-sm whitespace-pre-wrap",
2964
- children: message.content
2965
- })
2966
- }),
2967
- (showTimestamp || actions?.user) && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2968
- className: "flex items-center justify-end gap-1.5 px-1",
3841
+ message.images?.map((img, idx) => /* @__PURE__ */ jsx_runtime45.jsx(FilePreviewCard, {
3842
+ file: { name: img.revised_prompt || `Image ${idx + 1}`, type: "image/png", url: img.url },
3843
+ onClick: showImageLightbox ? () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx) : undefined
3844
+ }, `img-${idx}`)),
3845
+ message.audio?.map((audio, idx) => /* @__PURE__ */ jsx_runtime45.jsxs("div", {
3846
+ 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",
2969
3847
  children: [
2970
- actions?.user && /* @__PURE__ */ jsx_runtime35.jsx("div", {
2971
- className: "flex items-center gap-1",
2972
- children: actions.user(message)
2973
- }),
2974
- /* @__PURE__ */ jsx_runtime35.jsx(SmartTimestamp, {
2975
- date: new Date(message.created_at * 1000),
2976
- formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
2977
- className: "text-[11px] text-muted-foreground"
3848
+ /* @__PURE__ */ jsx_runtime45.jsx(import_lucide_react23.Music, {
3849
+ className: "h-3.5 w-3.5 text-muted-foreground"
2978
3850
  }),
2979
- hasError && /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.AlertCircle, {
2980
- className: "h-3 w-3 text-destructive"
3851
+ /* @__PURE__ */ jsx_runtime45.jsx("span", {
3852
+ className: "truncate max-w-[150px]",
3853
+ children: audio.id || `Audio ${idx + 1}`
2981
3854
  })
2982
3855
  ]
2983
- })
2984
- ]
2985
- })
2986
- ]
2987
- }) : /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2988
- className: "flex items-start gap-3 group/message",
2989
- children: [
2990
- avatars?.assistant,
2991
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2992
- className: cn("flex-1 min-w-0 space-y-3", classNames?.assistant?.container),
2993
- children: [
2994
- renderContent ? renderContent(message) : /* @__PURE__ */ jsx_runtime35.jsxs(jsx_runtime35.Fragment, {
3856
+ }, `audio-${idx}`)),
3857
+ message.files?.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx_runtime45.jsx(FilePreviewCard, {
3858
+ file: { name: file.name, type: file.type, url: file.url, size: file.size },
3859
+ onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
3860
+ }, `file-${idx}`) : /* @__PURE__ */ jsx_runtime45.jsxs("div", {
3861
+ 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",
2995
3862
  children: [
2996
- showReasoning && message.extra_data?.reasoning_steps && message.extra_data.reasoning_steps.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2997
- className: cn("space-y-2 pt-1", classNames?.assistant?.reasoning),
2998
- children: [
2999
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3000
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3001
- children: [
3002
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Lightbulb, {
3003
- className: "h-3.5 w-3.5"
3004
- }),
3005
- "Reasoning (",
3006
- message.extra_data.reasoning_steps.length,
3007
- " steps)"
3008
- ]
3009
- }),
3010
- /* @__PURE__ */ jsx_runtime35.jsx(Accordion, {
3011
- type: "multiple",
3012
- className: "w-full",
3013
- children: message.extra_data.reasoning_steps.map((step, idx) => /* @__PURE__ */ jsx_runtime35.jsxs(AccordionItem, {
3014
- value: `reasoning-${idx}`,
3015
- className: "border-muted",
3016
- children: [
3017
- /* @__PURE__ */ jsx_runtime35.jsx(AccordionTrigger, {
3018
- className: "text-xs py-1.5 hover:no-underline",
3019
- children: step.title || `Step ${idx + 1}`
3020
- }),
3021
- /* @__PURE__ */ jsx_runtime35.jsxs(AccordionContent, {
3022
- className: "space-y-1.5 text-xs text-muted-foreground",
3023
- children: [
3024
- step.action && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3025
- children: [
3026
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3027
- className: "font-medium text-foreground",
3028
- children: "Action:"
3029
- }),
3030
- " ",
3031
- step.action
3032
- ]
3033
- }),
3034
- step.reasoning && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3035
- children: [
3036
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3037
- className: "font-medium text-foreground",
3038
- children: "Reasoning:"
3039
- }),
3040
- " ",
3041
- step.reasoning
3042
- ]
3043
- }),
3044
- step.result && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3045
- children: [
3046
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3047
- className: "font-medium text-foreground",
3048
- children: "Result:"
3049
- }),
3050
- " ",
3051
- step.result
3052
- ]
3053
- }),
3054
- step.confidence !== undefined && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3055
- children: [
3056
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3057
- className: "font-medium text-foreground",
3058
- children: "Confidence:"
3059
- }),
3060
- " ",
3061
- (step.confidence * 100).toFixed(1),
3062
- "%"
3063
- ]
3064
- })
3065
- ]
3066
- })
3067
- ]
3068
- }, idx))
3069
- })
3070
- ]
3863
+ /* @__PURE__ */ jsx_runtime45.jsx(import_lucide_react23.FileIcon, {
3864
+ className: "h-3.5 w-3.5 text-muted-foreground"
3071
3865
  }),
3072
- message.content && /* @__PURE__ */ jsx_runtime35.jsx("div", {
3073
- 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",
3074
- children: /* @__PURE__ */ jsx_runtime35.jsx(Response, {
3075
- children: message.content
3076
- })
3077
- }),
3078
- showGenerativeUI && toolsWithUI.length > 0 && /* @__PURE__ */ jsx_runtime35.jsx("div", {
3079
- className: "space-y-3",
3080
- children: toolsWithUI.map((tool) => {
3081
- const uiComponent = tool.ui_component;
3082
- return /* @__PURE__ */ jsx_runtime35.jsx("div", {
3083
- children: uiComponent.layout === "artifact" ? /* @__PURE__ */ jsx_runtime35.jsx(Artifact, {
3084
- children: /* @__PURE__ */ jsx_runtime35.jsx(import_agno_react.GenerativeUIRenderer, {
3085
- spec: uiComponent,
3086
- className: "w-full p-2"
3087
- })
3088
- }) : /* @__PURE__ */ jsx_runtime35.jsx(import_agno_react.GenerativeUIRenderer, {
3089
- spec: uiComponent,
3090
- className: "w-full"
3091
- })
3092
- }, tool.tool_call_id);
3093
- })
3094
- }),
3095
- toolResultRenderers && message.tool_calls?.map((tool) => {
3096
- const renderer = toolResultRenderers[tool.tool_name];
3097
- const content = tool.result ?? tool.content;
3098
- if (!renderer || !content)
3099
- return null;
3100
- return /* @__PURE__ */ jsx_runtime35.jsx("div", {
3101
- children: renderer(tool.tool_args, content)
3102
- }, `result-${tool.tool_call_id}`);
3103
- }),
3104
- renderMedia ? renderMedia(message) : (() => {
3105
- const mediaClassName = classNames?.assistant?.media;
3106
- return /* @__PURE__ */ jsx_runtime35.jsxs(jsx_runtime35.Fragment, {
3107
- children: [
3108
- message.images && message.images.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3109
- className: cn("space-y-2 pt-1", mediaClassName),
3110
- children: [
3111
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3112
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3113
- children: [
3114
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Image, {
3115
- className: "h-3.5 w-3.5"
3116
- }),
3117
- "Images (",
3118
- message.images.length,
3119
- ")"
3120
- ]
3121
- }),
3122
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3123
- className: "grid grid-cols-2 gap-2",
3124
- children: message.images.map((img, idx) => /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3125
- className: "space-y-1",
3126
- children: [
3127
- showImageLightbox ? /* @__PURE__ */ jsx_runtime35.jsx("button", {
3128
- type: "button",
3129
- onClick: () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx),
3130
- 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",
3131
- children: /* @__PURE__ */ jsx_runtime35.jsx("img", {
3132
- src: img.url,
3133
- alt: img.revised_prompt || "Generated image",
3134
- className: "w-full rounded-lg"
3135
- })
3136
- }) : /* @__PURE__ */ jsx_runtime35.jsx("img", {
3137
- src: img.url,
3138
- alt: img.revised_prompt || "Generated image",
3139
- className: "w-full rounded-lg border border-border"
3140
- }),
3141
- img.revised_prompt && /* @__PURE__ */ jsx_runtime35.jsx("p", {
3142
- className: "text-[11px] text-muted-foreground italic px-0.5",
3143
- children: img.revised_prompt
3144
- })
3145
- ]
3146
- }, idx))
3147
- })
3148
- ]
3149
- }),
3150
- message.videos && message.videos.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3151
- className: cn("space-y-2 pt-1", mediaClassName),
3152
- children: [
3153
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3154
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3155
- children: [
3156
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Video, {
3157
- className: "h-3.5 w-3.5"
3158
- }),
3159
- "Videos (",
3160
- message.videos.length,
3161
- ")"
3162
- ]
3163
- }),
3164
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3165
- className: "space-y-2",
3166
- children: message.videos.map((video, idx) => /* @__PURE__ */ jsx_runtime35.jsx("div", {
3167
- children: video.url ? /* @__PURE__ */ jsx_runtime35.jsx("video", {
3168
- src: video.url,
3169
- controls: true,
3170
- className: "w-full rounded-lg border border-border"
3171
- }) : /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3172
- className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3173
- children: [
3174
- "Video ID: ",
3175
- video.id,
3176
- " (ETA: ",
3177
- video.eta,
3178
- "s)"
3179
- ]
3180
- })
3181
- }, idx))
3182
- })
3183
- ]
3184
- }),
3185
- message.audio && message.audio.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3186
- className: cn("space-y-2 pt-1", mediaClassName),
3187
- children: [
3188
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3189
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3190
- children: [
3191
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Music, {
3192
- className: "h-3.5 w-3.5"
3193
- }),
3194
- "Audio (",
3195
- message.audio.length,
3196
- ")"
3197
- ]
3198
- }),
3199
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3200
- className: "space-y-2",
3201
- children: message.audio.map((audio, idx) => /* @__PURE__ */ jsx_runtime35.jsx("div", {
3202
- children: audio.url ? /* @__PURE__ */ jsx_runtime35.jsx("audio", {
3203
- src: audio.url,
3204
- controls: true,
3205
- className: "w-full"
3206
- }) : audio.base64_audio ? /* @__PURE__ */ jsx_runtime35.jsx("audio", {
3207
- src: `data:${audio.mime_type || "audio/wav"};base64,${audio.base64_audio}`,
3208
- controls: true,
3209
- className: "w-full"
3210
- }) : /* @__PURE__ */ jsx_runtime35.jsx("div", {
3211
- className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3212
- children: "Audio data unavailable"
3213
- })
3214
- }, idx))
3215
- })
3216
- ]
3217
- }),
3218
- message.files && message.files.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3219
- className: cn("space-y-2 pt-1", mediaClassName),
3220
- children: [
3221
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3222
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3223
- children: [
3224
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Paperclip, {
3225
- className: "h-3.5 w-3.5"
3226
- }),
3227
- "Files (",
3228
- message.files.length,
3229
- ")"
3230
- ]
3231
- }),
3232
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3233
- className: "flex flex-wrap gap-2",
3234
- children: message.files.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx_runtime35.jsx(FilePreviewCard, {
3235
- file: { name: file.name, type: file.type, url: file.url, size: file.size },
3236
- onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
3237
- }, idx) : /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3238
- 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",
3239
- children: [
3240
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.FileIcon, {
3241
- className: "h-3.5 w-3.5 shrink-0 text-muted-foreground"
3242
- }),
3243
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3244
- className: "truncate max-w-[180px]",
3245
- children: file.name
3246
- }),
3247
- file.size && /* @__PURE__ */ jsx_runtime35.jsxs("span", {
3248
- className: "text-muted-foreground/70",
3249
- children: [
3250
- "(",
3251
- (file.size / 1024).toFixed(1),
3252
- "KB)"
3253
- ]
3254
- }),
3255
- file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsx_runtime35.jsx("a", {
3256
- href: file.url,
3257
- target: "_blank",
3258
- rel: "noopener noreferrer",
3259
- className: "text-primary hover:underline font-medium",
3260
- children: "View"
3261
- })
3262
- ]
3263
- }, idx))
3264
- })
3265
- ]
3266
- }),
3267
- message.response_audio && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3268
- className: cn("space-y-2 pt-1", mediaClassName),
3269
- children: [
3270
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3271
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3272
- children: [
3273
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Music, {
3274
- className: "h-3.5 w-3.5"
3275
- }),
3276
- "Response Audio"
3277
- ]
3278
- }),
3279
- message.response_audio.transcript && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3280
- className: "text-xs italic bg-muted/50 border border-border p-2.5 rounded-lg text-muted-foreground",
3281
- children: [
3282
- '"',
3283
- message.response_audio.transcript,
3284
- '"'
3285
- ]
3286
- }),
3287
- message.response_audio.content && /* @__PURE__ */ jsx_runtime35.jsx("audio", {
3288
- src: `data:audio/wav;base64,${message.response_audio.content}`,
3289
- controls: true,
3290
- className: "w-full"
3291
- })
3292
- ]
3293
- })
3294
- ]
3295
- });
3296
- })(),
3297
- showToolCalls && message.tool_calls && message.tool_calls.length > 0 && /* @__PURE__ */ jsx_runtime35.jsx("div", {
3298
- className: cn("space-y-2 pt-1", classNames?.assistant?.toolCalls),
3299
- children: message.tool_calls.map((tool, idx) => renderToolCall ? renderToolCall(tool, idx) : /* @__PURE__ */ jsx_runtime35.jsxs(Tool, {
3300
- defaultOpen: idx === 0,
3301
- children: [
3302
- /* @__PURE__ */ jsx_runtime35.jsx(ToolHeader, {
3303
- title: tool.tool_name,
3304
- type: "tool-use",
3305
- state: getToolState(tool)
3306
- }),
3307
- /* @__PURE__ */ jsx_runtime35.jsxs(ToolContent, {
3308
- children: [
3309
- /* @__PURE__ */ jsx_runtime35.jsx(ToolInput, {
3310
- input: tool.tool_args
3311
- }),
3312
- tool.content && /* @__PURE__ */ jsx_runtime35.jsx(ToolOutput, {
3313
- output: tool.content,
3314
- errorText: tool.tool_call_error ? "Tool execution failed" : undefined
3315
- })
3316
- ]
3317
- })
3318
- ]
3319
- }, tool.tool_call_id || idx))
3320
- }),
3321
- showReferences && message.extra_data?.references && message.extra_data.references.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3322
- className: cn("space-y-2 pt-1", classNames?.assistant?.references),
3323
- children: [
3324
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3325
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3326
- children: [
3327
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.FileText, {
3328
- className: "h-3.5 w-3.5"
3329
- }),
3330
- "References (",
3331
- message.extra_data.references.length,
3332
- ")"
3333
- ]
3334
- }),
3335
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3336
- className: "space-y-2",
3337
- children: message.extra_data.references.map((refData, idx) => /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3338
- className: "text-xs space-y-1.5",
3339
- children: [
3340
- refData.query && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3341
- className: "font-medium text-foreground",
3342
- children: [
3343
- "Query: ",
3344
- refData.query
3345
- ]
3346
- }),
3347
- refData.references.map((ref, refIdx) => /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3348
- className: "bg-muted/50 border border-border p-2.5 rounded-lg",
3349
- children: [
3350
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3351
- className: "italic text-muted-foreground mb-1",
3352
- children: [
3353
- '"',
3354
- ref.content,
3355
- '"'
3356
- ]
3357
- }),
3358
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3359
- className: "text-muted-foreground/70",
3360
- children: [
3361
- "Source: ",
3362
- ref.name,
3363
- " (chunk ",
3364
- ref.meta_data.chunk,
3365
- "/",
3366
- ref.meta_data.chunk_size,
3367
- ")"
3368
- ]
3369
- })
3370
- ]
3371
- }, refIdx))
3372
- ]
3373
- }, idx))
3374
- })
3375
- ]
3866
+ /* @__PURE__ */ jsx_runtime45.jsx("span", {
3867
+ className: "truncate max-w-[150px]",
3868
+ children: file.name
3376
3869
  })
3377
3870
  ]
3871
+ }, `file-${idx}`))
3872
+ ]
3873
+ }),
3874
+ message.content && /* @__PURE__ */ jsx_runtime45.jsx("div", {
3875
+ className: cn("rounded-2xl rounded-br-md px-4 py-2.5", classNames?.user?.bubble ?? "bg-primary text-primary-foreground", hasError && "opacity-70"),
3876
+ children: /* @__PURE__ */ jsx_runtime45.jsx("p", {
3877
+ className: "text-sm whitespace-pre-wrap",
3878
+ children: message.content
3879
+ })
3880
+ }),
3881
+ (showTimestamp || actions?.user) && /* @__PURE__ */ jsx_runtime45.jsxs("div", {
3882
+ className: "flex items-center justify-end gap-1.5 px-1",
3883
+ children: [
3884
+ actions?.user && /* @__PURE__ */ jsx_runtime45.jsx("div", {
3885
+ className: "flex items-center gap-1",
3886
+ children: actions.user(message)
3378
3887
  }),
3379
- (actions?.assistant || showTimestamp || hasError) && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3380
- className: "flex items-center gap-2 pt-1",
3381
- children: [
3382
- actions?.assistant && (() => {
3383
- const visibility = actions.visibility ?? "visible";
3384
- if (visibility === "last-assistant" && !isLastAssistantMessage)
3385
- return null;
3386
- const useHover = visibility === "hover" || visibility === "hover-last-visible" && !isLastAssistantMessage;
3387
- return /* @__PURE__ */ jsx_runtime35.jsx("div", {
3388
- className: cn("flex items-center gap-1 transition-opacity", useHover && "opacity-0 group-hover/message:opacity-100", classNames?.assistant?.actions),
3389
- children: actions.assistant(message)
3390
- });
3391
- })(),
3392
- hasError && /* @__PURE__ */ jsx_runtime35.jsxs("span", {
3393
- className: "flex items-center gap-1 text-[11px] text-destructive",
3394
- children: [
3395
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.AlertCircle, {
3396
- className: "h-3 w-3"
3397
- }),
3398
- "Error"
3399
- ]
3400
- }),
3401
- showTimestamp && /* @__PURE__ */ jsx_runtime35.jsx(SmartTimestamp, {
3402
- date: new Date(message.created_at * 1000),
3403
- formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
3404
- className: "text-[11px] text-muted-foreground"
3405
- })
3406
- ]
3888
+ /* @__PURE__ */ jsx_runtime45.jsx(SmartTimestamp, {
3889
+ date: new Date(message.created_at * 1000),
3890
+ formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
3891
+ className: "text-[11px] text-muted-foreground"
3892
+ }),
3893
+ hasError && /* @__PURE__ */ jsx_runtime45.jsx(import_lucide_react23.AlertCircle, {
3894
+ className: "h-3 w-3 text-destructive"
3407
3895
  })
3408
3896
  ]
3409
3897
  })
3410
3898
  ]
3411
- }),
3412
- preview?.type === "image" && /* @__PURE__ */ jsx_runtime35.jsx(ImageLightbox, {
3413
- open: true,
3414
- onOpenChange: (open) => {
3415
- if (!open)
3416
- closePreview();
3417
- },
3418
- images: preview.images,
3419
- initialIndex: preview.initialIndex
3420
- }),
3421
- preview?.type === "file" && /* @__PURE__ */ jsx_runtime35.jsx(FilePreviewModal, {
3422
- open: true,
3423
- onOpenChange: (open) => {
3424
- if (!open)
3425
- closePreview();
3426
- },
3427
- file: preview.file
3899
+ })
3900
+ ]
3901
+ });
3902
+ }
3903
+
3904
+ // src/ui/composed/AgnoMessageItem.tsx
3905
+ var jsx_runtime46 = require("react/jsx-runtime");
3906
+ function AgnoMessageItem({
3907
+ message,
3908
+ className,
3909
+ classNames,
3910
+ avatars,
3911
+ actions,
3912
+ isLastAssistantMessage = false,
3913
+ showReasoning = true,
3914
+ showReferences = true,
3915
+ showTimestamp = true,
3916
+ showFilePreview = true,
3917
+ showImageLightbox = true,
3918
+ formatTimestamp,
3919
+ renderTool
3920
+ }) {
3921
+ return /* @__PURE__ */ jsx_runtime46.jsxs(AgnoMessage, {
3922
+ message,
3923
+ className,
3924
+ classNames,
3925
+ avatars,
3926
+ actions,
3927
+ isLastAssistantMessage,
3928
+ showTimestamp,
3929
+ showFilePreview,
3930
+ showImageLightbox,
3931
+ formatTimestamp,
3932
+ renderTool,
3933
+ children: [
3934
+ showReasoning && /* @__PURE__ */ jsx_runtime46.jsx(AgnoMessage.Reasoning, {}),
3935
+ /* @__PURE__ */ jsx_runtime46.jsx(AgnoMessage.Media, {}),
3936
+ /* @__PURE__ */ jsx_runtime46.jsx(AgnoMessage.Tools, {}),
3937
+ /* @__PURE__ */ jsx_runtime46.jsx(AgnoMessage.Content, {}),
3938
+ showReferences && /* @__PURE__ */ jsx_runtime46.jsx(AgnoMessage.References, {}),
3939
+ /* @__PURE__ */ jsx_runtime46.jsx(AgnoMessage.Footer, {
3940
+ showTimestamp
3428
3941
  })
3429
3942
  ]
3430
3943
  });
3431
3944
  }
3432
3945
  // src/ui/composed/AgnoChatInput.tsx
3433
- var import_lucide_react20 = require("lucide-react");
3434
- var jsx_runtime36 = require("react/jsx-runtime");
3946
+ var import_lucide_react24 = require("lucide-react");
3947
+ var jsx_runtime47 = require("react/jsx-runtime");
3435
3948
  var DEFAULT_ACCEPTED_FILE_TYPES = "image/*,audio/*,.pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.ppt,.pptx,.md,.json,.xml";
3436
3949
  function normalizeAudio(audio) {
3437
3950
  if (audio === true)
@@ -3451,14 +3964,14 @@ function dataUrlToBlob(dataUrl) {
3451
3964
  return new Blob([buf], { type: mime });
3452
3965
  }
3453
3966
  function CancelButton({ onCancel }) {
3454
- return /* @__PURE__ */ jsx_runtime36.jsx(Button, {
3967
+ return /* @__PURE__ */ jsx_runtime47.jsx(Button, {
3455
3968
  type: "button",
3456
3969
  variant: "destructive",
3457
3970
  size: "icon",
3458
3971
  className: "h-8 w-8 rounded-lg",
3459
3972
  onClick: onCancel,
3460
3973
  "aria-label": "Stop",
3461
- children: /* @__PURE__ */ jsx_runtime36.jsx(import_lucide_react20.CircleStop, {
3974
+ children: /* @__PURE__ */ jsx_runtime47.jsx(import_lucide_react24.CircleStop, {
3462
3975
  className: "size-4"
3463
3976
  })
3464
3977
  });
@@ -3466,7 +3979,7 @@ function CancelButton({ onCancel }) {
3466
3979
  function SubmitButton({ disabled, status }) {
3467
3980
  const { textInput } = usePromptInputController();
3468
3981
  const hasText = textInput.value.trim().length > 0;
3469
- return /* @__PURE__ */ jsx_runtime36.jsx(PromptInputSubmit, {
3982
+ return /* @__PURE__ */ jsx_runtime47.jsx(PromptInputSubmit, {
3470
3983
  disabled: disabled || !hasText,
3471
3984
  status
3472
3985
  });
@@ -3475,9 +3988,9 @@ function AttachmentHeader() {
3475
3988
  const { files } = usePromptInputAttachments();
3476
3989
  if (files.length === 0)
3477
3990
  return null;
3478
- return /* @__PURE__ */ jsx_runtime36.jsx(PromptInputHeader, {
3479
- children: /* @__PURE__ */ jsx_runtime36.jsx(PromptInputAttachments, {
3480
- children: (attachment) => /* @__PURE__ */ jsx_runtime36.jsx(PromptInputAttachment, {
3991
+ return /* @__PURE__ */ jsx_runtime47.jsx(PromptInputHeader, {
3992
+ children: /* @__PURE__ */ jsx_runtime47.jsx(PromptInputAttachments, {
3993
+ children: (attachment) => /* @__PURE__ */ jsx_runtime47.jsx(PromptInputAttachment, {
3481
3994
  data: attachment
3482
3995
  })
3483
3996
  })
@@ -3492,7 +4005,7 @@ function TranscribeAudioRecorder({
3492
4005
  labels
3493
4006
  }) {
3494
4007
  const { textInput } = usePromptInputController();
3495
- return /* @__PURE__ */ jsx_runtime36.jsx(AudioRecorder, {
4008
+ return /* @__PURE__ */ jsx_runtime47.jsx(AudioRecorder, {
3496
4009
  mode: "transcribe",
3497
4010
  transcriptionEndpoint: endpoint,
3498
4011
  transcriptionHeaders: headers,
@@ -3556,8 +4069,8 @@ function AgnoChatInput({
3556
4069
  };
3557
4070
  const computedStatus = status ?? (disabled ? "submitted" : undefined);
3558
4071
  const showCancelButton = allowCancelRun && isStreaming && onCancel;
3559
- return /* @__PURE__ */ jsx_runtime36.jsx(PromptInputProvider, {
3560
- children: /* @__PURE__ */ jsx_runtime36.jsxs(PromptInput, {
4072
+ return /* @__PURE__ */ jsx_runtime47.jsx(PromptInputProvider, {
4073
+ children: /* @__PURE__ */ jsx_runtime47.jsxs(PromptInput, {
3561
4074
  onSubmit: handleSubmit,
3562
4075
  accept: fileUpload?.accept ?? DEFAULT_ACCEPTED_FILE_TYPES,
3563
4076
  multiple: fileUpload?.multiple ?? true,
@@ -3567,35 +4080,35 @@ function AgnoChatInput({
3567
4080
  dragListenerTarget: dropZoneContainerRef,
3568
4081
  className: cn("w-full", className),
3569
4082
  children: [
3570
- /* @__PURE__ */ jsx_runtime36.jsx(AttachmentHeader, {}),
3571
- /* @__PURE__ */ jsx_runtime36.jsx(PromptInputBody, {
3572
- children: /* @__PURE__ */ jsx_runtime36.jsx(PromptInputTextarea, {
4083
+ /* @__PURE__ */ jsx_runtime47.jsx(AttachmentHeader, {}),
4084
+ /* @__PURE__ */ jsx_runtime47.jsx(PromptInputBody, {
4085
+ children: /* @__PURE__ */ jsx_runtime47.jsx(PromptInputTextarea, {
3573
4086
  placeholder: placeholder || "Type your message... (Enter to send, Shift+Enter for new line)",
3574
4087
  disabled
3575
4088
  })
3576
4089
  }),
3577
- /* @__PURE__ */ jsx_runtime36.jsxs(PromptInputFooter, {
4090
+ /* @__PURE__ */ jsx_runtime47.jsxs(PromptInputFooter, {
3578
4091
  children: [
3579
- /* @__PURE__ */ jsx_runtime36.jsxs(PromptInputTools, {
4092
+ /* @__PURE__ */ jsx_runtime47.jsxs(PromptInputTools, {
3580
4093
  children: [
3581
- showAttachments && /* @__PURE__ */ jsx_runtime36.jsxs(PromptInputActionMenu, {
4094
+ showAttachments && /* @__PURE__ */ jsx_runtime47.jsxs(PromptInputActionMenu, {
3582
4095
  children: [
3583
- /* @__PURE__ */ jsx_runtime36.jsx(PromptInputActionMenuTrigger, {}),
3584
- /* @__PURE__ */ jsx_runtime36.jsx(PromptInputActionMenuContent, {
3585
- children: /* @__PURE__ */ jsx_runtime36.jsx(PromptInputActionAddAttachments, {
4096
+ /* @__PURE__ */ jsx_runtime47.jsx(PromptInputActionMenuTrigger, {}),
4097
+ /* @__PURE__ */ jsx_runtime47.jsx(PromptInputActionMenuContent, {
4098
+ children: /* @__PURE__ */ jsx_runtime47.jsx(PromptInputActionAddAttachments, {
3586
4099
  label: "Add files"
3587
4100
  })
3588
4101
  })
3589
4102
  ]
3590
4103
  }),
3591
- audioEnabled && (audioMode === "transcribe" && resolvedAudio?.endpoint ? /* @__PURE__ */ jsx_runtime36.jsx(TranscribeAudioRecorder, {
4104
+ audioEnabled && (audioMode === "transcribe" && resolvedAudio?.endpoint ? /* @__PURE__ */ jsx_runtime47.jsx(TranscribeAudioRecorder, {
3592
4105
  endpoint: resolvedAudio.endpoint,
3593
4106
  headers: resolvedAudio.headers,
3594
4107
  disabled,
3595
4108
  parseResponse: resolvedAudio.parseResponse,
3596
4109
  onRequestPermission: resolvedAudio.requestPermission,
3597
4110
  labels: resolvedAudio.labels
3598
- }) : /* @__PURE__ */ jsx_runtime36.jsx(AudioRecorder, {
4111
+ }) : /* @__PURE__ */ jsx_runtime47.jsx(AudioRecorder, {
3599
4112
  onRecordingComplete: handleAudioRecording,
3600
4113
  disabled,
3601
4114
  onRequestPermission: resolvedAudio?.requestPermission,
@@ -3604,15 +4117,15 @@ function AgnoChatInput({
3604
4117
  extraTools
3605
4118
  ]
3606
4119
  }),
3607
- showCancelButton ? /* @__PURE__ */ jsx_runtime36.jsx(CancelButton, {
4120
+ showCancelButton ? /* @__PURE__ */ jsx_runtime47.jsx(CancelButton, {
3608
4121
  onCancel
3609
- }) : /* @__PURE__ */ jsx_runtime36.jsx(SubmitButton, {
4122
+ }) : /* @__PURE__ */ jsx_runtime47.jsx(SubmitButton, {
3610
4123
  disabled,
3611
4124
  status: computedStatus
3612
4125
  })
3613
4126
  ]
3614
4127
  }),
3615
- showAttachments && /* @__PURE__ */ jsx_runtime36.jsx(PromptInputDropZone, {
4128
+ showAttachments && /* @__PURE__ */ jsx_runtime47.jsx(PromptInputDropZone, {
3616
4129
  ...dropZoneProps,
3617
4130
  container: dropZoneContainerRef
3618
4131
  })
@@ -3620,39 +4133,46 @@ function AgnoChatInput({
3620
4133
  })
3621
4134
  });
3622
4135
  }
3623
- // src/ui/composed/agno-chat/agno-chat.tsx
3624
- var import_react16 = require("react");
3625
- var import_agno_react2 = require("@rodrigocoliveira/agno-react");
3626
-
3627
- // src/ui/composed/agno-chat/context.ts
3628
- var import_react15 = require("react");
3629
- var AgnoChatContext = import_react15.createContext(null);
3630
- function useAgnoChatContext() {
3631
- const ctx = import_react15.useContext(AgnoChatContext);
3632
- if (!ctx) {
3633
- throw new Error("useAgnoChatContext must be used within an <AgnoChat> provider. " + "Wrap your component tree with <AgnoChat>.");
3634
- }
3635
- return ctx;
4136
+ // src/ui/composed/agno-chat/render-tool.ts
4137
+ function byToolName(map, fallback) {
4138
+ return (tool, args) => {
4139
+ if (!Object.prototype.hasOwnProperty.call(map, tool.tool_name)) {
4140
+ return fallback ? fallback(tool, args) : args.defaultRender();
4141
+ }
4142
+ const entry = map[tool.tool_name];
4143
+ if (entry === false)
4144
+ return null;
4145
+ return entry(tool, args);
4146
+ };
3636
4147
  }
3637
-
3638
4148
  // src/ui/composed/agno-chat/agno-chat.tsx
3639
- var jsx_runtime37 = require("react/jsx-runtime");
4149
+ var import_react21 = require("react");
4150
+ var import_agno_react = require("@rodrigocoliveira/agno-react");
4151
+ var jsx_runtime48 = require("react/jsx-runtime");
4152
+ function resolveDebug(debug) {
4153
+ if (typeof debug === "boolean")
4154
+ return debug;
4155
+ return typeof process !== "undefined" && process.env?.NODE_ENV === "development";
4156
+ }
3640
4157
  function AgnoChatRoot({
3641
4158
  children,
3642
4159
  toolHandlers = {},
3643
4160
  autoExecuteTools = true,
3644
- toolResultRenderers,
4161
+ renderTool,
4162
+ debug,
4163
+ skipHydration,
3645
4164
  className,
3646
4165
  ...divProps
3647
4166
  }) {
3648
- const chat = import_agno_react2.useAgnoChat();
3649
- const toolExec = import_agno_react2.useAgnoToolExecution(toolHandlers, autoExecuteTools, {
3650
- skipHydration: toolResultRenderers ? Object.keys(toolResultRenderers) : undefined
4167
+ const chat = import_agno_react.useAgnoChat();
4168
+ const toolExec = import_agno_react.useAgnoToolExecution(toolHandlers, autoExecuteTools, {
4169
+ skipHydration
3651
4170
  });
3652
- const containerRef = import_react16.useRef(null);
3653
- const sendRef = import_react16.useRef(chat.sendMessage);
4171
+ const containerRef = import_react21.useRef(null);
4172
+ const isDebug = resolveDebug(debug);
4173
+ const sendRef = import_react21.useRef(chat.sendMessage);
3654
4174
  sendRef.current = chat.sendMessage;
3655
- const handleSend = import_react16.useCallback(async (message) => {
4175
+ const handleSend = import_react21.useCallback(async (message) => {
3656
4176
  try {
3657
4177
  await sendRef.current(message);
3658
4178
  } catch {}
@@ -3678,7 +4198,7 @@ function AgnoChatRoot({
3678
4198
  continueWithResults,
3679
4199
  executionError
3680
4200
  } = toolExec;
3681
- const contextValue = import_react16.useMemo(() => ({
4201
+ const contextValue = import_react21.useMemo(() => ({
3682
4202
  messages,
3683
4203
  sendMessage,
3684
4204
  clearMessages,
@@ -3699,7 +4219,8 @@ function AgnoChatRoot({
3699
4219
  handleSend,
3700
4220
  inputDisabled: isStreaming || isPaused,
3701
4221
  dropZoneContainerRef: containerRef,
3702
- toolResultRenderers
4222
+ renderTool,
4223
+ isDebug
3703
4224
  }), [
3704
4225
  messages,
3705
4226
  sendMessage,
@@ -3719,11 +4240,12 @@ function AgnoChatRoot({
3719
4240
  continueWithResults,
3720
4241
  executionError,
3721
4242
  handleSend,
3722
- toolResultRenderers
4243
+ renderTool,
4244
+ isDebug
3723
4245
  ]);
3724
- return /* @__PURE__ */ jsx_runtime37.jsx(AgnoChatContext.Provider, {
4246
+ return /* @__PURE__ */ jsx_runtime48.jsx(AgnoChatContext.Provider, {
3725
4247
  value: contextValue,
3726
- children: /* @__PURE__ */ jsx_runtime37.jsx("div", {
4248
+ children: /* @__PURE__ */ jsx_runtime48.jsx("div", {
3727
4249
  ref: containerRef,
3728
4250
  className: cn("relative h-full flex flex-col", className),
3729
4251
  ...divProps,
@@ -3733,25 +4255,25 @@ function AgnoChatRoot({
3733
4255
  }
3734
4256
 
3735
4257
  // src/ui/composed/agno-chat/messages.tsx
3736
- var import_react17 = require("react");
4258
+ var import_react22 = require("react");
3737
4259
 
3738
4260
  // src/ui/composed/agno-chat/suggested-prompts.tsx
3739
- var jsx_runtime38 = require("react/jsx-runtime");
4261
+ var jsx_runtime49 = require("react/jsx-runtime");
3740
4262
  function AgnoChatSuggestedPrompts({ className, prompts }) {
3741
4263
  const { handleSend } = useAgnoChatContext();
3742
4264
  if (prompts.length === 0)
3743
4265
  return null;
3744
- return /* @__PURE__ */ jsx_runtime38.jsx("div", {
4266
+ return /* @__PURE__ */ jsx_runtime49.jsx("div", {
3745
4267
  className: cn("grid grid-cols-2 gap-2 w-full max-w-md", className),
3746
- children: prompts.map((prompt, idx) => /* @__PURE__ */ jsx_runtime38.jsxs("button", {
4268
+ children: prompts.map((prompt, idx) => /* @__PURE__ */ jsx_runtime49.jsxs("button", {
3747
4269
  onClick: () => handleSend(prompt.text),
3748
4270
  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",
3749
4271
  children: [
3750
- prompt.icon && /* @__PURE__ */ jsx_runtime38.jsx("span", {
4272
+ prompt.icon && /* @__PURE__ */ jsx_runtime49.jsx("span", {
3751
4273
  className: "text-muted-foreground group-hover:text-primary transition-colors",
3752
4274
  children: prompt.icon
3753
4275
  }),
3754
- /* @__PURE__ */ jsx_runtime38.jsx("span", {
4276
+ /* @__PURE__ */ jsx_runtime49.jsx("span", {
3755
4277
  className: "text-muted-foreground group-hover:text-foreground transition-colors text-xs leading-snug",
3756
4278
  children: prompt.text
3757
4279
  })
@@ -3761,12 +4283,12 @@ function AgnoChatSuggestedPrompts({ className, prompts }) {
3761
4283
  }
3762
4284
 
3763
4285
  // src/ui/composed/agno-chat/messages.tsx
3764
- var import_lucide_react21 = require("lucide-react");
3765
- var jsx_runtime39 = require("react/jsx-runtime");
4286
+ var import_lucide_react25 = require("lucide-react");
4287
+ var jsx_runtime50 = require("react/jsx-runtime");
3766
4288
  function ScrollOnNewUserMessage({ messageCount }) {
3767
4289
  const { scrollToBottom } = import_use_stick_to_bottom2.useStickToBottomContext();
3768
- const prevCount = import_react17.useRef(messageCount);
3769
- import_react17.useEffect(() => {
4290
+ const prevCount = import_react22.useRef(messageCount);
4291
+ import_react22.useEffect(() => {
3770
4292
  if (messageCount > prevCount.current) {
3771
4293
  scrollToBottom("smooth");
3772
4294
  }
@@ -3786,13 +4308,8 @@ function AgnoChatMessages({
3786
4308
  showReasoning,
3787
4309
  showReferences,
3788
4310
  showTimestamp,
3789
- showGenerativeUI,
3790
- showToolCalls,
3791
4311
  showFilePreview,
3792
4312
  showImageLightbox,
3793
- renderToolCall,
3794
- renderContent,
3795
- renderMedia,
3796
4313
  formatTimestamp,
3797
4314
  messageClassNames,
3798
4315
  emptyState,
@@ -3800,12 +4317,28 @@ function AgnoChatMessages({
3800
4317
  children,
3801
4318
  showThinkingIndicator = true,
3802
4319
  renderThinkingIndicator,
3803
- toolResultRenderers: propToolResultRenderers
4320
+ renderTool: propRenderTool,
4321
+ scrollBehavior,
4322
+ scrollToBottomButton
3804
4323
  }) {
3805
- const { messages, isStreaming, toolResultRenderers: contextToolResultRenderers } = useAgnoChatContext();
3806
- const toolResultRenderers = propToolResultRenderers ?? contextToolResultRenderers;
4324
+ const { messages, isStreaming } = useAgnoChatContext();
3807
4325
  const lastMessage = messages[messages.length - 1];
3808
4326
  const isThinking = showThinkingIndicator && isStreaming && (!lastMessage || lastMessage.role !== "user") && !lastMessage?.content;
4327
+ const resolvedScrollButton = (() => {
4328
+ if (scrollToBottomButton === false)
4329
+ return null;
4330
+ if (scrollToBottomButton === undefined || scrollToBottomButton === true) {
4331
+ return /* @__PURE__ */ jsx_runtime50.jsx(ConversationScrollButton, {});
4332
+ }
4333
+ if (import_react22.isValidElement(scrollToBottomButton))
4334
+ return scrollToBottomButton;
4335
+ if (typeof scrollToBottomButton === "object" && scrollToBottomButton !== null && "className" in scrollToBottomButton) {
4336
+ return /* @__PURE__ */ jsx_runtime50.jsx(ConversationScrollButton, {
4337
+ className: scrollToBottomButton.className
4338
+ });
4339
+ }
4340
+ return scrollToBottomButton;
4341
+ })();
3809
4342
  let lastAssistantIndex = -1;
3810
4343
  for (let i = messages.length - 1;i >= 0; i--) {
3811
4344
  if (messages[i].role !== "user") {
@@ -3817,70 +4350,66 @@ function AgnoChatMessages({
3817
4350
  ...showReasoning !== undefined && { showReasoning },
3818
4351
  ...showReferences !== undefined && { showReferences },
3819
4352
  ...showTimestamp !== undefined && { showTimestamp },
3820
- ...showGenerativeUI !== undefined && { showGenerativeUI },
3821
- ...showToolCalls !== undefined && { showToolCalls },
3822
4353
  ...showFilePreview !== undefined && { showFilePreview },
3823
4354
  ...showImageLightbox !== undefined && { showImageLightbox },
3824
- ...renderToolCall !== undefined && { renderToolCall },
3825
- ...renderContent !== undefined && { renderContent },
3826
- ...renderMedia !== undefined && { renderMedia },
3827
4355
  ...formatTimestamp !== undefined && { formatTimestamp },
3828
4356
  ...messageClassNames !== undefined && { classNames: messageClassNames },
3829
- ...toolResultRenderers !== undefined && { toolResultRenderers }
4357
+ ...propRenderTool !== undefined && { renderTool: propRenderTool }
3830
4358
  };
3831
- const resolvedEmptyState = children ?? emptyState ?? /* @__PURE__ */ jsx_runtime39.jsxs("div", {
4359
+ const resolvedEmptyState = children ?? emptyState ?? /* @__PURE__ */ jsx_runtime50.jsxs("div", {
3832
4360
  className: "flex flex-col items-center gap-6",
3833
4361
  children: [
3834
- /* @__PURE__ */ jsx_runtime39.jsxs("div", {
4362
+ /* @__PURE__ */ jsx_runtime50.jsxs("div", {
3835
4363
  className: "relative",
3836
4364
  children: [
3837
- /* @__PURE__ */ jsx_runtime39.jsx("div", {
4365
+ /* @__PURE__ */ jsx_runtime50.jsx("div", {
3838
4366
  className: "h-16 w-16 rounded-2xl bg-primary/10 flex items-center justify-center",
3839
- children: /* @__PURE__ */ jsx_runtime39.jsx(import_lucide_react21.Bot, {
4367
+ children: /* @__PURE__ */ jsx_runtime50.jsx(import_lucide_react25.Bot, {
3840
4368
  className: "h-8 w-8 text-primary"
3841
4369
  })
3842
4370
  }),
3843
- /* @__PURE__ */ jsx_runtime39.jsx("div", {
4371
+ /* @__PURE__ */ jsx_runtime50.jsx("div", {
3844
4372
  className: "absolute -bottom-1 -right-1 h-5 w-5 rounded-full bg-green-500 border-2 border-background flex items-center justify-center",
3845
- children: /* @__PURE__ */ jsx_runtime39.jsx("span", {
4373
+ children: /* @__PURE__ */ jsx_runtime50.jsx("span", {
3846
4374
  className: "h-2 w-2 rounded-full bg-white animate-pulse"
3847
4375
  })
3848
4376
  })
3849
4377
  ]
3850
4378
  }),
3851
- /* @__PURE__ */ jsx_runtime39.jsxs("div", {
4379
+ /* @__PURE__ */ jsx_runtime50.jsxs("div", {
3852
4380
  className: "space-y-2 text-center",
3853
4381
  children: [
3854
- /* @__PURE__ */ jsx_runtime39.jsx("h3", {
4382
+ /* @__PURE__ */ jsx_runtime50.jsx("h3", {
3855
4383
  className: "text-xl font-semibold tracking-tight",
3856
4384
  children: "Welcome to Agno Chat"
3857
4385
  }),
3858
- /* @__PURE__ */ jsx_runtime39.jsx("p", {
4386
+ /* @__PURE__ */ jsx_runtime50.jsx("p", {
3859
4387
  className: "text-muted-foreground text-sm max-w-sm",
3860
4388
  children: "Start a conversation with your AI agent. Ask questions, explore ideas, or run tools."
3861
4389
  })
3862
4390
  ]
3863
4391
  }),
3864
- suggestedPrompts.length > 0 && /* @__PURE__ */ jsx_runtime39.jsx(AgnoChatSuggestedPrompts, {
4392
+ suggestedPrompts.length > 0 && /* @__PURE__ */ jsx_runtime50.jsx(AgnoChatSuggestedPrompts, {
3865
4393
  prompts: suggestedPrompts
3866
4394
  })
3867
4395
  ]
3868
4396
  });
3869
- return /* @__PURE__ */ jsx_runtime39.jsxs(Conversation, {
4397
+ return /* @__PURE__ */ jsx_runtime50.jsxs(Conversation, {
3870
4398
  className: cn("relative flex-1 w-full", className),
4399
+ scrollBehavior,
3871
4400
  children: [
3872
- /* @__PURE__ */ jsx_runtime39.jsx(ScrollOnNewUserMessage, {
4401
+ /* @__PURE__ */ jsx_runtime50.jsx(ScrollOnNewUserMessage, {
3873
4402
  messageCount: messages.length
3874
4403
  }),
3875
- /* @__PURE__ */ jsx_runtime39.jsxs(ConversationContent, {
4404
+ /* @__PURE__ */ jsx_runtime50.jsxs(ConversationContent, {
3876
4405
  className: "max-w-3xl mx-auto",
3877
4406
  children: [
3878
- messages.length === 0 ? /* @__PURE__ */ jsx_runtime39.jsx(ConversationEmptyState, {
4407
+ messages.length === 0 ? /* @__PURE__ */ jsx_runtime50.jsx(ConversationEmptyState, {
3879
4408
  children: resolvedEmptyState
3880
4409
  }) : messages.map((message, index) => {
3881
4410
  if (isThinking && index === messages.length - 1 && message === lastMessage)
3882
4411
  return null;
3883
- return renderMessage ? renderMessage(message, index) : /* @__PURE__ */ jsx_runtime39.jsx(AgnoMessageItem, {
4412
+ return renderMessage ? renderMessage(message, index) : /* @__PURE__ */ jsx_runtime50.jsx(AgnoMessageItem, {
3884
4413
  message,
3885
4414
  avatars,
3886
4415
  actions,
@@ -3888,23 +4417,23 @@ function AgnoChatMessages({
3888
4417
  ...messageItemProps
3889
4418
  }, `msg-${index}-${message.created_at}`);
3890
4419
  }),
3891
- isThinking && /* @__PURE__ */ jsx_runtime39.jsx("div", {
4420
+ isThinking && /* @__PURE__ */ jsx_runtime50.jsx("div", {
3892
4421
  className: "py-2",
3893
- children: renderThinkingIndicator ?? /* @__PURE__ */ jsx_runtime39.jsx(StreamingIndicator, {
4422
+ children: renderThinkingIndicator ?? /* @__PURE__ */ jsx_runtime50.jsx(StreamingIndicator, {
3894
4423
  avatar: avatars?.assistant
3895
4424
  })
3896
4425
  })
3897
4426
  ]
3898
4427
  }),
3899
- /* @__PURE__ */ jsx_runtime39.jsx(ConversationScrollButton, {})
4428
+ resolvedScrollButton
3900
4429
  ]
3901
4430
  });
3902
4431
  }
3903
4432
 
3904
4433
  // src/ui/composed/agno-chat/empty-state.tsx
3905
- var jsx_runtime40 = require("react/jsx-runtime");
4434
+ var jsx_runtime51 = require("react/jsx-runtime");
3906
4435
  function AgnoChatEmptyState({ children, className, ...props }) {
3907
- return /* @__PURE__ */ jsx_runtime40.jsx("div", {
4436
+ return /* @__PURE__ */ jsx_runtime51.jsx("div", {
3908
4437
  className: cn("flex flex-col items-center gap-6", className),
3909
4438
  ...props,
3910
4439
  children
@@ -3912,8 +4441,8 @@ function AgnoChatEmptyState({ children, className, ...props }) {
3912
4441
  }
3913
4442
 
3914
4443
  // src/ui/composed/agno-chat/error-bar.tsx
3915
- var import_react18 = require("react");
3916
- var jsx_runtime41 = require("react/jsx-runtime");
4444
+ var import_react23 = require("react");
4445
+ var jsx_runtime52 = require("react/jsx-runtime");
3917
4446
  function AgnoChatErrorBar({
3918
4447
  className,
3919
4448
  text,
@@ -3923,10 +4452,10 @@ function AgnoChatErrorBar({
3923
4452
  children
3924
4453
  }) {
3925
4454
  const { error, executionError } = useAgnoChatContext();
3926
- const [hidden, setHidden] = import_react18.useState(false);
3927
- const timerRef = import_react18.useRef(null);
4455
+ const [hidden, setHidden] = import_react23.useState(false);
4456
+ const timerRef = import_react23.useRef(null);
3928
4457
  const rawMessage = error || executionError;
3929
- import_react18.useEffect(() => {
4458
+ import_react23.useEffect(() => {
3930
4459
  if (!rawMessage)
3931
4460
  return;
3932
4461
  setHidden(false);
@@ -3953,23 +4482,23 @@ function AgnoChatErrorBar({
3953
4482
  if (children) {
3954
4483
  return typeof children === "function" ? children(rawMessage) : children;
3955
4484
  }
3956
- return /* @__PURE__ */ jsx_runtime41.jsxs("div", {
4485
+ return /* @__PURE__ */ jsx_runtime52.jsxs("div", {
3957
4486
  className: "flex items-center gap-2 max-w-3xl mx-auto",
3958
4487
  children: [
3959
- icon && /* @__PURE__ */ jsx_runtime41.jsx("span", {
4488
+ icon && /* @__PURE__ */ jsx_runtime52.jsx("span", {
3960
4489
  className: "shrink-0",
3961
4490
  children: icon
3962
4491
  }),
3963
- /* @__PURE__ */ jsx_runtime41.jsx("p", {
4492
+ /* @__PURE__ */ jsx_runtime52.jsx("p", {
3964
4493
  className: "text-sm text-destructive flex-1",
3965
4494
  children: displayMessage
3966
4495
  }),
3967
- dismissible && /* @__PURE__ */ jsx_runtime41.jsx("button", {
4496
+ dismissible && /* @__PURE__ */ jsx_runtime52.jsx("button", {
3968
4497
  type: "button",
3969
4498
  onClick: () => setHidden(true),
3970
4499
  className: "shrink-0 text-destructive/60 hover:text-destructive transition-colors",
3971
4500
  "aria-label": "Dismiss error",
3972
- children: /* @__PURE__ */ jsx_runtime41.jsxs("svg", {
4501
+ children: /* @__PURE__ */ jsx_runtime52.jsxs("svg", {
3973
4502
  xmlns: "http://www.w3.org/2000/svg",
3974
4503
  width: "16",
3975
4504
  height: "16",
@@ -3980,10 +4509,10 @@ function AgnoChatErrorBar({
3980
4509
  strokeLinecap: "round",
3981
4510
  strokeLinejoin: "round",
3982
4511
  children: [
3983
- /* @__PURE__ */ jsx_runtime41.jsx("path", {
4512
+ /* @__PURE__ */ jsx_runtime52.jsx("path", {
3984
4513
  d: "M18 6 6 18"
3985
4514
  }),
3986
- /* @__PURE__ */ jsx_runtime41.jsx("path", {
4515
+ /* @__PURE__ */ jsx_runtime52.jsx("path", {
3987
4516
  d: "m6 6 12 12"
3988
4517
  })
3989
4518
  ]
@@ -3992,14 +4521,14 @@ function AgnoChatErrorBar({
3992
4521
  ]
3993
4522
  });
3994
4523
  };
3995
- return /* @__PURE__ */ jsx_runtime41.jsx("div", {
4524
+ return /* @__PURE__ */ jsx_runtime52.jsx("div", {
3996
4525
  className: cn("px-4 py-2.5 bg-destructive/5 border-t border-destructive/20", className),
3997
4526
  children: renderContent()
3998
4527
  });
3999
4528
  }
4000
4529
 
4001
4530
  // src/ui/composed/agno-chat/input.tsx
4002
- var jsx_runtime42 = require("react/jsx-runtime");
4531
+ var jsx_runtime53 = require("react/jsx-runtime");
4003
4532
  function AgnoChatInputArea({
4004
4533
  className,
4005
4534
  children,
@@ -4012,11 +4541,11 @@ function AgnoChatInputArea({
4012
4541
  dropZoneProps
4013
4542
  }) {
4014
4543
  const { handleSend, inputDisabled, isStreaming, isPaused, cancelRun, dropZoneContainerRef } = useAgnoChatContext();
4015
- return /* @__PURE__ */ jsx_runtime42.jsx("div", {
4544
+ return /* @__PURE__ */ jsx_runtime53.jsx("div", {
4016
4545
  className: cn("border-t border-border bg-background/80 backdrop-blur-sm", className),
4017
- children: /* @__PURE__ */ jsx_runtime42.jsx("div", {
4546
+ children: /* @__PURE__ */ jsx_runtime53.jsx("div", {
4018
4547
  className: "mx-auto px-4 py-2",
4019
- children: children ? children({ onSend: handleSend, disabled: inputDisabled, isStreaming, isPaused }) : /* @__PURE__ */ jsx_runtime42.jsx(AgnoChatInput, {
4548
+ children: children ? children({ onSend: handleSend, disabled: inputDisabled, isStreaming, isPaused }) : /* @__PURE__ */ jsx_runtime53.jsx(AgnoChatInput, {
4020
4549
  onSend: handleSend,
4021
4550
  disabled: inputDisabled,
4022
4551
  isStreaming,
@@ -4043,4 +4572,4 @@ var AgnoChat = Object.assign(AgnoChatRoot, {
4043
4572
  Input: AgnoChatInputArea
4044
4573
  });
4045
4574
 
4046
- //# debugId=7D6444DACC443C3D64756E2164756E21
4575
+ //# debugId=7C378B0E1199C3A164756E2164756E21