'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; 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; 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';