/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ 'use client' import { type ComponentProps, createContext, type ReactNode, useContext, } from 'react' import type { ToolUIPart } from 'ai' import { cn } from '@/lib/utils' import { Alert, AlertDescription } from '@/components/ui/alert' import { Button } from '@/components/ui/button' // Workaround for missing types in 'ai' package type ExtendedToolState = | ToolUIPart['state'] | 'approval-requested' | 'approval-responded' | 'output-denied' type ExtendedToolApproval = { approved: boolean } type ConfirmationContextValue = { approval: ExtendedToolApproval | undefined state: ExtendedToolState } 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?: ExtendedToolApproval state: ExtendedToolState } 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) => (