"use client"; import type { ToolCallMessagePartProps } from "@assistant-ui/react"; import { CornerDownLeftIcon, InfoIcon } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { TextShimmerLoader } from "@/components/prompt-kit/loader"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { useHitlPhase } from "@/hooks/use-hitl-phase"; interface GoogleDriveAccount { id: number; name: string; auth_expired?: boolean; } interface GoogleDriveFile { file_id: string; name: string; mime_type: string; web_view_link: string; } interface InterruptResult { __interrupt__: true; __decided__?: "approve" | "reject"; __completed__?: boolean; action_requests: Array<{ name: string; args: Record; }>; review_configs: Array<{ action_name: string; allowed_decisions: Array<"approve" | "reject">; }>; context?: { account?: GoogleDriveAccount; file?: GoogleDriveFile; error?: string; }; } interface SuccessResult { status: "success"; file_id: string; message?: string; deleted_from_kb?: boolean; } interface WarningResult { status: "success"; warning: string; file_id?: string; message?: string; } interface ErrorResult { status: "error"; message: string; } interface NotFoundResult { status: "not_found"; message: string; } interface InsufficientPermissionsResult { status: "insufficient_permissions"; connector_id: number; message: string; } interface AuthErrorResult { status: "auth_error"; message: string; connector_type?: string; } type DeleteGoogleDriveFileResult = | InterruptResult | SuccessResult | WarningResult | ErrorResult | NotFoundResult | InsufficientPermissionsResult | AuthErrorResult; function isInterruptResult(result: unknown): result is InterruptResult { return ( typeof result === "object" && result !== null && "__interrupt__" in result && (result as InterruptResult).__interrupt__ === true ); } function isErrorResult(result: unknown): result is ErrorResult { return ( typeof result === "object" && result !== null && "status" in result && (result as ErrorResult).status === "error" ); } function isNotFoundResult(result: unknown): result is NotFoundResult { return ( typeof result === "object" && result !== null && "status" in result && (result as NotFoundResult).status === "not_found" ); } function isWarningResult(result: unknown): result is WarningResult { return ( typeof result === "object" && result !== null && "status" in result && (result as WarningResult).status === "success" && "warning" in result && typeof (result as WarningResult).warning === "string" ); } function isInsufficientPermissionsResult(result: unknown): result is InsufficientPermissionsResult { return ( typeof result === "object" && result !== null && "status" in result && (result as InsufficientPermissionsResult).status === "insufficient_permissions" ); } function isAuthErrorResult(result: unknown): result is AuthErrorResult { return ( typeof result === "object" && result !== null && "status" in result && (result as AuthErrorResult).status === "auth_error" ); } const MIME_TYPE_LABELS: Record = { "application/vnd.google-apps.document": "Google Doc", "application/vnd.google-apps.spreadsheet": "Google Sheet", "application/vnd.google-apps.presentation": "Google Slides", }; function ApprovalCard({ interruptData, onDecision, }: { interruptData: InterruptResult; onDecision: (decision: { type: "approve" | "reject"; message?: string; edited_action?: { name: string; args: Record }; }) => void; }) { const { phase, setProcessing, setRejected } = useHitlPhase(interruptData); const [deleteFromKb, setDeleteFromKb] = useState(false); const context = interruptData.context; const account = context?.account; const file = context?.file; const fileLabel = file?.mime_type ? (MIME_TYPE_LABELS[file.mime_type] ?? "File") : "File"; const handleApprove = useCallback(() => { if (phase !== "pending") return; setProcessing(); onDecision({ type: "approve", edited_action: { name: interruptData.action_requests[0].name, args: { file_id: file?.file_id, connector_id: account?.id, delete_from_kb: deleteFromKb, }, }, }); }, [phase, setProcessing, onDecision, interruptData, file?.file_id, account?.id, deleteFromKb]); useEffect(() => { const handler = (e: KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey && !e.ctrlKey && !e.metaKey) { handleApprove(); } }; window.addEventListener("keydown", handler); return () => window.removeEventListener("keydown", handler); }, [handleApprove]); return (
{/* Header */}

{phase === "rejected" ? "Google Drive File Deletion Rejected" : phase === "processing" || phase === "complete" ? "Google Drive File Deletion Approved" : "Delete Google Drive File"}

{phase === "processing" ? ( ) : phase === "complete" ? (

File trashed

) : phase === "rejected" ? (

File deletion was cancelled

) : (

Requires your approval to proceed

)}
{/* Context — read-only file details (visible in pending, processing, complete) */} {phase !== "rejected" && context && ( <>
{context.error ? (

{context.error}

) : ( <> {account && (

Google Drive Account

{account.name}
)} {file && (

File to Trash

{file.name}
{fileLabel}
{file.web_view_link && ( Open in Drive )}
)} )}
)} {/* Trash warning + delete_from_kb toggle */} {phase === "pending" && ( <>

The file will be moved to Google Drive trash. You can restore it from trash within 30 days.

setDeleteFromKb(v === true)} className="shrink-0" />
)} {/* Action buttons - only shown when pending */} {phase === "pending" && ( <>
)}
); } function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) { return (

Additional Google Drive permissions required

{result.message}

); } function AuthErrorCard({ result }: { result: AuthErrorResult }) { return (

Google Drive authentication expired

{result.message}

); } function WarningCard({ result }: { result: WarningResult }) { return (

Partial success

{result.message &&

{result.message}

}

{result.warning}

); } function ErrorCard({ result }: { result: ErrorResult }) { return (

Failed to delete file

{result.message}

); } function NotFoundCard({ result }: { result: NotFoundResult }) { return (

{result.message}

); } function SuccessCard({ result }: { result: SuccessResult }) { return (

{result.message || "File moved to trash successfully"}

{result.deleted_from_kb && ( <>
Also removed from knowledge base
)}
); } export const DeleteGoogleDriveFileToolUI = ({ result }: ToolCallMessagePartProps<{ file_name: string; delete_from_kb?: boolean }, DeleteGoogleDriveFileResult>) => { if (!result) return null; if (isInterruptResult(result)) { return ( { const event = new CustomEvent("hitl-decision", { detail: { decisions: [decision] }, }); window.dispatchEvent(event); }} /> ); } if ( typeof result === "object" && result !== null && "status" in result && (result as { status: string }).status === "rejected" ) { return null; } if (isAuthErrorResult(result)) return ; if (isInsufficientPermissionsResult(result)) return ; if (isNotFoundResult(result)) return ; if (isWarningResult(result)) return ; if (isErrorResult(result)) return ; return ; };