File size: 2,799 Bytes
1a12d36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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;
  /** True when this message is actively receiving streaming chunks. */
  isStreaming?: boolean;
}

export default function AssistantMessage({ message, isStreaming = false }: AssistantMessageProps) {
  const renderSegments = () => {
    if (message.segments && message.segments.length > 0) {
      // Find the index of the last text segment (that's the one being streamed)
      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;
      });
    }

    // Fallback: render raw content
    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>
  );
}