@rodrigocoliveira/agno-react 1.4.0 → 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 (49) 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/composed/AgnoMessageItem.d.ts +12 -24
  9. package/dist/ui/composed/AgnoMessageItem.d.ts.map +1 -1
  10. package/dist/ui/composed/agno-chat/agno-chat.d.ts +23 -3
  11. package/dist/ui/composed/agno-chat/agno-chat.d.ts.map +1 -1
  12. package/dist/ui/composed/agno-chat/context.d.ts +4 -3
  13. package/dist/ui/composed/agno-chat/context.d.ts.map +1 -1
  14. package/dist/ui/composed/agno-chat/messages.d.ts +9 -15
  15. package/dist/ui/composed/agno-chat/messages.d.ts.map +1 -1
  16. package/dist/ui/composed/agno-chat/render-tool.d.ts +11 -0
  17. package/dist/ui/composed/agno-chat/render-tool.d.ts.map +1 -0
  18. package/dist/ui/composed/agno-chat/tool-building-blocks.d.ts +11 -0
  19. package/dist/ui/composed/agno-chat/tool-building-blocks.d.ts.map +1 -0
  20. package/dist/ui/composed/agno-message/content.d.ts +2 -0
  21. package/dist/ui/composed/agno-message/content.d.ts.map +1 -0
  22. package/dist/ui/composed/agno-message/context.d.ts +21 -0
  23. package/dist/ui/composed/agno-message/context.d.ts.map +1 -0
  24. package/dist/ui/composed/agno-message/footer.d.ts +6 -0
  25. package/dist/ui/composed/agno-message/footer.d.ts.map +1 -0
  26. package/dist/ui/composed/agno-message/index.d.ts +13 -0
  27. package/dist/ui/composed/agno-message/index.d.ts.map +1 -0
  28. package/dist/ui/composed/agno-message/media.d.ts +2 -0
  29. package/dist/ui/composed/agno-message/media.d.ts.map +1 -0
  30. package/dist/ui/composed/agno-message/message.d.ts +41 -0
  31. package/dist/ui/composed/agno-message/message.d.ts.map +1 -0
  32. package/dist/ui/composed/agno-message/reasoning.d.ts +2 -0
  33. package/dist/ui/composed/agno-message/reasoning.d.ts.map +1 -0
  34. package/dist/ui/composed/agno-message/references.d.ts +2 -0
  35. package/dist/ui/composed/agno-message/references.d.ts.map +1 -0
  36. package/dist/ui/composed/agno-message/tools.d.ts +7 -0
  37. package/dist/ui/composed/agno-message/tools.d.ts.map +1 -0
  38. package/dist/ui/composed/index.d.ts +6 -0
  39. package/dist/ui/composed/index.d.ts.map +1 -1
  40. package/dist/ui/index.d.ts +6 -0
  41. package/dist/ui/index.d.ts.map +1 -1
  42. package/dist/ui/primitives/badge.d.ts +1 -1
  43. package/dist/ui/primitives/button.d.ts +1 -1
  44. package/dist/ui/primitives/command.d.ts +1 -1
  45. package/dist/ui.js +1146 -643
  46. package/dist/ui.js.map +22 -7
  47. package/dist/ui.mjs +1139 -645
  48. package/dist/ui.mjs.map +22 -7
  49. 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,
@@ -2873,573 +2885,1066 @@ var PromptInputCommandSeparator = ({ className, ...props }) => /* @__PURE__ */ j
2873
2885
  className: cn(className),
2874
2886
  ...props
2875
2887
  });
2876
- // 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
2877
2893
  var import_react14 = require("react");
2878
- 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
2879
2904
  var import_lucide_react19 = require("lucide-react");
2880
2905
  var jsx_runtime35 = require("react/jsx-runtime");
2881
- var defaultFormatTimestamp = formatSmartTimestamp;
2882
- var getToolState = (tool) => {
2883
- return tool.tool_call_error ? "output-error" : "output-available";
2884
- };
2885
- 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({
2886
3710
  message,
2887
3711
  className,
2888
3712
  classNames,
2889
- renderContent,
2890
- renderToolCall,
2891
- renderMedia,
2892
3713
  avatars,
2893
3714
  actions,
2894
3715
  isLastAssistantMessage = false,
2895
- showReasoning = true,
2896
- showReferences = true,
2897
- showTimestamp = true,
2898
- showGenerativeUI = true,
2899
- showToolCalls = true,
2900
3716
  showFilePreview = true,
2901
3717
  showImageLightbox = true,
3718
+ showTimestamp = true,
2902
3719
  formatTimestamp,
2903
- toolResultRenderers
3720
+ renderTool,
3721
+ children
2904
3722
  }) {
2905
3723
  const isUser = message.role === "user";
2906
3724
  const hasError = message.streamingError;
2907
- const toolsWithUI = message.tool_calls?.filter((tool) => tool.ui_component) || [];
2908
- const [preview, setPreview] = import_react14.useState(null);
3725
+ const [preview, setPreview] = import_react20.useState(null);
2909
3726
  const isCustomTimestamp = !!formatTimestamp;
2910
- const resolvedFormatTimestamp = formatTimestamp ?? defaultFormatTimestamp;
2911
- const openImageLightbox = (images, index) => {
2912
- if (!showImageLightbox)
2913
- return;
2914
- setPreview({ type: "image", images, initialIndex: index });
2915
- };
2916
- const openFilePreview = (file) => {
2917
- if (!showFilePreview)
2918
- return;
2919
- setPreview({ type: "file", file });
2920
- };
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
+ ]);
2921
3759
  const closePreview = () => setPreview(null);
2922
- return /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2923
- 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",
2924
3833
  children: [
2925
- isUser ? /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2926
- 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",
2927
3837
  children: [
2928
- avatars?.user,
2929
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2930
- 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",
2931
3840
  children: [
2932
- (message.images && message.images.length > 0 || message.audio && message.audio.length > 0 || message.files && message.files.length > 0) && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2933
- className: "flex flex-wrap gap-2 justify-end",
2934
- children: [
2935
- message.images?.map((img, idx) => /* @__PURE__ */ jsx_runtime35.jsx(FilePreviewCard, {
2936
- file: { name: img.revised_prompt || `Image ${idx + 1}`, type: "image/png", url: img.url },
2937
- onClick: showImageLightbox ? () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx) : undefined
2938
- }, `img-${idx}`)),
2939
- message.audio?.map((audio, idx) => /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2940
- 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",
2941
- children: [
2942
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Music, {
2943
- className: "h-3.5 w-3.5 text-muted-foreground"
2944
- }),
2945
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
2946
- className: "truncate max-w-[150px]",
2947
- children: audio.id || `Audio ${idx + 1}`
2948
- })
2949
- ]
2950
- }, `audio-${idx}`)),
2951
- message.files?.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx_runtime35.jsx(FilePreviewCard, {
2952
- file: { name: file.name, type: file.type, url: file.url, size: file.size },
2953
- onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
2954
- }, `file-${idx}`) : /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2955
- 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",
2956
- children: [
2957
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.FileIcon, {
2958
- className: "h-3.5 w-3.5 text-muted-foreground"
2959
- }),
2960
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
2961
- className: "truncate max-w-[150px]",
2962
- children: file.name
2963
- })
2964
- ]
2965
- }, `file-${idx}`))
2966
- ]
2967
- }),
2968
- message.content && /* @__PURE__ */ jsx_runtime35.jsx("div", {
2969
- className: cn("rounded-2xl rounded-br-md px-4 py-2.5", classNames?.user?.bubble ?? "bg-primary text-primary-foreground", hasError && "opacity-70"),
2970
- children: /* @__PURE__ */ jsx_runtime35.jsx("p", {
2971
- className: "text-sm whitespace-pre-wrap",
2972
- children: message.content
2973
- })
2974
- }),
2975
- (showTimestamp || actions?.user) && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2976
- 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",
2977
3847
  children: [
2978
- actions?.user && /* @__PURE__ */ jsx_runtime35.jsx("div", {
2979
- className: "flex items-center gap-1",
2980
- children: actions.user(message)
2981
- }),
2982
- /* @__PURE__ */ jsx_runtime35.jsx(SmartTimestamp, {
2983
- date: new Date(message.created_at * 1000),
2984
- formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
2985
- 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"
2986
3850
  }),
2987
- hasError && /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.AlertCircle, {
2988
- 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}`
2989
3854
  })
2990
3855
  ]
2991
- })
2992
- ]
2993
- })
2994
- ]
2995
- }) : /* @__PURE__ */ jsx_runtime35.jsxs("div", {
2996
- className: "flex items-start gap-3 group/message",
2997
- children: [
2998
- avatars?.assistant,
2999
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3000
- className: cn("flex-1 min-w-0 space-y-3", classNames?.assistant?.container),
3001
- children: [
3002
- 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",
3003
3862
  children: [
3004
- showReasoning && message.extra_data?.reasoning_steps && message.extra_data.reasoning_steps.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3005
- className: cn("space-y-2 pt-1", classNames?.assistant?.reasoning),
3006
- children: [
3007
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3008
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3009
- children: [
3010
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Lightbulb, {
3011
- className: "h-3.5 w-3.5"
3012
- }),
3013
- "Reasoning (",
3014
- message.extra_data.reasoning_steps.length,
3015
- " steps)"
3016
- ]
3017
- }),
3018
- /* @__PURE__ */ jsx_runtime35.jsx(Accordion, {
3019
- type: "multiple",
3020
- className: "w-full",
3021
- children: message.extra_data.reasoning_steps.map((step, idx) => /* @__PURE__ */ jsx_runtime35.jsxs(AccordionItem, {
3022
- value: `reasoning-${idx}`,
3023
- className: "border-muted",
3024
- children: [
3025
- /* @__PURE__ */ jsx_runtime35.jsx(AccordionTrigger, {
3026
- className: "text-xs py-1.5 hover:no-underline",
3027
- children: step.title || `Step ${idx + 1}`
3028
- }),
3029
- /* @__PURE__ */ jsx_runtime35.jsxs(AccordionContent, {
3030
- className: "space-y-1.5 text-xs text-muted-foreground",
3031
- children: [
3032
- step.action && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3033
- children: [
3034
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3035
- className: "font-medium text-foreground",
3036
- children: "Action:"
3037
- }),
3038
- " ",
3039
- step.action
3040
- ]
3041
- }),
3042
- step.reasoning && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3043
- children: [
3044
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3045
- className: "font-medium text-foreground",
3046
- children: "Reasoning:"
3047
- }),
3048
- " ",
3049
- step.reasoning
3050
- ]
3051
- }),
3052
- step.result && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3053
- children: [
3054
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3055
- className: "font-medium text-foreground",
3056
- children: "Result:"
3057
- }),
3058
- " ",
3059
- step.result
3060
- ]
3061
- }),
3062
- step.confidence !== undefined && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3063
- children: [
3064
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3065
- className: "font-medium text-foreground",
3066
- children: "Confidence:"
3067
- }),
3068
- " ",
3069
- (step.confidence * 100).toFixed(1),
3070
- "%"
3071
- ]
3072
- })
3073
- ]
3074
- })
3075
- ]
3076
- }, idx))
3077
- })
3078
- ]
3863
+ /* @__PURE__ */ jsx_runtime45.jsx(import_lucide_react23.FileIcon, {
3864
+ className: "h-3.5 w-3.5 text-muted-foreground"
3079
3865
  }),
3080
- message.content && /* @__PURE__ */ jsx_runtime35.jsx("div", {
3081
- 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",
3082
- children: /* @__PURE__ */ jsx_runtime35.jsx(Response, {
3083
- children: message.content
3084
- })
3085
- }),
3086
- showGenerativeUI && toolsWithUI.length > 0 && /* @__PURE__ */ jsx_runtime35.jsx("div", {
3087
- className: "space-y-3",
3088
- children: toolsWithUI.map((tool) => {
3089
- const uiComponent = tool.ui_component;
3090
- return /* @__PURE__ */ jsx_runtime35.jsx("div", {
3091
- children: uiComponent.layout === "artifact" ? /* @__PURE__ */ jsx_runtime35.jsx(Artifact, {
3092
- children: /* @__PURE__ */ jsx_runtime35.jsx(import_agno_react.GenerativeUIRenderer, {
3093
- spec: uiComponent,
3094
- className: "w-full p-2"
3095
- })
3096
- }) : /* @__PURE__ */ jsx_runtime35.jsx(import_agno_react.GenerativeUIRenderer, {
3097
- spec: uiComponent,
3098
- className: "w-full"
3099
- })
3100
- }, tool.tool_call_id);
3101
- })
3102
- }),
3103
- toolResultRenderers && message.tool_calls?.map((tool) => {
3104
- const renderer = toolResultRenderers[tool.tool_name];
3105
- const content = tool.result ?? tool.content;
3106
- if (!renderer || !content)
3107
- return null;
3108
- return /* @__PURE__ */ jsx_runtime35.jsx("div", {
3109
- children: renderer(tool.tool_args, content)
3110
- }, `result-${tool.tool_call_id}`);
3111
- }),
3112
- renderMedia ? renderMedia(message) : (() => {
3113
- const mediaClassName = classNames?.assistant?.media;
3114
- return /* @__PURE__ */ jsx_runtime35.jsxs(jsx_runtime35.Fragment, {
3115
- children: [
3116
- message.images && message.images.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3117
- className: cn("space-y-2 pt-1", mediaClassName),
3118
- children: [
3119
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3120
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3121
- children: [
3122
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Image, {
3123
- className: "h-3.5 w-3.5"
3124
- }),
3125
- "Images (",
3126
- message.images.length,
3127
- ")"
3128
- ]
3129
- }),
3130
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3131
- className: "grid grid-cols-2 gap-2",
3132
- children: message.images.map((img, idx) => /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3133
- className: "space-y-1",
3134
- children: [
3135
- showImageLightbox ? /* @__PURE__ */ jsx_runtime35.jsx("button", {
3136
- type: "button",
3137
- onClick: () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx),
3138
- 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",
3139
- children: /* @__PURE__ */ jsx_runtime35.jsx("img", {
3140
- src: img.url,
3141
- alt: img.revised_prompt || "Generated image",
3142
- className: "w-full rounded-lg"
3143
- })
3144
- }) : /* @__PURE__ */ jsx_runtime35.jsx("img", {
3145
- src: img.url,
3146
- alt: img.revised_prompt || "Generated image",
3147
- className: "w-full rounded-lg border border-border"
3148
- }),
3149
- img.revised_prompt && /* @__PURE__ */ jsx_runtime35.jsx("p", {
3150
- className: "text-[11px] text-muted-foreground italic px-0.5",
3151
- children: img.revised_prompt
3152
- })
3153
- ]
3154
- }, idx))
3155
- })
3156
- ]
3157
- }),
3158
- message.videos && message.videos.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3159
- className: cn("space-y-2 pt-1", mediaClassName),
3160
- children: [
3161
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3162
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3163
- children: [
3164
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Video, {
3165
- className: "h-3.5 w-3.5"
3166
- }),
3167
- "Videos (",
3168
- message.videos.length,
3169
- ")"
3170
- ]
3171
- }),
3172
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3173
- className: "space-y-2",
3174
- children: message.videos.map((video, idx) => /* @__PURE__ */ jsx_runtime35.jsx("div", {
3175
- children: video.url ? /* @__PURE__ */ jsx_runtime35.jsx("video", {
3176
- src: video.url,
3177
- controls: true,
3178
- className: "w-full rounded-lg border border-border"
3179
- }) : /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3180
- className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3181
- children: [
3182
- "Video ID: ",
3183
- video.id,
3184
- " (ETA: ",
3185
- video.eta,
3186
- "s)"
3187
- ]
3188
- })
3189
- }, idx))
3190
- })
3191
- ]
3192
- }),
3193
- message.audio && message.audio.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3194
- className: cn("space-y-2 pt-1", mediaClassName),
3195
- children: [
3196
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3197
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3198
- children: [
3199
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Music, {
3200
- className: "h-3.5 w-3.5"
3201
- }),
3202
- "Audio (",
3203
- message.audio.length,
3204
- ")"
3205
- ]
3206
- }),
3207
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3208
- className: "space-y-2",
3209
- children: message.audio.map((audio, idx) => /* @__PURE__ */ jsx_runtime35.jsx("div", {
3210
- children: audio.url ? /* @__PURE__ */ jsx_runtime35.jsx("audio", {
3211
- src: audio.url,
3212
- controls: true,
3213
- className: "w-full"
3214
- }) : audio.base64_audio ? /* @__PURE__ */ jsx_runtime35.jsx("audio", {
3215
- src: `data:${audio.mime_type || "audio/wav"};base64,${audio.base64_audio}`,
3216
- controls: true,
3217
- className: "w-full"
3218
- }) : /* @__PURE__ */ jsx_runtime35.jsx("div", {
3219
- className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3220
- children: "Audio data unavailable"
3221
- })
3222
- }, idx))
3223
- })
3224
- ]
3225
- }),
3226
- message.files && message.files.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3227
- className: cn("space-y-2 pt-1", mediaClassName),
3228
- children: [
3229
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3230
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3231
- children: [
3232
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Paperclip, {
3233
- className: "h-3.5 w-3.5"
3234
- }),
3235
- "Files (",
3236
- message.files.length,
3237
- ")"
3238
- ]
3239
- }),
3240
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3241
- className: "flex flex-wrap gap-2",
3242
- children: message.files.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsx_runtime35.jsx(FilePreviewCard, {
3243
- file: { name: file.name, type: file.type, url: file.url, size: file.size },
3244
- onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
3245
- }, idx) : /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3246
- 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",
3247
- children: [
3248
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.FileIcon, {
3249
- className: "h-3.5 w-3.5 shrink-0 text-muted-foreground"
3250
- }),
3251
- /* @__PURE__ */ jsx_runtime35.jsx("span", {
3252
- className: "truncate max-w-[180px]",
3253
- children: file.name
3254
- }),
3255
- file.size && /* @__PURE__ */ jsx_runtime35.jsxs("span", {
3256
- className: "text-muted-foreground/70",
3257
- children: [
3258
- "(",
3259
- (file.size / 1024).toFixed(1),
3260
- "KB)"
3261
- ]
3262
- }),
3263
- file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsx_runtime35.jsx("a", {
3264
- href: file.url,
3265
- target: "_blank",
3266
- rel: "noopener noreferrer",
3267
- className: "text-primary hover:underline font-medium",
3268
- children: "View"
3269
- })
3270
- ]
3271
- }, idx))
3272
- })
3273
- ]
3274
- }),
3275
- message.response_audio && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3276
- className: cn("space-y-2 pt-1", mediaClassName),
3277
- children: [
3278
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3279
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3280
- children: [
3281
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.Music, {
3282
- className: "h-3.5 w-3.5"
3283
- }),
3284
- "Response Audio"
3285
- ]
3286
- }),
3287
- message.response_audio.transcript && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3288
- className: "text-xs italic bg-muted/50 border border-border p-2.5 rounded-lg text-muted-foreground",
3289
- children: [
3290
- '"',
3291
- message.response_audio.transcript,
3292
- '"'
3293
- ]
3294
- }),
3295
- message.response_audio.content && /* @__PURE__ */ jsx_runtime35.jsx("audio", {
3296
- src: `data:audio/wav;base64,${message.response_audio.content}`,
3297
- controls: true,
3298
- className: "w-full"
3299
- })
3300
- ]
3301
- })
3302
- ]
3303
- });
3304
- })(),
3305
- showToolCalls && message.tool_calls && message.tool_calls.length > 0 && /* @__PURE__ */ jsx_runtime35.jsx("div", {
3306
- className: cn("space-y-2 pt-1", classNames?.assistant?.toolCalls),
3307
- children: message.tool_calls.map((tool, idx) => renderToolCall ? renderToolCall(tool, idx) : /* @__PURE__ */ jsx_runtime35.jsxs(Tool, {
3308
- defaultOpen: idx === 0,
3309
- children: [
3310
- /* @__PURE__ */ jsx_runtime35.jsx(ToolHeader, {
3311
- title: tool.tool_name,
3312
- type: "tool-use",
3313
- state: getToolState(tool)
3314
- }),
3315
- /* @__PURE__ */ jsx_runtime35.jsxs(ToolContent, {
3316
- children: [
3317
- /* @__PURE__ */ jsx_runtime35.jsx(ToolInput, {
3318
- input: tool.tool_args
3319
- }),
3320
- tool.content && /* @__PURE__ */ jsx_runtime35.jsx(ToolOutput, {
3321
- output: tool.content,
3322
- errorText: tool.tool_call_error ? "Tool execution failed" : undefined
3323
- })
3324
- ]
3325
- })
3326
- ]
3327
- }, tool.tool_call_id || idx))
3328
- }),
3329
- showReferences && message.extra_data?.references && message.extra_data.references.length > 0 && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3330
- className: cn("space-y-2 pt-1", classNames?.assistant?.references),
3331
- children: [
3332
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3333
- className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3334
- children: [
3335
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.FileText, {
3336
- className: "h-3.5 w-3.5"
3337
- }),
3338
- "References (",
3339
- message.extra_data.references.length,
3340
- ")"
3341
- ]
3342
- }),
3343
- /* @__PURE__ */ jsx_runtime35.jsx("div", {
3344
- className: "space-y-2",
3345
- children: message.extra_data.references.map((refData, idx) => /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3346
- className: "text-xs space-y-1.5",
3347
- children: [
3348
- refData.query && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3349
- className: "font-medium text-foreground",
3350
- children: [
3351
- "Query: ",
3352
- refData.query
3353
- ]
3354
- }),
3355
- refData.references.map((ref, refIdx) => /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3356
- className: "bg-muted/50 border border-border p-2.5 rounded-lg",
3357
- children: [
3358
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3359
- className: "italic text-muted-foreground mb-1",
3360
- children: [
3361
- '"',
3362
- ref.content,
3363
- '"'
3364
- ]
3365
- }),
3366
- /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3367
- className: "text-muted-foreground/70",
3368
- children: [
3369
- "Source: ",
3370
- ref.name,
3371
- " (chunk ",
3372
- ref.meta_data.chunk,
3373
- "/",
3374
- ref.meta_data.chunk_size,
3375
- ")"
3376
- ]
3377
- })
3378
- ]
3379
- }, refIdx))
3380
- ]
3381
- }, idx))
3382
- })
3383
- ]
3866
+ /* @__PURE__ */ jsx_runtime45.jsx("span", {
3867
+ className: "truncate max-w-[150px]",
3868
+ children: file.name
3384
3869
  })
3385
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)
3386
3887
  }),
3387
- (actions?.assistant || showTimestamp || hasError) && /* @__PURE__ */ jsx_runtime35.jsxs("div", {
3388
- className: "flex items-center gap-2 pt-1",
3389
- children: [
3390
- actions?.assistant && (() => {
3391
- const visibility = actions.visibility ?? "visible";
3392
- if (visibility === "last-assistant" && !isLastAssistantMessage)
3393
- return null;
3394
- const useHover = visibility === "hover" || visibility === "hover-last-visible" && !isLastAssistantMessage;
3395
- return /* @__PURE__ */ jsx_runtime35.jsx("div", {
3396
- className: cn("flex items-center gap-1 transition-opacity", useHover && "opacity-0 group-hover/message:opacity-100", classNames?.assistant?.actions),
3397
- children: actions.assistant(message)
3398
- });
3399
- })(),
3400
- hasError && /* @__PURE__ */ jsx_runtime35.jsxs("span", {
3401
- className: "flex items-center gap-1 text-[11px] text-destructive",
3402
- children: [
3403
- /* @__PURE__ */ jsx_runtime35.jsx(import_lucide_react19.AlertCircle, {
3404
- className: "h-3 w-3"
3405
- }),
3406
- "Error"
3407
- ]
3408
- }),
3409
- showTimestamp && /* @__PURE__ */ jsx_runtime35.jsx(SmartTimestamp, {
3410
- date: new Date(message.created_at * 1000),
3411
- formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
3412
- className: "text-[11px] text-muted-foreground"
3413
- })
3414
- ]
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"
3415
3895
  })
3416
3896
  ]
3417
3897
  })
3418
3898
  ]
3419
- }),
3420
- preview?.type === "image" && /* @__PURE__ */ jsx_runtime35.jsx(ImageLightbox, {
3421
- open: true,
3422
- onOpenChange: (open) => {
3423
- if (!open)
3424
- closePreview();
3425
- },
3426
- images: preview.images,
3427
- initialIndex: preview.initialIndex
3428
- }),
3429
- preview?.type === "file" && /* @__PURE__ */ jsx_runtime35.jsx(FilePreviewModal, {
3430
- open: true,
3431
- onOpenChange: (open) => {
3432
- if (!open)
3433
- closePreview();
3434
- },
3435
- 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
3436
3941
  })
3437
3942
  ]
3438
3943
  });
3439
3944
  }
3440
3945
  // src/ui/composed/AgnoChatInput.tsx
3441
- var import_lucide_react20 = require("lucide-react");
3442
- var jsx_runtime36 = require("react/jsx-runtime");
3946
+ var import_lucide_react24 = require("lucide-react");
3947
+ var jsx_runtime47 = require("react/jsx-runtime");
3443
3948
  var DEFAULT_ACCEPTED_FILE_TYPES = "image/*,audio/*,.pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.ppt,.pptx,.md,.json,.xml";
3444
3949
  function normalizeAudio(audio) {
3445
3950
  if (audio === true)
@@ -3459,14 +3964,14 @@ function dataUrlToBlob(dataUrl) {
3459
3964
  return new Blob([buf], { type: mime });
3460
3965
  }
3461
3966
  function CancelButton({ onCancel }) {
3462
- return /* @__PURE__ */ jsx_runtime36.jsx(Button, {
3967
+ return /* @__PURE__ */ jsx_runtime47.jsx(Button, {
3463
3968
  type: "button",
3464
3969
  variant: "destructive",
3465
3970
  size: "icon",
3466
3971
  className: "h-8 w-8 rounded-lg",
3467
3972
  onClick: onCancel,
3468
3973
  "aria-label": "Stop",
3469
- children: /* @__PURE__ */ jsx_runtime36.jsx(import_lucide_react20.CircleStop, {
3974
+ children: /* @__PURE__ */ jsx_runtime47.jsx(import_lucide_react24.CircleStop, {
3470
3975
  className: "size-4"
3471
3976
  })
3472
3977
  });
@@ -3474,7 +3979,7 @@ function CancelButton({ onCancel }) {
3474
3979
  function SubmitButton({ disabled, status }) {
3475
3980
  const { textInput } = usePromptInputController();
3476
3981
  const hasText = textInput.value.trim().length > 0;
3477
- return /* @__PURE__ */ jsx_runtime36.jsx(PromptInputSubmit, {
3982
+ return /* @__PURE__ */ jsx_runtime47.jsx(PromptInputSubmit, {
3478
3983
  disabled: disabled || !hasText,
3479
3984
  status
3480
3985
  });
@@ -3483,9 +3988,9 @@ function AttachmentHeader() {
3483
3988
  const { files } = usePromptInputAttachments();
3484
3989
  if (files.length === 0)
3485
3990
  return null;
3486
- return /* @__PURE__ */ jsx_runtime36.jsx(PromptInputHeader, {
3487
- children: /* @__PURE__ */ jsx_runtime36.jsx(PromptInputAttachments, {
3488
- 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, {
3489
3994
  data: attachment
3490
3995
  })
3491
3996
  })
@@ -3500,7 +4005,7 @@ function TranscribeAudioRecorder({
3500
4005
  labels
3501
4006
  }) {
3502
4007
  const { textInput } = usePromptInputController();
3503
- return /* @__PURE__ */ jsx_runtime36.jsx(AudioRecorder, {
4008
+ return /* @__PURE__ */ jsx_runtime47.jsx(AudioRecorder, {
3504
4009
  mode: "transcribe",
3505
4010
  transcriptionEndpoint: endpoint,
3506
4011
  transcriptionHeaders: headers,
@@ -3564,8 +4069,8 @@ function AgnoChatInput({
3564
4069
  };
3565
4070
  const computedStatus = status ?? (disabled ? "submitted" : undefined);
3566
4071
  const showCancelButton = allowCancelRun && isStreaming && onCancel;
3567
- return /* @__PURE__ */ jsx_runtime36.jsx(PromptInputProvider, {
3568
- children: /* @__PURE__ */ jsx_runtime36.jsxs(PromptInput, {
4072
+ return /* @__PURE__ */ jsx_runtime47.jsx(PromptInputProvider, {
4073
+ children: /* @__PURE__ */ jsx_runtime47.jsxs(PromptInput, {
3569
4074
  onSubmit: handleSubmit,
3570
4075
  accept: fileUpload?.accept ?? DEFAULT_ACCEPTED_FILE_TYPES,
3571
4076
  multiple: fileUpload?.multiple ?? true,
@@ -3575,35 +4080,35 @@ function AgnoChatInput({
3575
4080
  dragListenerTarget: dropZoneContainerRef,
3576
4081
  className: cn("w-full", className),
3577
4082
  children: [
3578
- /* @__PURE__ */ jsx_runtime36.jsx(AttachmentHeader, {}),
3579
- /* @__PURE__ */ jsx_runtime36.jsx(PromptInputBody, {
3580
- 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, {
3581
4086
  placeholder: placeholder || "Type your message... (Enter to send, Shift+Enter for new line)",
3582
4087
  disabled
3583
4088
  })
3584
4089
  }),
3585
- /* @__PURE__ */ jsx_runtime36.jsxs(PromptInputFooter, {
4090
+ /* @__PURE__ */ jsx_runtime47.jsxs(PromptInputFooter, {
3586
4091
  children: [
3587
- /* @__PURE__ */ jsx_runtime36.jsxs(PromptInputTools, {
4092
+ /* @__PURE__ */ jsx_runtime47.jsxs(PromptInputTools, {
3588
4093
  children: [
3589
- showAttachments && /* @__PURE__ */ jsx_runtime36.jsxs(PromptInputActionMenu, {
4094
+ showAttachments && /* @__PURE__ */ jsx_runtime47.jsxs(PromptInputActionMenu, {
3590
4095
  children: [
3591
- /* @__PURE__ */ jsx_runtime36.jsx(PromptInputActionMenuTrigger, {}),
3592
- /* @__PURE__ */ jsx_runtime36.jsx(PromptInputActionMenuContent, {
3593
- 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, {
3594
4099
  label: "Add files"
3595
4100
  })
3596
4101
  })
3597
4102
  ]
3598
4103
  }),
3599
- audioEnabled && (audioMode === "transcribe" && resolvedAudio?.endpoint ? /* @__PURE__ */ jsx_runtime36.jsx(TranscribeAudioRecorder, {
4104
+ audioEnabled && (audioMode === "transcribe" && resolvedAudio?.endpoint ? /* @__PURE__ */ jsx_runtime47.jsx(TranscribeAudioRecorder, {
3600
4105
  endpoint: resolvedAudio.endpoint,
3601
4106
  headers: resolvedAudio.headers,
3602
4107
  disabled,
3603
4108
  parseResponse: resolvedAudio.parseResponse,
3604
4109
  onRequestPermission: resolvedAudio.requestPermission,
3605
4110
  labels: resolvedAudio.labels
3606
- }) : /* @__PURE__ */ jsx_runtime36.jsx(AudioRecorder, {
4111
+ }) : /* @__PURE__ */ jsx_runtime47.jsx(AudioRecorder, {
3607
4112
  onRecordingComplete: handleAudioRecording,
3608
4113
  disabled,
3609
4114
  onRequestPermission: resolvedAudio?.requestPermission,
@@ -3612,15 +4117,15 @@ function AgnoChatInput({
3612
4117
  extraTools
3613
4118
  ]
3614
4119
  }),
3615
- showCancelButton ? /* @__PURE__ */ jsx_runtime36.jsx(CancelButton, {
4120
+ showCancelButton ? /* @__PURE__ */ jsx_runtime47.jsx(CancelButton, {
3616
4121
  onCancel
3617
- }) : /* @__PURE__ */ jsx_runtime36.jsx(SubmitButton, {
4122
+ }) : /* @__PURE__ */ jsx_runtime47.jsx(SubmitButton, {
3618
4123
  disabled,
3619
4124
  status: computedStatus
3620
4125
  })
3621
4126
  ]
3622
4127
  }),
3623
- showAttachments && /* @__PURE__ */ jsx_runtime36.jsx(PromptInputDropZone, {
4128
+ showAttachments && /* @__PURE__ */ jsx_runtime47.jsx(PromptInputDropZone, {
3624
4129
  ...dropZoneProps,
3625
4130
  container: dropZoneContainerRef
3626
4131
  })
@@ -3628,39 +4133,46 @@ function AgnoChatInput({
3628
4133
  })
3629
4134
  });
3630
4135
  }
3631
- // src/ui/composed/agno-chat/agno-chat.tsx
3632
- var import_react16 = require("react");
3633
- var import_agno_react2 = require("@rodrigocoliveira/agno-react");
3634
-
3635
- // src/ui/composed/agno-chat/context.ts
3636
- var import_react15 = require("react");
3637
- var AgnoChatContext = import_react15.createContext(null);
3638
- function useAgnoChatContext() {
3639
- const ctx = import_react15.useContext(AgnoChatContext);
3640
- if (!ctx) {
3641
- throw new Error("useAgnoChatContext must be used within an <AgnoChat> provider. " + "Wrap your component tree with <AgnoChat>.");
3642
- }
3643
- 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
+ };
3644
4147
  }
3645
-
3646
4148
  // src/ui/composed/agno-chat/agno-chat.tsx
3647
- 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
+ }
3648
4157
  function AgnoChatRoot({
3649
4158
  children,
3650
4159
  toolHandlers = {},
3651
4160
  autoExecuteTools = true,
3652
- toolResultRenderers,
4161
+ renderTool,
4162
+ debug,
4163
+ skipHydration,
3653
4164
  className,
3654
4165
  ...divProps
3655
4166
  }) {
3656
- const chat = import_agno_react2.useAgnoChat();
3657
- const toolExec = import_agno_react2.useAgnoToolExecution(toolHandlers, autoExecuteTools, {
3658
- skipHydration: toolResultRenderers ? Object.keys(toolResultRenderers) : undefined
4167
+ const chat = import_agno_react.useAgnoChat();
4168
+ const toolExec = import_agno_react.useAgnoToolExecution(toolHandlers, autoExecuteTools, {
4169
+ skipHydration
3659
4170
  });
3660
- const containerRef = import_react16.useRef(null);
3661
- 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);
3662
4174
  sendRef.current = chat.sendMessage;
3663
- const handleSend = import_react16.useCallback(async (message) => {
4175
+ const handleSend = import_react21.useCallback(async (message) => {
3664
4176
  try {
3665
4177
  await sendRef.current(message);
3666
4178
  } catch {}
@@ -3686,7 +4198,7 @@ function AgnoChatRoot({
3686
4198
  continueWithResults,
3687
4199
  executionError
3688
4200
  } = toolExec;
3689
- const contextValue = import_react16.useMemo(() => ({
4201
+ const contextValue = import_react21.useMemo(() => ({
3690
4202
  messages,
3691
4203
  sendMessage,
3692
4204
  clearMessages,
@@ -3707,7 +4219,8 @@ function AgnoChatRoot({
3707
4219
  handleSend,
3708
4220
  inputDisabled: isStreaming || isPaused,
3709
4221
  dropZoneContainerRef: containerRef,
3710
- toolResultRenderers
4222
+ renderTool,
4223
+ isDebug
3711
4224
  }), [
3712
4225
  messages,
3713
4226
  sendMessage,
@@ -3727,11 +4240,12 @@ function AgnoChatRoot({
3727
4240
  continueWithResults,
3728
4241
  executionError,
3729
4242
  handleSend,
3730
- toolResultRenderers
4243
+ renderTool,
4244
+ isDebug
3731
4245
  ]);
3732
- return /* @__PURE__ */ jsx_runtime37.jsx(AgnoChatContext.Provider, {
4246
+ return /* @__PURE__ */ jsx_runtime48.jsx(AgnoChatContext.Provider, {
3733
4247
  value: contextValue,
3734
- children: /* @__PURE__ */ jsx_runtime37.jsx("div", {
4248
+ children: /* @__PURE__ */ jsx_runtime48.jsx("div", {
3735
4249
  ref: containerRef,
3736
4250
  className: cn("relative h-full flex flex-col", className),
3737
4251
  ...divProps,
@@ -3741,25 +4255,25 @@ function AgnoChatRoot({
3741
4255
  }
3742
4256
 
3743
4257
  // src/ui/composed/agno-chat/messages.tsx
3744
- var import_react17 = require("react");
4258
+ var import_react22 = require("react");
3745
4259
 
3746
4260
  // src/ui/composed/agno-chat/suggested-prompts.tsx
3747
- var jsx_runtime38 = require("react/jsx-runtime");
4261
+ var jsx_runtime49 = require("react/jsx-runtime");
3748
4262
  function AgnoChatSuggestedPrompts({ className, prompts }) {
3749
4263
  const { handleSend } = useAgnoChatContext();
3750
4264
  if (prompts.length === 0)
3751
4265
  return null;
3752
- return /* @__PURE__ */ jsx_runtime38.jsx("div", {
4266
+ return /* @__PURE__ */ jsx_runtime49.jsx("div", {
3753
4267
  className: cn("grid grid-cols-2 gap-2 w-full max-w-md", className),
3754
- children: prompts.map((prompt, idx) => /* @__PURE__ */ jsx_runtime38.jsxs("button", {
4268
+ children: prompts.map((prompt, idx) => /* @__PURE__ */ jsx_runtime49.jsxs("button", {
3755
4269
  onClick: () => handleSend(prompt.text),
3756
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",
3757
4271
  children: [
3758
- prompt.icon && /* @__PURE__ */ jsx_runtime38.jsx("span", {
4272
+ prompt.icon && /* @__PURE__ */ jsx_runtime49.jsx("span", {
3759
4273
  className: "text-muted-foreground group-hover:text-primary transition-colors",
3760
4274
  children: prompt.icon
3761
4275
  }),
3762
- /* @__PURE__ */ jsx_runtime38.jsx("span", {
4276
+ /* @__PURE__ */ jsx_runtime49.jsx("span", {
3763
4277
  className: "text-muted-foreground group-hover:text-foreground transition-colors text-xs leading-snug",
3764
4278
  children: prompt.text
3765
4279
  })
@@ -3769,12 +4283,12 @@ function AgnoChatSuggestedPrompts({ className, prompts }) {
3769
4283
  }
3770
4284
 
3771
4285
  // src/ui/composed/agno-chat/messages.tsx
3772
- var import_lucide_react21 = require("lucide-react");
3773
- var jsx_runtime39 = require("react/jsx-runtime");
4286
+ var import_lucide_react25 = require("lucide-react");
4287
+ var jsx_runtime50 = require("react/jsx-runtime");
3774
4288
  function ScrollOnNewUserMessage({ messageCount }) {
3775
4289
  const { scrollToBottom } = import_use_stick_to_bottom2.useStickToBottomContext();
3776
- const prevCount = import_react17.useRef(messageCount);
3777
- import_react17.useEffect(() => {
4290
+ const prevCount = import_react22.useRef(messageCount);
4291
+ import_react22.useEffect(() => {
3778
4292
  if (messageCount > prevCount.current) {
3779
4293
  scrollToBottom("smooth");
3780
4294
  }
@@ -3794,13 +4308,8 @@ function AgnoChatMessages({
3794
4308
  showReasoning,
3795
4309
  showReferences,
3796
4310
  showTimestamp,
3797
- showGenerativeUI,
3798
- showToolCalls,
3799
4311
  showFilePreview,
3800
4312
  showImageLightbox,
3801
- renderToolCall,
3802
- renderContent,
3803
- renderMedia,
3804
4313
  formatTimestamp,
3805
4314
  messageClassNames,
3806
4315
  emptyState,
@@ -3808,24 +4317,23 @@ function AgnoChatMessages({
3808
4317
  children,
3809
4318
  showThinkingIndicator = true,
3810
4319
  renderThinkingIndicator,
3811
- toolResultRenderers: propToolResultRenderers,
4320
+ renderTool: propRenderTool,
3812
4321
  scrollBehavior,
3813
4322
  scrollToBottomButton
3814
4323
  }) {
3815
- const { messages, isStreaming, toolResultRenderers: contextToolResultRenderers } = useAgnoChatContext();
3816
- const toolResultRenderers = propToolResultRenderers ?? contextToolResultRenderers;
4324
+ const { messages, isStreaming } = useAgnoChatContext();
3817
4325
  const lastMessage = messages[messages.length - 1];
3818
4326
  const isThinking = showThinkingIndicator && isStreaming && (!lastMessage || lastMessage.role !== "user") && !lastMessage?.content;
3819
4327
  const resolvedScrollButton = (() => {
3820
4328
  if (scrollToBottomButton === false)
3821
4329
  return null;
3822
4330
  if (scrollToBottomButton === undefined || scrollToBottomButton === true) {
3823
- return /* @__PURE__ */ jsx_runtime39.jsx(ConversationScrollButton, {});
4331
+ return /* @__PURE__ */ jsx_runtime50.jsx(ConversationScrollButton, {});
3824
4332
  }
3825
- if (import_react17.isValidElement(scrollToBottomButton))
4333
+ if (import_react22.isValidElement(scrollToBottomButton))
3826
4334
  return scrollToBottomButton;
3827
4335
  if (typeof scrollToBottomButton === "object" && scrollToBottomButton !== null && "className" in scrollToBottomButton) {
3828
- return /* @__PURE__ */ jsx_runtime39.jsx(ConversationScrollButton, {
4336
+ return /* @__PURE__ */ jsx_runtime50.jsx(ConversationScrollButton, {
3829
4337
  className: scrollToBottomButton.className
3830
4338
  });
3831
4339
  }
@@ -3842,71 +4350,66 @@ function AgnoChatMessages({
3842
4350
  ...showReasoning !== undefined && { showReasoning },
3843
4351
  ...showReferences !== undefined && { showReferences },
3844
4352
  ...showTimestamp !== undefined && { showTimestamp },
3845
- ...showGenerativeUI !== undefined && { showGenerativeUI },
3846
- ...showToolCalls !== undefined && { showToolCalls },
3847
4353
  ...showFilePreview !== undefined && { showFilePreview },
3848
4354
  ...showImageLightbox !== undefined && { showImageLightbox },
3849
- ...renderToolCall !== undefined && { renderToolCall },
3850
- ...renderContent !== undefined && { renderContent },
3851
- ...renderMedia !== undefined && { renderMedia },
3852
4355
  ...formatTimestamp !== undefined && { formatTimestamp },
3853
4356
  ...messageClassNames !== undefined && { classNames: messageClassNames },
3854
- ...toolResultRenderers !== undefined && { toolResultRenderers }
4357
+ ...propRenderTool !== undefined && { renderTool: propRenderTool }
3855
4358
  };
3856
- const resolvedEmptyState = children ?? emptyState ?? /* @__PURE__ */ jsx_runtime39.jsxs("div", {
4359
+ const resolvedEmptyState = children ?? emptyState ?? /* @__PURE__ */ jsx_runtime50.jsxs("div", {
3857
4360
  className: "flex flex-col items-center gap-6",
3858
4361
  children: [
3859
- /* @__PURE__ */ jsx_runtime39.jsxs("div", {
4362
+ /* @__PURE__ */ jsx_runtime50.jsxs("div", {
3860
4363
  className: "relative",
3861
4364
  children: [
3862
- /* @__PURE__ */ jsx_runtime39.jsx("div", {
4365
+ /* @__PURE__ */ jsx_runtime50.jsx("div", {
3863
4366
  className: "h-16 w-16 rounded-2xl bg-primary/10 flex items-center justify-center",
3864
- children: /* @__PURE__ */ jsx_runtime39.jsx(import_lucide_react21.Bot, {
4367
+ children: /* @__PURE__ */ jsx_runtime50.jsx(import_lucide_react25.Bot, {
3865
4368
  className: "h-8 w-8 text-primary"
3866
4369
  })
3867
4370
  }),
3868
- /* @__PURE__ */ jsx_runtime39.jsx("div", {
4371
+ /* @__PURE__ */ jsx_runtime50.jsx("div", {
3869
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",
3870
- children: /* @__PURE__ */ jsx_runtime39.jsx("span", {
4373
+ children: /* @__PURE__ */ jsx_runtime50.jsx("span", {
3871
4374
  className: "h-2 w-2 rounded-full bg-white animate-pulse"
3872
4375
  })
3873
4376
  })
3874
4377
  ]
3875
4378
  }),
3876
- /* @__PURE__ */ jsx_runtime39.jsxs("div", {
4379
+ /* @__PURE__ */ jsx_runtime50.jsxs("div", {
3877
4380
  className: "space-y-2 text-center",
3878
4381
  children: [
3879
- /* @__PURE__ */ jsx_runtime39.jsx("h3", {
4382
+ /* @__PURE__ */ jsx_runtime50.jsx("h3", {
3880
4383
  className: "text-xl font-semibold tracking-tight",
3881
4384
  children: "Welcome to Agno Chat"
3882
4385
  }),
3883
- /* @__PURE__ */ jsx_runtime39.jsx("p", {
4386
+ /* @__PURE__ */ jsx_runtime50.jsx("p", {
3884
4387
  className: "text-muted-foreground text-sm max-w-sm",
3885
4388
  children: "Start a conversation with your AI agent. Ask questions, explore ideas, or run tools."
3886
4389
  })
3887
4390
  ]
3888
4391
  }),
3889
- suggestedPrompts.length > 0 && /* @__PURE__ */ jsx_runtime39.jsx(AgnoChatSuggestedPrompts, {
4392
+ suggestedPrompts.length > 0 && /* @__PURE__ */ jsx_runtime50.jsx(AgnoChatSuggestedPrompts, {
3890
4393
  prompts: suggestedPrompts
3891
4394
  })
3892
4395
  ]
3893
4396
  });
3894
- return /* @__PURE__ */ jsx_runtime39.jsxs(Conversation, {
4397
+ return /* @__PURE__ */ jsx_runtime50.jsxs(Conversation, {
3895
4398
  className: cn("relative flex-1 w-full", className),
3896
4399
  scrollBehavior,
3897
4400
  children: [
3898
- /* @__PURE__ */ jsx_runtime39.jsx(ScrollOnNewUserMessage, {
4401
+ /* @__PURE__ */ jsx_runtime50.jsx(ScrollOnNewUserMessage, {
3899
4402
  messageCount: messages.length
3900
4403
  }),
3901
- /* @__PURE__ */ jsx_runtime39.jsxs(ConversationContent, {
4404
+ /* @__PURE__ */ jsx_runtime50.jsxs(ConversationContent, {
3902
4405
  className: "max-w-3xl mx-auto",
3903
4406
  children: [
3904
- messages.length === 0 ? /* @__PURE__ */ jsx_runtime39.jsx(ConversationEmptyState, {
4407
+ messages.length === 0 ? /* @__PURE__ */ jsx_runtime50.jsx(ConversationEmptyState, {
3905
4408
  children: resolvedEmptyState
3906
4409
  }) : messages.map((message, index) => {
3907
4410
  if (isThinking && index === messages.length - 1 && message === lastMessage)
3908
4411
  return null;
3909
- return renderMessage ? renderMessage(message, index) : /* @__PURE__ */ jsx_runtime39.jsx(AgnoMessageItem, {
4412
+ return renderMessage ? renderMessage(message, index) : /* @__PURE__ */ jsx_runtime50.jsx(AgnoMessageItem, {
3910
4413
  message,
3911
4414
  avatars,
3912
4415
  actions,
@@ -3914,9 +4417,9 @@ function AgnoChatMessages({
3914
4417
  ...messageItemProps
3915
4418
  }, `msg-${index}-${message.created_at}`);
3916
4419
  }),
3917
- isThinking && /* @__PURE__ */ jsx_runtime39.jsx("div", {
4420
+ isThinking && /* @__PURE__ */ jsx_runtime50.jsx("div", {
3918
4421
  className: "py-2",
3919
- children: renderThinkingIndicator ?? /* @__PURE__ */ jsx_runtime39.jsx(StreamingIndicator, {
4422
+ children: renderThinkingIndicator ?? /* @__PURE__ */ jsx_runtime50.jsx(StreamingIndicator, {
3920
4423
  avatar: avatars?.assistant
3921
4424
  })
3922
4425
  })
@@ -3928,9 +4431,9 @@ function AgnoChatMessages({
3928
4431
  }
3929
4432
 
3930
4433
  // src/ui/composed/agno-chat/empty-state.tsx
3931
- var jsx_runtime40 = require("react/jsx-runtime");
4434
+ var jsx_runtime51 = require("react/jsx-runtime");
3932
4435
  function AgnoChatEmptyState({ children, className, ...props }) {
3933
- return /* @__PURE__ */ jsx_runtime40.jsx("div", {
4436
+ return /* @__PURE__ */ jsx_runtime51.jsx("div", {
3934
4437
  className: cn("flex flex-col items-center gap-6", className),
3935
4438
  ...props,
3936
4439
  children
@@ -3938,8 +4441,8 @@ function AgnoChatEmptyState({ children, className, ...props }) {
3938
4441
  }
3939
4442
 
3940
4443
  // src/ui/composed/agno-chat/error-bar.tsx
3941
- var import_react18 = require("react");
3942
- var jsx_runtime41 = require("react/jsx-runtime");
4444
+ var import_react23 = require("react");
4445
+ var jsx_runtime52 = require("react/jsx-runtime");
3943
4446
  function AgnoChatErrorBar({
3944
4447
  className,
3945
4448
  text,
@@ -3949,10 +4452,10 @@ function AgnoChatErrorBar({
3949
4452
  children
3950
4453
  }) {
3951
4454
  const { error, executionError } = useAgnoChatContext();
3952
- const [hidden, setHidden] = import_react18.useState(false);
3953
- const timerRef = import_react18.useRef(null);
4455
+ const [hidden, setHidden] = import_react23.useState(false);
4456
+ const timerRef = import_react23.useRef(null);
3954
4457
  const rawMessage = error || executionError;
3955
- import_react18.useEffect(() => {
4458
+ import_react23.useEffect(() => {
3956
4459
  if (!rawMessage)
3957
4460
  return;
3958
4461
  setHidden(false);
@@ -3979,23 +4482,23 @@ function AgnoChatErrorBar({
3979
4482
  if (children) {
3980
4483
  return typeof children === "function" ? children(rawMessage) : children;
3981
4484
  }
3982
- return /* @__PURE__ */ jsx_runtime41.jsxs("div", {
4485
+ return /* @__PURE__ */ jsx_runtime52.jsxs("div", {
3983
4486
  className: "flex items-center gap-2 max-w-3xl mx-auto",
3984
4487
  children: [
3985
- icon && /* @__PURE__ */ jsx_runtime41.jsx("span", {
4488
+ icon && /* @__PURE__ */ jsx_runtime52.jsx("span", {
3986
4489
  className: "shrink-0",
3987
4490
  children: icon
3988
4491
  }),
3989
- /* @__PURE__ */ jsx_runtime41.jsx("p", {
4492
+ /* @__PURE__ */ jsx_runtime52.jsx("p", {
3990
4493
  className: "text-sm text-destructive flex-1",
3991
4494
  children: displayMessage
3992
4495
  }),
3993
- dismissible && /* @__PURE__ */ jsx_runtime41.jsx("button", {
4496
+ dismissible && /* @__PURE__ */ jsx_runtime52.jsx("button", {
3994
4497
  type: "button",
3995
4498
  onClick: () => setHidden(true),
3996
4499
  className: "shrink-0 text-destructive/60 hover:text-destructive transition-colors",
3997
4500
  "aria-label": "Dismiss error",
3998
- children: /* @__PURE__ */ jsx_runtime41.jsxs("svg", {
4501
+ children: /* @__PURE__ */ jsx_runtime52.jsxs("svg", {
3999
4502
  xmlns: "http://www.w3.org/2000/svg",
4000
4503
  width: "16",
4001
4504
  height: "16",
@@ -4006,10 +4509,10 @@ function AgnoChatErrorBar({
4006
4509
  strokeLinecap: "round",
4007
4510
  strokeLinejoin: "round",
4008
4511
  children: [
4009
- /* @__PURE__ */ jsx_runtime41.jsx("path", {
4512
+ /* @__PURE__ */ jsx_runtime52.jsx("path", {
4010
4513
  d: "M18 6 6 18"
4011
4514
  }),
4012
- /* @__PURE__ */ jsx_runtime41.jsx("path", {
4515
+ /* @__PURE__ */ jsx_runtime52.jsx("path", {
4013
4516
  d: "m6 6 12 12"
4014
4517
  })
4015
4518
  ]
@@ -4018,14 +4521,14 @@ function AgnoChatErrorBar({
4018
4521
  ]
4019
4522
  });
4020
4523
  };
4021
- return /* @__PURE__ */ jsx_runtime41.jsx("div", {
4524
+ return /* @__PURE__ */ jsx_runtime52.jsx("div", {
4022
4525
  className: cn("px-4 py-2.5 bg-destructive/5 border-t border-destructive/20", className),
4023
4526
  children: renderContent()
4024
4527
  });
4025
4528
  }
4026
4529
 
4027
4530
  // src/ui/composed/agno-chat/input.tsx
4028
- var jsx_runtime42 = require("react/jsx-runtime");
4531
+ var jsx_runtime53 = require("react/jsx-runtime");
4029
4532
  function AgnoChatInputArea({
4030
4533
  className,
4031
4534
  children,
@@ -4038,11 +4541,11 @@ function AgnoChatInputArea({
4038
4541
  dropZoneProps
4039
4542
  }) {
4040
4543
  const { handleSend, inputDisabled, isStreaming, isPaused, cancelRun, dropZoneContainerRef } = useAgnoChatContext();
4041
- return /* @__PURE__ */ jsx_runtime42.jsx("div", {
4544
+ return /* @__PURE__ */ jsx_runtime53.jsx("div", {
4042
4545
  className: cn("border-t border-border bg-background/80 backdrop-blur-sm", className),
4043
- children: /* @__PURE__ */ jsx_runtime42.jsx("div", {
4546
+ children: /* @__PURE__ */ jsx_runtime53.jsx("div", {
4044
4547
  className: "mx-auto px-4 py-2",
4045
- 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, {
4046
4549
  onSend: handleSend,
4047
4550
  disabled: inputDisabled,
4048
4551
  isStreaming,
@@ -4069,4 +4572,4 @@ var AgnoChat = Object.assign(AgnoChatRoot, {
4069
4572
  Input: AgnoChatInputArea
4070
4573
  });
4071
4574
 
4072
- //# debugId=81B6F63AF2B96BA664756E2164756E21
4575
+ //# debugId=7C378B0E1199C3A164756E2164756E21