@tetrascience-npm/tetrascience-react-ui 0.5.0-beta.39.1 → 0.5.0-beta.41.1
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/components/ai/attachments.cjs +2 -0
- package/dist/components/ai/attachments.cjs.map +1 -0
- package/dist/components/ai/attachments.js +224 -0
- package/dist/components/ai/attachments.js.map +1 -0
- package/dist/components/ai/chain-of-thought.cjs +2 -0
- package/dist/components/ai/chain-of-thought.cjs.map +1 -0
- package/dist/components/ai/chain-of-thought.js +145 -0
- package/dist/components/ai/chain-of-thought.js.map +1 -0
- package/dist/components/ai/confirmation.cjs +2 -0
- package/dist/components/ai/confirmation.cjs.map +1 -0
- package/dist/components/ai/confirmation.js +109 -0
- package/dist/components/ai/confirmation.js.map +1 -0
- package/dist/components/ai/context.cjs +2 -0
- package/dist/components/ai/context.cjs.map +1 -0
- package/dist/components/ai/context.js +266 -0
- package/dist/components/ai/context.js.map +1 -0
- package/dist/components/ai/conversation.cjs +4 -0
- package/dist/components/ai/conversation.cjs.map +1 -0
- package/dist/components/ai/conversation.js +108 -0
- package/dist/components/ai/conversation.js.map +1 -0
- package/dist/components/ai/inline-citation.cjs +2 -0
- package/dist/components/ai/inline-citation.cjs.map +1 -0
- package/dist/components/ai/inline-citation.js +182 -0
- package/dist/components/ai/inline-citation.js.map +1 -0
- package/dist/components/ai/message.cjs +2 -0
- package/dist/components/ai/message.cjs.map +1 -0
- package/dist/components/ai/message.js +237 -0
- package/dist/components/ai/message.js.map +1 -0
- package/dist/components/ai/model-selector.cjs +2 -0
- package/dist/components/ai/model-selector.cjs.map +1 -0
- package/dist/components/ai/model-selector.js +77 -0
- package/dist/components/ai/model-selector.js.map +1 -0
- package/dist/components/ai/prompt-input.cjs +2 -0
- package/dist/components/ai/prompt-input.cjs.map +1 -0
- package/dist/components/ai/prompt-input.js +774 -0
- package/dist/components/ai/prompt-input.js.map +1 -0
- package/dist/components/ai/queue.cjs +2 -0
- package/dist/components/ai/queue.cjs.map +1 -0
- package/dist/components/ai/queue.js +209 -0
- package/dist/components/ai/queue.js.map +1 -0
- package/dist/components/ai/reasoning.cjs +2 -0
- package/dist/components/ai/reasoning.cjs.map +1 -0
- package/dist/components/ai/reasoning.js +129 -0
- package/dist/components/ai/reasoning.js.map +1 -0
- package/dist/components/ai/shimmer.cjs +2 -0
- package/dist/components/ai/shimmer.cjs.map +1 -0
- package/dist/components/ai/shimmer.js +49 -0
- package/dist/components/ai/shimmer.js.map +1 -0
- package/dist/components/ai/sources.cjs +2 -0
- package/dist/components/ai/sources.cjs.map +1 -0
- package/dist/components/ai/sources.js +54 -0
- package/dist/components/ai/sources.js.map +1 -0
- package/dist/components/ai/speech-input.cjs +2 -0
- package/dist/components/ai/speech-input.cjs.map +1 -0
- package/dist/components/ai/speech-input.js +123 -0
- package/dist/components/ai/speech-input.js.map +1 -0
- package/dist/components/ai/stream-status.cjs +2 -0
- package/dist/components/ai/stream-status.cjs.map +1 -0
- package/dist/components/ai/stream-status.js +106 -0
- package/dist/components/ai/stream-status.js.map +1 -0
- package/dist/components/ai/suggestion.cjs +2 -0
- package/dist/components/ai/suggestion.cjs.map +1 -0
- package/dist/components/ai/suggestion.js +38 -0
- package/dist/components/ai/suggestion.js.map +1 -0
- package/dist/components/ai/task.cjs +2 -0
- package/dist/components/ai/task.cjs.map +1 -0
- package/dist/components/ai/task.js +94 -0
- package/dist/components/ai/task.js.map +1 -0
- package/dist/components/ai/tool.cjs +2 -0
- package/dist/components/ai/tool.cjs.map +1 -0
- package/dist/components/ai/tool.js +143 -0
- package/dist/components/ai/tool.js.map +1 -0
- package/dist/components/composed/Chat/Chat.cjs +2 -0
- package/dist/components/composed/Chat/Chat.cjs.map +1 -0
- package/dist/components/composed/Chat/Chat.js +167 -0
- package/dist/components/composed/Chat/Chat.js.map +1 -0
- package/dist/components/ui/code-block.cjs +4 -0
- package/dist/components/ui/code-block.cjs.map +1 -0
- package/dist/components/ui/code-block.js +306 -0
- package/dist/components/ui/code-block.js.map +1 -0
- package/dist/components/ui/progress.cjs +2 -0
- package/dist/components/ui/progress.cjs.map +1 -0
- package/dist/components/ui/progress.js +32 -0
- package/dist/components/ui/progress.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1145 -0
- package/dist/index.js +574 -372
- package/dist/index.js.map +1 -1
- package/dist/index.tailwind.css +1 -1
- package/package.json +12 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback as i } from "react";
|
|
3
|
+
import { Button as p } from "../ui/button.js";
|
|
4
|
+
import { cn as l } from "../../lib/utils.js";
|
|
5
|
+
const w = ({
|
|
6
|
+
className: o,
|
|
7
|
+
children: r,
|
|
8
|
+
...e
|
|
9
|
+
}) => /* @__PURE__ */ t("div", { className: "w-full overflow-x-auto py-1", ...e, children: /* @__PURE__ */ t("div", { className: l("flex w-max flex-nowrap items-center gap-2 px-4", o), children: r }) }), h = ({
|
|
10
|
+
suggestion: o,
|
|
11
|
+
onClick: r,
|
|
12
|
+
className: e,
|
|
13
|
+
variant: n = "outline",
|
|
14
|
+
size: m = "sm",
|
|
15
|
+
children: a,
|
|
16
|
+
...c
|
|
17
|
+
}) => {
|
|
18
|
+
const s = i(() => {
|
|
19
|
+
r?.(o);
|
|
20
|
+
}, [r, o]);
|
|
21
|
+
return /* @__PURE__ */ t(
|
|
22
|
+
p,
|
|
23
|
+
{
|
|
24
|
+
className: l("cursor-pointer rounded-full px-4", e),
|
|
25
|
+
onClick: s,
|
|
26
|
+
size: m,
|
|
27
|
+
type: "button",
|
|
28
|
+
variant: n,
|
|
29
|
+
...c,
|
|
30
|
+
children: a || o
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
export {
|
|
35
|
+
h as Suggestion,
|
|
36
|
+
w as Suggestions
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=suggestion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggestion.js","sources":["../../../src/components/ai/suggestion.tsx"],"sourcesContent":["import { useCallback } from \"react\";\n\nimport type { ComponentProps } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\n\nexport type SuggestionsProps = ComponentProps<\"div\">;\n\nexport const Suggestions = ({\n className,\n children,\n ...props\n}: SuggestionsProps) => (\n <div className=\"w-full overflow-x-auto py-1\" {...props}>\n <div className={cn(\"flex w-max flex-nowrap items-center gap-2 px-4\", className)}>\n {children}\n </div>\n </div>\n);\n\nexport type SuggestionProps = Omit<ComponentProps<typeof Button>, \"onClick\"> & {\n suggestion: string;\n onClick?: (suggestion: string) => void;\n};\n\nexport const Suggestion = ({\n suggestion,\n onClick,\n className,\n variant = \"outline\",\n size = \"sm\",\n children,\n ...props\n}: SuggestionProps) => {\n const handleClick = useCallback(() => {\n onClick?.(suggestion);\n }, [onClick, suggestion]);\n\n return (\n <Button\n className={cn(\"cursor-pointer rounded-full px-4\", className)}\n onClick={handleClick}\n size={size}\n type=\"button\"\n variant={variant}\n {...props}\n >\n {children || suggestion}\n </Button>\n );\n};\n"],"names":["Suggestions","className","children","props","jsx","cn","Suggestion","suggestion","onClick","variant","size","handleClick","useCallback","Button"],"mappings":";;;;AASO,MAAMA,IAAc,CAAC;AAAA,EAC1B,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,MACE,gBAAAC,EAAC,OAAA,EAAI,WAAU,+BAA+B,GAAGD,GAC/C,UAAA,gBAAAC,EAAC,OAAA,EAAI,WAAWC,EAAG,kDAAkDJ,CAAS,GAC3E,UAAAC,GACH,EAAA,CACF,GAQWI,IAAa,CAAC;AAAA,EACzB,YAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAP;AAAA,EACA,SAAAQ,IAAU;AAAA,EACV,MAAAC,IAAO;AAAA,EACP,UAAAR;AAAA,EACA,GAAGC;AACL,MAAuB;AACrB,QAAMQ,IAAcC,EAAY,MAAM;AACpC,IAAAJ,IAAUD,CAAU;AAAA,EACtB,GAAG,CAACC,GAASD,CAAU,CAAC;AAExB,SACE,gBAAAH;AAAA,IAACS;AAAA,IAAA;AAAA,MACC,WAAWR,EAAG,oCAAoCJ,CAAS;AAAA,MAC3D,SAASU;AAAA,MACT,MAAAD;AAAA,MACA,MAAK;AAAA,MACL,SAAAD;AAAA,MACC,GAAGN;AAAA,MAEH,UAAAD,KAAYK;AAAA,IAAA;AAAA,EAAA;AAGnB;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),T=require("@radix-ui/react-use-controllable-state"),m=require("lucide-react"),a=require("react"),u=require("../ui/collapsible.cjs"),r=require("../../lib/utils.cjs"),b=({children:s,className:e,...o})=>t.jsx("div",{className:r.cn("inline-flex items-center gap-1 rounded-md border bg-secondary px-1.5 py-0.5 text-foreground text-xs",e),...o,children:s}),h=({children:s,className:e,...o})=>t.jsx("div",{className:r.cn("text-muted-foreground text-sm",e),...o,children:s}),j=1e3,v=({defaultOpen:s=!0,isStreaming:e=!1,open:o,onOpenChange:l,className:f,...x})=>{const[c,n]=T.useControllableState({defaultProp:s,onChange:l,prop:o}),d=a.useRef(e),[p,g]=a.useState(!1);a.useEffect(()=>{e&&(d.current=!0)},[e]),a.useEffect(()=>{if(d.current&&!e&&c&&!p){const i=setTimeout(()=>{n(!1),g(!0)},j);return()=>clearTimeout(i)}},[e,c,n,p]);const C=a.useCallback(i=>n(i),[n]);return t.jsx(u.Collapsible,{className:r.cn(f),onOpenChange:C,open:c,...x})},k=({children:s,className:e,title:o,...l})=>t.jsx(u.CollapsibleTrigger,{asChild:!0,className:r.cn("group",e),...l,children:s??t.jsxs("div",{className:"group flex w-full cursor-pointer items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground",children:[t.jsx(m.SearchIcon,{className:"size-4"}),t.jsx("p",{className:"text-sm",children:o}),t.jsx(m.ChevronDownIcon,{className:"size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100 group-data-[state=open]:rotate-180 group-data-[state=open]:opacity-100","data-slot":"collapsible-chevron"})]})}),N=({children:s,className:e,...o})=>t.jsx(u.CollapsibleContent,{className:r.cn("data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",e),...o,children:t.jsx("div",{className:"mt-4 space-y-2 border-border border-l-2 pl-4",children:s})});exports.Task=v;exports.TaskContent=N;exports.TaskItem=h;exports.TaskItemFile=b;exports.TaskTrigger=k;
|
|
2
|
+
//# sourceMappingURL=task.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.cjs","sources":["../../../src/components/ai/task.tsx"],"sourcesContent":["import { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { ChevronDownIcon, SearchIcon } from \"lucide-react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport type { ComponentProps } from \"react\";\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\n\nexport type TaskItemFileProps = ComponentProps<\"div\">;\n\nexport const TaskItemFile = ({\n children,\n className,\n ...props\n}: TaskItemFileProps) => (\n <div\n className={cn(\n \"inline-flex items-center gap-1 rounded-md border bg-secondary px-1.5 py-0.5 text-foreground text-xs\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport type TaskItemProps = ComponentProps<\"div\">;\n\nexport const TaskItem = ({ children, className, ...props }: TaskItemProps) => (\n <div className={cn(\"text-muted-foreground text-sm\", className)} {...props}>\n {children}\n </div>\n);\n\nconst AUTO_CLOSE_DELAY = 1000;\n\nexport type TaskProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n};\n\nexport const Task = ({\n defaultOpen = true,\n isStreaming = false,\n open,\n onOpenChange,\n className,\n ...props\n}: TaskProps) => {\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n\n useEffect(() => {\n if (isStreaming) hasEverStreamedRef.current = true;\n }, [isStreaming]);\n\n useEffect(() => {\n if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n return () => clearTimeout(timer);\n }\n }, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => setIsOpen(newOpen),\n [setIsOpen]\n );\n\n return (\n <Collapsible\n className={cn(className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n />\n );\n};\n\nexport type TaskTriggerProps = ComponentProps<typeof CollapsibleTrigger> & {\n title: string;\n};\n\nexport const TaskTrigger = ({\n children,\n className,\n title,\n ...props\n}: TaskTriggerProps) => (\n <CollapsibleTrigger asChild className={cn(\"group\", className)} {...props}>\n {children ?? (\n <div className=\"group flex w-full cursor-pointer items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground\">\n <SearchIcon className=\"size-4\" />\n <p className=\"text-sm\">{title}</p>\n <ChevronDownIcon\n className=\"size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100 group-data-[state=open]:rotate-180 group-data-[state=open]:opacity-100\"\n data-slot=\"collapsible-chevron\"\n />\n </div>\n )}\n </CollapsibleTrigger>\n);\n\nexport type TaskContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const TaskContent = ({\n children,\n className,\n ...props\n}: TaskContentProps) => (\n <CollapsibleContent\n className={cn(\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className\n )}\n {...props}\n >\n <div className=\"mt-4 space-y-2 border-border border-l-2 pl-4\">\n {children}\n </div>\n </CollapsibleContent>\n);\n"],"names":["TaskItemFile","children","className","props","jsx","cn","TaskItem","AUTO_CLOSE_DELAY","Task","defaultOpen","isStreaming","open","onOpenChange","isOpen","setIsOpen","useControllableState","hasEverStreamedRef","useRef","hasAutoClosed","setHasAutoClosed","useState","useEffect","timer","handleOpenChange","useCallback","newOpen","Collapsible","TaskTrigger","title","CollapsibleTrigger","jsxs","SearchIcon","ChevronDownIcon","TaskContent","CollapsibleContent"],"mappings":"0RAeaA,EAAe,CAAC,CAC3B,SAAAC,EACA,UAAAC,EACA,GAAGC,CACL,IACEC,EAAAA,IAAC,MAAA,CACC,UAAWC,EAAAA,GACT,sGACAH,CAAA,EAED,GAAGC,EAEH,SAAAF,CAAA,CACH,EAKWK,EAAW,CAAC,CAAE,SAAAL,EAAU,UAAAC,EAAW,GAAGC,CAAA,IACjDC,MAAC,MAAA,CAAI,UAAWC,EAAAA,GAAG,gCAAiCH,CAAS,EAAI,GAAGC,EACjE,SAAAF,CAAA,CACH,EAGIM,EAAmB,IAMZC,EAAO,CAAC,CACnB,YAAAC,EAAc,GACd,YAAAC,EAAc,GACd,KAAAC,EACA,aAAAC,EACA,UAAAV,EACA,GAAGC,CACL,IAAiB,CACf,KAAM,CAACU,EAAQC,CAAS,EAAIC,uBAA8B,CACxD,YAAaN,EACb,SAAUG,EACV,KAAMD,CAAA,CACP,EAEKK,EAAqBC,EAAAA,OAAOP,CAAW,EACvC,CAACQ,EAAeC,CAAgB,EAAIC,EAAAA,SAAS,EAAK,EAExDC,EAAAA,UAAU,IAAM,CACVX,MAAgC,QAAU,GAChD,EAAG,CAACA,CAAW,CAAC,EAEhBW,EAAAA,UAAU,IAAM,CACd,GAAIL,EAAmB,SAAW,CAACN,GAAeG,GAAU,CAACK,EAAe,CAC1E,MAAMI,EAAQ,WAAW,IAAM,CAC7BR,EAAU,EAAK,EACfK,EAAiB,EAAI,CACvB,EAAGZ,CAAgB,EACnB,MAAO,IAAM,aAAae,CAAK,CACjC,CACF,EAAG,CAACZ,EAAaG,EAAQC,EAAWI,CAAa,CAAC,EAElD,MAAMK,EAAmBC,EAAAA,YACtBC,GAAqBX,EAAUW,CAAO,EACvC,CAACX,CAAS,CAAA,EAGZ,OACEV,EAAAA,IAACsB,EAAAA,YAAA,CACC,UAAWrB,EAAAA,GAAGH,CAAS,EACvB,aAAcqB,EACd,KAAMV,EACL,GAAGV,CAAA,CAAA,CAGV,EAMawB,EAAc,CAAC,CAC1B,SAAA1B,EACA,UAAAC,EACA,MAAA0B,EACA,GAAGzB,CACL,IACEC,EAAAA,IAACyB,EAAAA,mBAAA,CAAmB,QAAO,GAAC,UAAWxB,EAAAA,GAAG,QAASH,CAAS,EAAI,GAAGC,EAChE,SAAAF,GACC6B,EAAAA,KAAC,MAAA,CAAI,UAAU,4HACb,SAAA,CAAA1B,EAAAA,IAAC2B,EAAAA,WAAA,CAAW,UAAU,QAAA,CAAS,EAC/B3B,EAAAA,IAAC,IAAA,CAAE,UAAU,UAAW,SAAAwB,EAAM,EAC9BxB,EAAAA,IAAC4B,EAAAA,gBAAA,CACC,UAAU,iKACV,YAAU,qBAAA,CAAA,CACZ,CAAA,CACF,CAAA,CAEJ,EAKWC,EAAc,CAAC,CAC1B,SAAAhC,EACA,UAAAC,EACA,GAAGC,CACL,IACEC,EAAAA,IAAC8B,EAAAA,mBAAA,CACC,UAAW7B,EAAAA,GACT,gNACAH,CAAA,EAED,GAAGC,EAEJ,SAAAC,EAAAA,IAAC,MAAA,CAAI,UAAU,+CACZ,SAAAH,CAAA,CACH,CAAA,CACF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { jsx as s, jsxs as h } from "react/jsx-runtime";
|
|
2
|
+
import { useControllableState as x } from "@radix-ui/react-use-controllable-state";
|
|
3
|
+
import { SearchIcon as C, ChevronDownIcon as b } from "lucide-react";
|
|
4
|
+
import { useRef as v, useState as N, useEffect as d, useCallback as T } from "react";
|
|
5
|
+
import { Collapsible as y, CollapsibleContent as k, CollapsibleTrigger as O } from "../ui/collapsible.js";
|
|
6
|
+
import { cn as a } from "../../lib/utils.js";
|
|
7
|
+
const L = ({
|
|
8
|
+
children: t,
|
|
9
|
+
className: e,
|
|
10
|
+
...o
|
|
11
|
+
}) => /* @__PURE__ */ s(
|
|
12
|
+
"div",
|
|
13
|
+
{
|
|
14
|
+
className: a(
|
|
15
|
+
"inline-flex items-center gap-1 rounded-md border bg-secondary px-1.5 py-0.5 text-foreground text-xs",
|
|
16
|
+
e
|
|
17
|
+
),
|
|
18
|
+
...o,
|
|
19
|
+
children: t
|
|
20
|
+
}
|
|
21
|
+
), R = ({ children: t, className: e, ...o }) => /* @__PURE__ */ s("div", { className: a("text-muted-foreground text-sm", e), ...o, children: t }), I = 1e3, _ = ({
|
|
22
|
+
defaultOpen: t = !0,
|
|
23
|
+
isStreaming: e = !1,
|
|
24
|
+
open: o,
|
|
25
|
+
onOpenChange: n,
|
|
26
|
+
className: u,
|
|
27
|
+
...m
|
|
28
|
+
}) => {
|
|
29
|
+
const [l, r] = x({
|
|
30
|
+
defaultProp: t,
|
|
31
|
+
onChange: n,
|
|
32
|
+
prop: o
|
|
33
|
+
}), p = v(e), [i, f] = N(!1);
|
|
34
|
+
d(() => {
|
|
35
|
+
e && (p.current = !0);
|
|
36
|
+
}, [e]), d(() => {
|
|
37
|
+
if (p.current && !e && l && !i) {
|
|
38
|
+
const c = setTimeout(() => {
|
|
39
|
+
r(!1), f(!0);
|
|
40
|
+
}, I);
|
|
41
|
+
return () => clearTimeout(c);
|
|
42
|
+
}
|
|
43
|
+
}, [e, l, r, i]);
|
|
44
|
+
const g = T(
|
|
45
|
+
(c) => r(c),
|
|
46
|
+
[r]
|
|
47
|
+
);
|
|
48
|
+
return /* @__PURE__ */ s(
|
|
49
|
+
y,
|
|
50
|
+
{
|
|
51
|
+
className: a(u),
|
|
52
|
+
onOpenChange: g,
|
|
53
|
+
open: l,
|
|
54
|
+
...m
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}, F = ({
|
|
58
|
+
children: t,
|
|
59
|
+
className: e,
|
|
60
|
+
title: o,
|
|
61
|
+
...n
|
|
62
|
+
}) => /* @__PURE__ */ s(O, { asChild: !0, className: a("group", e), ...n, children: t ?? /* @__PURE__ */ h("div", { className: "group flex w-full cursor-pointer items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground", children: [
|
|
63
|
+
/* @__PURE__ */ s(C, { className: "size-4" }),
|
|
64
|
+
/* @__PURE__ */ s("p", { className: "text-sm", children: o }),
|
|
65
|
+
/* @__PURE__ */ s(
|
|
66
|
+
b,
|
|
67
|
+
{
|
|
68
|
+
className: "size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100 group-data-[state=open]:rotate-180 group-data-[state=open]:opacity-100",
|
|
69
|
+
"data-slot": "collapsible-chevron"
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
] }) }), H = ({
|
|
73
|
+
children: t,
|
|
74
|
+
className: e,
|
|
75
|
+
...o
|
|
76
|
+
}) => /* @__PURE__ */ s(
|
|
77
|
+
k,
|
|
78
|
+
{
|
|
79
|
+
className: a(
|
|
80
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
81
|
+
e
|
|
82
|
+
),
|
|
83
|
+
...o,
|
|
84
|
+
children: /* @__PURE__ */ s("div", { className: "mt-4 space-y-2 border-border border-l-2 pl-4", children: t })
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
export {
|
|
88
|
+
_ as Task,
|
|
89
|
+
H as TaskContent,
|
|
90
|
+
R as TaskItem,
|
|
91
|
+
L as TaskItemFile,
|
|
92
|
+
F as TaskTrigger
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.js","sources":["../../../src/components/ai/task.tsx"],"sourcesContent":["import { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { ChevronDownIcon, SearchIcon } from \"lucide-react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport type { ComponentProps } from \"react\";\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\n\nexport type TaskItemFileProps = ComponentProps<\"div\">;\n\nexport const TaskItemFile = ({\n children,\n className,\n ...props\n}: TaskItemFileProps) => (\n <div\n className={cn(\n \"inline-flex items-center gap-1 rounded-md border bg-secondary px-1.5 py-0.5 text-foreground text-xs\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport type TaskItemProps = ComponentProps<\"div\">;\n\nexport const TaskItem = ({ children, className, ...props }: TaskItemProps) => (\n <div className={cn(\"text-muted-foreground text-sm\", className)} {...props}>\n {children}\n </div>\n);\n\nconst AUTO_CLOSE_DELAY = 1000;\n\nexport type TaskProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n};\n\nexport const Task = ({\n defaultOpen = true,\n isStreaming = false,\n open,\n onOpenChange,\n className,\n ...props\n}: TaskProps) => {\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n\n useEffect(() => {\n if (isStreaming) hasEverStreamedRef.current = true;\n }, [isStreaming]);\n\n useEffect(() => {\n if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n return () => clearTimeout(timer);\n }\n }, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => setIsOpen(newOpen),\n [setIsOpen]\n );\n\n return (\n <Collapsible\n className={cn(className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n />\n );\n};\n\nexport type TaskTriggerProps = ComponentProps<typeof CollapsibleTrigger> & {\n title: string;\n};\n\nexport const TaskTrigger = ({\n children,\n className,\n title,\n ...props\n}: TaskTriggerProps) => (\n <CollapsibleTrigger asChild className={cn(\"group\", className)} {...props}>\n {children ?? (\n <div className=\"group flex w-full cursor-pointer items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground\">\n <SearchIcon className=\"size-4\" />\n <p className=\"text-sm\">{title}</p>\n <ChevronDownIcon\n className=\"size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100 group-data-[state=open]:rotate-180 group-data-[state=open]:opacity-100\"\n data-slot=\"collapsible-chevron\"\n />\n </div>\n )}\n </CollapsibleTrigger>\n);\n\nexport type TaskContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const TaskContent = ({\n children,\n className,\n ...props\n}: TaskContentProps) => (\n <CollapsibleContent\n className={cn(\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className\n )}\n {...props}\n >\n <div className=\"mt-4 space-y-2 border-border border-l-2 pl-4\">\n {children}\n </div>\n </CollapsibleContent>\n);\n"],"names":["TaskItemFile","children","className","props","jsx","cn","TaskItem","AUTO_CLOSE_DELAY","Task","defaultOpen","isStreaming","open","onOpenChange","isOpen","setIsOpen","useControllableState","hasEverStreamedRef","useRef","hasAutoClosed","setHasAutoClosed","useState","useEffect","timer","handleOpenChange","useCallback","newOpen","Collapsible","TaskTrigger","title","CollapsibleTrigger","jsxs","SearchIcon","ChevronDownIcon","TaskContent","CollapsibleContent"],"mappings":";;;;;;AAeO,MAAMA,IAAe,CAAC;AAAA,EAC3B,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,MACE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,IAEH,UAAAF;AAAA,EAAA;AACH,GAKWK,IAAW,CAAC,EAAE,UAAAL,GAAU,WAAAC,GAAW,GAAGC,EAAA,MACjD,gBAAAC,EAAC,OAAA,EAAI,WAAWC,EAAG,iCAAiCH,CAAS,GAAI,GAAGC,GACjE,UAAAF,EAAA,CACH,GAGIM,IAAmB,KAMZC,IAAO,CAAC;AAAA,EACnB,aAAAC,IAAc;AAAA,EACd,aAAAC,IAAc;AAAA,EACd,MAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAV;AAAA,EACA,GAAGC;AACL,MAAiB;AACf,QAAM,CAACU,GAAQC,CAAS,IAAIC,EAA8B;AAAA,IACxD,aAAaN;AAAA,IACb,UAAUG;AAAA,IACV,MAAMD;AAAA,EAAA,CACP,GAEKK,IAAqBC,EAAOP,CAAW,GACvC,CAACQ,GAAeC,CAAgB,IAAIC,EAAS,EAAK;AAExD,EAAAC,EAAU,MAAM;AACd,IAAIX,QAAgC,UAAU;AAAA,EAChD,GAAG,CAACA,CAAW,CAAC,GAEhBW,EAAU,MAAM;AACd,QAAIL,EAAmB,WAAW,CAACN,KAAeG,KAAU,CAACK,GAAe;AAC1E,YAAMI,IAAQ,WAAW,MAAM;AAC7B,QAAAR,EAAU,EAAK,GACfK,EAAiB,EAAI;AAAA,MACvB,GAAGZ,CAAgB;AACnB,aAAO,MAAM,aAAae,CAAK;AAAA,IACjC;AAAA,EACF,GAAG,CAACZ,GAAaG,GAAQC,GAAWI,CAAa,CAAC;AAElD,QAAMK,IAAmBC;AAAA,IACvB,CAACC,MAAqBX,EAAUW,CAAO;AAAA,IACvC,CAACX,CAAS;AAAA,EAAA;AAGZ,SACE,gBAAAV;AAAA,IAACsB;AAAA,IAAA;AAAA,MACC,WAAWrB,EAAGH,CAAS;AAAA,MACvB,cAAcqB;AAAA,MACd,MAAMV;AAAA,MACL,GAAGV;AAAA,IAAA;AAAA,EAAA;AAGV,GAMawB,IAAc,CAAC;AAAA,EAC1B,UAAA1B;AAAA,EACA,WAAAC;AAAA,EACA,OAAA0B;AAAA,EACA,GAAGzB;AACL,MACE,gBAAAC,EAACyB,GAAA,EAAmB,SAAO,IAAC,WAAWxB,EAAG,SAASH,CAAS,GAAI,GAAGC,GAChE,UAAAF,KACC,gBAAA6B,EAAC,OAAA,EAAI,WAAU,6HACb,UAAA;AAAA,EAAA,gBAAA1B,EAAC2B,GAAA,EAAW,WAAU,SAAA,CAAS;AAAA,EAC/B,gBAAA3B,EAAC,KAAA,EAAE,WAAU,WAAW,UAAAwB,GAAM;AAAA,EAC9B,gBAAAxB;AAAA,IAAC4B;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,aAAU;AAAA,IAAA;AAAA,EAAA;AACZ,EAAA,CACF,EAAA,CAEJ,GAKWC,IAAc,CAAC;AAAA,EAC1B,UAAAhC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,MACE,gBAAAC;AAAA,EAAC8B;AAAA,EAAA;AAAA,IACC,WAAW7B;AAAA,MACT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,IAEJ,UAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,gDACZ,UAAAH,EAAA,CACH;AAAA,EAAA;AACF;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),v=require("@radix-ui/react-use-controllable-state"),a=require("lucide-react"),l=require("react"),b=require("../ui/badge.cjs"),m=require("../ui/code-block.cjs"),x=require("../ui/collapsible.cjs"),c=require("../../lib/utils.cjs"),N=1e3,y=({className:s,isStreaming:t=!1,open:o,onOpenChange:r,defaultOpen:n,...u})=>{const[i,d]=v.useControllableState({defaultProp:n??!0,onChange:r,prop:o}),g=l.useRef(t),[f,C]=l.useState(!1);l.useEffect(()=>{t&&(g.current=!0)},[t]),l.useEffect(()=>{if(g.current&&!t&&i&&!f){const p=setTimeout(()=>{d(!1),C(!0)},N);return()=>clearTimeout(p)}},[t,i,d,f]);const h=l.useCallback(p=>d(p),[d]);return e.jsx(x.Collapsible,{className:c.cn("group not-prose mb-4 w-full rounded-md border bg-background",s),onOpenChange:h,open:i,...u})},I={"approval-requested":"Awaiting Approval","approval-responded":"Responded","input-available":"Running","input-streaming":"Pending","output-available":"Completed","output-denied":"Denied","output-error":"Error"},k={"approval-requested":e.jsx(a.ClockIcon,{className:"size-4 text-yellow-600"}),"approval-responded":e.jsx(a.CheckCircleIcon,{className:"size-4 text-blue-600"}),"input-available":e.jsx(a.ClockIcon,{className:"size-4 animate-pulse"}),"input-streaming":e.jsx(a.CircleIcon,{className:"size-4"}),"output-available":e.jsx(a.CheckCircleIcon,{className:"size-4 text-green-600"}),"output-denied":e.jsx(a.XCircleIcon,{className:"size-4 text-orange-600"}),"output-error":e.jsx(a.XCircleIcon,{className:"size-4 text-red-600"})},j=s=>e.jsxs(b.Badge,{className:"gap-1.5 rounded-full text-xs",variant:"secondary",children:[k[s],I[s]]}),w=({className:s,title:t,type:o,state:r,toolName:n,...u})=>{const i=o==="dynamic-tool"?n:o.split("-").slice(1).join("-");return e.jsxs(x.CollapsibleTrigger,{className:c.cn("flex w-full items-center justify-between gap-4 p-3",s),...u,children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(a.WrenchIcon,{className:"size-4 text-muted-foreground"}),e.jsx("span",{className:"font-medium text-sm",children:t??i}),j(r)]}),e.jsx(a.ChevronDownIcon,{className:"size-4 text-muted-foreground opacity-0 transition-all group-focus-within:opacity-100 group-hover:opacity-100 group-data-[state=open]:rotate-180 group-data-[state=open]:opacity-100","data-slot":"collapsible-chevron"})]})},O=({className:s,...t})=>e.jsx(x.CollapsibleContent,{className:c.cn("data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 space-y-4 p-4 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",s),...t}),T=({className:s,input:t,...o})=>e.jsxs("div",{className:c.cn("space-y-2 overflow-hidden",s),...o,children:[e.jsx("h4",{className:"font-medium text-muted-foreground text-xs uppercase tracking-wide",children:"Parameters"}),e.jsx("div",{className:"rounded-md bg-muted/50",children:e.jsx(m.CodeBlock,{code:JSON.stringify(t,null,2),language:"json"})})]}),q=({className:s,output:t,errorText:o,...r})=>{if(!(t||o))return null;let n=e.jsx("div",{children:t});return typeof t=="object"&&!l.isValidElement(t)?n=e.jsx(m.CodeBlock,{code:JSON.stringify(t,null,2),language:"json"}):typeof t=="string"&&(n=e.jsx(m.CodeBlock,{code:t,language:"json"})),e.jsxs("div",{className:c.cn("space-y-2",s),...r,children:[e.jsx("h4",{className:"font-medium text-muted-foreground text-xs uppercase tracking-wide",children:o?"Error":"Result"}),e.jsxs("div",{className:c.cn("overflow-x-auto rounded-md text-xs [&_table]:w-full",o?"bg-destructive/10 text-destructive":"bg-muted/50 text-foreground"),children:[o&&e.jsx("div",{children:o}),n]})]})};exports.Tool=y;exports.ToolContent=O;exports.ToolHeader=w;exports.ToolInput=T;exports.ToolOutput=q;exports.getStatusBadge=j;
|
|
2
|
+
//# sourceMappingURL=tool.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.cjs","sources":["../../../src/components/ai/tool.tsx"],"sourcesContent":["import { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport {\n CheckCircleIcon,\n ChevronDownIcon,\n CircleIcon,\n ClockIcon,\n WrenchIcon,\n XCircleIcon,\n} from \"lucide-react\";\nimport { isValidElement, useCallback, useEffect, useRef, useState } from \"react\";\n\n\nimport type { DynamicToolUIPart, ToolUIPart } from \"ai\";\nimport type { ComponentProps, ReactNode } from \"react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { CodeBlock } from \"@/components/ui/code-block\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\n\n\n\n\nconst AUTO_CLOSE_DELAY = 1000;\n\nexport type ToolProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n};\n\nexport const Tool = ({\n className,\n isStreaming = false,\n open,\n onOpenChange,\n defaultOpen,\n ...props\n}: ToolProps) => {\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: defaultOpen ?? true,\n onChange: onOpenChange,\n prop: open,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n\n useEffect(() => {\n if (isStreaming) hasEverStreamedRef.current = true;\n }, [isStreaming]);\n\n useEffect(() => {\n if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n return () => clearTimeout(timer);\n }\n }, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => setIsOpen(newOpen),\n [setIsOpen]\n );\n\n return (\n <Collapsible\n className={cn(\"group not-prose mb-4 w-full rounded-md border bg-background\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n />\n );\n};\n\nexport type ToolPart = ToolUIPart | DynamicToolUIPart;\n\nexport type ToolHeaderProps = {\n title?: string;\n className?: string;\n} & (\n | { type: ToolUIPart[\"type\"]; state: ToolUIPart[\"state\"]; toolName?: never }\n | {\n type: DynamicToolUIPart[\"type\"];\n state: DynamicToolUIPart[\"state\"];\n toolName: string;\n }\n);\n\nconst statusLabels: Record<ToolPart[\"state\"], string> = {\n \"approval-requested\": \"Awaiting Approval\",\n \"approval-responded\": \"Responded\",\n \"input-available\": \"Running\",\n \"input-streaming\": \"Pending\",\n \"output-available\": \"Completed\",\n \"output-denied\": \"Denied\",\n \"output-error\": \"Error\",\n};\n\nconst statusIcons: Record<ToolPart[\"state\"], ReactNode> = {\n \"approval-requested\": <ClockIcon className=\"size-4 text-yellow-600\" />,\n \"approval-responded\": <CheckCircleIcon className=\"size-4 text-blue-600\" />,\n \"input-available\": <ClockIcon className=\"size-4 animate-pulse\" />,\n \"input-streaming\": <CircleIcon className=\"size-4\" />,\n \"output-available\": <CheckCircleIcon className=\"size-4 text-green-600\" />,\n \"output-denied\": <XCircleIcon className=\"size-4 text-orange-600\" />,\n \"output-error\": <XCircleIcon className=\"size-4 text-red-600\" />,\n};\n\nexport const getStatusBadge = (status: ToolPart[\"state\"]) => (\n <Badge className=\"gap-1.5 rounded-full text-xs\" variant=\"secondary\">\n {statusIcons[status]}\n {statusLabels[status]}\n </Badge>\n);\n\nexport const ToolHeader = ({\n className,\n title,\n type,\n state,\n toolName,\n ...props\n}: ToolHeaderProps) => {\n const derivedName =\n type === \"dynamic-tool\" ? toolName : type.split(\"-\").slice(1).join(\"-\");\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-full items-center justify-between gap-4 p-3\",\n className\n )}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n <WrenchIcon className=\"size-4 text-muted-foreground\" />\n <span className=\"font-medium text-sm\">{title ?? derivedName}</span>\n {getStatusBadge(state)}\n </div>\n <ChevronDownIcon\n className=\"size-4 text-muted-foreground opacity-0 transition-all group-focus-within:opacity-100 group-hover:opacity-100 group-data-[state=open]:rotate-180 group-data-[state=open]:opacity-100\"\n data-slot=\"collapsible-chevron\"\n />\n </CollapsibleTrigger>\n );\n};\n\nexport type ToolContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const ToolContent = ({ className, ...props }: ToolContentProps) => (\n <CollapsibleContent\n className={cn(\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 space-y-4 p-4 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className\n )}\n {...props}\n />\n);\n\nexport type ToolInputProps = ComponentProps<\"div\"> & {\n input: ToolPart[\"input\"];\n};\n\nexport const ToolInput = ({ className, input, ...props }: ToolInputProps) => (\n <div className={cn(\"space-y-2 overflow-hidden\", className)} {...props}>\n <h4 className=\"font-medium text-muted-foreground text-xs uppercase tracking-wide\">\n Parameters\n </h4>\n <div className=\"rounded-md bg-muted/50\">\n <CodeBlock code={JSON.stringify(input, null, 2)} language=\"json\" />\n </div>\n </div>\n);\n\nexport type ToolOutputProps = ComponentProps<\"div\"> & {\n output: ToolPart[\"output\"];\n errorText: ToolPart[\"errorText\"];\n};\n\nexport const ToolOutput = ({\n className,\n output,\n errorText,\n ...props\n}: ToolOutputProps) => {\n if (!(output || errorText)) {\n return null;\n }\n\n let Output = <div>{output as ReactNode}</div>;\n\n if (typeof output === \"object\" && !isValidElement(output)) {\n Output = (\n <CodeBlock code={JSON.stringify(output, null, 2)} language=\"json\" />\n );\n } else if (typeof output === \"string\") {\n Output = <CodeBlock code={output} language=\"json\" />;\n }\n\n return (\n <div className={cn(\"space-y-2\", className)} {...props}>\n <h4 className=\"font-medium text-muted-foreground text-xs uppercase tracking-wide\">\n {errorText ? \"Error\" : \"Result\"}\n </h4>\n <div\n className={cn(\n \"overflow-x-auto rounded-md text-xs [&_table]:w-full\",\n errorText\n ? \"bg-destructive/10 text-destructive\"\n : \"bg-muted/50 text-foreground\"\n )}\n >\n {errorText && <div>{errorText}</div>}\n {Output}\n </div>\n </div>\n );\n};\n"],"names":["AUTO_CLOSE_DELAY","Tool","className","isStreaming","open","onOpenChange","defaultOpen","props","isOpen","setIsOpen","useControllableState","hasEverStreamedRef","useRef","hasAutoClosed","setHasAutoClosed","useState","useEffect","timer","handleOpenChange","useCallback","newOpen","jsx","Collapsible","cn","statusLabels","statusIcons","ClockIcon","CheckCircleIcon","CircleIcon","XCircleIcon","getStatusBadge","status","jsxs","Badge","ToolHeader","title","type","state","toolName","derivedName","CollapsibleTrigger","WrenchIcon","ChevronDownIcon","ToolContent","CollapsibleContent","ToolInput","input","CodeBlock","ToolOutput","output","errorText","Output","isValidElement"],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { jsx as e, jsxs as n } from "react/jsx-runtime";
|
|
2
|
+
import { useControllableState as C } from "@radix-ui/react-use-controllable-state";
|
|
3
|
+
import { WrenchIcon as y, ChevronDownIcon as w, XCircleIcon as g, CheckCircleIcon as h, CircleIcon as O, ClockIcon as v } from "lucide-react";
|
|
4
|
+
import { useRef as z, useState as I, useEffect as N, useCallback as j, isValidElement as k } from "react";
|
|
5
|
+
import { Badge as E } from "../ui/badge.js";
|
|
6
|
+
import { CodeBlock as p } from "../ui/code-block.js";
|
|
7
|
+
import { Collapsible as A, CollapsibleContent as R, CollapsibleTrigger as T } from "../ui/collapsible.js";
|
|
8
|
+
import { cn as l } from "../../lib/utils.js";
|
|
9
|
+
const B = 1e3, X = ({
|
|
10
|
+
className: o,
|
|
11
|
+
isStreaming: t = !1,
|
|
12
|
+
open: a,
|
|
13
|
+
onOpenChange: r,
|
|
14
|
+
defaultOpen: s,
|
|
15
|
+
...c
|
|
16
|
+
}) => {
|
|
17
|
+
const [i, d] = C({
|
|
18
|
+
defaultProp: s ?? !0,
|
|
19
|
+
onChange: r,
|
|
20
|
+
prop: a
|
|
21
|
+
}), m = z(t), [f, x] = I(!1);
|
|
22
|
+
N(() => {
|
|
23
|
+
t && (m.current = !0);
|
|
24
|
+
}, [t]), N(() => {
|
|
25
|
+
if (m.current && !t && i && !f) {
|
|
26
|
+
const u = setTimeout(() => {
|
|
27
|
+
d(!1), x(!0);
|
|
28
|
+
}, B);
|
|
29
|
+
return () => clearTimeout(u);
|
|
30
|
+
}
|
|
31
|
+
}, [t, i, d, f]);
|
|
32
|
+
const b = j(
|
|
33
|
+
(u) => d(u),
|
|
34
|
+
[d]
|
|
35
|
+
);
|
|
36
|
+
return /* @__PURE__ */ e(
|
|
37
|
+
A,
|
|
38
|
+
{
|
|
39
|
+
className: l("group not-prose mb-4 w-full rounded-md border bg-background", o),
|
|
40
|
+
onOpenChange: b,
|
|
41
|
+
open: i,
|
|
42
|
+
...c
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}, D = {
|
|
46
|
+
"approval-requested": "Awaiting Approval",
|
|
47
|
+
"approval-responded": "Responded",
|
|
48
|
+
"input-available": "Running",
|
|
49
|
+
"input-streaming": "Pending",
|
|
50
|
+
"output-available": "Completed",
|
|
51
|
+
"output-denied": "Denied",
|
|
52
|
+
"output-error": "Error"
|
|
53
|
+
}, L = {
|
|
54
|
+
"approval-requested": /* @__PURE__ */ e(v, { className: "size-4 text-yellow-600" }),
|
|
55
|
+
"approval-responded": /* @__PURE__ */ e(h, { className: "size-4 text-blue-600" }),
|
|
56
|
+
"input-available": /* @__PURE__ */ e(v, { className: "size-4 animate-pulse" }),
|
|
57
|
+
"input-streaming": /* @__PURE__ */ e(O, { className: "size-4" }),
|
|
58
|
+
"output-available": /* @__PURE__ */ e(h, { className: "size-4 text-green-600" }),
|
|
59
|
+
"output-denied": /* @__PURE__ */ e(g, { className: "size-4 text-orange-600" }),
|
|
60
|
+
"output-error": /* @__PURE__ */ e(g, { className: "size-4 text-red-600" })
|
|
61
|
+
}, P = (o) => /* @__PURE__ */ n(E, { className: "gap-1.5 rounded-full text-xs", variant: "secondary", children: [
|
|
62
|
+
L[o],
|
|
63
|
+
D[o]
|
|
64
|
+
] }), Y = ({
|
|
65
|
+
className: o,
|
|
66
|
+
title: t,
|
|
67
|
+
type: a,
|
|
68
|
+
state: r,
|
|
69
|
+
toolName: s,
|
|
70
|
+
...c
|
|
71
|
+
}) => {
|
|
72
|
+
const i = a === "dynamic-tool" ? s : a.split("-").slice(1).join("-");
|
|
73
|
+
return /* @__PURE__ */ n(
|
|
74
|
+
T,
|
|
75
|
+
{
|
|
76
|
+
className: l(
|
|
77
|
+
"flex w-full items-center justify-between gap-4 p-3",
|
|
78
|
+
o
|
|
79
|
+
),
|
|
80
|
+
...c,
|
|
81
|
+
children: [
|
|
82
|
+
/* @__PURE__ */ n("div", { className: "flex items-center gap-2", children: [
|
|
83
|
+
/* @__PURE__ */ e(y, { className: "size-4 text-muted-foreground" }),
|
|
84
|
+
/* @__PURE__ */ e("span", { className: "font-medium text-sm", children: t ?? i }),
|
|
85
|
+
P(r)
|
|
86
|
+
] }),
|
|
87
|
+
/* @__PURE__ */ e(
|
|
88
|
+
w,
|
|
89
|
+
{
|
|
90
|
+
className: "size-4 text-muted-foreground opacity-0 transition-all group-focus-within:opacity-100 group-hover:opacity-100 group-data-[state=open]:rotate-180 group-data-[state=open]:opacity-100",
|
|
91
|
+
"data-slot": "collapsible-chevron"
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
}, F = ({ className: o, ...t }) => /* @__PURE__ */ e(
|
|
98
|
+
R,
|
|
99
|
+
{
|
|
100
|
+
className: l(
|
|
101
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 space-y-4 p-4 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
102
|
+
o
|
|
103
|
+
),
|
|
104
|
+
...t
|
|
105
|
+
}
|
|
106
|
+
), G = ({ className: o, input: t, ...a }) => /* @__PURE__ */ n("div", { className: l("space-y-2 overflow-hidden", o), ...a, children: [
|
|
107
|
+
/* @__PURE__ */ e("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: "Parameters" }),
|
|
108
|
+
/* @__PURE__ */ e("div", { className: "rounded-md bg-muted/50", children: /* @__PURE__ */ e(p, { code: JSON.stringify(t, null, 2), language: "json" }) })
|
|
109
|
+
] }), K = ({
|
|
110
|
+
className: o,
|
|
111
|
+
output: t,
|
|
112
|
+
errorText: a,
|
|
113
|
+
...r
|
|
114
|
+
}) => {
|
|
115
|
+
if (!(t || a))
|
|
116
|
+
return null;
|
|
117
|
+
let s = /* @__PURE__ */ e("div", { children: t });
|
|
118
|
+
return typeof t == "object" && !k(t) ? s = /* @__PURE__ */ e(p, { code: JSON.stringify(t, null, 2), language: "json" }) : typeof t == "string" && (s = /* @__PURE__ */ e(p, { code: t, language: "json" })), /* @__PURE__ */ n("div", { className: l("space-y-2", o), ...r, children: [
|
|
119
|
+
/* @__PURE__ */ e("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: a ? "Error" : "Result" }),
|
|
120
|
+
/* @__PURE__ */ n(
|
|
121
|
+
"div",
|
|
122
|
+
{
|
|
123
|
+
className: l(
|
|
124
|
+
"overflow-x-auto rounded-md text-xs [&_table]:w-full",
|
|
125
|
+
a ? "bg-destructive/10 text-destructive" : "bg-muted/50 text-foreground"
|
|
126
|
+
),
|
|
127
|
+
children: [
|
|
128
|
+
a && /* @__PURE__ */ e("div", { children: a }),
|
|
129
|
+
s
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
] });
|
|
134
|
+
};
|
|
135
|
+
export {
|
|
136
|
+
X as Tool,
|
|
137
|
+
F as ToolContent,
|
|
138
|
+
Y as ToolHeader,
|
|
139
|
+
G as ToolInput,
|
|
140
|
+
K as ToolOutput,
|
|
141
|
+
P as getStatusBadge
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.js","sources":["../../../src/components/ai/tool.tsx"],"sourcesContent":["import { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport {\n CheckCircleIcon,\n ChevronDownIcon,\n CircleIcon,\n ClockIcon,\n WrenchIcon,\n XCircleIcon,\n} from \"lucide-react\";\nimport { isValidElement, useCallback, useEffect, useRef, useState } from \"react\";\n\n\nimport type { DynamicToolUIPart, ToolUIPart } from \"ai\";\nimport type { ComponentProps, ReactNode } from \"react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { CodeBlock } from \"@/components/ui/code-block\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\n\n\n\n\nconst AUTO_CLOSE_DELAY = 1000;\n\nexport type ToolProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n};\n\nexport const Tool = ({\n className,\n isStreaming = false,\n open,\n onOpenChange,\n defaultOpen,\n ...props\n}: ToolProps) => {\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: defaultOpen ?? true,\n onChange: onOpenChange,\n prop: open,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n\n useEffect(() => {\n if (isStreaming) hasEverStreamedRef.current = true;\n }, [isStreaming]);\n\n useEffect(() => {\n if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n return () => clearTimeout(timer);\n }\n }, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => setIsOpen(newOpen),\n [setIsOpen]\n );\n\n return (\n <Collapsible\n className={cn(\"group not-prose mb-4 w-full rounded-md border bg-background\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n />\n );\n};\n\nexport type ToolPart = ToolUIPart | DynamicToolUIPart;\n\nexport type ToolHeaderProps = {\n title?: string;\n className?: string;\n} & (\n | { type: ToolUIPart[\"type\"]; state: ToolUIPart[\"state\"]; toolName?: never }\n | {\n type: DynamicToolUIPart[\"type\"];\n state: DynamicToolUIPart[\"state\"];\n toolName: string;\n }\n);\n\nconst statusLabels: Record<ToolPart[\"state\"], string> = {\n \"approval-requested\": \"Awaiting Approval\",\n \"approval-responded\": \"Responded\",\n \"input-available\": \"Running\",\n \"input-streaming\": \"Pending\",\n \"output-available\": \"Completed\",\n \"output-denied\": \"Denied\",\n \"output-error\": \"Error\",\n};\n\nconst statusIcons: Record<ToolPart[\"state\"], ReactNode> = {\n \"approval-requested\": <ClockIcon className=\"size-4 text-yellow-600\" />,\n \"approval-responded\": <CheckCircleIcon className=\"size-4 text-blue-600\" />,\n \"input-available\": <ClockIcon className=\"size-4 animate-pulse\" />,\n \"input-streaming\": <CircleIcon className=\"size-4\" />,\n \"output-available\": <CheckCircleIcon className=\"size-4 text-green-600\" />,\n \"output-denied\": <XCircleIcon className=\"size-4 text-orange-600\" />,\n \"output-error\": <XCircleIcon className=\"size-4 text-red-600\" />,\n};\n\nexport const getStatusBadge = (status: ToolPart[\"state\"]) => (\n <Badge className=\"gap-1.5 rounded-full text-xs\" variant=\"secondary\">\n {statusIcons[status]}\n {statusLabels[status]}\n </Badge>\n);\n\nexport const ToolHeader = ({\n className,\n title,\n type,\n state,\n toolName,\n ...props\n}: ToolHeaderProps) => {\n const derivedName =\n type === \"dynamic-tool\" ? toolName : type.split(\"-\").slice(1).join(\"-\");\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-full items-center justify-between gap-4 p-3\",\n className\n )}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n <WrenchIcon className=\"size-4 text-muted-foreground\" />\n <span className=\"font-medium text-sm\">{title ?? derivedName}</span>\n {getStatusBadge(state)}\n </div>\n <ChevronDownIcon\n className=\"size-4 text-muted-foreground opacity-0 transition-all group-focus-within:opacity-100 group-hover:opacity-100 group-data-[state=open]:rotate-180 group-data-[state=open]:opacity-100\"\n data-slot=\"collapsible-chevron\"\n />\n </CollapsibleTrigger>\n );\n};\n\nexport type ToolContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const ToolContent = ({ className, ...props }: ToolContentProps) => (\n <CollapsibleContent\n className={cn(\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 space-y-4 p-4 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className\n )}\n {...props}\n />\n);\n\nexport type ToolInputProps = ComponentProps<\"div\"> & {\n input: ToolPart[\"input\"];\n};\n\nexport const ToolInput = ({ className, input, ...props }: ToolInputProps) => (\n <div className={cn(\"space-y-2 overflow-hidden\", className)} {...props}>\n <h4 className=\"font-medium text-muted-foreground text-xs uppercase tracking-wide\">\n Parameters\n </h4>\n <div className=\"rounded-md bg-muted/50\">\n <CodeBlock code={JSON.stringify(input, null, 2)} language=\"json\" />\n </div>\n </div>\n);\n\nexport type ToolOutputProps = ComponentProps<\"div\"> & {\n output: ToolPart[\"output\"];\n errorText: ToolPart[\"errorText\"];\n};\n\nexport const ToolOutput = ({\n className,\n output,\n errorText,\n ...props\n}: ToolOutputProps) => {\n if (!(output || errorText)) {\n return null;\n }\n\n let Output = <div>{output as ReactNode}</div>;\n\n if (typeof output === \"object\" && !isValidElement(output)) {\n Output = (\n <CodeBlock code={JSON.stringify(output, null, 2)} language=\"json\" />\n );\n } else if (typeof output === \"string\") {\n Output = <CodeBlock code={output} language=\"json\" />;\n }\n\n return (\n <div className={cn(\"space-y-2\", className)} {...props}>\n <h4 className=\"font-medium text-muted-foreground text-xs uppercase tracking-wide\">\n {errorText ? \"Error\" : \"Result\"}\n </h4>\n <div\n className={cn(\n \"overflow-x-auto rounded-md text-xs [&_table]:w-full\",\n errorText\n ? \"bg-destructive/10 text-destructive\"\n : \"bg-muted/50 text-foreground\"\n )}\n >\n {errorText && <div>{errorText}</div>}\n {Output}\n </div>\n </div>\n );\n};\n"],"names":["AUTO_CLOSE_DELAY","Tool","className","isStreaming","open","onOpenChange","defaultOpen","props","isOpen","setIsOpen","useControllableState","hasEverStreamedRef","useRef","hasAutoClosed","setHasAutoClosed","useState","useEffect","timer","handleOpenChange","useCallback","newOpen","jsx","Collapsible","cn","statusLabels","statusIcons","ClockIcon","CheckCircleIcon","CircleIcon","XCircleIcon","getStatusBadge","status","jsxs","Badge","ToolHeader","title","type","state","toolName","derivedName","CollapsibleTrigger","WrenchIcon","ChevronDownIcon","ToolContent","CollapsibleContent","ToolInput","input","CodeBlock","ToolOutput","output","errorText","Output","isValidElement"],"mappings":";;;;;;;;AA2BA,MAAMA,IAAmB,KAMZC,IAAO,CAAC;AAAA,EACnB,WAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,MAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,GAAGC;AACL,MAAiB;AACf,QAAM,CAACC,GAAQC,CAAS,IAAIC,EAA8B;AAAA,IACxD,aAAaJ,KAAe;AAAA,IAC5B,UAAUD;AAAA,IACV,MAAMD;AAAA,EAAA,CACP,GAEKO,IAAqBC,EAAOT,CAAW,GACvC,CAACU,GAAeC,CAAgB,IAAIC,EAAS,EAAK;AAExD,EAAAC,EAAU,MAAM;AACd,IAAIb,QAAgC,UAAU;AAAA,EAChD,GAAG,CAACA,CAAW,CAAC,GAEhBa,EAAU,MAAM;AACd,QAAIL,EAAmB,WAAW,CAACR,KAAeK,KAAU,CAACK,GAAe;AAC1E,YAAMI,IAAQ,WAAW,MAAM;AAC7B,QAAAR,EAAU,EAAK,GACfK,EAAiB,EAAI;AAAA,MACvB,GAAGd,CAAgB;AACnB,aAAO,MAAM,aAAaiB,CAAK;AAAA,IACjC;AAAA,EACF,GAAG,CAACd,GAAaK,GAAQC,GAAWI,CAAa,CAAC;AAElD,QAAMK,IAAmBC;AAAA,IACvB,CAACC,MAAqBX,EAAUW,CAAO;AAAA,IACvC,CAACX,CAAS;AAAA,EAAA;AAGZ,SACE,gBAAAY;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAG,+DAA+DrB,CAAS;AAAA,MACtF,cAAcgB;AAAA,MACd,MAAMV;AAAA,MACL,GAAGD;AAAA,IAAA;AAAA,EAAA;AAGV,GAgBMiB,IAAkD;AAAA,EACtD,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,gBAAgB;AAClB,GAEMC,IAAoD;AAAA,EACxD,sBAAsB,gBAAAJ,EAACK,GAAA,EAAU,WAAU,yBAAA,CAAyB;AAAA,EACpE,sBAAsB,gBAAAL,EAACM,GAAA,EAAgB,WAAU,uBAAA,CAAuB;AAAA,EACxE,mBAAmB,gBAAAN,EAACK,GAAA,EAAU,WAAU,uBAAA,CAAuB;AAAA,EAC/D,mBAAmB,gBAAAL,EAACO,GAAA,EAAW,WAAU,SAAA,CAAS;AAAA,EAClD,oBAAoB,gBAAAP,EAACM,GAAA,EAAgB,WAAU,wBAAA,CAAwB;AAAA,EACvE,iBAAiB,gBAAAN,EAACQ,GAAA,EAAY,WAAU,yBAAA,CAAyB;AAAA,EACjE,gBAAgB,gBAAAR,EAACQ,GAAA,EAAY,WAAU,sBAAA,CAAsB;AAC/D,GAEaC,IAAiB,CAACC,MAC7B,gBAAAC,EAACC,KAAM,WAAU,gCAA+B,SAAQ,aACrD,UAAA;AAAA,EAAAR,EAAYM,CAAM;AAAA,EAClBP,EAAaO,CAAM;AAAA,EAAA,CACtB,GAGWG,IAAa,CAAC;AAAA,EACzB,WAAAhC;AAAA,EACA,OAAAiC;AAAA,EACA,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAG/B;AACL,MAAuB;AACrB,QAAMgC,IACJH,MAAS,iBAAiBE,IAAWF,EAAK,MAAM,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG;AAExE,SACE,gBAAAJ;AAAA,IAACQ;AAAA,IAAA;AAAA,MACC,WAAWjB;AAAA,QACT;AAAA,QACArB;AAAA,MAAA;AAAA,MAED,GAAGK;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAyB,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,UAAA,gBAAAX,EAACoB,GAAA,EAAW,WAAU,+BAAA,CAA+B;AAAA,UACrD,gBAAApB,EAAC,QAAA,EAAK,WAAU,uBAAuB,eAASkB,GAAY;AAAA,UAC3DT,EAAeO,CAAK;AAAA,QAAA,GACvB;AAAA,QACA,gBAAAhB;AAAA,UAACqB;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,aAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ;AAAA,IAAA;AAAA,EAAA;AAGN,GAIaC,IAAc,CAAC,EAAE,WAAAzC,GAAW,GAAGK,QAC1C,gBAAAc;AAAA,EAACuB;AAAA,EAAA;AAAA,IACC,WAAWrB;AAAA,MACT;AAAA,MACArB;AAAA,IAAA;AAAA,IAED,GAAGK;AAAA,EAAA;AACN,GAOWsC,IAAY,CAAC,EAAE,WAAA3C,GAAW,OAAA4C,GAAO,GAAGvC,EAAA,MAC/C,gBAAAyB,EAAC,OAAA,EAAI,WAAWT,EAAG,6BAA6BrB,CAAS,GAAI,GAAGK,GAC9D,UAAA;AAAA,EAAA,gBAAAc,EAAC,MAAA,EAAG,WAAU,qEAAoE,UAAA,cAElF;AAAA,EACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0BACb,4BAAC0B,GAAA,EAAU,MAAM,KAAK,UAAUD,GAAO,MAAM,CAAC,GAAG,UAAS,QAAO,EAAA,CACnE;AAAA,EAAA,CACF,GAQWE,IAAa,CAAC;AAAA,EACzB,WAAA9C;AAAA,EACA,QAAA+C;AAAA,EACA,WAAAC;AAAA,EACA,GAAG3C;AACL,MAAuB;AACrB,MAAI,EAAE0C,KAAUC;AACd,WAAO;AAGT,MAAIC,IAAS,gBAAA9B,EAAC,OAAA,EAAK,UAAA4B,EAAA,CAAoB;AAEvC,SAAI,OAAOA,KAAW,YAAY,CAACG,EAAeH,CAAM,IACtDE,IACE,gBAAA9B,EAAC0B,GAAA,EAAU,MAAM,KAAK,UAAUE,GAAQ,MAAM,CAAC,GAAG,UAAS,OAAA,CAAO,IAE3D,OAAOA,KAAW,aAC3BE,IAAS,gBAAA9B,EAAC0B,GAAA,EAAU,MAAME,GAAQ,UAAS,QAAO,IAIlD,gBAAAjB,EAAC,SAAI,WAAWT,EAAG,aAAarB,CAAS,GAAI,GAAGK,GAC9C,UAAA;AAAA,IAAA,gBAAAc,EAAC,MAAA,EAAG,WAAU,qEACX,UAAA6B,IAAY,UAAU,UACzB;AAAA,IACA,gBAAAlB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWT;AAAA,UACT;AAAA,UACA2B,IACI,uCACA;AAAA,QAAA;AAAA,QAGL,UAAA;AAAA,UAAAA,KAAa,gBAAA7B,EAAC,SAAK,UAAA6B,EAAA,CAAU;AAAA,UAC7BC;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GACF;AAEJ;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),v=require("lucide-react"),a=require("react"),j=require("../../ai/conversation.cjs"),t=require("../../ai/message.cjs"),n=require("../../ai/prompt-input.cjs"),M=require("../../ai/reasoning.cjs"),m=require("../../ai/sources.cjs"),L=require("../../ai/stream-status.cjs"),N=require("../../ai/suggestion.cjs"),O=require("../../../lib/utils.cjs"),z=[{id:"claude-sonnet-4-6",name:"Claude Sonnet"},{id:"claude-opus-4-7",name:"Claude Opus"}],V=["Explain quantum entanglement simply","Write a Python script to rename files","Summarise the latest AI research trends","What is the difference between TCP and UDP?"];let k=0;const w=()=>(k+=1,`chat-msg-${k}`),W=3e3,H=({initialMessages:S=[],models:c=z,defaultModel:d,suggestions:i=V,onSend:h,className:C})=>{const u=a.useId(),[x,b]=a.useState(S),[g,y]=a.useState(""),[I,B]=a.useState(d??c[0]?.id??""),[E,_]=a.useState(!1),[p,f]=a.useState("ready"),[P,T]=a.useState(),D=a.useCallback(async s=>{const r=g.trim();if(!r||p==="streaming")return;const l={id:w(),role:"user",content:r};b(o=>[...o,l]),y(""),f("streaming"),T(new Date);try{const o=await h?.(r,I),F={id:w(),role:"assistant",content:o??"I received your message."};b(G=>[...G,F])}finally{f("ready"),setTimeout(()=>T(void 0),W)}},[g,p,I,h]),U=a.useCallback(s=>{y(s)},[]),R=a.useCallback(s=>{navigator.clipboard.writeText(s).catch(()=>{})},[]),q=a.useCallback(s=>{b(r=>{const l=r.findIndex(o=>o.id===s);return l===-1?r:r.slice(0,l)})},[]);return e.jsxs("div",{className:O.cn("mx-auto flex h-full w-full max-w-[980px] flex-col",C),children:[e.jsxs(j.Conversation,{className:"flex-1",children:[e.jsxs(j.ConversationContent,{children:[x.length===0?e.jsx(j.ConversationEmptyState,{description:"Send a message or pick a suggestion below to start.",title:"Start a conversation"}):null,x.map((s,r)=>e.jsxs("div",{className:"space-y-1",children:[s.role==="assistant"&&s.branches&&s.branches.length>1?e.jsxs(t.MessageBranch,{children:[e.jsx(t.MessageBranchContent,{children:s.branches.map((l,o)=>e.jsx(A,{content:l,id:s.id,onCopy:R,onRetry:q,reasoning:o===0?s.reasoning:void 0,sources:o===0?s.sources:void 0},o))}),e.jsx(t.MessageToolbar,{children:e.jsxs(t.MessageBranchSelector,{children:[e.jsx(t.MessageBranchPrevious,{}),e.jsx(t.MessageBranchPage,{}),e.jsx(t.MessageBranchNext,{})]})})]}):s.role==="assistant"?e.jsx(e.Fragment,{children:e.jsx(A,{content:s.content,id:s.id,onCopy:R,onRetry:q,reasoning:s.reasoning,sources:s.sources})}):e.jsx(t.Message,{from:"user",children:e.jsx(t.MessageContent,{children:e.jsx(t.MessageResponse,{children:s.content})})}),r===x.length-1&&P&&e.jsx("div",{className:"mt-3",children:e.jsx(L.StreamStatus,{iconVariant:"loader-circle",isStreaming:p==="streaming",startTime:P})})]},s.id))]}),e.jsx(j.ConversationScrollButton,{})]}),x.length===0&&i.length>0&&e.jsx("div",{className:"px-4 pb-2",children:e.jsx(N.Suggestions,{children:i.map(s=>e.jsx(N.Suggestion,{onClick:U,suggestion:s},s))})}),e.jsx("div",{className:"px-4 pt-3 pb-4",children:e.jsxs(n.PromptInput,{onSubmit:D,children:[e.jsx(n.PromptInputBody,{children:e.jsx(n.PromptInputTextarea,{"aria-labelledby":u,onChange:s=>y(s.target.value),placeholder:"Ask anything...",value:g})}),e.jsxs(n.PromptInputFooter,{children:[e.jsxs(n.PromptInputTools,{children:[c.length>1&&e.jsxs(n.PromptInputSelect,{onValueChange:B,value:I,children:[e.jsx(n.PromptInputSelectTrigger,{children:e.jsx(n.PromptInputSelectValue,{})}),e.jsx(n.PromptInputSelectContent,{children:c.map(s=>e.jsx(n.PromptInputSelectItem,{value:s.id,children:s.name},s.id))})]}),e.jsxs(n.PromptInputButton,{onClick:()=>_(s=>!s),tooltip:{content:"Search the web"},variant:E?"default":"ghost",children:[e.jsx(v.GlobeIcon,{size:16}),e.jsx("span",{children:"Search"})]})]}),e.jsx(n.PromptInputSubmit,{disabled:!g.trim(),status:p})]})]})})]})},A=({id:S,content:c,reasoning:d,sources:i,onCopy:h,onRetry:C})=>e.jsxs("div",{className:"space-y-2",children:[d&&e.jsxs(M.Reasoning,{children:[e.jsx(M.ReasoningTrigger,{}),e.jsx(M.ReasoningContent,{children:d})]}),e.jsx(t.Message,{from:"assistant",children:e.jsx(t.MessageContent,{children:e.jsx(t.MessageResponse,{children:c})})}),i&&i.length>0&&e.jsxs(m.Sources,{children:[e.jsx(m.SourcesTrigger,{count:i.length}),e.jsx(m.SourcesContent,{children:i.map(u=>e.jsx(m.Source,{href:u.href,title:u.title},u.href))})]}),e.jsxs(t.MessageActions,{children:[e.jsx(t.MessageAction,{label:"Copy",onClick:()=>h(c),children:e.jsx(v.CopyIcon,{className:"size-3"})}),e.jsx(t.MessageAction,{label:"Retry",onClick:()=>C(S),children:e.jsx(v.RefreshCcwIcon,{className:"size-3"})})]})]});exports.Chat=H;
|
|
2
|
+
//# sourceMappingURL=Chat.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Chat.cjs","sources":["../../../../src/components/composed/Chat/Chat.tsx"],"sourcesContent":["import { CopyIcon, GlobeIcon, RefreshCcwIcon } from \"lucide-react\"\nimport { useCallback, useId, useState } from \"react\"\n\nimport {\n Conversation,\n ConversationContent,\n ConversationEmptyState,\n ConversationScrollButton,\n} from \"@/components/ai/conversation\"\nimport {\n Message,\n MessageAction,\n MessageActions,\n MessageBranch,\n MessageBranchContent,\n MessageBranchNext,\n MessageBranchPage,\n MessageBranchPrevious,\n MessageBranchSelector,\n MessageContent,\n MessageResponse,\n MessageToolbar,\n} from \"@/components/ai/message\"\nimport {\n PromptInput,\n PromptInputBody,\n PromptInputButton,\n PromptInputFooter,\n PromptInputSelect,\n PromptInputSelectContent,\n PromptInputSelectItem,\n PromptInputSelectTrigger,\n PromptInputSelectValue,\n PromptInputSubmit,\n PromptInputTextarea,\n PromptInputTools,\n type PromptInputMessage,\n} from \"@/components/ai/prompt-input\"\nimport { Reasoning, ReasoningContent, ReasoningTrigger } from \"@/components/ai/reasoning\"\nimport { Source, Sources, SourcesContent, SourcesTrigger } from \"@/components/ai/sources\"\nimport { StreamStatus } from \"@/components/ai/stream-status\"\nimport { Suggestion, Suggestions } from \"@/components/ai/suggestion\"\nimport { cn } from \"@/lib/utils\"\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ChatSource {\n href: string\n title: string\n}\n\nexport interface ChatMessage {\n id: string\n role: \"user\" | \"assistant\"\n content: string\n /** Displayed in a collapsible Reasoning panel above the message content. */\n reasoning?: string\n /** Web sources used to produce this message. */\n sources?: ChatSource[]\n /** Multiple alternative responses (for branching). When provided, the\n * array should include `content` as one of its items. */\n branches?: string[]\n}\n\nexport interface ChatModel {\n id: string\n name: string\n}\n\nexport interface ChatProps {\n /** Initial messages to pre-populate the conversation. */\n initialMessages?: ChatMessage[]\n /** Available models shown in the model-selector dropdown. */\n models?: ChatModel[]\n /** Initial model id. Defaults to the first model in `models`. */\n defaultModel?: string\n /** Suggestion chips shown when the conversation is empty. */\n suggestions?: string[]\n /** Called when the user submits a message. The returned string (if any)\n * will be appended as the assistant's reply. Defaults to a no-op. */\n onSend?: (message: string, model: string) => Promise<string | undefined> | string | undefined\n className?: string\n}\n\n// ---------------------------------------------------------------------------\n// Default values\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_MODELS: ChatModel[] = [\n { id: \"claude-sonnet-4-6\", name: \"Claude Sonnet\" },\n { id: \"claude-opus-4-7\", name: \"Claude Opus\" },\n]\n\nconst DEFAULT_SUGGESTIONS = [\n \"Explain quantum entanglement simply\",\n \"Write a Python script to rename files\",\n \"Summarise the latest AI research trends\",\n \"What is the difference between TCP and UDP?\",\n]\n\nlet _idCounter = 0\nconst nextId = () => {\n _idCounter += 1\n return `chat-msg-${_idCounter}`\n}\n\nconst STREAM_STATUS_LINGER_MS = 3000\n\n// ---------------------------------------------------------------------------\n// Chat component\n// ---------------------------------------------------------------------------\n\nexport const Chat = ({\n initialMessages = [],\n models = DEFAULT_MODELS,\n defaultModel,\n suggestions = DEFAULT_SUGGESTIONS,\n onSend,\n className,\n}: ChatProps) => {\n const labelId = useId()\n const [messages, setMessages] = useState<ChatMessage[]>(initialMessages)\n const [text, setText] = useState(\"\")\n const [model, setModel] = useState(defaultModel ?? models[0]?.id ?? \"\")\n const [webSearch, setWebSearch] = useState(false)\n const [status, setStatus] = useState<\"ready\" | \"streaming\">(\"ready\")\n const [streamStart, setStreamStart] = useState<Date | undefined>()\n\n const handleSubmit = useCallback(\n async (_msg: PromptInputMessage) => {\n const trimmed = text.trim()\n if (!trimmed || status === \"streaming\") return\n\n const userMsg: ChatMessage = {\n id: nextId(),\n role: \"user\",\n content: trimmed,\n }\n setMessages((prev) => [...prev, userMsg])\n setText(\"\")\n setStatus(\"streaming\")\n setStreamStart(new Date())\n\n try {\n const reply = await onSend?.(trimmed, model)\n const assistantMsg: ChatMessage = {\n id: nextId(),\n role: \"assistant\",\n content: reply ?? \"I received your message.\",\n }\n setMessages((prev) => [...prev, assistantMsg])\n } finally {\n setStatus(\"ready\")\n // Keep streamStart briefly so the bubble-confirm ripple can play out\n setTimeout(() => setStreamStart(undefined), STREAM_STATUS_LINGER_MS)\n }\n },\n [text, status, model, onSend],\n )\n\n const handleSuggestion = useCallback((suggestion: string) => {\n setText(suggestion)\n }, [])\n\n const handleCopy = useCallback((content: string) => {\n navigator.clipboard.writeText(content).catch(() => {})\n }, [])\n\n const handleRetry = useCallback((id: string) => {\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === id)\n if (idx === -1) return prev\n return prev.slice(0, idx)\n })\n }, [])\n\n return (\n <div className={cn(\"mx-auto flex h-full w-full max-w-[980px] flex-col\", className)}>\n {/* Conversation */}\n <Conversation className=\"flex-1\">\n <ConversationContent>\n {messages.length === 0 ? (\n <ConversationEmptyState\n description=\"Send a message or pick a suggestion below to start.\"\n title=\"Start a conversation\"\n />\n ) : null}\n\n {messages.map((msg, index) => (\n <div className=\"space-y-1\" key={msg.id}>\n {/* Branch wrapper — renders alt responses side-by-side when branches exist */}\n {msg.role === \"assistant\" && msg.branches && msg.branches.length > 1 ? (\n <MessageBranch>\n <MessageBranchContent>\n {msg.branches.map((branch, i) => (\n <AssistantMessage\n key={i}\n content={branch}\n id={msg.id}\n onCopy={handleCopy}\n onRetry={handleRetry}\n reasoning={i === 0 ? msg.reasoning : undefined}\n sources={i === 0 ? msg.sources : undefined}\n />\n ))}\n </MessageBranchContent>\n <MessageToolbar>\n <MessageBranchSelector>\n <MessageBranchPrevious />\n <MessageBranchPage />\n <MessageBranchNext />\n </MessageBranchSelector>\n </MessageToolbar>\n </MessageBranch>\n ) : msg.role === \"assistant\" ? (\n <>\n <AssistantMessage\n content={msg.content}\n id={msg.id}\n onCopy={handleCopy}\n onRetry={handleRetry}\n reasoning={msg.reasoning}\n sources={msg.sources}\n />\n </>\n ) : (\n <Message from=\"user\">\n <MessageContent>\n <MessageResponse>{msg.content}</MessageResponse>\n </MessageContent>\n </Message>\n )}\n\n {index === messages.length - 1 && streamStart && (\n <div className=\"mt-3\">\n <StreamStatus\n iconVariant=\"loader-circle\"\n isStreaming={status === \"streaming\"}\n startTime={streamStart}\n />\n </div>\n )}\n </div>\n ))}\n </ConversationContent>\n <ConversationScrollButton />\n </Conversation>\n\n {/* Suggestions — only shown when conversation is empty */}\n {messages.length === 0 && suggestions.length > 0 && (\n <div className=\"px-4 pb-2\">\n <Suggestions>\n {suggestions.map((s) => (\n <Suggestion key={s} onClick={handleSuggestion} suggestion={s} />\n ))}\n </Suggestions>\n </div>\n )}\n\n {/* Prompt input */}\n <div className=\"px-4 pt-3 pb-4\">\n <PromptInput onSubmit={handleSubmit}>\n <PromptInputBody>\n <PromptInputTextarea\n aria-labelledby={labelId}\n onChange={(e) => setText(e.target.value)}\n placeholder=\"Ask anything...\"\n value={text}\n />\n </PromptInputBody>\n <PromptInputFooter>\n <PromptInputTools>\n {/* Model selector */}\n {models.length > 1 && (\n <PromptInputSelect onValueChange={setModel} value={model}>\n <PromptInputSelectTrigger>\n <PromptInputSelectValue />\n </PromptInputSelectTrigger>\n <PromptInputSelectContent>\n {models.map((m) => (\n <PromptInputSelectItem key={m.id} value={m.id}>\n {m.name}\n </PromptInputSelectItem>\n ))}\n </PromptInputSelectContent>\n </PromptInputSelect>\n )}\n\n {/* Web search toggle */}\n <PromptInputButton\n onClick={() => setWebSearch((v) => !v)}\n tooltip={{ content: \"Search the web\" }}\n variant={webSearch ? \"default\" : \"ghost\"}\n >\n <GlobeIcon size={16} />\n <span>Search</span>\n </PromptInputButton>\n </PromptInputTools>\n\n <PromptInputSubmit disabled={!text.trim()} status={status} />\n </PromptInputFooter>\n </PromptInput>\n </div>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Internal sub-component for assistant messages\n// ---------------------------------------------------------------------------\n\ninterface AssistantMessageProps {\n id: string\n content: string\n reasoning?: string\n sources?: ChatSource[]\n onCopy: (content: string) => void\n onRetry: (id: string) => void\n}\n\nconst AssistantMessage = ({ id, content, reasoning, sources, onCopy, onRetry }: AssistantMessageProps) => (\n <div className=\"space-y-2\">\n {reasoning && (\n <Reasoning>\n <ReasoningTrigger />\n <ReasoningContent>{reasoning}</ReasoningContent>\n </Reasoning>\n )}\n\n <Message from=\"assistant\">\n <MessageContent>\n <MessageResponse>{content}</MessageResponse>\n </MessageContent>\n </Message>\n\n {sources && sources.length > 0 && (\n <Sources>\n <SourcesTrigger count={sources.length} />\n <SourcesContent>\n {sources.map((s) => (\n <Source href={s.href} key={s.href} title={s.title} />\n ))}\n </SourcesContent>\n </Sources>\n )}\n\n <MessageActions>\n <MessageAction label=\"Copy\" onClick={() => onCopy(content)}>\n <CopyIcon className=\"size-3\" />\n </MessageAction>\n <MessageAction label=\"Retry\" onClick={() => onRetry(id)}>\n <RefreshCcwIcon className=\"size-3\" />\n </MessageAction>\n </MessageActions>\n </div>\n)\n"],"names":["DEFAULT_MODELS","DEFAULT_SUGGESTIONS","_idCounter","nextId","STREAM_STATUS_LINGER_MS","Chat","initialMessages","models","defaultModel","suggestions","onSend","className","labelId","useId","messages","setMessages","useState","text","setText","model","setModel","webSearch","setWebSearch","status","setStatus","streamStart","setStreamStart","handleSubmit","useCallback","_msg","trimmed","userMsg","prev","reply","assistantMsg","handleSuggestion","suggestion","handleCopy","content","handleRetry","id","idx","m","cn","jsxs","Conversation","ConversationContent","jsx","ConversationEmptyState","msg","index","MessageBranch","MessageBranchContent","branch","i","AssistantMessage","MessageToolbar","MessageBranchSelector","MessageBranchPrevious","MessageBranchPage","MessageBranchNext","Fragment","Message","MessageContent","MessageResponse","StreamStatus","ConversationScrollButton","Suggestions","Suggestion","PromptInput","PromptInputBody","PromptInputTextarea","e","PromptInputFooter","PromptInputTools","PromptInputSelect","PromptInputSelectTrigger","PromptInputSelectValue","PromptInputSelectContent","PromptInputSelectItem","PromptInputButton","v","GlobeIcon","PromptInputSubmit","reasoning","sources","onCopy","onRetry","Reasoning","ReasoningTrigger","ReasoningContent","Sources","SourcesTrigger","SourcesContent","s","Source","MessageActions","MessageAction","CopyIcon","RefreshCcwIcon"],"mappings":"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"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { jsxs as n, jsx as e, Fragment as z } from "react/jsx-runtime";
|
|
2
|
+
import { GlobeIcon as O, CopyIcon as V, RefreshCcwIcon as W } from "lucide-react";
|
|
3
|
+
import { useId as j, useState as c, useCallback as g } from "react";
|
|
4
|
+
import { Conversation as q, ConversationContent as $, ConversationEmptyState as H, ConversationScrollButton as J } from "../../ai/conversation.js";
|
|
5
|
+
import { MessageBranch as K, MessageBranchContent as Q, MessageToolbar as X, MessageBranchSelector as Y, MessageBranchPrevious as Z, MessageBranchPage as ee, MessageBranchNext as te, Message as A, MessageContent as B, MessageResponse as E, MessageActions as ne, MessageAction as T } from "../../ai/message.js";
|
|
6
|
+
import { PromptInput as re, PromptInputBody as ae, PromptInputTextarea as se, PromptInputFooter as oe, PromptInputTools as ie, PromptInputSelect as ce, PromptInputSelectTrigger as le, PromptInputSelectValue as de, PromptInputSelectContent as he, PromptInputSelectItem as me, PromptInputButton as pe, PromptInputSubmit as ue } from "../../ai/prompt-input.js";
|
|
7
|
+
import { Reasoning as ge, ReasoningTrigger as Se, ReasoningContent as fe } from "../../ai/reasoning.js";
|
|
8
|
+
import { Sources as Ce, SourcesTrigger as ye, SourcesContent as Ie, Source as be } from "../../ai/sources.js";
|
|
9
|
+
import { StreamStatus as ve } from "../../ai/stream-status.js";
|
|
10
|
+
import { Suggestions as xe, Suggestion as Me } from "../../ai/suggestion.js";
|
|
11
|
+
import { cn as Pe } from "../../../lib/utils.js";
|
|
12
|
+
const Te = [
|
|
13
|
+
{ id: "claude-sonnet-4-6", name: "Claude Sonnet" },
|
|
14
|
+
{ id: "claude-opus-4-7", name: "Claude Opus" }
|
|
15
|
+
], Ne = [
|
|
16
|
+
"Explain quantum entanglement simply",
|
|
17
|
+
"Write a Python script to rename files",
|
|
18
|
+
"Summarise the latest AI research trends",
|
|
19
|
+
"What is the difference between TCP and UDP?"
|
|
20
|
+
];
|
|
21
|
+
let N = 0;
|
|
22
|
+
const R = () => (N += 1, `chat-msg-${N}`), Re = 3e3, ze = ({
|
|
23
|
+
initialMessages: S = [],
|
|
24
|
+
models: o = Te,
|
|
25
|
+
defaultModel: d,
|
|
26
|
+
suggestions: s = Ne,
|
|
27
|
+
onSend: h,
|
|
28
|
+
className: f
|
|
29
|
+
}) => {
|
|
30
|
+
const l = j(), [m, C] = c(S), [p, y] = c(""), [I, k] = c(d ?? o[0]?.id ?? ""), [_, D] = c(!1), [u, b] = c("ready"), [v, x] = c(), U = g(
|
|
31
|
+
async (t) => {
|
|
32
|
+
const r = p.trim();
|
|
33
|
+
if (!r || u === "streaming") return;
|
|
34
|
+
const i = {
|
|
35
|
+
id: R(),
|
|
36
|
+
role: "user",
|
|
37
|
+
content: r
|
|
38
|
+
};
|
|
39
|
+
C((a) => [...a, i]), y(""), b("streaming"), x(/* @__PURE__ */ new Date());
|
|
40
|
+
try {
|
|
41
|
+
const a = await h?.(r, I), G = {
|
|
42
|
+
id: R(),
|
|
43
|
+
role: "assistant",
|
|
44
|
+
content: a ?? "I received your message."
|
|
45
|
+
};
|
|
46
|
+
C((L) => [...L, G]);
|
|
47
|
+
} finally {
|
|
48
|
+
b("ready"), setTimeout(() => x(void 0), Re);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
[p, u, I, h]
|
|
52
|
+
), F = g((t) => {
|
|
53
|
+
y(t);
|
|
54
|
+
}, []), M = g((t) => {
|
|
55
|
+
navigator.clipboard.writeText(t).catch(() => {
|
|
56
|
+
});
|
|
57
|
+
}, []), P = g((t) => {
|
|
58
|
+
C((r) => {
|
|
59
|
+
const i = r.findIndex((a) => a.id === t);
|
|
60
|
+
return i === -1 ? r : r.slice(0, i);
|
|
61
|
+
});
|
|
62
|
+
}, []);
|
|
63
|
+
return /* @__PURE__ */ n("div", { className: Pe("mx-auto flex h-full w-full max-w-[980px] flex-col", f), children: [
|
|
64
|
+
/* @__PURE__ */ n(q, { className: "flex-1", children: [
|
|
65
|
+
/* @__PURE__ */ n($, { children: [
|
|
66
|
+
m.length === 0 ? /* @__PURE__ */ e(
|
|
67
|
+
H,
|
|
68
|
+
{
|
|
69
|
+
description: "Send a message or pick a suggestion below to start.",
|
|
70
|
+
title: "Start a conversation"
|
|
71
|
+
}
|
|
72
|
+
) : null,
|
|
73
|
+
m.map((t, r) => /* @__PURE__ */ n("div", { className: "space-y-1", children: [
|
|
74
|
+
t.role === "assistant" && t.branches && t.branches.length > 1 ? /* @__PURE__ */ n(K, { children: [
|
|
75
|
+
/* @__PURE__ */ e(Q, { children: t.branches.map((i, a) => /* @__PURE__ */ e(
|
|
76
|
+
w,
|
|
77
|
+
{
|
|
78
|
+
content: i,
|
|
79
|
+
id: t.id,
|
|
80
|
+
onCopy: M,
|
|
81
|
+
onRetry: P,
|
|
82
|
+
reasoning: a === 0 ? t.reasoning : void 0,
|
|
83
|
+
sources: a === 0 ? t.sources : void 0
|
|
84
|
+
},
|
|
85
|
+
a
|
|
86
|
+
)) }),
|
|
87
|
+
/* @__PURE__ */ e(X, { children: /* @__PURE__ */ n(Y, { children: [
|
|
88
|
+
/* @__PURE__ */ e(Z, {}),
|
|
89
|
+
/* @__PURE__ */ e(ee, {}),
|
|
90
|
+
/* @__PURE__ */ e(te, {})
|
|
91
|
+
] }) })
|
|
92
|
+
] }) : t.role === "assistant" ? /* @__PURE__ */ e(z, { children: /* @__PURE__ */ e(
|
|
93
|
+
w,
|
|
94
|
+
{
|
|
95
|
+
content: t.content,
|
|
96
|
+
id: t.id,
|
|
97
|
+
onCopy: M,
|
|
98
|
+
onRetry: P,
|
|
99
|
+
reasoning: t.reasoning,
|
|
100
|
+
sources: t.sources
|
|
101
|
+
}
|
|
102
|
+
) }) : /* @__PURE__ */ e(A, { from: "user", children: /* @__PURE__ */ e(B, { children: /* @__PURE__ */ e(E, { children: t.content }) }) }),
|
|
103
|
+
r === m.length - 1 && v && /* @__PURE__ */ e("div", { className: "mt-3", children: /* @__PURE__ */ e(
|
|
104
|
+
ve,
|
|
105
|
+
{
|
|
106
|
+
iconVariant: "loader-circle",
|
|
107
|
+
isStreaming: u === "streaming",
|
|
108
|
+
startTime: v
|
|
109
|
+
}
|
|
110
|
+
) })
|
|
111
|
+
] }, t.id))
|
|
112
|
+
] }),
|
|
113
|
+
/* @__PURE__ */ e(J, {})
|
|
114
|
+
] }),
|
|
115
|
+
m.length === 0 && s.length > 0 && /* @__PURE__ */ e("div", { className: "px-4 pb-2", children: /* @__PURE__ */ e(xe, { children: s.map((t) => /* @__PURE__ */ e(Me, { onClick: F, suggestion: t }, t)) }) }),
|
|
116
|
+
/* @__PURE__ */ e("div", { className: "px-4 pt-3 pb-4", children: /* @__PURE__ */ n(re, { onSubmit: U, children: [
|
|
117
|
+
/* @__PURE__ */ e(ae, { children: /* @__PURE__ */ e(
|
|
118
|
+
se,
|
|
119
|
+
{
|
|
120
|
+
"aria-labelledby": l,
|
|
121
|
+
onChange: (t) => y(t.target.value),
|
|
122
|
+
placeholder: "Ask anything...",
|
|
123
|
+
value: p
|
|
124
|
+
}
|
|
125
|
+
) }),
|
|
126
|
+
/* @__PURE__ */ n(oe, { children: [
|
|
127
|
+
/* @__PURE__ */ n(ie, { children: [
|
|
128
|
+
o.length > 1 && /* @__PURE__ */ n(ce, { onValueChange: k, value: I, children: [
|
|
129
|
+
/* @__PURE__ */ e(le, { children: /* @__PURE__ */ e(de, {}) }),
|
|
130
|
+
/* @__PURE__ */ e(he, { children: o.map((t) => /* @__PURE__ */ e(me, { value: t.id, children: t.name }, t.id)) })
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ n(
|
|
133
|
+
pe,
|
|
134
|
+
{
|
|
135
|
+
onClick: () => D((t) => !t),
|
|
136
|
+
tooltip: { content: "Search the web" },
|
|
137
|
+
variant: _ ? "default" : "ghost",
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ e(O, { size: 16 }),
|
|
140
|
+
/* @__PURE__ */ e("span", { children: "Search" })
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
] }),
|
|
145
|
+
/* @__PURE__ */ e(ue, { disabled: !p.trim(), status: u })
|
|
146
|
+
] })
|
|
147
|
+
] }) })
|
|
148
|
+
] });
|
|
149
|
+
}, w = ({ id: S, content: o, reasoning: d, sources: s, onCopy: h, onRetry: f }) => /* @__PURE__ */ n("div", { className: "space-y-2", children: [
|
|
150
|
+
d && /* @__PURE__ */ n(ge, { children: [
|
|
151
|
+
/* @__PURE__ */ e(Se, {}),
|
|
152
|
+
/* @__PURE__ */ e(fe, { children: d })
|
|
153
|
+
] }),
|
|
154
|
+
/* @__PURE__ */ e(A, { from: "assistant", children: /* @__PURE__ */ e(B, { children: /* @__PURE__ */ e(E, { children: o }) }) }),
|
|
155
|
+
s && s.length > 0 && /* @__PURE__ */ n(Ce, { children: [
|
|
156
|
+
/* @__PURE__ */ e(ye, { count: s.length }),
|
|
157
|
+
/* @__PURE__ */ e(Ie, { children: s.map((l) => /* @__PURE__ */ e(be, { href: l.href, title: l.title }, l.href)) })
|
|
158
|
+
] }),
|
|
159
|
+
/* @__PURE__ */ n(ne, { children: [
|
|
160
|
+
/* @__PURE__ */ e(T, { label: "Copy", onClick: () => h(o), children: /* @__PURE__ */ e(V, { className: "size-3" }) }),
|
|
161
|
+
/* @__PURE__ */ e(T, { label: "Retry", onClick: () => f(S), children: /* @__PURE__ */ e(W, { className: "size-3" }) })
|
|
162
|
+
] })
|
|
163
|
+
] });
|
|
164
|
+
export {
|
|
165
|
+
ze as Chat
|
|
166
|
+
};
|
|
167
|
+
//# sourceMappingURL=Chat.js.map
|