akseljoonas HF Staff commited on
Commit
3cb2d2e
Β·
1 Parent(s): fe018ce

welcome message change

Browse files
frontend/src/components/Chat/MessageList.tsx CHANGED
@@ -1,9 +1,7 @@
1
  import { useEffect, useRef, useMemo, useCallback } from 'react';
2
- import { Box, Stack, Typography, Avatar } from '@mui/material';
3
- import SmartToyOutlinedIcon from '@mui/icons-material/SmartToyOutlined';
4
  import MessageBubble from './MessageBubble';
5
  import ThinkingIndicator from './ThinkingIndicator';
6
- import MarkdownContent from './MarkdownContent';
7
  import { useAgentStore } from '@/store/agentStore';
8
  import { useSessionStore } from '@/store/sessionStore';
9
  import { apiFetch } from '@/utils/api';
@@ -15,66 +13,48 @@ interface MessageListProps {
15
  isProcessing: boolean;
16
  }
17
 
18
- const WELCOME_MD = `I'm ready to help you with machine learning tasks using the Hugging Face ecosystem.
19
-
20
- **Training & Fine-tuning** β€” SFT, DPO, GRPO, PPO with TRL Β· LoRA/PEFT Β· Submit and monitor jobs on cloud GPUs
21
-
22
- **Data** β€” Find and explore datasets Β· Process, filter, transform Β· Push to the Hub
23
-
24
- **Models** β€” Search and discover models Β· Get details and configs Β· Deploy for inference
25
-
26
- **Research** β€” Find papers and documentation Β· Explore code examples Β· Check APIs and best practices
27
-
28
- **Infrastructure** β€” Run jobs on CPU/GPU instances Β· Manage repos, branches, PRs Β· Monitor Spaces and endpoints
29
 
30
- What would you like to do?`;
 
 
 
 
31
 
32
- /** Static welcome message rendered when the conversation is empty. */
33
- function WelcomeMessage() {
34
  return (
35
- <Stack direction="row" spacing={1.5} alignItems="flex-start">
36
- <Avatar
 
 
 
 
 
 
 
 
 
 
37
  sx={{
38
- width: 28,
39
- height: 28,
40
- bgcolor: 'primary.main',
41
- flexShrink: 0,
42
- mt: 0.5,
43
  }}
44
  >
45
- <SmartToyOutlinedIcon sx={{ fontSize: 16, color: '#fff' }} />
46
- </Avatar>
47
-
48
- <Box sx={{ flex: 1, minWidth: 0 }}>
49
- <Stack direction="row" alignItems="baseline" spacing={1} sx={{ mb: 0.5 }}>
50
- <Typography
51
- variant="caption"
52
- sx={{
53
- fontWeight: 700,
54
- fontSize: '0.72rem',
55
- color: 'var(--muted-text)',
56
- textTransform: 'uppercase',
57
- letterSpacing: '0.04em',
58
- }}
59
- >
60
- Assistant
61
- </Typography>
62
- </Stack>
63
- <Box
64
- sx={{
65
- maxWidth: { xs: '95%', md: '85%' },
66
- bgcolor: 'var(--surface)',
67
- borderRadius: 1.5,
68
- borderTopLeftRadius: 4,
69
- px: { xs: 1.5, md: 2.5 },
70
- py: 1.5,
71
- border: '1px solid var(--border)',
72
- }}
73
- >
74
- <MarkdownContent content={WELCOME_MD} />
75
- </Box>
76
- </Box>
77
- </Stack>
78
  );
79
  }
80
 
@@ -91,8 +71,6 @@ export default function MessageList({ messages, isProcessing }: MessageListProps
91
  }, []);
92
 
93
  // ── Track user scroll intent ────────────────────────────────────
94
- // When user scrolls up (>80px from bottom), disable auto-scroll.
95
- // When they scroll back to bottom, re-enable it.
96
  useEffect(() => {
97
  const el = scrollContainerRef.current;
98
  if (!el) return;
@@ -112,8 +90,6 @@ export default function MessageList({ messages, isProcessing }: MessageListProps
112
  }, [messages, isProcessing, scrollToBottom]);
113
 
114
  // ── Auto-scroll on DOM mutations (streaming content growth) ─────
115
- // This catches token-by-token updates that don't change the messages
116
- // array reference (appendToMessage mutates in place).
117
  useEffect(() => {
118
  const el = scrollContainerRef.current;
119
  if (!el) return;
@@ -145,7 +121,6 @@ export default function MessageList({ messages, isProcessing }: MessageListProps
145
  if (!activeSessionId) return;
146
  try {
147
  await apiFetch(`/api/undo/${activeSessionId}`, { method: 'POST' });
148
- // Optimistic removal β€” backend will also confirm via undo_complete WS event
149
  removeLastTurn(activeSessionId);
150
  } catch (e) {
151
  logger.error('Undo failed:', e);
@@ -160,6 +135,8 @@ export default function MessageList({ messages, isProcessing }: MessageListProps
160
  overflow: 'auto',
161
  px: { xs: 0.5, sm: 1, md: 2 },
162
  py: { xs: 2, md: 3 },
 
 
163
  }}
164
  >
165
  <Stack
@@ -168,12 +145,12 @@ export default function MessageList({ messages, isProcessing }: MessageListProps
168
  maxWidth: 880,
169
  mx: 'auto',
170
  width: '100%',
 
171
  }}
172
  >
173
- {/* Always show the welcome message at the top */}
174
- <WelcomeMessage />
175
-
176
- {messages.length > 0 && (
177
  messages.map((msg) => (
178
  <MessageBubble
179
  key={msg.id}
 
1
  import { useEffect, useRef, useMemo, useCallback } from 'react';
2
+ import { Box, Stack, Typography } from '@mui/material';
 
3
  import MessageBubble from './MessageBubble';
4
  import ThinkingIndicator from './ThinkingIndicator';
 
5
  import { useAgentStore } from '@/store/agentStore';
6
  import { useSessionStore } from '@/store/sessionStore';
7
  import { apiFetch } from '@/utils/api';
 
13
  isProcessing: boolean;
14
  }
15
 
16
+ function getGreeting(): string {
17
+ const h = new Date().getHours();
18
+ if (h < 12) return 'Morning';
19
+ if (h < 17) return 'Afternoon';
20
+ return 'Evening';
21
+ }
 
 
 
 
 
22
 
23
+ /** Minimal greeting shown when the conversation is empty. */
24
+ function WelcomeGreeting() {
25
+ const { user } = useAgentStore();
26
+ const firstName = user?.name?.split(' ')[0] || user?.username;
27
+ const greeting = firstName ? `${getGreeting()}, ${firstName}` : getGreeting();
28
 
 
 
29
  return (
30
+ <Box
31
+ sx={{
32
+ flex: 1,
33
+ display: 'flex',
34
+ flexDirection: 'column',
35
+ alignItems: 'center',
36
+ justifyContent: 'center',
37
+ py: 8,
38
+ gap: 1.5,
39
+ }}
40
+ >
41
+ <Typography
42
  sx={{
43
+ fontFamily: 'monospace',
44
+ fontSize: '1.1rem',
45
+ color: 'var(--text)',
46
+ fontWeight: 600,
 
47
  }}
48
  >
49
+ {greeting}
50
+ </Typography>
51
+ <Typography
52
+ color="text.secondary"
53
+ sx={{ fontFamily: 'monospace', fontSize: '0.8rem' }}
54
+ >
55
+ Let's build something impressive?
56
+ </Typography>
57
+ </Box>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  );
59
  }
60
 
 
71
  }, []);
72
 
73
  // ── Track user scroll intent ────────────────────────────────────
 
 
74
  useEffect(() => {
75
  const el = scrollContainerRef.current;
76
  if (!el) return;
 
90
  }, [messages, isProcessing, scrollToBottom]);
91
 
92
  // ── Auto-scroll on DOM mutations (streaming content growth) ─────
 
 
93
  useEffect(() => {
94
  const el = scrollContainerRef.current;
95
  if (!el) return;
 
121
  if (!activeSessionId) return;
122
  try {
123
  await apiFetch(`/api/undo/${activeSessionId}`, { method: 'POST' });
 
124
  removeLastTurn(activeSessionId);
125
  } catch (e) {
126
  logger.error('Undo failed:', e);
 
135
  overflow: 'auto',
136
  px: { xs: 0.5, sm: 1, md: 2 },
137
  py: { xs: 2, md: 3 },
138
+ display: 'flex',
139
+ flexDirection: 'column',
140
  }}
141
  >
142
  <Stack
 
145
  maxWidth: 880,
146
  mx: 'auto',
147
  width: '100%',
148
+ flex: messages.length === 0 && !isProcessing ? 1 : undefined,
149
  }}
150
  >
151
+ {messages.length === 0 && !isProcessing ? (
152
+ <WelcomeGreeting />
153
+ ) : (
 
154
  messages.map((msg) => (
155
  <MessageBubble
156
  key={msg.id}