@rodrigocoliveira/agno-react 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ui.mjs CHANGED
@@ -2684,116 +2684,6 @@ var PromptInputCommandSeparator = ({ className, ...props }) => /* @__PURE__ */ j
2684
2684
  className: cn(className),
2685
2685
  ...props
2686
2686
  }, undefined, false, undefined, this);
2687
- // src/ui/composed/agno-chat/agno-chat.tsx
2688
- import { useCallback as useCallback7, useMemo as useMemo3, useRef as useRef6 } from "react";
2689
- import { useAgnoChat, useAgnoToolExecution } from "@rodrigocoliveira/agno-react";
2690
-
2691
- // src/ui/composed/agno-chat/context.ts
2692
- import { createContext as createContext3, useContext as useContext3 } from "react";
2693
- var AgnoChatContext = createContext3(null);
2694
- function useAgnoChatContext() {
2695
- const ctx = useContext3(AgnoChatContext);
2696
- if (!ctx) {
2697
- throw new Error("useAgnoChatContext must be used within an <AgnoChat> provider. " + "Wrap your component tree with <AgnoChat>.");
2698
- }
2699
- return ctx;
2700
- }
2701
-
2702
- // src/ui/composed/agno-chat/agno-chat.tsx
2703
- import { jsxDEV as jsxDEV35 } from "react/jsx-dev-runtime";
2704
- function AgnoChatRoot({
2705
- children,
2706
- toolHandlers = {},
2707
- autoExecuteTools = true,
2708
- className,
2709
- ...divProps
2710
- }) {
2711
- const chat = useAgnoChat();
2712
- const toolExec = useAgnoToolExecution(toolHandlers, autoExecuteTools);
2713
- const containerRef = useRef6(null);
2714
- const sendRef = useRef6(chat.sendMessage);
2715
- sendRef.current = chat.sendMessage;
2716
- const handleSend = useCallback7(async (message) => {
2717
- try {
2718
- await sendRef.current(message);
2719
- } catch {}
2720
- }, []);
2721
- const {
2722
- messages,
2723
- sendMessage,
2724
- clearMessages,
2725
- cancelRun,
2726
- isStreaming,
2727
- isRefreshing,
2728
- isCancelling,
2729
- currentRunId,
2730
- error,
2731
- state
2732
- } = chat;
2733
- const {
2734
- isPaused,
2735
- isExecuting,
2736
- pendingTools,
2737
- executeAndContinue,
2738
- executeTools,
2739
- continueWithResults,
2740
- executionError
2741
- } = toolExec;
2742
- const contextValue = useMemo3(() => ({
2743
- messages,
2744
- sendMessage,
2745
- clearMessages,
2746
- cancelRun,
2747
- isStreaming,
2748
- isRefreshing,
2749
- isCancelling: isCancelling ?? false,
2750
- currentRunId,
2751
- error,
2752
- state,
2753
- isPaused,
2754
- isExecuting,
2755
- pendingTools,
2756
- executeAndContinue,
2757
- executeTools,
2758
- continueWithResults,
2759
- executionError,
2760
- handleSend,
2761
- inputDisabled: isStreaming || isPaused,
2762
- dropZoneContainerRef: containerRef
2763
- }), [
2764
- messages,
2765
- sendMessage,
2766
- clearMessages,
2767
- cancelRun,
2768
- isStreaming,
2769
- isRefreshing,
2770
- isCancelling,
2771
- currentRunId,
2772
- error,
2773
- state,
2774
- isPaused,
2775
- isExecuting,
2776
- pendingTools,
2777
- executeAndContinue,
2778
- executeTools,
2779
- continueWithResults,
2780
- executionError,
2781
- handleSend
2782
- ]);
2783
- return /* @__PURE__ */ jsxDEV35(AgnoChatContext.Provider, {
2784
- value: contextValue,
2785
- children: /* @__PURE__ */ jsxDEV35("div", {
2786
- ref: containerRef,
2787
- className: cn("relative h-full flex flex-col", className),
2788
- ...divProps,
2789
- children
2790
- }, undefined, false, undefined, this)
2791
- }, undefined, false, undefined, this);
2792
- }
2793
-
2794
- // src/ui/composed/agno-chat/messages.tsx
2795
- import { useEffect as useEffect6, useRef as useRef7 } from "react";
2796
-
2797
2687
  // src/ui/composed/AgnoMessageItem.tsx
2798
2688
  import { useState as useState8 } from "react";
2799
2689
  import { GenerativeUIRenderer } from "@rodrigocoliveira/agno-react";
@@ -2807,7 +2697,7 @@ import {
2807
2697
  Paperclip,
2808
2698
  Video
2809
2699
  } from "lucide-react";
2810
- import { jsxDEV as jsxDEV36, Fragment as Fragment5 } from "react/jsx-dev-runtime";
2700
+ import { jsxDEV as jsxDEV35, Fragment as Fragment5 } from "react/jsx-dev-runtime";
2811
2701
  var defaultFormatTimestamp = formatSmartTimestamp;
2812
2702
  var getToolState = (tool) => {
2813
2703
  return tool.tool_call_error ? "output-error" : "output-available";
@@ -2819,9 +2709,9 @@ function AgnoMessageItem({
2819
2709
  renderContent,
2820
2710
  renderToolCall,
2821
2711
  renderMedia,
2822
- renderActions,
2823
- userAvatar,
2824
- assistantAvatar,
2712
+ avatars,
2713
+ actions,
2714
+ isLastAssistantMessage = false,
2825
2715
  showReasoning = true,
2826
2716
  showReferences = true,
2827
2717
  showTimestamp = true,
@@ -2848,45 +2738,45 @@ function AgnoMessageItem({
2848
2738
  setPreview({ type: "file", file });
2849
2739
  };
2850
2740
  const closePreview = () => setPreview(null);
2851
- return /* @__PURE__ */ jsxDEV36("div", {
2741
+ return /* @__PURE__ */ jsxDEV35("div", {
2852
2742
  className: cn("py-5 first:pt-2", isUser ? "flex justify-end" : "", classNames?.root, className),
2853
2743
  children: [
2854
- isUser ? /* @__PURE__ */ jsxDEV36("div", {
2744
+ isUser ? /* @__PURE__ */ jsxDEV35("div", {
2855
2745
  className: "flex items-start gap-2.5 max-w-[80%] flex-row-reverse",
2856
2746
  children: [
2857
- userAvatar,
2858
- /* @__PURE__ */ jsxDEV36("div", {
2747
+ avatars?.user,
2748
+ /* @__PURE__ */ jsxDEV35("div", {
2859
2749
  className: "space-y-1.5 flex flex-col items-end min-w-0",
2860
2750
  children: [
2861
- (message.images && message.images.length > 0 || message.audio && message.audio.length > 0 || message.files && message.files.length > 0) && /* @__PURE__ */ jsxDEV36("div", {
2751
+ (message.images && message.images.length > 0 || message.audio && message.audio.length > 0 || message.files && message.files.length > 0) && /* @__PURE__ */ jsxDEV35("div", {
2862
2752
  className: "flex flex-wrap gap-2 justify-end",
2863
2753
  children: [
2864
- message.images?.map((img, idx) => /* @__PURE__ */ jsxDEV36(FilePreviewCard, {
2754
+ message.images?.map((img, idx) => /* @__PURE__ */ jsxDEV35(FilePreviewCard, {
2865
2755
  file: { name: img.revised_prompt || `Image ${idx + 1}`, type: "image/png", url: img.url },
2866
2756
  onClick: showImageLightbox ? () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx) : undefined
2867
2757
  }, `img-${idx}`, false, undefined, this)),
2868
- message.audio?.map((audio, idx) => /* @__PURE__ */ jsxDEV36("div", {
2758
+ message.audio?.map((audio, idx) => /* @__PURE__ */ jsxDEV35("div", {
2869
2759
  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",
2870
2760
  children: [
2871
- /* @__PURE__ */ jsxDEV36(Music, {
2761
+ /* @__PURE__ */ jsxDEV35(Music, {
2872
2762
  className: "h-3.5 w-3.5 text-muted-foreground"
2873
2763
  }, undefined, false, undefined, this),
2874
- /* @__PURE__ */ jsxDEV36("span", {
2764
+ /* @__PURE__ */ jsxDEV35("span", {
2875
2765
  className: "truncate max-w-[150px]",
2876
2766
  children: audio.id || `Audio ${idx + 1}`
2877
2767
  }, undefined, false, undefined, this)
2878
2768
  ]
2879
2769
  }, `audio-${idx}`, true, undefined, this)),
2880
- message.files?.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsxDEV36(FilePreviewCard, {
2770
+ message.files?.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsxDEV35(FilePreviewCard, {
2881
2771
  file: { name: file.name, type: file.type, url: file.url, size: file.size },
2882
2772
  onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
2883
- }, `file-${idx}`, false, undefined, this) : /* @__PURE__ */ jsxDEV36("div", {
2773
+ }, `file-${idx}`, false, undefined, this) : /* @__PURE__ */ jsxDEV35("div", {
2884
2774
  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",
2885
2775
  children: [
2886
- /* @__PURE__ */ jsxDEV36(FileIcon3, {
2776
+ /* @__PURE__ */ jsxDEV35(FileIcon3, {
2887
2777
  className: "h-3.5 w-3.5 text-muted-foreground"
2888
2778
  }, undefined, false, undefined, this),
2889
- /* @__PURE__ */ jsxDEV36("span", {
2779
+ /* @__PURE__ */ jsxDEV35("span", {
2890
2780
  className: "truncate max-w-[150px]",
2891
2781
  children: file.name
2892
2782
  }, undefined, false, undefined, this)
@@ -2894,22 +2784,26 @@ function AgnoMessageItem({
2894
2784
  }, `file-${idx}`, true, undefined, this))
2895
2785
  ]
2896
2786
  }, undefined, true, undefined, this),
2897
- message.content && /* @__PURE__ */ jsxDEV36("div", {
2898
- className: cn("rounded-2xl rounded-br-md px-4 py-2.5", classNames?.userBubble ?? "bg-primary text-primary-foreground", hasError && "opacity-70"),
2899
- children: /* @__PURE__ */ jsxDEV36("p", {
2787
+ message.content && /* @__PURE__ */ jsxDEV35("div", {
2788
+ className: cn("rounded-2xl rounded-br-md px-4 py-2.5", classNames?.user?.bubble ?? "bg-primary text-primary-foreground", hasError && "opacity-70"),
2789
+ children: /* @__PURE__ */ jsxDEV35("p", {
2900
2790
  className: "text-sm whitespace-pre-wrap",
2901
2791
  children: message.content
2902
2792
  }, undefined, false, undefined, this)
2903
2793
  }, undefined, false, undefined, this),
2904
- showTimestamp && /* @__PURE__ */ jsxDEV36("div", {
2794
+ (showTimestamp || actions?.user) && /* @__PURE__ */ jsxDEV35("div", {
2905
2795
  className: "flex items-center justify-end gap-1.5 px-1",
2906
2796
  children: [
2907
- /* @__PURE__ */ jsxDEV36(SmartTimestamp, {
2797
+ actions?.user && /* @__PURE__ */ jsxDEV35("div", {
2798
+ className: "flex items-center gap-1",
2799
+ children: actions.user(message)
2800
+ }, undefined, false, undefined, this),
2801
+ /* @__PURE__ */ jsxDEV35(SmartTimestamp, {
2908
2802
  date: new Date(message.created_at * 1000),
2909
2803
  formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
2910
2804
  className: "text-[11px] text-muted-foreground"
2911
2805
  }, undefined, false, undefined, this),
2912
- hasError && /* @__PURE__ */ jsxDEV36(AlertCircle, {
2806
+ hasError && /* @__PURE__ */ jsxDEV35(AlertCircle, {
2913
2807
  className: "h-3 w-3 text-destructive"
2914
2808
  }, undefined, false, undefined, this)
2915
2809
  ]
@@ -2917,22 +2811,22 @@ function AgnoMessageItem({
2917
2811
  ]
2918
2812
  }, undefined, true, undefined, this)
2919
2813
  ]
2920
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV36("div", {
2921
- className: "flex items-start gap-3",
2814
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV35("div", {
2815
+ className: "flex items-start gap-3 group/message",
2922
2816
  children: [
2923
- assistantAvatar,
2924
- /* @__PURE__ */ jsxDEV36("div", {
2925
- className: cn("flex-1 min-w-0 space-y-3", classNames?.assistantContainer),
2817
+ avatars?.assistant,
2818
+ /* @__PURE__ */ jsxDEV35("div", {
2819
+ className: cn("flex-1 min-w-0 space-y-3", classNames?.assistant?.container),
2926
2820
  children: [
2927
- renderContent ? renderContent(message) : /* @__PURE__ */ jsxDEV36(Fragment5, {
2821
+ renderContent ? renderContent(message) : /* @__PURE__ */ jsxDEV35(Fragment5, {
2928
2822
  children: [
2929
- showReasoning && message.extra_data?.reasoning_steps && message.extra_data.reasoning_steps.length > 0 && /* @__PURE__ */ jsxDEV36("div", {
2930
- className: cn("space-y-2 pt-1", classNames?.reasoning),
2823
+ showReasoning && message.extra_data?.reasoning_steps && message.extra_data.reasoning_steps.length > 0 && /* @__PURE__ */ jsxDEV35("div", {
2824
+ className: cn("space-y-2 pt-1", classNames?.assistant?.reasoning),
2931
2825
  children: [
2932
- /* @__PURE__ */ jsxDEV36("div", {
2826
+ /* @__PURE__ */ jsxDEV35("div", {
2933
2827
  className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
2934
2828
  children: [
2935
- /* @__PURE__ */ jsxDEV36(Lightbulb, {
2829
+ /* @__PURE__ */ jsxDEV35(Lightbulb, {
2936
2830
  className: "h-3.5 w-3.5"
2937
2831
  }, undefined, false, undefined, this),
2938
2832
  "Reasoning (",
@@ -2940,23 +2834,23 @@ function AgnoMessageItem({
2940
2834
  " steps)"
2941
2835
  ]
2942
2836
  }, undefined, true, undefined, this),
2943
- /* @__PURE__ */ jsxDEV36(Accordion, {
2837
+ /* @__PURE__ */ jsxDEV35(Accordion, {
2944
2838
  type: "multiple",
2945
2839
  className: "w-full",
2946
- children: message.extra_data.reasoning_steps.map((step, idx) => /* @__PURE__ */ jsxDEV36(AccordionItem, {
2840
+ children: message.extra_data.reasoning_steps.map((step, idx) => /* @__PURE__ */ jsxDEV35(AccordionItem, {
2947
2841
  value: `reasoning-${idx}`,
2948
2842
  className: "border-muted",
2949
2843
  children: [
2950
- /* @__PURE__ */ jsxDEV36(AccordionTrigger, {
2844
+ /* @__PURE__ */ jsxDEV35(AccordionTrigger, {
2951
2845
  className: "text-xs py-1.5 hover:no-underline",
2952
2846
  children: step.title || `Step ${idx + 1}`
2953
2847
  }, undefined, false, undefined, this),
2954
- /* @__PURE__ */ jsxDEV36(AccordionContent, {
2848
+ /* @__PURE__ */ jsxDEV35(AccordionContent, {
2955
2849
  className: "space-y-1.5 text-xs text-muted-foreground",
2956
2850
  children: [
2957
- step.action && /* @__PURE__ */ jsxDEV36("div", {
2851
+ step.action && /* @__PURE__ */ jsxDEV35("div", {
2958
2852
  children: [
2959
- /* @__PURE__ */ jsxDEV36("span", {
2853
+ /* @__PURE__ */ jsxDEV35("span", {
2960
2854
  className: "font-medium text-foreground",
2961
2855
  children: "Action:"
2962
2856
  }, undefined, false, undefined, this),
@@ -2964,9 +2858,9 @@ function AgnoMessageItem({
2964
2858
  step.action
2965
2859
  ]
2966
2860
  }, undefined, true, undefined, this),
2967
- step.reasoning && /* @__PURE__ */ jsxDEV36("div", {
2861
+ step.reasoning && /* @__PURE__ */ jsxDEV35("div", {
2968
2862
  children: [
2969
- /* @__PURE__ */ jsxDEV36("span", {
2863
+ /* @__PURE__ */ jsxDEV35("span", {
2970
2864
  className: "font-medium text-foreground",
2971
2865
  children: "Reasoning:"
2972
2866
  }, undefined, false, undefined, this),
@@ -2974,9 +2868,9 @@ function AgnoMessageItem({
2974
2868
  step.reasoning
2975
2869
  ]
2976
2870
  }, undefined, true, undefined, this),
2977
- step.result && /* @__PURE__ */ jsxDEV36("div", {
2871
+ step.result && /* @__PURE__ */ jsxDEV35("div", {
2978
2872
  children: [
2979
- /* @__PURE__ */ jsxDEV36("span", {
2873
+ /* @__PURE__ */ jsxDEV35("span", {
2980
2874
  className: "font-medium text-foreground",
2981
2875
  children: "Result:"
2982
2876
  }, undefined, false, undefined, this),
@@ -2984,9 +2878,9 @@ function AgnoMessageItem({
2984
2878
  step.result
2985
2879
  ]
2986
2880
  }, undefined, true, undefined, this),
2987
- step.confidence !== undefined && /* @__PURE__ */ jsxDEV36("div", {
2881
+ step.confidence !== undefined && /* @__PURE__ */ jsxDEV35("div", {
2988
2882
  children: [
2989
- /* @__PURE__ */ jsxDEV36("span", {
2883
+ /* @__PURE__ */ jsxDEV35("span", {
2990
2884
  className: "font-medium text-foreground",
2991
2885
  children: "Confidence:"
2992
2886
  }, undefined, false, undefined, this),
@@ -3002,23 +2896,23 @@ function AgnoMessageItem({
3002
2896
  }, undefined, false, undefined, this)
3003
2897
  ]
3004
2898
  }, undefined, true, undefined, this),
3005
- message.content && /* @__PURE__ */ jsxDEV36("div", {
2899
+ message.content && /* @__PURE__ */ jsxDEV35("div", {
3006
2900
  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",
3007
- children: /* @__PURE__ */ jsxDEV36(Response, {
2901
+ children: /* @__PURE__ */ jsxDEV35(Response, {
3008
2902
  children: message.content
3009
2903
  }, undefined, false, undefined, this)
3010
2904
  }, undefined, false, undefined, this),
3011
- showGenerativeUI && toolsWithUI.length > 0 && /* @__PURE__ */ jsxDEV36("div", {
2905
+ showGenerativeUI && toolsWithUI.length > 0 && /* @__PURE__ */ jsxDEV35("div", {
3012
2906
  className: "space-y-3",
3013
2907
  children: toolsWithUI.map((tool) => {
3014
2908
  const uiComponent = tool.ui_component;
3015
- return /* @__PURE__ */ jsxDEV36("div", {
3016
- children: uiComponent.layout === "artifact" ? /* @__PURE__ */ jsxDEV36(Artifact, {
3017
- children: /* @__PURE__ */ jsxDEV36(GenerativeUIRenderer, {
2909
+ return /* @__PURE__ */ jsxDEV35("div", {
2910
+ children: uiComponent.layout === "artifact" ? /* @__PURE__ */ jsxDEV35(Artifact, {
2911
+ children: /* @__PURE__ */ jsxDEV35(GenerativeUIRenderer, {
3018
2912
  spec: uiComponent,
3019
2913
  className: "w-full p-2"
3020
2914
  }, undefined, false, undefined, this)
3021
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV36(GenerativeUIRenderer, {
2915
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV35(GenerativeUIRenderer, {
3022
2916
  spec: uiComponent,
3023
2917
  className: "w-full"
3024
2918
  }, undefined, false, undefined, this)
@@ -3026,16 +2920,16 @@ function AgnoMessageItem({
3026
2920
  })
3027
2921
  }, undefined, false, undefined, this),
3028
2922
  renderMedia ? renderMedia(message) : (() => {
3029
- const mediaClassName = classNames?.media;
3030
- return /* @__PURE__ */ jsxDEV36(Fragment5, {
2923
+ const mediaClassName = classNames?.assistant?.media;
2924
+ return /* @__PURE__ */ jsxDEV35(Fragment5, {
3031
2925
  children: [
3032
- message.images && message.images.length > 0 && /* @__PURE__ */ jsxDEV36("div", {
2926
+ message.images && message.images.length > 0 && /* @__PURE__ */ jsxDEV35("div", {
3033
2927
  className: cn("space-y-2 pt-1", mediaClassName),
3034
2928
  children: [
3035
- /* @__PURE__ */ jsxDEV36("div", {
2929
+ /* @__PURE__ */ jsxDEV35("div", {
3036
2930
  className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3037
2931
  children: [
3038
- /* @__PURE__ */ jsxDEV36(ImageIcon2, {
2932
+ /* @__PURE__ */ jsxDEV35(ImageIcon2, {
3039
2933
  className: "h-3.5 w-3.5"
3040
2934
  }, undefined, false, undefined, this),
3041
2935
  "Images (",
@@ -3043,26 +2937,26 @@ function AgnoMessageItem({
3043
2937
  ")"
3044
2938
  ]
3045
2939
  }, undefined, true, undefined, this),
3046
- /* @__PURE__ */ jsxDEV36("div", {
2940
+ /* @__PURE__ */ jsxDEV35("div", {
3047
2941
  className: "grid grid-cols-2 gap-2",
3048
- children: message.images.map((img, idx) => /* @__PURE__ */ jsxDEV36("div", {
2942
+ children: message.images.map((img, idx) => /* @__PURE__ */ jsxDEV35("div", {
3049
2943
  className: "space-y-1",
3050
2944
  children: [
3051
- showImageLightbox ? /* @__PURE__ */ jsxDEV36("button", {
2945
+ showImageLightbox ? /* @__PURE__ */ jsxDEV35("button", {
3052
2946
  type: "button",
3053
2947
  onClick: () => openImageLightbox(message.images.map((i) => ({ url: i.url, alt: i.revised_prompt })), idx),
3054
2948
  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",
3055
- children: /* @__PURE__ */ jsxDEV36("img", {
2949
+ children: /* @__PURE__ */ jsxDEV35("img", {
3056
2950
  src: img.url,
3057
2951
  alt: img.revised_prompt || "Generated image",
3058
2952
  className: "w-full rounded-lg"
3059
2953
  }, undefined, false, undefined, this)
3060
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV36("img", {
2954
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV35("img", {
3061
2955
  src: img.url,
3062
2956
  alt: img.revised_prompt || "Generated image",
3063
2957
  className: "w-full rounded-lg border border-border"
3064
2958
  }, undefined, false, undefined, this),
3065
- img.revised_prompt && /* @__PURE__ */ jsxDEV36("p", {
2959
+ img.revised_prompt && /* @__PURE__ */ jsxDEV35("p", {
3066
2960
  className: "text-[11px] text-muted-foreground italic px-0.5",
3067
2961
  children: img.revised_prompt
3068
2962
  }, undefined, false, undefined, this)
@@ -3071,13 +2965,13 @@ function AgnoMessageItem({
3071
2965
  }, undefined, false, undefined, this)
3072
2966
  ]
3073
2967
  }, undefined, true, undefined, this),
3074
- message.videos && message.videos.length > 0 && /* @__PURE__ */ jsxDEV36("div", {
2968
+ message.videos && message.videos.length > 0 && /* @__PURE__ */ jsxDEV35("div", {
3075
2969
  className: cn("space-y-2 pt-1", mediaClassName),
3076
2970
  children: [
3077
- /* @__PURE__ */ jsxDEV36("div", {
2971
+ /* @__PURE__ */ jsxDEV35("div", {
3078
2972
  className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3079
2973
  children: [
3080
- /* @__PURE__ */ jsxDEV36(Video, {
2974
+ /* @__PURE__ */ jsxDEV35(Video, {
3081
2975
  className: "h-3.5 w-3.5"
3082
2976
  }, undefined, false, undefined, this),
3083
2977
  "Videos (",
@@ -3085,14 +2979,14 @@ function AgnoMessageItem({
3085
2979
  ")"
3086
2980
  ]
3087
2981
  }, undefined, true, undefined, this),
3088
- /* @__PURE__ */ jsxDEV36("div", {
2982
+ /* @__PURE__ */ jsxDEV35("div", {
3089
2983
  className: "space-y-2",
3090
- children: message.videos.map((video, idx) => /* @__PURE__ */ jsxDEV36("div", {
3091
- children: video.url ? /* @__PURE__ */ jsxDEV36("video", {
2984
+ children: message.videos.map((video, idx) => /* @__PURE__ */ jsxDEV35("div", {
2985
+ children: video.url ? /* @__PURE__ */ jsxDEV35("video", {
3092
2986
  src: video.url,
3093
2987
  controls: true,
3094
2988
  className: "w-full rounded-lg border border-border"
3095
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV36("div", {
2989
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV35("div", {
3096
2990
  className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3097
2991
  children: [
3098
2992
  "Video ID: ",
@@ -3106,13 +3000,13 @@ function AgnoMessageItem({
3106
3000
  }, undefined, false, undefined, this)
3107
3001
  ]
3108
3002
  }, undefined, true, undefined, this),
3109
- message.audio && message.audio.length > 0 && /* @__PURE__ */ jsxDEV36("div", {
3003
+ message.audio && message.audio.length > 0 && /* @__PURE__ */ jsxDEV35("div", {
3110
3004
  className: cn("space-y-2 pt-1", mediaClassName),
3111
3005
  children: [
3112
- /* @__PURE__ */ jsxDEV36("div", {
3006
+ /* @__PURE__ */ jsxDEV35("div", {
3113
3007
  className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3114
3008
  children: [
3115
- /* @__PURE__ */ jsxDEV36(Music, {
3009
+ /* @__PURE__ */ jsxDEV35(Music, {
3116
3010
  className: "h-3.5 w-3.5"
3117
3011
  }, undefined, false, undefined, this),
3118
3012
  "Audio (",
@@ -3120,18 +3014,18 @@ function AgnoMessageItem({
3120
3014
  ")"
3121
3015
  ]
3122
3016
  }, undefined, true, undefined, this),
3123
- /* @__PURE__ */ jsxDEV36("div", {
3017
+ /* @__PURE__ */ jsxDEV35("div", {
3124
3018
  className: "space-y-2",
3125
- children: message.audio.map((audio, idx) => /* @__PURE__ */ jsxDEV36("div", {
3126
- children: audio.url ? /* @__PURE__ */ jsxDEV36("audio", {
3019
+ children: message.audio.map((audio, idx) => /* @__PURE__ */ jsxDEV35("div", {
3020
+ children: audio.url ? /* @__PURE__ */ jsxDEV35("audio", {
3127
3021
  src: audio.url,
3128
3022
  controls: true,
3129
3023
  className: "w-full"
3130
- }, undefined, false, undefined, this) : audio.base64_audio ? /* @__PURE__ */ jsxDEV36("audio", {
3024
+ }, undefined, false, undefined, this) : audio.base64_audio ? /* @__PURE__ */ jsxDEV35("audio", {
3131
3025
  src: `data:${audio.mime_type || "audio/wav"};base64,${audio.base64_audio}`,
3132
3026
  controls: true,
3133
3027
  className: "w-full"
3134
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV36("div", {
3028
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV35("div", {
3135
3029
  className: "bg-muted/50 border border-border p-2.5 rounded-lg text-xs text-muted-foreground",
3136
3030
  children: "Audio data unavailable"
3137
3031
  }, undefined, false, undefined, this)
@@ -3139,13 +3033,13 @@ function AgnoMessageItem({
3139
3033
  }, undefined, false, undefined, this)
3140
3034
  ]
3141
3035
  }, undefined, true, undefined, this),
3142
- message.files && message.files.length > 0 && /* @__PURE__ */ jsxDEV36("div", {
3036
+ message.files && message.files.length > 0 && /* @__PURE__ */ jsxDEV35("div", {
3143
3037
  className: cn("space-y-2 pt-1", mediaClassName),
3144
3038
  children: [
3145
- /* @__PURE__ */ jsxDEV36("div", {
3039
+ /* @__PURE__ */ jsxDEV35("div", {
3146
3040
  className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3147
3041
  children: [
3148
- /* @__PURE__ */ jsxDEV36(Paperclip, {
3042
+ /* @__PURE__ */ jsxDEV35(Paperclip, {
3149
3043
  className: "h-3.5 w-3.5"
3150
3044
  }, undefined, false, undefined, this),
3151
3045
  "Files (",
@@ -3153,22 +3047,22 @@ function AgnoMessageItem({
3153
3047
  ")"
3154
3048
  ]
3155
3049
  }, undefined, true, undefined, this),
3156
- /* @__PURE__ */ jsxDEV36("div", {
3050
+ /* @__PURE__ */ jsxDEV35("div", {
3157
3051
  className: "flex flex-wrap gap-2",
3158
- children: message.files.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsxDEV36(FilePreviewCard, {
3052
+ children: message.files.map((file, idx) => showFilePreview ? /* @__PURE__ */ jsxDEV35(FilePreviewCard, {
3159
3053
  file: { name: file.name, type: file.type, url: file.url, size: file.size },
3160
3054
  onClick: () => openFilePreview({ name: file.name, type: file.type, url: file.url, size: file.size })
3161
- }, idx, false, undefined, this) : /* @__PURE__ */ jsxDEV36("div", {
3055
+ }, idx, false, undefined, this) : /* @__PURE__ */ jsxDEV35("div", {
3162
3056
  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",
3163
3057
  children: [
3164
- /* @__PURE__ */ jsxDEV36(FileIcon3, {
3058
+ /* @__PURE__ */ jsxDEV35(FileIcon3, {
3165
3059
  className: "h-3.5 w-3.5 shrink-0 text-muted-foreground"
3166
3060
  }, undefined, false, undefined, this),
3167
- /* @__PURE__ */ jsxDEV36("span", {
3061
+ /* @__PURE__ */ jsxDEV35("span", {
3168
3062
  className: "truncate max-w-[180px]",
3169
3063
  children: file.name
3170
3064
  }, undefined, false, undefined, this),
3171
- file.size && /* @__PURE__ */ jsxDEV36("span", {
3065
+ file.size && /* @__PURE__ */ jsxDEV35("span", {
3172
3066
  className: "text-muted-foreground/70",
3173
3067
  children: [
3174
3068
  "(",
@@ -3176,7 +3070,7 @@ function AgnoMessageItem({
3176
3070
  "KB)"
3177
3071
  ]
3178
3072
  }, undefined, true, undefined, this),
3179
- file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsxDEV36("a", {
3073
+ file.url && /^https?:\/\//i.test(file.url) && /* @__PURE__ */ jsxDEV35("a", {
3180
3074
  href: file.url,
3181
3075
  target: "_blank",
3182
3076
  rel: "noopener noreferrer",
@@ -3188,19 +3082,19 @@ function AgnoMessageItem({
3188
3082
  }, undefined, false, undefined, this)
3189
3083
  ]
3190
3084
  }, undefined, true, undefined, this),
3191
- message.response_audio && /* @__PURE__ */ jsxDEV36("div", {
3085
+ message.response_audio && /* @__PURE__ */ jsxDEV35("div", {
3192
3086
  className: cn("space-y-2 pt-1", mediaClassName),
3193
3087
  children: [
3194
- /* @__PURE__ */ jsxDEV36("div", {
3088
+ /* @__PURE__ */ jsxDEV35("div", {
3195
3089
  className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3196
3090
  children: [
3197
- /* @__PURE__ */ jsxDEV36(Music, {
3091
+ /* @__PURE__ */ jsxDEV35(Music, {
3198
3092
  className: "h-3.5 w-3.5"
3199
3093
  }, undefined, false, undefined, this),
3200
3094
  "Response Audio"
3201
3095
  ]
3202
3096
  }, undefined, true, undefined, this),
3203
- message.response_audio.transcript && /* @__PURE__ */ jsxDEV36("div", {
3097
+ message.response_audio.transcript && /* @__PURE__ */ jsxDEV35("div", {
3204
3098
  className: "text-xs italic bg-muted/50 border border-border p-2.5 rounded-lg text-muted-foreground",
3205
3099
  children: [
3206
3100
  '"',
@@ -3208,7 +3102,7 @@ function AgnoMessageItem({
3208
3102
  '"'
3209
3103
  ]
3210
3104
  }, undefined, true, undefined, this),
3211
- message.response_audio.content && /* @__PURE__ */ jsxDEV36("audio", {
3105
+ message.response_audio.content && /* @__PURE__ */ jsxDEV35("audio", {
3212
3106
  src: `data:audio/wav;base64,${message.response_audio.content}`,
3213
3107
  controls: true,
3214
3108
  className: "w-full"
@@ -3218,22 +3112,22 @@ function AgnoMessageItem({
3218
3112
  ]
3219
3113
  }, undefined, true, undefined, this);
3220
3114
  })(),
3221
- showToolCalls && message.tool_calls && message.tool_calls.length > 0 && /* @__PURE__ */ jsxDEV36("div", {
3222
- className: cn("space-y-2 pt-1", classNames?.toolCalls),
3223
- children: message.tool_calls.map((tool, idx) => renderToolCall ? renderToolCall(tool, idx) : /* @__PURE__ */ jsxDEV36(Tool, {
3115
+ showToolCalls && message.tool_calls && message.tool_calls.length > 0 && /* @__PURE__ */ jsxDEV35("div", {
3116
+ className: cn("space-y-2 pt-1", classNames?.assistant?.toolCalls),
3117
+ children: message.tool_calls.map((tool, idx) => renderToolCall ? renderToolCall(tool, idx) : /* @__PURE__ */ jsxDEV35(Tool, {
3224
3118
  defaultOpen: idx === 0,
3225
3119
  children: [
3226
- /* @__PURE__ */ jsxDEV36(ToolHeader, {
3120
+ /* @__PURE__ */ jsxDEV35(ToolHeader, {
3227
3121
  title: tool.tool_name,
3228
3122
  type: "tool-use",
3229
3123
  state: getToolState(tool)
3230
3124
  }, undefined, false, undefined, this),
3231
- /* @__PURE__ */ jsxDEV36(ToolContent, {
3125
+ /* @__PURE__ */ jsxDEV35(ToolContent, {
3232
3126
  children: [
3233
- /* @__PURE__ */ jsxDEV36(ToolInput, {
3127
+ /* @__PURE__ */ jsxDEV35(ToolInput, {
3234
3128
  input: tool.tool_args
3235
3129
  }, undefined, false, undefined, this),
3236
- tool.content && /* @__PURE__ */ jsxDEV36(ToolOutput, {
3130
+ tool.content && /* @__PURE__ */ jsxDEV35(ToolOutput, {
3237
3131
  output: tool.content,
3238
3132
  errorText: tool.tool_call_error ? "Tool execution failed" : undefined
3239
3133
  }, undefined, false, undefined, this)
@@ -3242,13 +3136,13 @@ function AgnoMessageItem({
3242
3136
  ]
3243
3137
  }, tool.tool_call_id || idx, true, undefined, this))
3244
3138
  }, undefined, false, undefined, this),
3245
- showReferences && message.extra_data?.references && message.extra_data.references.length > 0 && /* @__PURE__ */ jsxDEV36("div", {
3246
- className: cn("space-y-2 pt-1", classNames?.references),
3139
+ showReferences && message.extra_data?.references && message.extra_data.references.length > 0 && /* @__PURE__ */ jsxDEV35("div", {
3140
+ className: cn("space-y-2 pt-1", classNames?.assistant?.references),
3247
3141
  children: [
3248
- /* @__PURE__ */ jsxDEV36("div", {
3142
+ /* @__PURE__ */ jsxDEV35("div", {
3249
3143
  className: "flex items-center gap-2 text-xs font-medium text-muted-foreground",
3250
3144
  children: [
3251
- /* @__PURE__ */ jsxDEV36(FileText, {
3145
+ /* @__PURE__ */ jsxDEV35(FileText, {
3252
3146
  className: "h-3.5 w-3.5"
3253
3147
  }, undefined, false, undefined, this),
3254
3148
  "References (",
@@ -3256,22 +3150,22 @@ function AgnoMessageItem({
3256
3150
  ")"
3257
3151
  ]
3258
3152
  }, undefined, true, undefined, this),
3259
- /* @__PURE__ */ jsxDEV36("div", {
3153
+ /* @__PURE__ */ jsxDEV35("div", {
3260
3154
  className: "space-y-2",
3261
- children: message.extra_data.references.map((refData, idx) => /* @__PURE__ */ jsxDEV36("div", {
3155
+ children: message.extra_data.references.map((refData, idx) => /* @__PURE__ */ jsxDEV35("div", {
3262
3156
  className: "text-xs space-y-1.5",
3263
3157
  children: [
3264
- refData.query && /* @__PURE__ */ jsxDEV36("div", {
3158
+ refData.query && /* @__PURE__ */ jsxDEV35("div", {
3265
3159
  className: "font-medium text-foreground",
3266
3160
  children: [
3267
3161
  "Query: ",
3268
3162
  refData.query
3269
3163
  ]
3270
3164
  }, undefined, true, undefined, this),
3271
- refData.references.map((ref, refIdx) => /* @__PURE__ */ jsxDEV36("div", {
3165
+ refData.references.map((ref, refIdx) => /* @__PURE__ */ jsxDEV35("div", {
3272
3166
  className: "bg-muted/50 border border-border p-2.5 rounded-lg",
3273
3167
  children: [
3274
- /* @__PURE__ */ jsxDEV36("div", {
3168
+ /* @__PURE__ */ jsxDEV35("div", {
3275
3169
  className: "italic text-muted-foreground mb-1",
3276
3170
  children: [
3277
3171
  '"',
@@ -3279,7 +3173,7 @@ function AgnoMessageItem({
3279
3173
  '"'
3280
3174
  ]
3281
3175
  }, undefined, true, undefined, this),
3282
- /* @__PURE__ */ jsxDEV36("div", {
3176
+ /* @__PURE__ */ jsxDEV35("div", {
3283
3177
  className: "text-muted-foreground/70",
3284
3178
  children: [
3285
3179
  "Source: ",
@@ -3300,23 +3194,29 @@ function AgnoMessageItem({
3300
3194
  }, undefined, true, undefined, this)
3301
3195
  ]
3302
3196
  }, undefined, true, undefined, this),
3303
- (renderActions || showTimestamp || hasError) && /* @__PURE__ */ jsxDEV36("div", {
3197
+ (actions?.assistant || showTimestamp || hasError) && /* @__PURE__ */ jsxDEV35("div", {
3304
3198
  className: "flex items-center gap-2 pt-1",
3305
3199
  children: [
3306
- renderActions && /* @__PURE__ */ jsxDEV36("div", {
3307
- className: cn("flex items-center gap-1", classNames?.actions),
3308
- children: renderActions(message)
3309
- }, undefined, false, undefined, this),
3310
- hasError && /* @__PURE__ */ jsxDEV36("span", {
3200
+ actions?.assistant && (() => {
3201
+ const visibility = actions.visibility ?? "visible";
3202
+ if (visibility === "last-assistant" && !isLastAssistantMessage)
3203
+ return null;
3204
+ const useHover = visibility === "hover" || visibility === "hover-last-visible" && !isLastAssistantMessage;
3205
+ return /* @__PURE__ */ jsxDEV35("div", {
3206
+ className: cn("flex items-center gap-1 transition-opacity", useHover && "opacity-0 group-hover/message:opacity-100", classNames?.assistant?.actions),
3207
+ children: actions.assistant(message)
3208
+ }, undefined, false, undefined, this);
3209
+ })(),
3210
+ hasError && /* @__PURE__ */ jsxDEV35("span", {
3311
3211
  className: "flex items-center gap-1 text-[11px] text-destructive",
3312
3212
  children: [
3313
- /* @__PURE__ */ jsxDEV36(AlertCircle, {
3213
+ /* @__PURE__ */ jsxDEV35(AlertCircle, {
3314
3214
  className: "h-3 w-3"
3315
3215
  }, undefined, false, undefined, this),
3316
3216
  "Error"
3317
3217
  ]
3318
3218
  }, undefined, true, undefined, this),
3319
- showTimestamp && /* @__PURE__ */ jsxDEV36(SmartTimestamp, {
3219
+ showTimestamp && /* @__PURE__ */ jsxDEV35(SmartTimestamp, {
3320
3220
  date: new Date(message.created_at * 1000),
3321
3221
  formatShort: isCustomTimestamp ? resolvedFormatTimestamp : undefined,
3322
3222
  className: "text-[11px] text-muted-foreground"
@@ -3327,7 +3227,7 @@ function AgnoMessageItem({
3327
3227
  }, undefined, true, undefined, this)
3328
3228
  ]
3329
3229
  }, undefined, true, undefined, this),
3330
- preview?.type === "image" && /* @__PURE__ */ jsxDEV36(ImageLightbox, {
3230
+ preview?.type === "image" && /* @__PURE__ */ jsxDEV35(ImageLightbox, {
3331
3231
  open: true,
3332
3232
  onOpenChange: (open) => {
3333
3233
  if (!open)
@@ -3336,7 +3236,7 @@ function AgnoMessageItem({
3336
3236
  images: preview.images,
3337
3237
  initialIndex: preview.initialIndex
3338
3238
  }, undefined, false, undefined, this),
3339
- preview?.type === "file" && /* @__PURE__ */ jsxDEV36(FilePreviewModal, {
3239
+ preview?.type === "file" && /* @__PURE__ */ jsxDEV35(FilePreviewModal, {
3340
3240
  open: true,
3341
3241
  onOpenChange: (open) => {
3342
3242
  if (!open)
@@ -3347,267 +3247,55 @@ function AgnoMessageItem({
3347
3247
  ]
3348
3248
  }, undefined, true, undefined, this);
3349
3249
  }
3350
-
3351
- // src/ui/composed/agno-chat/suggested-prompts.tsx
3352
- import { jsxDEV as jsxDEV37 } from "react/jsx-dev-runtime";
3353
- function AgnoChatSuggestedPrompts({ className, prompts }) {
3354
- const { handleSend } = useAgnoChatContext();
3355
- if (prompts.length === 0)
3356
- return null;
3357
- return /* @__PURE__ */ jsxDEV37("div", {
3358
- className: cn("grid grid-cols-2 gap-2 w-full max-w-md", className),
3359
- children: prompts.map((prompt, idx) => /* @__PURE__ */ jsxDEV37("button", {
3360
- onClick: () => handleSend(prompt.text),
3361
- 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",
3362
- children: [
3363
- prompt.icon && /* @__PURE__ */ jsxDEV37("span", {
3364
- className: "text-muted-foreground group-hover:text-primary transition-colors",
3365
- children: prompt.icon
3366
- }, undefined, false, undefined, this),
3367
- /* @__PURE__ */ jsxDEV37("span", {
3368
- className: "text-muted-foreground group-hover:text-foreground transition-colors text-xs leading-snug",
3369
- children: prompt.text
3370
- }, undefined, false, undefined, this)
3371
- ]
3372
- }, idx, true, undefined, this))
3373
- }, undefined, false, undefined, this);
3250
+ // src/ui/composed/AgnoChatInput.tsx
3251
+ import { CircleStop } from "lucide-react";
3252
+ import { jsxDEV as jsxDEV36 } from "react/jsx-dev-runtime";
3253
+ var DEFAULT_ACCEPTED_FILE_TYPES = "image/*,audio/*,.pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.ppt,.pptx,.md,.json,.xml";
3254
+ function normalizeAudio(audio) {
3255
+ if (audio === true)
3256
+ return { enabled: true };
3257
+ if (!audio)
3258
+ return;
3259
+ return audio;
3374
3260
  }
3375
-
3376
- // src/ui/composed/agno-chat/messages.tsx
3377
- import { Bot as Bot2 } from "lucide-react";
3378
- import { jsxDEV as jsxDEV38 } from "react/jsx-dev-runtime";
3379
- function ScrollOnNewUserMessage({ messageCount }) {
3380
- const { scrollToBottom } = useStickToBottomContext2();
3381
- const prevCount = useRef7(messageCount);
3382
- useEffect6(() => {
3383
- if (messageCount > prevCount.current) {
3384
- scrollToBottom("smooth");
3385
- }
3386
- prevCount.current = messageCount;
3387
- }, [messageCount, scrollToBottom]);
3388
- return null;
3261
+ function dataUrlToBlob(dataUrl) {
3262
+ const [header, base64] = dataUrl.split(",");
3263
+ const mime = header.match(/:(.*?);/)?.[1] || "application/octet-stream";
3264
+ const bytes = atob(base64);
3265
+ const buf = new Uint8Array(bytes.length);
3266
+ for (let i = 0;i < bytes.length; i++) {
3267
+ buf[i] = bytes.charCodeAt(i);
3268
+ }
3269
+ return new Blob([buf], { type: mime });
3389
3270
  }
3390
- var DEFAULT_PROMPTS = [
3391
- { text: "What can you help me with?" },
3392
- { text: "Explain how you work" }
3393
- ];
3394
- function AgnoChatMessages({
3395
- className,
3396
- renderMessage,
3397
- userAvatar,
3398
- assistantAvatar,
3399
- messageItemProps,
3400
- emptyState,
3401
- suggestedPrompts = DEFAULT_PROMPTS,
3402
- children,
3403
- showThinkingIndicator = true,
3404
- renderThinkingIndicator
3405
- }) {
3406
- const { messages, isStreaming } = useAgnoChatContext();
3407
- const lastMessage = messages[messages.length - 1];
3408
- const isThinking = showThinkingIndicator && isStreaming && (!lastMessage || lastMessage.role !== "user") && !lastMessage?.content;
3409
- const resolvedEmptyState = children ?? emptyState ?? /* @__PURE__ */ jsxDEV38("div", {
3410
- className: "flex flex-col items-center gap-6",
3411
- children: [
3412
- /* @__PURE__ */ jsxDEV38("div", {
3413
- className: "relative",
3414
- children: [
3415
- /* @__PURE__ */ jsxDEV38("div", {
3416
- className: "h-16 w-16 rounded-2xl bg-primary/10 flex items-center justify-center",
3417
- children: /* @__PURE__ */ jsxDEV38(Bot2, {
3418
- className: "h-8 w-8 text-primary"
3419
- }, undefined, false, undefined, this)
3420
- }, undefined, false, undefined, this),
3421
- /* @__PURE__ */ jsxDEV38("div", {
3422
- className: "absolute -bottom-1 -right-1 h-5 w-5 rounded-full bg-green-500 border-2 border-background flex items-center justify-center",
3423
- children: /* @__PURE__ */ jsxDEV38("span", {
3424
- className: "h-2 w-2 rounded-full bg-white animate-pulse"
3425
- }, undefined, false, undefined, this)
3426
- }, undefined, false, undefined, this)
3427
- ]
3428
- }, undefined, true, undefined, this),
3429
- /* @__PURE__ */ jsxDEV38("div", {
3430
- className: "space-y-2 text-center",
3431
- children: [
3432
- /* @__PURE__ */ jsxDEV38("h3", {
3433
- className: "text-xl font-semibold tracking-tight",
3434
- children: "Welcome to Agno Chat"
3435
- }, undefined, false, undefined, this),
3436
- /* @__PURE__ */ jsxDEV38("p", {
3437
- className: "text-muted-foreground text-sm max-w-sm",
3438
- children: "Start a conversation with your AI agent. Ask questions, explore ideas, or run tools."
3439
- }, undefined, false, undefined, this)
3440
- ]
3441
- }, undefined, true, undefined, this),
3442
- suggestedPrompts.length > 0 && /* @__PURE__ */ jsxDEV38(AgnoChatSuggestedPrompts, {
3443
- prompts: suggestedPrompts
3444
- }, undefined, false, undefined, this)
3445
- ]
3446
- }, undefined, true, undefined, this);
3447
- return /* @__PURE__ */ jsxDEV38(Conversation, {
3448
- className: cn("relative flex-1 w-full", className),
3449
- children: [
3450
- /* @__PURE__ */ jsxDEV38(ScrollOnNewUserMessage, {
3451
- messageCount: messages.length
3452
- }, undefined, false, undefined, this),
3453
- /* @__PURE__ */ jsxDEV38(ConversationContent, {
3454
- className: "max-w-3xl mx-auto",
3455
- children: [
3456
- messages.length === 0 ? /* @__PURE__ */ jsxDEV38(ConversationEmptyState, {
3457
- children: resolvedEmptyState
3458
- }, undefined, false, undefined, this) : messages.map((message, index) => {
3459
- if (isThinking && index === messages.length - 1 && message === lastMessage)
3460
- return null;
3461
- return renderMessage ? renderMessage(message, index) : /* @__PURE__ */ jsxDEV38(AgnoMessageItem, {
3462
- message,
3463
- userAvatar,
3464
- assistantAvatar,
3465
- ...messageItemProps
3466
- }, `msg-${index}-${message.created_at}`, false, undefined, this);
3467
- }),
3468
- isThinking && /* @__PURE__ */ jsxDEV38("div", {
3469
- className: "py-2",
3470
- children: renderThinkingIndicator ?? /* @__PURE__ */ jsxDEV38(StreamingIndicator, {
3471
- avatar: assistantAvatar
3472
- }, undefined, false, undefined, this)
3473
- }, undefined, false, undefined, this)
3474
- ]
3475
- }, undefined, true, undefined, this),
3476
- /* @__PURE__ */ jsxDEV38(ConversationScrollButton, {}, undefined, false, undefined, this)
3477
- ]
3478
- }, undefined, true, undefined, this);
3271
+ function CancelButton({ onCancel }) {
3272
+ return /* @__PURE__ */ jsxDEV36(Button, {
3273
+ type: "button",
3274
+ variant: "destructive",
3275
+ size: "icon",
3276
+ className: "h-8 w-8 rounded-lg",
3277
+ onClick: onCancel,
3278
+ "aria-label": "Stop",
3279
+ children: /* @__PURE__ */ jsxDEV36(CircleStop, {
3280
+ className: "size-4"
3281
+ }, undefined, false, undefined, this)
3282
+ }, undefined, false, undefined, this);
3479
3283
  }
3480
-
3481
- // src/ui/composed/agno-chat/empty-state.tsx
3482
- import { jsxDEV as jsxDEV39 } from "react/jsx-dev-runtime";
3483
- function AgnoChatEmptyState({ children, className, ...props }) {
3484
- return /* @__PURE__ */ jsxDEV39("div", {
3485
- className: cn("flex flex-col items-center gap-6", className),
3486
- ...props,
3487
- children
3284
+ function SubmitButton({ disabled, status }) {
3285
+ const { textInput } = usePromptInputController();
3286
+ const hasText = textInput.value.trim().length > 0;
3287
+ return /* @__PURE__ */ jsxDEV36(PromptInputSubmit, {
3288
+ disabled: disabled || !hasText,
3289
+ status
3488
3290
  }, undefined, false, undefined, this);
3489
3291
  }
3490
-
3491
- // src/ui/composed/agno-chat/tool-status.tsx
3492
- import { Loader2 as Loader22, Wrench } from "lucide-react";
3493
- import { jsxDEV as jsxDEV40, Fragment as Fragment6 } from "react/jsx-dev-runtime";
3494
- function AgnoChatToolStatus({ className }) {
3495
- const { isPaused, isExecuting, pendingTools } = useAgnoChatContext();
3496
- if (!isPaused && !isExecuting)
3292
+ function AttachmentHeader() {
3293
+ const { files } = usePromptInputAttachments();
3294
+ if (files.length === 0)
3497
3295
  return null;
3498
- return /* @__PURE__ */ jsxDEV40("div", {
3499
- className: cn("px-4 py-2.5 border-t border-border bg-primary/5", className),
3500
- children: /* @__PURE__ */ jsxDEV40("div", {
3501
- className: "flex items-center gap-2.5 text-sm max-w-3xl mx-auto",
3502
- children: isExecuting ? /* @__PURE__ */ jsxDEV40(Fragment6, {
3503
- children: [
3504
- /* @__PURE__ */ jsxDEV40("div", {
3505
- className: "h-5 w-5 rounded-full bg-primary/10 flex items-center justify-center",
3506
- children: /* @__PURE__ */ jsxDEV40(Loader22, {
3507
- className: "h-3 w-3 animate-spin text-primary"
3508
- }, undefined, false, undefined, this)
3509
- }, undefined, false, undefined, this),
3510
- /* @__PURE__ */ jsxDEV40("span", {
3511
- className: "text-muted-foreground",
3512
- children: [
3513
- "Executing",
3514
- " ",
3515
- /* @__PURE__ */ jsxDEV40("span", {
3516
- className: "font-medium text-foreground",
3517
- children: pendingTools.length
3518
- }, undefined, false, undefined, this),
3519
- " tool",
3520
- pendingTools.length !== 1 ? "s" : "",
3521
- "..."
3522
- ]
3523
- }, undefined, true, undefined, this)
3524
- ]
3525
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV40(Fragment6, {
3526
- children: [
3527
- /* @__PURE__ */ jsxDEV40("div", {
3528
- className: "h-5 w-5 rounded-full bg-amber-500/10 flex items-center justify-center",
3529
- children: /* @__PURE__ */ jsxDEV40(Wrench, {
3530
- className: "h-3 w-3 text-amber-600 dark:text-amber-400"
3531
- }, undefined, false, undefined, this)
3532
- }, undefined, false, undefined, this),
3533
- /* @__PURE__ */ jsxDEV40("span", {
3534
- className: "text-muted-foreground",
3535
- children: [
3536
- "Preparing",
3537
- " ",
3538
- /* @__PURE__ */ jsxDEV40("span", {
3539
- className: "font-medium text-foreground",
3540
- children: pendingTools.length
3541
- }, undefined, false, undefined, this),
3542
- " tool",
3543
- pendingTools.length !== 1 ? "s" : "",
3544
- "..."
3545
- ]
3546
- }, undefined, true, undefined, this)
3547
- ]
3548
- }, undefined, true, undefined, this)
3549
- }, undefined, false, undefined, this)
3550
- }, undefined, false, undefined, this);
3551
- }
3552
-
3553
- // src/ui/composed/agno-chat/error-bar.tsx
3554
- import { jsxDEV as jsxDEV41 } from "react/jsx-dev-runtime";
3555
- function AgnoChatErrorBar({ className }) {
3556
- const { error, executionError } = useAgnoChatContext();
3557
- const message = error || executionError;
3558
- if (!message)
3559
- return null;
3560
- return /* @__PURE__ */ jsxDEV41("div", {
3561
- className: cn("px-4 py-2.5 bg-destructive/5 border-t border-destructive/20", className),
3562
- children: /* @__PURE__ */ jsxDEV41("p", {
3563
- className: "text-sm text-destructive max-w-3xl mx-auto",
3564
- children: message
3565
- }, undefined, false, undefined, this)
3566
- }, undefined, false, undefined, this);
3567
- }
3568
-
3569
- // src/ui/composed/AgnoChatInput.tsx
3570
- import { CircleStop } from "lucide-react";
3571
- import { jsxDEV as jsxDEV42 } from "react/jsx-dev-runtime";
3572
- var DEFAULT_ACCEPTED_FILE_TYPES = "image/*,audio/*,.pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.ppt,.pptx,.md,.json,.xml";
3573
- function dataUrlToBlob(dataUrl) {
3574
- const [header, base64] = dataUrl.split(",");
3575
- const mime = header.match(/:(.*?);/)?.[1] || "application/octet-stream";
3576
- const bytes = atob(base64);
3577
- const buf = new Uint8Array(bytes.length);
3578
- for (let i = 0;i < bytes.length; i++) {
3579
- buf[i] = bytes.charCodeAt(i);
3580
- }
3581
- return new Blob([buf], { type: mime });
3582
- }
3583
- function CancelButton({ onCancel }) {
3584
- return /* @__PURE__ */ jsxDEV42(Button, {
3585
- type: "button",
3586
- variant: "destructive",
3587
- size: "icon",
3588
- className: "h-8 w-8 rounded-lg",
3589
- onClick: onCancel,
3590
- "aria-label": "Stop",
3591
- children: /* @__PURE__ */ jsxDEV42(CircleStop, {
3592
- className: "size-4"
3593
- }, undefined, false, undefined, this)
3594
- }, undefined, false, undefined, this);
3595
- }
3596
- function SubmitButton({ disabled, status }) {
3597
- const { textInput } = usePromptInputController();
3598
- const hasText = textInput.value.trim().length > 0;
3599
- return /* @__PURE__ */ jsxDEV42(PromptInputSubmit, {
3600
- disabled: disabled || !hasText,
3601
- status
3602
- }, undefined, false, undefined, this);
3603
- }
3604
- function AttachmentHeader() {
3605
- const { files } = usePromptInputAttachments();
3606
- if (files.length === 0)
3607
- return null;
3608
- return /* @__PURE__ */ jsxDEV42(PromptInputHeader, {
3609
- children: /* @__PURE__ */ jsxDEV42(PromptInputAttachments, {
3610
- children: (attachment) => /* @__PURE__ */ jsxDEV42(PromptInputAttachment, {
3296
+ return /* @__PURE__ */ jsxDEV36(PromptInputHeader, {
3297
+ children: /* @__PURE__ */ jsxDEV36(PromptInputAttachments, {
3298
+ children: (attachment) => /* @__PURE__ */ jsxDEV36(PromptInputAttachment, {
3611
3299
  data: attachment
3612
3300
  }, undefined, false, undefined, this)
3613
3301
  }, undefined, false, undefined, this)
@@ -3622,7 +3310,7 @@ function TranscribeAudioRecorder({
3622
3310
  labels
3623
3311
  }) {
3624
3312
  const { textInput } = usePromptInputController();
3625
- return /* @__PURE__ */ jsxDEV42(AudioRecorder, {
3313
+ return /* @__PURE__ */ jsxDEV36(AudioRecorder, {
3626
3314
  mode: "transcribe",
3627
3315
  transcriptionEndpoint: endpoint,
3628
3316
  transcriptionHeaders: headers,
@@ -3643,22 +3331,19 @@ function AgnoChatInput({
3643
3331
  placeholder,
3644
3332
  className,
3645
3333
  fileUpload,
3646
- showAudioRecorder = false,
3334
+ audio,
3647
3335
  showAttachments = true,
3648
3336
  status,
3649
3337
  isStreaming,
3650
3338
  onCancel,
3651
3339
  allowCancelRun = false,
3652
3340
  extraTools,
3653
- audioMode = "send",
3654
- transcriptionEndpoint,
3655
- transcriptionHeaders,
3656
- parseTranscriptionResponse,
3657
- onRequestPermission,
3658
- audioRecorderLabels,
3659
3341
  dropZoneContainerRef,
3660
3342
  dropZoneProps
3661
3343
  }) {
3344
+ const resolvedAudio = normalizeAudio(audio);
3345
+ const audioEnabled = resolvedAudio?.enabled ?? false;
3346
+ const audioMode = resolvedAudio?.mode ?? "send";
3662
3347
  const handleSubmit = (message) => {
3663
3348
  const text = message.text?.trim() || "";
3664
3349
  const files = message.files || [];
@@ -3689,8 +3374,8 @@ function AgnoChatInput({
3689
3374
  };
3690
3375
  const computedStatus = status ?? (disabled ? "submitted" : undefined);
3691
3376
  const showCancelButton = allowCancelRun && isStreaming && onCancel;
3692
- return /* @__PURE__ */ jsxDEV42(PromptInputProvider, {
3693
- children: /* @__PURE__ */ jsxDEV42(PromptInput, {
3377
+ return /* @__PURE__ */ jsxDEV36(PromptInputProvider, {
3378
+ children: /* @__PURE__ */ jsxDEV36(PromptInput, {
3694
3379
  onSubmit: handleSubmit,
3695
3380
  accept: fileUpload?.accept ?? DEFAULT_ACCEPTED_FILE_TYPES,
3696
3381
  multiple: fileUpload?.multiple ?? true,
@@ -3700,52 +3385,52 @@ function AgnoChatInput({
3700
3385
  dragListenerTarget: dropZoneContainerRef,
3701
3386
  className: cn("w-full", className),
3702
3387
  children: [
3703
- /* @__PURE__ */ jsxDEV42(AttachmentHeader, {}, undefined, false, undefined, this),
3704
- /* @__PURE__ */ jsxDEV42(PromptInputBody, {
3705
- children: /* @__PURE__ */ jsxDEV42(PromptInputTextarea, {
3388
+ /* @__PURE__ */ jsxDEV36(AttachmentHeader, {}, undefined, false, undefined, this),
3389
+ /* @__PURE__ */ jsxDEV36(PromptInputBody, {
3390
+ children: /* @__PURE__ */ jsxDEV36(PromptInputTextarea, {
3706
3391
  placeholder: placeholder || "Type your message... (Enter to send, Shift+Enter for new line)",
3707
3392
  disabled
3708
3393
  }, undefined, false, undefined, this)
3709
3394
  }, undefined, false, undefined, this),
3710
- /* @__PURE__ */ jsxDEV42(PromptInputFooter, {
3395
+ /* @__PURE__ */ jsxDEV36(PromptInputFooter, {
3711
3396
  children: [
3712
- /* @__PURE__ */ jsxDEV42(PromptInputTools, {
3397
+ /* @__PURE__ */ jsxDEV36(PromptInputTools, {
3713
3398
  children: [
3714
- showAttachments && /* @__PURE__ */ jsxDEV42(PromptInputActionMenu, {
3399
+ showAttachments && /* @__PURE__ */ jsxDEV36(PromptInputActionMenu, {
3715
3400
  children: [
3716
- /* @__PURE__ */ jsxDEV42(PromptInputActionMenuTrigger, {}, undefined, false, undefined, this),
3717
- /* @__PURE__ */ jsxDEV42(PromptInputActionMenuContent, {
3718
- children: /* @__PURE__ */ jsxDEV42(PromptInputActionAddAttachments, {
3401
+ /* @__PURE__ */ jsxDEV36(PromptInputActionMenuTrigger, {}, undefined, false, undefined, this),
3402
+ /* @__PURE__ */ jsxDEV36(PromptInputActionMenuContent, {
3403
+ children: /* @__PURE__ */ jsxDEV36(PromptInputActionAddAttachments, {
3719
3404
  label: "Add files"
3720
3405
  }, undefined, false, undefined, this)
3721
3406
  }, undefined, false, undefined, this)
3722
3407
  ]
3723
3408
  }, undefined, true, undefined, this),
3724
- showAudioRecorder && (audioMode === "transcribe" && transcriptionEndpoint ? /* @__PURE__ */ jsxDEV42(TranscribeAudioRecorder, {
3725
- endpoint: transcriptionEndpoint,
3726
- headers: transcriptionHeaders,
3409
+ audioEnabled && (audioMode === "transcribe" && resolvedAudio?.endpoint ? /* @__PURE__ */ jsxDEV36(TranscribeAudioRecorder, {
3410
+ endpoint: resolvedAudio.endpoint,
3411
+ headers: resolvedAudio.headers,
3727
3412
  disabled,
3728
- parseResponse: parseTranscriptionResponse,
3729
- onRequestPermission,
3730
- labels: audioRecorderLabels
3731
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV42(AudioRecorder, {
3413
+ parseResponse: resolvedAudio.parseResponse,
3414
+ onRequestPermission: resolvedAudio.requestPermission,
3415
+ labels: resolvedAudio.labels
3416
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV36(AudioRecorder, {
3732
3417
  onRecordingComplete: handleAudioRecording,
3733
3418
  disabled,
3734
- onRequestPermission,
3735
- labels: audioRecorderLabels
3419
+ onRequestPermission: resolvedAudio?.requestPermission,
3420
+ labels: resolvedAudio?.labels
3736
3421
  }, undefined, false, undefined, this)),
3737
3422
  extraTools
3738
3423
  ]
3739
3424
  }, undefined, true, undefined, this),
3740
- showCancelButton ? /* @__PURE__ */ jsxDEV42(CancelButton, {
3425
+ showCancelButton ? /* @__PURE__ */ jsxDEV36(CancelButton, {
3741
3426
  onCancel
3742
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV42(SubmitButton, {
3427
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV36(SubmitButton, {
3743
3428
  disabled,
3744
3429
  status: computedStatus
3745
3430
  }, undefined, false, undefined, this)
3746
3431
  ]
3747
3432
  }, undefined, true, undefined, this),
3748
- showAttachments && /* @__PURE__ */ jsxDEV42(PromptInputDropZone, {
3433
+ showAttachments && /* @__PURE__ */ jsxDEV36(PromptInputDropZone, {
3749
3434
  ...dropZoneProps,
3750
3435
  container: dropZoneContainerRef
3751
3436
  }, undefined, false, undefined, this)
@@ -3753,6 +3438,437 @@ function AgnoChatInput({
3753
3438
  }, undefined, true, undefined, this)
3754
3439
  }, undefined, false, undefined, this);
3755
3440
  }
3441
+ // src/ui/composed/agno-chat/agno-chat.tsx
3442
+ import { useCallback as useCallback7, useMemo as useMemo3, useRef as useRef6 } from "react";
3443
+ import { useAgnoChat, useAgnoToolExecution } from "@rodrigocoliveira/agno-react";
3444
+
3445
+ // src/ui/composed/agno-chat/context.ts
3446
+ import { createContext as createContext3, useContext as useContext3 } from "react";
3447
+ var AgnoChatContext = createContext3(null);
3448
+ function useAgnoChatContext() {
3449
+ const ctx = useContext3(AgnoChatContext);
3450
+ if (!ctx) {
3451
+ throw new Error("useAgnoChatContext must be used within an <AgnoChat> provider. " + "Wrap your component tree with <AgnoChat>.");
3452
+ }
3453
+ return ctx;
3454
+ }
3455
+
3456
+ // src/ui/composed/agno-chat/agno-chat.tsx
3457
+ import { jsxDEV as jsxDEV37 } from "react/jsx-dev-runtime";
3458
+ function AgnoChatRoot({
3459
+ children,
3460
+ toolHandlers = {},
3461
+ autoExecuteTools = true,
3462
+ className,
3463
+ ...divProps
3464
+ }) {
3465
+ const chat = useAgnoChat();
3466
+ const toolExec = useAgnoToolExecution(toolHandlers, autoExecuteTools);
3467
+ const containerRef = useRef6(null);
3468
+ const sendRef = useRef6(chat.sendMessage);
3469
+ sendRef.current = chat.sendMessage;
3470
+ const handleSend = useCallback7(async (message) => {
3471
+ try {
3472
+ await sendRef.current(message);
3473
+ } catch {}
3474
+ }, []);
3475
+ const {
3476
+ messages,
3477
+ sendMessage,
3478
+ clearMessages,
3479
+ cancelRun,
3480
+ isStreaming,
3481
+ isRefreshing,
3482
+ isCancelling,
3483
+ currentRunId,
3484
+ error,
3485
+ state
3486
+ } = chat;
3487
+ const {
3488
+ isPaused,
3489
+ isExecuting,
3490
+ pendingTools,
3491
+ executeAndContinue,
3492
+ executeTools,
3493
+ continueWithResults,
3494
+ executionError
3495
+ } = toolExec;
3496
+ const contextValue = useMemo3(() => ({
3497
+ messages,
3498
+ sendMessage,
3499
+ clearMessages,
3500
+ cancelRun,
3501
+ isStreaming,
3502
+ isRefreshing,
3503
+ isCancelling: isCancelling ?? false,
3504
+ currentRunId,
3505
+ error,
3506
+ state,
3507
+ isPaused,
3508
+ isExecuting,
3509
+ pendingTools,
3510
+ executeAndContinue,
3511
+ executeTools,
3512
+ continueWithResults,
3513
+ executionError,
3514
+ handleSend,
3515
+ inputDisabled: isStreaming || isPaused,
3516
+ dropZoneContainerRef: containerRef
3517
+ }), [
3518
+ messages,
3519
+ sendMessage,
3520
+ clearMessages,
3521
+ cancelRun,
3522
+ isStreaming,
3523
+ isRefreshing,
3524
+ isCancelling,
3525
+ currentRunId,
3526
+ error,
3527
+ state,
3528
+ isPaused,
3529
+ isExecuting,
3530
+ pendingTools,
3531
+ executeAndContinue,
3532
+ executeTools,
3533
+ continueWithResults,
3534
+ executionError,
3535
+ handleSend
3536
+ ]);
3537
+ return /* @__PURE__ */ jsxDEV37(AgnoChatContext.Provider, {
3538
+ value: contextValue,
3539
+ children: /* @__PURE__ */ jsxDEV37("div", {
3540
+ ref: containerRef,
3541
+ className: cn("relative h-full flex flex-col", className),
3542
+ ...divProps,
3543
+ children
3544
+ }, undefined, false, undefined, this)
3545
+ }, undefined, false, undefined, this);
3546
+ }
3547
+
3548
+ // src/ui/composed/agno-chat/messages.tsx
3549
+ import { useEffect as useEffect6, useRef as useRef7 } from "react";
3550
+
3551
+ // src/ui/composed/agno-chat/suggested-prompts.tsx
3552
+ import { jsxDEV as jsxDEV38 } from "react/jsx-dev-runtime";
3553
+ function AgnoChatSuggestedPrompts({ className, prompts }) {
3554
+ const { handleSend } = useAgnoChatContext();
3555
+ if (prompts.length === 0)
3556
+ return null;
3557
+ return /* @__PURE__ */ jsxDEV38("div", {
3558
+ className: cn("grid grid-cols-2 gap-2 w-full max-w-md", className),
3559
+ children: prompts.map((prompt, idx) => /* @__PURE__ */ jsxDEV38("button", {
3560
+ onClick: () => handleSend(prompt.text),
3561
+ 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",
3562
+ children: [
3563
+ prompt.icon && /* @__PURE__ */ jsxDEV38("span", {
3564
+ className: "text-muted-foreground group-hover:text-primary transition-colors",
3565
+ children: prompt.icon
3566
+ }, undefined, false, undefined, this),
3567
+ /* @__PURE__ */ jsxDEV38("span", {
3568
+ className: "text-muted-foreground group-hover:text-foreground transition-colors text-xs leading-snug",
3569
+ children: prompt.text
3570
+ }, undefined, false, undefined, this)
3571
+ ]
3572
+ }, idx, true, undefined, this))
3573
+ }, undefined, false, undefined, this);
3574
+ }
3575
+
3576
+ // src/ui/composed/agno-chat/messages.tsx
3577
+ import { Bot as Bot2 } from "lucide-react";
3578
+ import { jsxDEV as jsxDEV39 } from "react/jsx-dev-runtime";
3579
+ function ScrollOnNewUserMessage({ messageCount }) {
3580
+ const { scrollToBottom } = useStickToBottomContext2();
3581
+ const prevCount = useRef7(messageCount);
3582
+ useEffect6(() => {
3583
+ if (messageCount > prevCount.current) {
3584
+ scrollToBottom("smooth");
3585
+ }
3586
+ prevCount.current = messageCount;
3587
+ }, [messageCount, scrollToBottom]);
3588
+ return null;
3589
+ }
3590
+ var DEFAULT_PROMPTS = [
3591
+ { text: "What can you help me with?" },
3592
+ { text: "Explain how you work" }
3593
+ ];
3594
+ function AgnoChatMessages({
3595
+ className,
3596
+ renderMessage,
3597
+ avatars,
3598
+ actions,
3599
+ showReasoning,
3600
+ showReferences,
3601
+ showTimestamp,
3602
+ showGenerativeUI,
3603
+ showToolCalls,
3604
+ showFilePreview,
3605
+ showImageLightbox,
3606
+ renderToolCall,
3607
+ renderContent,
3608
+ renderMedia,
3609
+ formatTimestamp,
3610
+ messageClassNames,
3611
+ emptyState,
3612
+ suggestedPrompts = DEFAULT_PROMPTS,
3613
+ children,
3614
+ showThinkingIndicator = true,
3615
+ renderThinkingIndicator
3616
+ }) {
3617
+ const { messages, isStreaming } = useAgnoChatContext();
3618
+ const lastMessage = messages[messages.length - 1];
3619
+ const isThinking = showThinkingIndicator && isStreaming && (!lastMessage || lastMessage.role !== "user") && !lastMessage?.content;
3620
+ let lastAssistantIndex = -1;
3621
+ for (let i = messages.length - 1;i >= 0; i--) {
3622
+ if (messages[i].role !== "user") {
3623
+ lastAssistantIndex = i;
3624
+ break;
3625
+ }
3626
+ }
3627
+ const messageItemProps = {
3628
+ ...showReasoning !== undefined && { showReasoning },
3629
+ ...showReferences !== undefined && { showReferences },
3630
+ ...showTimestamp !== undefined && { showTimestamp },
3631
+ ...showGenerativeUI !== undefined && { showGenerativeUI },
3632
+ ...showToolCalls !== undefined && { showToolCalls },
3633
+ ...showFilePreview !== undefined && { showFilePreview },
3634
+ ...showImageLightbox !== undefined && { showImageLightbox },
3635
+ ...renderToolCall !== undefined && { renderToolCall },
3636
+ ...renderContent !== undefined && { renderContent },
3637
+ ...renderMedia !== undefined && { renderMedia },
3638
+ ...formatTimestamp !== undefined && { formatTimestamp },
3639
+ ...messageClassNames !== undefined && { classNames: messageClassNames }
3640
+ };
3641
+ const resolvedEmptyState = children ?? emptyState ?? /* @__PURE__ */ jsxDEV39("div", {
3642
+ className: "flex flex-col items-center gap-6",
3643
+ children: [
3644
+ /* @__PURE__ */ jsxDEV39("div", {
3645
+ className: "relative",
3646
+ children: [
3647
+ /* @__PURE__ */ jsxDEV39("div", {
3648
+ className: "h-16 w-16 rounded-2xl bg-primary/10 flex items-center justify-center",
3649
+ children: /* @__PURE__ */ jsxDEV39(Bot2, {
3650
+ className: "h-8 w-8 text-primary"
3651
+ }, undefined, false, undefined, this)
3652
+ }, undefined, false, undefined, this),
3653
+ /* @__PURE__ */ jsxDEV39("div", {
3654
+ className: "absolute -bottom-1 -right-1 h-5 w-5 rounded-full bg-green-500 border-2 border-background flex items-center justify-center",
3655
+ children: /* @__PURE__ */ jsxDEV39("span", {
3656
+ className: "h-2 w-2 rounded-full bg-white animate-pulse"
3657
+ }, undefined, false, undefined, this)
3658
+ }, undefined, false, undefined, this)
3659
+ ]
3660
+ }, undefined, true, undefined, this),
3661
+ /* @__PURE__ */ jsxDEV39("div", {
3662
+ className: "space-y-2 text-center",
3663
+ children: [
3664
+ /* @__PURE__ */ jsxDEV39("h3", {
3665
+ className: "text-xl font-semibold tracking-tight",
3666
+ children: "Welcome to Agno Chat"
3667
+ }, undefined, false, undefined, this),
3668
+ /* @__PURE__ */ jsxDEV39("p", {
3669
+ className: "text-muted-foreground text-sm max-w-sm",
3670
+ children: "Start a conversation with your AI agent. Ask questions, explore ideas, or run tools."
3671
+ }, undefined, false, undefined, this)
3672
+ ]
3673
+ }, undefined, true, undefined, this),
3674
+ suggestedPrompts.length > 0 && /* @__PURE__ */ jsxDEV39(AgnoChatSuggestedPrompts, {
3675
+ prompts: suggestedPrompts
3676
+ }, undefined, false, undefined, this)
3677
+ ]
3678
+ }, undefined, true, undefined, this);
3679
+ return /* @__PURE__ */ jsxDEV39(Conversation, {
3680
+ className: cn("relative flex-1 w-full", className),
3681
+ children: [
3682
+ /* @__PURE__ */ jsxDEV39(ScrollOnNewUserMessage, {
3683
+ messageCount: messages.length
3684
+ }, undefined, false, undefined, this),
3685
+ /* @__PURE__ */ jsxDEV39(ConversationContent, {
3686
+ className: "max-w-3xl mx-auto",
3687
+ children: [
3688
+ messages.length === 0 ? /* @__PURE__ */ jsxDEV39(ConversationEmptyState, {
3689
+ children: resolvedEmptyState
3690
+ }, undefined, false, undefined, this) : messages.map((message, index) => {
3691
+ if (isThinking && index === messages.length - 1 && message === lastMessage)
3692
+ return null;
3693
+ return renderMessage ? renderMessage(message, index) : /* @__PURE__ */ jsxDEV39(AgnoMessageItem, {
3694
+ message,
3695
+ avatars,
3696
+ actions,
3697
+ isLastAssistantMessage: index === lastAssistantIndex,
3698
+ ...messageItemProps
3699
+ }, `msg-${index}-${message.created_at}`, false, undefined, this);
3700
+ }),
3701
+ isThinking && /* @__PURE__ */ jsxDEV39("div", {
3702
+ className: "py-2",
3703
+ children: renderThinkingIndicator ?? /* @__PURE__ */ jsxDEV39(StreamingIndicator, {
3704
+ avatar: avatars?.assistant
3705
+ }, undefined, false, undefined, this)
3706
+ }, undefined, false, undefined, this)
3707
+ ]
3708
+ }, undefined, true, undefined, this),
3709
+ /* @__PURE__ */ jsxDEV39(ConversationScrollButton, {}, undefined, false, undefined, this)
3710
+ ]
3711
+ }, undefined, true, undefined, this);
3712
+ }
3713
+
3714
+ // src/ui/composed/agno-chat/empty-state.tsx
3715
+ import { jsxDEV as jsxDEV40 } from "react/jsx-dev-runtime";
3716
+ function AgnoChatEmptyState({ children, className, ...props }) {
3717
+ return /* @__PURE__ */ jsxDEV40("div", {
3718
+ className: cn("flex flex-col items-center gap-6", className),
3719
+ ...props,
3720
+ children
3721
+ }, undefined, false, undefined, this);
3722
+ }
3723
+
3724
+ // src/ui/composed/agno-chat/tool-status.tsx
3725
+ import { Loader2 as Loader22, Wrench } from "lucide-react";
3726
+ import { jsxDEV as jsxDEV41, Fragment as Fragment6 } from "react/jsx-dev-runtime";
3727
+ function AgnoChatToolStatus({ className }) {
3728
+ const { isPaused, isExecuting, pendingTools } = useAgnoChatContext();
3729
+ if (!isPaused && !isExecuting)
3730
+ return null;
3731
+ return /* @__PURE__ */ jsxDEV41("div", {
3732
+ className: cn("px-4 py-2.5 border-t border-border bg-primary/5", className),
3733
+ children: /* @__PURE__ */ jsxDEV41("div", {
3734
+ className: "flex items-center gap-2.5 text-sm max-w-3xl mx-auto",
3735
+ children: isExecuting ? /* @__PURE__ */ jsxDEV41(Fragment6, {
3736
+ children: [
3737
+ /* @__PURE__ */ jsxDEV41("div", {
3738
+ className: "h-5 w-5 rounded-full bg-primary/10 flex items-center justify-center",
3739
+ children: /* @__PURE__ */ jsxDEV41(Loader22, {
3740
+ className: "h-3 w-3 animate-spin text-primary"
3741
+ }, undefined, false, undefined, this)
3742
+ }, undefined, false, undefined, this),
3743
+ /* @__PURE__ */ jsxDEV41("span", {
3744
+ className: "text-muted-foreground",
3745
+ children: [
3746
+ "Executing",
3747
+ " ",
3748
+ /* @__PURE__ */ jsxDEV41("span", {
3749
+ className: "font-medium text-foreground",
3750
+ children: pendingTools.length
3751
+ }, undefined, false, undefined, this),
3752
+ " tool",
3753
+ pendingTools.length !== 1 ? "s" : "",
3754
+ "..."
3755
+ ]
3756
+ }, undefined, true, undefined, this)
3757
+ ]
3758
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV41(Fragment6, {
3759
+ children: [
3760
+ /* @__PURE__ */ jsxDEV41("div", {
3761
+ className: "h-5 w-5 rounded-full bg-amber-500/10 flex items-center justify-center",
3762
+ children: /* @__PURE__ */ jsxDEV41(Wrench, {
3763
+ className: "h-3 w-3 text-amber-600 dark:text-amber-400"
3764
+ }, undefined, false, undefined, this)
3765
+ }, undefined, false, undefined, this),
3766
+ /* @__PURE__ */ jsxDEV41("span", {
3767
+ className: "text-muted-foreground",
3768
+ children: [
3769
+ "Preparing",
3770
+ " ",
3771
+ /* @__PURE__ */ jsxDEV41("span", {
3772
+ className: "font-medium text-foreground",
3773
+ children: pendingTools.length
3774
+ }, undefined, false, undefined, this),
3775
+ " tool",
3776
+ pendingTools.length !== 1 ? "s" : "",
3777
+ "..."
3778
+ ]
3779
+ }, undefined, true, undefined, this)
3780
+ ]
3781
+ }, undefined, true, undefined, this)
3782
+ }, undefined, false, undefined, this)
3783
+ }, undefined, false, undefined, this);
3784
+ }
3785
+
3786
+ // src/ui/composed/agno-chat/error-bar.tsx
3787
+ import { useState as useState9, useEffect as useEffect7, useRef as useRef8 } from "react";
3788
+ import { jsxDEV as jsxDEV42 } from "react/jsx-dev-runtime";
3789
+ function AgnoChatErrorBar({
3790
+ className,
3791
+ text,
3792
+ icon,
3793
+ dismissible = false,
3794
+ timeout = 1e4,
3795
+ children
3796
+ }) {
3797
+ const { error, executionError } = useAgnoChatContext();
3798
+ const [hidden, setHidden] = useState9(false);
3799
+ const timerRef = useRef8(null);
3800
+ const rawMessage = error || executionError;
3801
+ useEffect7(() => {
3802
+ if (!rawMessage)
3803
+ return;
3804
+ setHidden(false);
3805
+ if (timerRef.current) {
3806
+ clearTimeout(timerRef.current);
3807
+ timerRef.current = null;
3808
+ }
3809
+ if (timeout > 0) {
3810
+ timerRef.current = setTimeout(() => {
3811
+ setHidden(true);
3812
+ }, timeout);
3813
+ }
3814
+ return () => {
3815
+ if (timerRef.current) {
3816
+ clearTimeout(timerRef.current);
3817
+ timerRef.current = null;
3818
+ }
3819
+ };
3820
+ }, [rawMessage, timeout]);
3821
+ if (!rawMessage || hidden)
3822
+ return null;
3823
+ const displayMessage = text ?? rawMessage;
3824
+ const renderContent = () => {
3825
+ if (children) {
3826
+ return typeof children === "function" ? children(rawMessage) : children;
3827
+ }
3828
+ return /* @__PURE__ */ jsxDEV42("div", {
3829
+ className: "flex items-center gap-2 max-w-3xl mx-auto",
3830
+ children: [
3831
+ icon && /* @__PURE__ */ jsxDEV42("span", {
3832
+ className: "shrink-0",
3833
+ children: icon
3834
+ }, undefined, false, undefined, this),
3835
+ /* @__PURE__ */ jsxDEV42("p", {
3836
+ className: "text-sm text-destructive flex-1",
3837
+ children: displayMessage
3838
+ }, undefined, false, undefined, this),
3839
+ dismissible && /* @__PURE__ */ jsxDEV42("button", {
3840
+ type: "button",
3841
+ onClick: () => setHidden(true),
3842
+ className: "shrink-0 text-destructive/60 hover:text-destructive transition-colors",
3843
+ "aria-label": "Dismiss error",
3844
+ children: /* @__PURE__ */ jsxDEV42("svg", {
3845
+ xmlns: "http://www.w3.org/2000/svg",
3846
+ width: "16",
3847
+ height: "16",
3848
+ viewBox: "0 0 24 24",
3849
+ fill: "none",
3850
+ stroke: "currentColor",
3851
+ strokeWidth: "2",
3852
+ strokeLinecap: "round",
3853
+ strokeLinejoin: "round",
3854
+ children: [
3855
+ /* @__PURE__ */ jsxDEV42("path", {
3856
+ d: "M18 6 6 18"
3857
+ }, undefined, false, undefined, this),
3858
+ /* @__PURE__ */ jsxDEV42("path", {
3859
+ d: "m6 6 12 12"
3860
+ }, undefined, false, undefined, this)
3861
+ ]
3862
+ }, undefined, true, undefined, this)
3863
+ }, undefined, false, undefined, this)
3864
+ ]
3865
+ }, undefined, true, undefined, this);
3866
+ };
3867
+ return /* @__PURE__ */ jsxDEV42("div", {
3868
+ className: cn("px-4 py-2.5 bg-destructive/5 border-t border-destructive/20", className),
3869
+ children: renderContent()
3870
+ }, undefined, false, undefined, this);
3871
+ }
3756
3872
 
3757
3873
  // src/ui/composed/agno-chat/input.tsx
3758
3874
  import { jsxDEV as jsxDEV43 } from "react/jsx-dev-runtime";
@@ -3761,16 +3877,9 @@ function AgnoChatInputArea({
3761
3877
  children,
3762
3878
  placeholder,
3763
3879
  fileUpload,
3764
- showAudioRecorder = false,
3880
+ audio,
3765
3881
  showAttachments,
3766
3882
  extraTools,
3767
- chatInputProps,
3768
- audioMode,
3769
- transcriptionEndpoint,
3770
- transcriptionHeaders,
3771
- parseTranscriptionResponse,
3772
- onRequestPermission,
3773
- audioRecorderLabels,
3774
3883
  allowCancelRun = false,
3775
3884
  dropZoneProps
3776
3885
  }) {
@@ -3780,23 +3889,16 @@ function AgnoChatInputArea({
3780
3889
  children: /* @__PURE__ */ jsxDEV43("div", {
3781
3890
  className: "mx-auto px-4 py-2",
3782
3891
  children: children ? children({ onSend: handleSend, disabled: inputDisabled, isStreaming, isPaused }) : /* @__PURE__ */ jsxDEV43(AgnoChatInput, {
3783
- ...chatInputProps,
3784
3892
  onSend: handleSend,
3785
3893
  disabled: inputDisabled,
3786
3894
  isStreaming,
3787
3895
  onCancel: cancelRun,
3788
3896
  allowCancelRun,
3789
- placeholder: placeholder ?? chatInputProps?.placeholder ?? "Message your agent...",
3897
+ placeholder: placeholder ?? "Message your agent...",
3790
3898
  fileUpload,
3791
- showAudioRecorder,
3899
+ audio,
3792
3900
  showAttachments,
3793
3901
  extraTools,
3794
- audioMode,
3795
- transcriptionEndpoint,
3796
- transcriptionHeaders,
3797
- parseTranscriptionResponse,
3798
- onRequestPermission,
3799
- audioRecorderLabels,
3800
3902
  dropZoneContainerRef,
3801
3903
  dropZoneProps
3802
3904
  }, undefined, false, undefined, this)
@@ -3813,74 +3915,6 @@ var AgnoChat = Object.assign(AgnoChatRoot, {
3813
3915
  ErrorBar: AgnoChatErrorBar,
3814
3916
  Input: AgnoChatInputArea
3815
3917
  });
3816
-
3817
- // src/ui/composed/AgnoChatInterface.tsx
3818
- import { Bot as Bot3, Sparkles } from "lucide-react";
3819
- import { jsxDEV as jsxDEV44 } from "react/jsx-dev-runtime";
3820
- var DEFAULT_PROMPTS2 = [
3821
- { icon: /* @__PURE__ */ jsxDEV44(Sparkles, {
3822
- className: "h-3.5 w-3.5"
3823
- }, undefined, false, undefined, this), text: "What can you help me with?" },
3824
- { icon: /* @__PURE__ */ jsxDEV44(Bot3, {
3825
- className: "h-3.5 w-3.5"
3826
- }, undefined, false, undefined, this), text: "Explain how you work" }
3827
- ];
3828
- function AgnoChatInterface({
3829
- className,
3830
- classNames,
3831
- renderMessage,
3832
- renderInput,
3833
- emptyState,
3834
- headerSlot,
3835
- inputToolbarSlot,
3836
- suggestedPrompts = DEFAULT_PROMPTS2,
3837
- toolHandlers = {},
3838
- autoExecuteTools = true,
3839
- placeholder,
3840
- userAvatar,
3841
- assistantAvatar,
3842
- fileUpload,
3843
- showAudioRecorder = true,
3844
- showAttachments = true,
3845
- messageItemProps,
3846
- chatInputProps,
3847
- dropZoneLabel
3848
- }) {
3849
- return /* @__PURE__ */ jsxDEV44(AgnoChat, {
3850
- toolHandlers,
3851
- autoExecuteTools,
3852
- className: cn(classNames?.root, className),
3853
- children: [
3854
- headerSlot,
3855
- /* @__PURE__ */ jsxDEV44(AgnoChat.Messages, {
3856
- className: classNames?.messagesArea,
3857
- renderMessage,
3858
- userAvatar,
3859
- assistantAvatar,
3860
- messageItemProps,
3861
- emptyState,
3862
- suggestedPrompts
3863
- }, undefined, false, undefined, this),
3864
- /* @__PURE__ */ jsxDEV44(AgnoChat.ToolStatus, {
3865
- className: classNames?.toolStatusBar
3866
- }, undefined, false, undefined, this),
3867
- /* @__PURE__ */ jsxDEV44(AgnoChat.ErrorBar, {
3868
- className: classNames?.errorBar
3869
- }, undefined, false, undefined, this),
3870
- /* @__PURE__ */ jsxDEV44(AgnoChat.Input, {
3871
- className: classNames?.inputArea,
3872
- placeholder,
3873
- fileUpload,
3874
- showAudioRecorder,
3875
- showAttachments,
3876
- extraTools: inputToolbarSlot,
3877
- chatInputProps,
3878
- dropZoneProps: { className: classNames?.dropZone, label: dropZoneLabel },
3879
- children: renderInput ? ({ onSend, disabled }) => renderInput({ onSend, disabled }) : undefined
3880
- }, undefined, false, undefined, this)
3881
- ]
3882
- }, undefined, true, undefined, this);
3883
- }
3884
3918
  export {
3885
3919
  useProviderAttachments,
3886
3920
  usePromptInputDropZone,
@@ -4029,7 +4063,6 @@ export {
4029
4063
  AgnoChatSuggestedPrompts,
4030
4064
  AgnoChatRoot,
4031
4065
  AgnoChatMessages,
4032
- AgnoChatInterface,
4033
4066
  AgnoChatInputArea,
4034
4067
  AgnoChatInput,
4035
4068
  AgnoChatErrorBar,
@@ -4041,4 +4074,4 @@ export {
4041
4074
  Accordion
4042
4075
  };
4043
4076
 
4044
- //# debugId=2F56CC8E4E8AD83564756E2164756E21
4077
+ //# debugId=6E9B25001B68B11264756E2164756E21