| import { Box, Stack, Typography } from '@mui/material';
|
| import MarkdownContent from './MarkdownContent';
|
| import ToolCallGroup from './ToolCallGroup';
|
| import type { Message } from '@/types/agent';
|
|
|
| interface AssistantMessageProps {
|
| message: Message;
|
|
|
| isStreaming?: boolean;
|
| }
|
|
|
| export default function AssistantMessage({ message, isStreaming = false }: AssistantMessageProps) {
|
| const renderSegments = () => {
|
| if (message.segments && message.segments.length > 0) {
|
|
|
| let lastTextIdx = -1;
|
| for (let i = message.segments.length - 1; i >= 0; i--) {
|
| if (message.segments[i].type === 'text') {
|
| lastTextIdx = i;
|
| break;
|
| }
|
| }
|
|
|
| return message.segments.map((segment, idx) => {
|
| if (segment.type === 'text' && segment.content) {
|
| return (
|
| <MarkdownContent
|
| key={idx}
|
| content={segment.content}
|
| isStreaming={isStreaming && idx === lastTextIdx}
|
| />
|
| );
|
| }
|
| if (segment.type === 'tools' && segment.tools && segment.tools.length > 0) {
|
| return <ToolCallGroup key={idx} tools={segment.tools} />;
|
| }
|
| return null;
|
| });
|
| }
|
|
|
|
|
| if (message.content) {
|
| return <MarkdownContent content={message.content} isStreaming={isStreaming} />;
|
| }
|
|
|
| return null;
|
| };
|
|
|
| return (
|
| <Box sx={{ minWidth: 0 }}>
|
| {/* Role label + timestamp */}
|
| <Stack direction="row" alignItems="baseline" spacing={1} sx={{ mb: 0.5 }}>
|
| <Typography
|
| variant="caption"
|
| sx={{
|
| fontWeight: 700,
|
| fontSize: '0.72rem',
|
| color: 'var(--muted-text)',
|
| textTransform: 'uppercase',
|
| letterSpacing: '0.04em',
|
| }}
|
| >
|
| Assistant
|
| </Typography>
|
| <Typography
|
| variant="caption"
|
| sx={{
|
| fontSize: '0.66rem',
|
| color: 'var(--muted-text)',
|
| opacity: 0.6,
|
| }}
|
| >
|
| {new Date(message.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
|
| </Typography>
|
| </Stack>
|
|
|
| {/* Message bubble */}
|
| <Box
|
| sx={{
|
| maxWidth: { xs: '95%', md: '85%' },
|
| bgcolor: 'var(--surface)',
|
| borderRadius: 1.5,
|
| borderTopLeftRadius: 4,
|
| px: { xs: 1.5, md: 2.5 },
|
| py: 1.5,
|
| border: '1px solid var(--border)',
|
| }}
|
| >
|
| {renderSegments()}
|
| </Box>
|
| </Box>
|
| );
|
| }
|
|
|