"use client"; import { makeAssistantToolUI } from "@assistant-ui/react"; import { AlertTriangleIcon, CheckIcon, InfoIcon, Loader2Icon, TriangleAlertIcon, XIcon, } from "lucide-react"; import { useState } from "react"; import { Button } from "@/components/ui/button"; interface InterruptResult { __interrupt__: true; __decided__?: "approve" | "reject"; action_requests: Array<{ name: string; args: Record; }>; review_configs: Array<{ action_name: string; allowed_decisions: Array<"approve" | "reject">; }>; interrupt_type?: string; context?: { workspace?: { id: number; organization_name: string }; issue?: { id: string; identifier: string; title: string; state?: string; document_id?: number; indexed_at?: string; }; error?: string; }; } interface SuccessResult { status: "success"; deleted_from_kb?: boolean; message?: string; } interface ErrorResult { status: "error"; message: string; } interface NotFoundResult { status: "not_found"; message: string; } interface WarningResult { status: "success"; warning: string; message?: string; } type DeleteLinearIssueResult = | InterruptResult | SuccessResult | ErrorResult | NotFoundResult | WarningResult; 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 ApprovalCard({ interruptData, onDecision, }: { interruptData: InterruptResult; onDecision: (decision: { type: "approve" | "reject"; message?: string; edited_action?: { name: string; args: Record }; }) => void; }) { const actionArgs = interruptData.action_requests[0]?.args ?? {}; const context = interruptData.context; const issue = context?.issue; const [decided, setDecided] = useState<"approve" | "reject" | null>( interruptData.__decided__ ?? null ); const [deleteFromKb, setDeleteFromKb] = useState( typeof actionArgs.delete_from_kb === "boolean" ? actionArgs.delete_from_kb : false ); return (
{/* Header */}

Delete Linear Issue

Requires your approval to proceed

{/* Context section — workspace + issue info (read-only) */} {!decided && (
{context?.error ? (

{context.error}

) : ( <> {context?.workspace && (
Linear Account
{context.workspace.organization_name}
)} {issue && (
Issue to Archive
{issue.identifier}: {issue.title}
{issue.state && (
{issue.state}
)}
)} )}
)} {/* delete_from_kb toggle */} {!decided && (
)} {/* Action buttons */}
{decided ? (

{decided === "approve" ? ( <> Approved ) : ( <> Rejected )}

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

Failed to delete Linear issue

{result.message}

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

{result.message}

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

Partial success

{result.warning}

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

{result.message || "Linear issue archived successfully"}

{result.deleted_from_kb && (
✓ Also removed from knowledge base
)}
); } export const DeleteLinearIssueToolUI = makeAssistantToolUI< { issue_ref: string; delete_from_kb?: boolean }, DeleteLinearIssueResult >({ toolName: "delete_linear_issue", render: function DeleteLinearIssueUI({ result, status }) { if (status.type === "running") { return (

Preparing Linear issue deletion...

); } if (!result) return null; if (isInterruptResult(result)) { return ( { window.dispatchEvent( new CustomEvent("hitl-decision", { detail: { decisions: [decision] } }) ); }} /> ); } if ( typeof result === "object" && result !== null && "status" in result && (result as { status: string }).status === "rejected" ) { return null; } if (isNotFoundResult(result)) return ; if (isWarningResult(result)) return ; if (isErrorResult(result)) return ; return ; }, });