"use client"; import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { Badge } from "@/components/ui/badge"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible"; import { cn } from "@/lib/utils"; import { BrainIcon, ChevronDownIcon, DotIcon, type LucideIcon, } from "lucide-react"; import type { ComponentProps, ReactNode } from "react"; import { createContext, memo, useContext, useMemo } from "react"; type ChainOfThoughtContextValue = { isOpen: boolean; setIsOpen: (open: boolean) => void; }; const ChainOfThoughtContext = createContext( null ); const useChainOfThought = () => { const context = useContext(ChainOfThoughtContext); if (!context) { throw new Error( "ChainOfThought components must be used within ChainOfThought" ); } return context; }; export type ChainOfThoughtProps = ComponentProps<"div"> & { open?: boolean; defaultOpen?: boolean; onOpenChange?: (open: boolean) => void; }; export const ChainOfThought = memo( ({ className, open, defaultOpen = false, onOpenChange, children, ...props }: ChainOfThoughtProps) => { const [isOpen, setIsOpen] = useControllableState({ prop: open, defaultProp: defaultOpen, onChange: onOpenChange, }); const chainOfThoughtContext = useMemo( () => ({ isOpen, setIsOpen }), [isOpen, setIsOpen] ); return (
{children}
); } ); export type ChainOfThoughtHeaderProps = ComponentProps< typeof CollapsibleTrigger >; export const ChainOfThoughtHeader = memo( ({ className, children, ...props }: ChainOfThoughtHeaderProps) => { const { isOpen, setIsOpen } = useChainOfThought(); return ( {children ?? "Chain of Thought"} ); } ); export type ChainOfThoughtStepProps = ComponentProps<"div"> & { icon?: LucideIcon; label: ReactNode; description?: ReactNode; status?: "complete" | "active" | "pending"; }; export const ChainOfThoughtStep = memo( ({ className, icon: Icon = DotIcon, label, description, status = "complete", children, ...props }: ChainOfThoughtStepProps) => { const statusStyles = { complete: "text-muted-foreground", active: "text-foreground", pending: "text-muted-foreground/50", }; return (
{label}
{description && (
{description}
)} {children}
); } ); export type ChainOfThoughtSearchResultsProps = ComponentProps<"div">; export const ChainOfThoughtSearchResults = memo( ({ className, ...props }: ChainOfThoughtSearchResultsProps) => (
) ); export type ChainOfThoughtSearchResultProps = ComponentProps; export const ChainOfThoughtSearchResult = memo( ({ className, children, ...props }: ChainOfThoughtSearchResultProps) => ( {children} ) ); export type ChainOfThoughtContentProps = ComponentProps< typeof CollapsibleContent >; export const ChainOfThoughtContent = memo( ({ className, children, ...props }: ChainOfThoughtContentProps) => { const { isOpen } = useChainOfThought(); return ( {children} ); } ); export type ChainOfThoughtImageProps = ComponentProps<"div"> & { caption?: string; }; export const ChainOfThoughtImage = memo( ({ className, children, caption, ...props }: ChainOfThoughtImageProps) => (
{children}
{caption &&

{caption}

}
) ); ChainOfThought.displayName = "ChainOfThought"; ChainOfThoughtHeader.displayName = "ChainOfThoughtHeader"; ChainOfThoughtStep.displayName = "ChainOfThoughtStep"; ChainOfThoughtSearchResults.displayName = "ChainOfThoughtSearchResults"; ChainOfThoughtSearchResult.displayName = "ChainOfThoughtSearchResult"; ChainOfThoughtContent.displayName = "ChainOfThoughtContent"; ChainOfThoughtImage.displayName = "ChainOfThoughtImage";