diff --git a/src/components/chat/AgentTurn.tsx b/src/components/chat/AgentTurn.tsx index ab13f01..9b53bc1 100644 --- a/src/components/chat/AgentTurn.tsx +++ b/src/components/chat/AgentTurn.tsx @@ -20,6 +20,7 @@ import { alpha, useTheme, } from "@mui/material"; +import type { Theme } from "@mui/material/styles"; import ContentCopyRounded from "@mui/icons-material/ContentCopyRounded"; import RefreshRounded from "@mui/icons-material/RefreshRounded"; import EditRounded from "@mui/icons-material/EditRounded"; @@ -149,6 +150,27 @@ const getPermissionStatusLabel = (status: NonNullable[nu }; const pendingPermissionColor = "#f9a825"; +const approvedOncePermissionColor = "#00838f"; + +const getPermissionStatusColor = ( + status: NonNullable[number]["status"], + theme: Theme, +) => { + if (status === "approved_once") return approvedOncePermissionColor; + if (status === "approved_always") return theme.palette.success.main; + if (status === "rejected" || status === "error") return theme.palette.error.main; + return pendingPermissionColor; +}; + +const getPermissionStatusTextColor = ( + status: NonNullable[number]["status"], + theme: Theme, +) => { + if (status === "approved_once") return "#006c78"; + if (status === "approved_always") return theme.palette.success.dark; + if (status === "rejected" || status === "error") return theme.palette.error.main; + return "#8a5a00"; +}; const PermissionRequestCard = ({ permission, @@ -162,19 +184,9 @@ const PermissionRequestCard = ({ const isSubmitting = permission.status === "submitting"; const primaryValue = getPermissionPrimaryValue(permission); const metadataText = formatMetadata(permission.metadata); - const accentColor = - permission.status === "rejected" || permission.status === "error" - ? theme.palette.error.main - : permission.status === "pending" || permission.status === "submitting" - ? pendingPermissionColor - : theme.palette.success.main; + const accentColor = getPermissionStatusColor(permission.status, theme); + const statusTextColor = getPermissionStatusTextColor(permission.status, theme); const statusLabel = getPermissionStatusLabel(permission.status); - const statusColor = - permission.status === "rejected" || permission.status === "error" - ? "error" - : permission.status === "pending" || permission.status === "submitting" - ? "warning" - : "success"; return ( @@ -401,9 +402,11 @@ const PermissionRequestCard = ({ const PermissionRequestGroup = ({ permissions, + isRunning, onReply, }: { permissions: NonNullable; + isRunning: boolean; onReply: (requestId: string, reply: PermissionReply) => void; }) => { const theme = useTheme(); @@ -422,11 +425,12 @@ const PermissionRequestGroup = ({ ); const summaryItems = [ { label: "共", value: permissions.length, color: theme.palette.text.secondary }, - { label: "允许一次", value: onceCount, color: "#00838f" }, - { label: "始终允许", value: alwaysCount, color: theme.palette.success.main }, - { label: "拒绝", value: rejectedCount, color: theme.palette.error.main }, + { label: "允许一次", value: onceCount, color: getPermissionStatusColor("approved_once", theme), textColor: getPermissionStatusTextColor("approved_once", theme) }, + { label: "始终允许", value: alwaysCount, color: getPermissionStatusColor("approved_always", theme), textColor: getPermissionStatusTextColor("approved_always", theme) }, + { label: "拒绝", value: rejectedCount, color: getPermissionStatusColor("rejected", theme), textColor: getPermissionStatusTextColor("rejected", theme) }, ]; - const chipColor = pendingCount > 0 ? pendingPermissionColor : rejectedCount > 0 ? theme.palette.error.main : theme.palette.success.main; + const chipColor = pendingCount > 0 ? getPermissionStatusColor("pending", theme) : rejectedCount > 0 ? getPermissionStatusColor("rejected", theme) : getPermissionStatusColor("approved_always", theme); + const chipTextColor = pendingCount > 0 ? getPermissionStatusTextColor("pending", theme) : rejectedCount > 0 ? getPermissionStatusTextColor("rejected", theme) : getPermissionStatusTextColor("approved_always", theme); return ( - + {item.label} {item.value} 项 @@ -513,19 +523,21 @@ const PermissionRequestGroup = ({ ))} - + {isRunning && pendingCount > 0 ? ( + + ) : null} - {!expanded && !hasPendingPermissions && latestPermissions.length > 0 ? ( + {!expanded && isRunning && !hasPendingPermissions && latestPermissions.length > 0 ? ( {latestPermissions.map((permission, index) => { const primaryValue = getPermissionPrimaryValue(permission); const isLast = index === latestPermissions.length - 1; - const itemColor = - permission.status === "rejected" || permission.status === "error" - ? theme.palette.error.main - : permission.status === "approved_once" || permission.status === "approved_always" - ? theme.palette.success.main - : pendingPermissionColor; + const itemColor = getPermissionStatusColor(permission.status, theme); + const itemTextColor = getPermissionStatusTextColor(permission.status, theme); return ( - {!expanded && hasPendingPermissions ? ( + {!expanded && isRunning && hasPendingPermissions ? ( item.phase === "complete" && item.status === "completed", + ) ?? false; + const isProgressRunning = !isErrorMessage && !isProgressComplete && ( + message.progress?.some((item) => item.status === "running") ?? false + ); const parsedAssistantSections = useMemo( () => @@ -956,6 +970,7 @@ export const AgentTurn = React.memo( {message.permissions?.length ? ( ) : null}