"use client"; import { ShieldAlert } from "lucide-react"; import { useTranslations } from "next-intl"; import { useEffect, useState } from "react"; import { MicroLabel } from "../../../components/typography"; import { Badge, Button } from "../../../shadcnui"; import type { AssistantMessageInterface } from "../../assistant-message/data/AssistantMessageInterface"; import type { AssistantActionStatus } from "../data/AssistantActionInterface"; import { AssistantActionService } from "../data/AssistantActionService"; /** * Status pill variants. Soft `Badge` variants only — a hand-rolled * `bg-*-100 text-*-800` span is never a status pill (typography rule 8). */ const STATUS_VARIANT: Record = { pending: "softBlue", approved: "softBlue", executed: "softGreen", denied: "softRed", failed: "softRed", expired: "softGray", }; /** * Literal i18n keys (not a template literal) so the key set stays greppable * and every one of them can be verified against the app's messages file. */ const STATUS_LABEL_KEY: Record = { pending: "features.assistant.approval.status.pending", approved: "features.assistant.approval.status.approved", executed: "features.assistant.approval.status.executed", denied: "features.assistant.approval.status.denied", failed: "features.assistant.approval.status.failed", expired: "features.assistant.approval.status.expired", }; interface Props { /** Id of the pending AssistantAction linked to the approval-request message. */ actionId: string; /** Human-readable summary fallback (the approval-request message content). */ summary?: string; /** Invoked with the resumed assistant message returned by approve/deny. */ onResolved?: (message: AssistantMessageInterface) => void; } /** * Renders an `approval-request` assistant message as an action card: * the destructive-tool summary plus Approve / Deny buttons. Buttons are * only actionable while the underlying AssistantAction is `pending`. * * NOTE: plain ` ); }