"use client"; 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, ReactNode } from "react"; import { createContext, useContext, useMemo } 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; interface 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) => { const contextValue = useMemo(() => ({ approval, state }), [approval, state]); if (!approval || state === "input-streaming" || state === "input-available") { return null; } return ( ); }; export type ConfirmationTitleProps = ComponentProps; export const ConfirmationTitle = ({ className, ...props }: ConfirmationTitleProps) => ( ); export interface 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 interface 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 interface 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) => (