import { ArrowLeftIcon, CheckIcon, ChevronRightIcon, CircleAlertIcon, CircleSlashIcon, LoaderCircleIcon, ShieldCheckIcon, } from "lucide-react"; import { useEffect, useId, useRef, useState, type HTMLAttributes, type ReactNode } from "react"; import type { ToolActionReview, ToolReviewDetailsPage, ToolReviewStatus } from "@opengeni/sdk"; import { cn } from "../lib/cn"; import { SecretRefText } from "./secret-ref-chip"; import { useOpenGeniText, type OpenGeniText } from "../messages/runtime"; export type ToolReviewDetailsLoader = ( review: ToolActionReview, path: string, offset: number, ) => Promise; const statusText = (t: OpenGeniText): Record => ({ pending: t("toolActionReview.approvalNeeded"), approved: t("toolActionReview.approved"), executing: t("toolActionReview.approvedRunning"), completed: t("toolActionReview.approvedDone"), partial: t("toolActionReview.partlyDone"), unknown: t("toolActionReview.outcomeUnknown"), rejected: t("toolActionReview.declined"), cancelled: t("toolActionReview.cancelled"), expired: t("toolActionReview.expired"), revoked: t("toolActionReview.accessUnavailable"), blocked: t("toolActionReview.blocked"), stale: t("toolActionReview.noLongerValid"), failed: t("toolActionReview.failed"), unavailable: t("toolActionReview.detailsUnavailable"), }); const statusDetail = (t: OpenGeniText): Partial> => ({ unknown: t("toolActionReview.itMayHaveRunCheck"), rejected: t("toolActionReview.thisActionDidNotRun"), cancelled: t("toolActionReview.thisActionDidNotRun"), expired: t("toolActionReview.thisActionDidNotRun2"), revoked: t("toolActionReview.thisActionDidNotRun3"), stale: t("toolActionReview.theToolOrAccountChanged"), partial: t("toolActionReview.someOfItRanCheck"), failed: t("toolActionReview.theActionRanButReturned"), }); type Tone = "waiting" | "ok" | "failed" | "muted"; const statusTone: Record = { pending: "waiting", approved: "ok", executing: "ok", completed: "ok", partial: "failed", unknown: "failed", rejected: "muted", cancelled: "muted", expired: "muted", revoked: "muted", blocked: "muted", stale: "muted", failed: "failed", unavailable: "muted", }; const toneText: Record = { waiting: "text-og-status-waiting", ok: "text-og-fg-muted", failed: "text-og-status-failed", muted: "text-og-fg-muted", }; /** Fields that only identify the selection; the count, examples and details cover them. */ const selectionPaths = new Set([ "/messageIds", "/messageId", "/threadId", "/addLabelIds", "/removeLabelIds", "/labelIds", ]); /** Shown when an older request's saved values are gone: approval is impossible, decline is not. */ export const UNRECOVERABLE_TEXT = (t: OpenGeniText) => t("toolActionReview.theDetailsOfThisOlder"); /** Long argument lists stay readable; the full set is one click away in details. */ const VISIBLE_FIELDS = 6; function StatusIcon({ status, busy }: { status: ToolReviewStatus; busy?: boolean }) { const className = "size-4"; if (busy || status === "executing" || status === "approved") return