import { Alert, AlertDescription } from '@/components/ui/alert'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import type { ToolUIPart } from 'ai'; import { type ComponentProps, createContext, type ReactNode, useContext } from 'react'; type ToolUIPartApproval = | { id: string; approved?: never; reason?: never; } | { id: string; approved: boolean; reason?: string; } | { id: string; approved: true; reason?: string; } | { id: string; approved: true; reason?: string; } | { id: string; approved: false; reason?: string; } | undefined; type ConfirmationContextValue = { approval: ToolUIPartApproval; state: ToolUIPart['state']; }; const ConfirmationContext = createContext(null); const useConfirmation = () => { const context = useContext(ConfirmationContext); if (!context) { throw new Error('Confirmation components must be used within Confirmation'); } return context; }; export type ConfirmationProps = ComponentProps & { approval?: ToolUIPartApproval; state: ToolUIPart['state']; }; export const Confirmation = ({ className, approval, state, ...props }: ConfirmationProps) => { if (!approval || state === 'input-streaming' || state === 'input-available') { return null; } return ( ); }; export type ConfirmationTitleProps = ComponentProps; export const ConfirmationTitle = ({ className, ...props }: ConfirmationTitleProps) => ( ); export type ConfirmationRequestProps = { children?: ReactNode; }; export const ConfirmationRequest = ({ children }: ConfirmationRequestProps) => { const { state } = useConfirmation(); // Only show when approval is requested if (state !== 'approval-requested') { return null; } return children; }; export type ConfirmationAcceptedProps = { children?: ReactNode; }; export const ConfirmationAccepted = ({ children }: ConfirmationAcceptedProps) => { const { approval, state } = useConfirmation(); // Only show when approved and in response states if ( !approval?.approved || (state !== 'approval-responded' && state !== 'output-denied' && state !== 'output-available') ) { return null; } return children; }; export type ConfirmationRejectedProps = { children?: ReactNode; }; export const ConfirmationRejected = ({ children }: ConfirmationRejectedProps) => { const { approval, state } = useConfirmation(); // Only show when rejected and in response states if ( approval?.approved !== false || (state !== 'approval-responded' && state !== 'output-denied' && state !== 'output-available') ) { return null; } return children; }; export type ConfirmationActionsProps = ComponentProps<'div'>; export const ConfirmationActions = ({ className, ...props }: ConfirmationActionsProps) => { const { state } = useConfirmation(); // Only show when approval is requested if (state !== 'approval-requested') { return null; } return (
); }; export type ConfirmationActionProps = ComponentProps; export const ConfirmationAction = (props: ConfirmationActionProps) => (