diff --git a/web-app/src/containers/dialogs/MessageMetadataDialog.tsx b/web-app/src/containers/dialogs/MessageMetadataDialog.tsx index 05ce29246..429c7c4b5 100644 --- a/web-app/src/containers/dialogs/MessageMetadataDialog.tsx +++ b/web-app/src/containers/dialogs/MessageMetadataDialog.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useState, useMemo } from 'react' import { useTranslation } from '@/i18n/react-i18next-compat' import { Dialog, @@ -7,21 +7,96 @@ import { DialogTitle, DialogHeader, } from '@/components/ui/dialog' -import { IconInfoCircle } from '@tabler/icons-react' +import { + IconInfoCircle, + IconRobot, + IconGauge, + IconId, + IconCalendar, + IconTemperature, + IconHierarchy, + IconTool, + IconBoxMultiple, + IconRuler, + IconMessageCircle, +} from '@tabler/icons-react' import { Tooltip, TooltipContent, TooltipTrigger, } from '@/components/ui/tooltip' -import CodeEditor from '@uiw/react-textarea-code-editor' -import '@uiw/react-textarea-code-editor/dist.css' +// Removed CodeEditor and its styles + +// Type definitions for the provided metadata structure +interface Parameters { + temperature: number + top_k: number + top_p: number +} + +interface AssistantMetadata { + avatar: string + created_at: number + description: string + id: string + instructions: string + name: string + parameters: Parameters + tool_steps: number +} + +interface TokenSpeedMetadata { + lastTimestamp: number + message: string + tokenCount: number + tokenSpeed: number +} + +interface MessageMetadata { + assistant?: AssistantMetadata + tokenSpeed?: TokenSpeedMetadata +} interface MessageMetadataDialogProps { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - metadata: any + metadata: MessageMetadata // Use the specific interface triggerElement?: React.ReactNode } +// --- Helper Components & Utilities --- + +// A utility component to display a single detail row +const DetailItem: React.FC<{ + icon: React.ReactNode + label: string + value: React.ReactNode +}> = ({ icon, label, value }) => ( +
+
{icon}
+
+ {label}: + + {value} + +
+
+) + +// Helper for formatting timestamps +const formatDate = (timestamp: number) => { + if (!timestamp) return 'N/A' + return new Intl.DateTimeFormat('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + timeZoneName: 'short', + }).format(new Date(timestamp)) +} + +// --- Main Component --- + export function MessageMetadataDialog({ metadata, triggerElement, @@ -29,10 +104,12 @@ export function MessageMetadataDialog({ const { t } = useTranslation() const [isOpen, setIsOpen] = useState(false) + const { assistant, tokenSpeed } = (metadata || {}) as MessageMetadata + const defaultTrigger = ( -
) + const formattedTokenSpeed = useMemo(() => { + if (tokenSpeed?.tokenSpeed === undefined) return 'N/A' + return ( + new Intl.NumberFormat('en-US', { + style: 'decimal', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }).format(tokenSpeed.tokenSpeed) + ' tokens/s' + ) + }, [tokenSpeed]) + return ( {triggerElement || defaultTrigger} - + {t('common:dialogs.messageMetadata.title')} -
-
- -
+
+ {/* --- Assistant/Model Section --- */} + {assistant && ( +
+

+ + {t('common:dialogs.messageMetadata.model')} +

+
+ } + label={t('common:dialogs.messageMetadata.name')} + value={`${assistant.avatar} ${assistant.name}`} + /> + } + label={t('common:dialogs.messageMetadata.id')} + value={assistant.id} + /> + } + label={t('common:dialogs.messageMetadata.createdAt')} + value={formatDate(assistant.created_at)} + /> + } + label={t('common:dialogs.messageMetadata.toolSteps')} + value={assistant.tool_steps} + /> + + {/* Parameters */} +
+ } + label={t('common:dialogs.messageMetadata.temperature')} + value={assistant.parameters.temperature} + /> + } + label={t('common:dialogs.messageMetadata.topK')} + value={assistant.parameters.top_k} + /> + } + label={t('common:dialogs.messageMetadata.topP')} + value={assistant.parameters.top_p} + /> +
+ + {/* Description/Instructions */} + {(assistant.description || assistant.instructions) && ( +
+ {assistant.description && ( + } + label={t('common:dialogs.messageMetadata.description')} + value={assistant.description} + /> + )} + {assistant.instructions && ( + } + label={t('common:dialogs.messageMetadata.instructions')} + value={assistant.instructions} + /> + )} +
+ )} +
+
+ )} + + {/* --- Token Speed Section --- */} + {tokenSpeed && ( +
+

+ + {t('Performance')} +

+
+ } + label={t('common:dialogs.messageMetadata.tokenSpeed')} + value={formattedTokenSpeed} + /> + } + label={t('common:dialogs.messageMetadata.tokenCount')} + value={tokenSpeed.tokenCount} + /> + } + label={t('common:dialogs.messageMetadata.lastUpdate')} + value={formatDate(tokenSpeed.lastTimestamp)} + /> +
+
+ )} + + {!assistant && !tokenSpeed && ( +

+ {t('common:dialogs.messageMetadata.noMetadataAvailable.')} +

+ )}
diff --git a/web-app/src/locales/en/common.json b/web-app/src/locales/en/common.json index 950879bf6..f5f9d819a 100644 --- a/web-app/src/locales/en/common.json +++ b/web-app/src/locales/en/common.json @@ -235,7 +235,21 @@ "title": "Edit Message" }, "messageMetadata": { - "title": "Message Metadata" + "title": "Message Metadata", + "model": "Model", + "name": "Name", + "id": "ID", + "createdAt": "Created At", + "toolSteps": "Tool Steps", + "temperature": "Temperature", + "topK": "Top K", + "topP": "Top P", + "description": "Description", + "instructions": "Instructions", + "tokenSpeed": "Token Speed", + "tokenCount": "Token Count", + "lastUpdate": "Last Update", + "noMessageMetadataAvailable": "No Message Metadata Available" } }, "projects": {