Skip to content

Commit d54d1c4

Browse files
committed
feat(FR-536): Move LLM Playground to on the top menu (#3195)
resolves #NNN (FR-536) Adds a dedicated Chat page accessible from the main navigation menu. The chat functionality has been moved from the Serving page to its own route at /chat. This change includes: - New Chat menu item in the main navigation sidebar - Relocated chat components from lablupTalkativotUI to a dedicated Chat directory - Added chat-related translations for all supported languages - Simplified the initial chat interface to start with a single chat window instead of two
1 parent 6017f00 commit d54d1c4

39 files changed

+107
-103
lines changed

react/src/App.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ const SessionDetailAndContainerLogOpenerLegacy = React.lazy(
6969
() => import('./components/SessionDetailAndContainerLogOpenerLegacy'),
7070
);
7171

72+
const ChatPage = React.lazy(() => import('./pages/ChatPage'));
73+
7274
interface CustomHandle {
7375
title?: string;
7476
labelKey?: string;
@@ -122,6 +124,11 @@ const router = createBrowserRouter([
122124
path: '/app/index.html',
123125
element: <WebUINavigate to="/summary" replace />,
124126
},
127+
{
128+
path: '/chat',
129+
handle: { labelKey: 'webui.menu.Chat' },
130+
Component: ChatPage,
131+
},
125132
{
126133
path: '/summary',
127134
Component: () => {

react/src/components/MainLayout/WebUISider.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
FileDoneOutlined,
2626
HddOutlined,
2727
InfoCircleOutlined,
28+
MessageOutlined,
2829
SolutionOutlined,
2930
ToolOutlined,
3031
UserOutlined,
@@ -113,6 +114,11 @@ const WebUISider: React.FC<WebUISiderProps> = (props) => {
113114
icon: <PlayIcon style={{ color: token.colorPrimary }} />,
114115
key: 'import',
115116
},
117+
{
118+
label: <WebUILink to="/chat">{t('webui.menu.Chat')}</WebUILink>,
119+
icon: <MessageOutlined style={{ color: token.colorPrimary }} />,
120+
key: 'chat',
121+
},
116122
{
117123
label: <WebUILink to="/data">{t('webui.menu.Data&Storage')}</WebUILink>,
118124
icon: <CloudUploadOutlined style={{ color: token.colorPrimary }} />,

react/src/components/lablupTalkativotUI/LLMPlaygroundPage.tsx renamed to react/src/pages/ChatPage.tsx

Lines changed: 49 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import Flex from '../Flex';
2-
import EndpointLLMChatCard from './EndpointLLMChatCard';
3-
import { LLMPlaygroundPageQuery } from './__generated__/LLMPlaygroundPageQuery.graphql';
1+
import BAICard from '../components/BAICard';
2+
import EndpointLLMChatCard from '../components/Chat/EndpointLLMChatCard';
3+
import Flex from '../components/Flex';
4+
import { ChatPageQuery } from './__generated__/ChatPageQuery.graphql';
45
import { PlusOutlined } from '@ant-design/icons';
56
import { useDynamicList } from 'ahooks';
67
import { Button, Card, Skeleton, Switch, theme, Typography } from 'antd';
@@ -11,26 +12,23 @@ import { useTranslation } from 'react-i18next';
1112
import { useLazyLoadQuery } from 'react-relay';
1213
import { StringParam, useQueryParam } from 'use-query-params';
1314

14-
interface LLMPlaygroundPageProps {}
15+
interface ChatPageProps {}
1516

16-
const LLMPlaygroundPage: React.FC<LLMPlaygroundPageProps> = ({ ...props }) => {
17+
const ChatPage: React.FC<ChatPageProps> = ({ ...props }) => {
1718
const { token } = theme.useToken();
1819
const { t } = useTranslation();
1920
// Set the initial list to have two items
20-
const { list, remove, getKey, push } = useDynamicList(['0', '1']);
21+
const { list, remove, getKey, push } = useDynamicList(['0']);
2122

2223
const [isSynchronous, setSynchronous] = useState(false);
2324

2425
const [endpointId] = useQueryParam('endpointId', StringParam);
2526
const [modelId] = useQueryParam('modelId', StringParam);
2627
const isEmptyEndpointId = !endpointId;
2728

28-
const { endpoint, endpoint_list } = useLazyLoadQuery<LLMPlaygroundPageQuery>(
29+
const { endpoint, endpoint_list } = useLazyLoadQuery<ChatPageQuery>(
2930
graphql`
30-
query LLMPlaygroundPageQuery(
31-
$endpointId: UUID!
32-
$isEmptyEndpointId: Boolean!
33-
) {
31+
query ChatPageQuery($endpointId: UUID!, $isEmptyEndpointId: Boolean!) {
3432
endpoint(endpoint_id: $endpointId)
3533
@skipOnClient(if: $isEmptyEndpointId) {
3634
...EndpointLLMChatCard_endpoint
@@ -48,49 +46,47 @@ const LLMPlaygroundPage: React.FC<LLMPlaygroundPageProps> = ({ ...props }) => {
4846
},
4947
);
5048
return (
51-
<>
52-
<Flex direction="column" align="stretch">
53-
<Flex
54-
direction="row"
55-
justify="between"
56-
wrap="wrap"
57-
gap={'xs'}
58-
style={{
59-
padding: token.paddingContentVertical,
60-
paddingLeft: token.paddingContentHorizontalSM,
61-
paddingRight: token.paddingContentHorizontalSM,
62-
}}
63-
>
64-
<Flex direction="column" align="start">
65-
<Typography.Text style={{ margin: 0, padding: 0 }}>
66-
LLM Playground
49+
<BAICard
50+
title={t('webui.menu.Chat')}
51+
styles={{
52+
body: {
53+
padding: 0,
54+
paddingTop: 1,
55+
overflow: 'hidden',
56+
},
57+
}}
58+
extra={
59+
<Flex direction="row" gap={'xs'} wrap="wrap" style={{ flexShrink: 1 }}>
60+
<Flex gap={'xs'}>
61+
<Typography.Text type="secondary">
62+
{t('chatui.SyncInput')}
6763
</Typography.Text>
68-
</Flex>
69-
<Flex
70-
direction="row"
71-
gap={'xs'}
72-
wrap="wrap"
73-
style={{ flexShrink: 1 }}
74-
>
75-
<Flex gap={'xs'}>
76-
<Typography.Text type="secondary">
77-
{t('chatui.SyncInput')}
78-
</Typography.Text>
79-
<Switch
80-
value={isSynchronous}
81-
onClick={(v) => {
82-
setSynchronous(v);
83-
}}
84-
/>
85-
<Button
86-
onClick={() => {
87-
push(new Date().toString());
88-
}}
89-
icon={<PlusOutlined />}
90-
/>
91-
</Flex>
64+
<Switch
65+
value={isSynchronous}
66+
onClick={(v) => {
67+
setSynchronous(v);
68+
}}
69+
/>
70+
<Button
71+
onClick={() => {
72+
push(new Date().toString());
73+
}}
74+
icon={<PlusOutlined />}
75+
/>
9276
</Flex>
9377
</Flex>
78+
}
79+
>
80+
<Flex
81+
direction="column"
82+
align="stretch"
83+
gap={'xs'}
84+
style={{
85+
padding: token.paddingContentVertical,
86+
paddingLeft: token.paddingContentHorizontalSM,
87+
paddingRight: token.paddingContentHorizontalSM,
88+
}}
89+
>
9490
<Flex
9591
gap={'xs'}
9692
direction="row"
@@ -139,8 +135,8 @@ const LLMPlaygroundPage: React.FC<LLMPlaygroundPageProps> = ({ ...props }) => {
139135
))}
140136
</Flex>
141137
</Flex>
142-
</>
138+
</BAICard>
143139
);
144140
};
145141

146-
export default LLMPlaygroundPage;
142+
export default ChatPage;

react/src/pages/EndpointDetailPage.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import UnmountModalAfterClose from '../components/UnmountModalAfterClose';
1616
import VFolderLazyView from '../components/VFolderLazyView';
1717
import { AutoScalingRuleEditorModalFragment$key } from '../components/__generated__/AutoScalingRuleEditorModalFragment.graphql';
1818
import { InferenceSessionErrorModalFragment$key } from '../components/__generated__/InferenceSessionErrorModalFragment.graphql';
19-
import ChatUIModal from '../components/lablupTalkativotUI/ChatUIModal';
2019
import { baiSignedRequestWithPromise, filterNonNullItems } from '../helper';
2120
import {
2221
useSuspendedBackendaiClient,
@@ -123,7 +122,6 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
123122
useState<AutoScalingRuleEditorModalFragment$key | null>(null);
124123
const [isOpenTokenGenerationModal, setIsOpenTokenGenerationModal] =
125124
useState(false);
126-
const [openChatModal, setOpenChatModal] = useState(false);
127125
const [isOpenAutoScalingRuleModal, setIsOpenAutoScalingRuleModal] =
128126
useState(false);
129127
const [currentUser] = useCurrentUserInfo();
@@ -214,7 +212,6 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
214212
created_user_email @since(version: "23.09.8")
215213
...EndpointOwnerInfoFragment
216214
...EndpointStatusTagFragment
217-
...ChatUIModalFragment
218215
...ServiceLauncherPageContentFragment
219216
}
220217
endpoint_token_list(
@@ -233,7 +230,6 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
233230
created_at
234231
valid_until
235232
}
236-
...ChatUIModalEndpointTokenListFragment
237233
}
238234
endpoint_auto_scaling_rules: endpoint_auto_scaling_rule_nodes(
239235
endpoint: $autoScalingRules_endpointId
@@ -386,7 +382,7 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
386382
type="link"
387383
icon={<BotMessageSquareIcon />}
388384
onClick={() => {
389-
setOpenChatModal(true);
385+
webuiNavigate(`/chat?endpointId=${endpoint?.endpoint_id}`);
390386
}}
391387
disabled={endpoint?.status !== 'HEALTHY'}
392388
/>
@@ -1080,14 +1076,6 @@ const EndpointDetailPage: React.FC<EndpointDetailPageProps> = () => {
10801076
}}
10811077
endpoint_id={endpoint?.endpoint_id || ''}
10821078
></EndpointTokenGenerationModal>
1083-
<ChatUIModal
1084-
endpointFrgmt={endpoint}
1085-
endpointTokenFrgmt={endpoint_token_list}
1086-
open={openChatModal}
1087-
onCancel={() => {
1088-
setOpenChatModal(false);
1089-
}}
1090-
/>
10911079
{isSupportAutoScalingRule && (
10921080
<UnmountModalAfterClose>
10931081
<AutoScalingRuleEditorModal

react/src/pages/ServingPage.tsx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import Flex from '../components/Flex';
22
import { filterEmptyItem } from '../helper';
3-
import { useSuspendedBackendaiClient } from '../hooks';
43
import { Card, Skeleton, theme } from 'antd';
54
import React, { Suspense } from 'react';
65
import { useTranslation } from 'react-i18next';
@@ -10,9 +9,6 @@ import { StringParam, useQueryParam, withDefault } from 'use-query-params';
109
type TabKey = 'services' | 'chatting'; // "running" | "finished" | "others";
1110

1211
const EndpointListPage = React.lazy(() => import('./EndpointListPage'));
13-
const ChattingPage = React.lazy(
14-
() => import('../components/lablupTalkativotUI/LLMPlaygroundPage'),
15-
);
1612

1713
interface ServingPageProps {}
1814

@@ -24,7 +20,6 @@ const ServingPage: React.FC<ServingPageProps> = ({ ...props }) => {
2420
const [curTabKey, setCurTabKey] = useQueryParam('tab', tabParam, {
2521
updateType: 'replace',
2622
});
27-
const baiClient = useSuspendedBackendaiClient();
2823

2924
const tabList = filterEmptyItem([
3025
{ key: 'services', label: t('modelService.Services') },
@@ -41,10 +36,6 @@ const ServingPage: React.FC<ServingPageProps> = ({ ...props }) => {
4136
// key: "others",
4237
// label: t("session.Others"),
4338
// },
44-
baiClient._config.enableLLMPlayground && {
45-
key: 'chatting',
46-
label: 'LLM Playground',
47-
},
4839
]);
4940
return (
5041
<Flex direction="column" align="stretch" gap={'md'}>
@@ -69,13 +60,6 @@ const ServingPage: React.FC<ServingPageProps> = ({ ...props }) => {
6960
<EndpointListPage />
7061
</Suspense>
7162
) : null}
72-
{curTabKey === 'chatting' && baiClient._config.enableLLMPlayground ? (
73-
<Suspense
74-
fallback={<Skeleton active style={{ padding: token.paddingMD }} />}
75-
>
76-
<ChattingPage />
77-
</Suspense>
78-
) : null}
7963
</Card>
8064
</Flex>
8165
);

resources/i18n/de.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
"DisMatchUserEmail": "Die E-Mail-Adresse des Benutzers stimmt nicht überein",
6767
"MyEnvironments": "Meine Umgebungen",
6868
"ResourcePolicy": "Ressourcenpolitik",
69-
"FullNameUpdated": "Der vollständige Name wurde erfolgreich aktualisiert."
69+
"FullNameUpdated": "Der vollständige Name wurde erfolgreich aktualisiert.",
70+
"Chat": "Chat"
7071
},
7172
"YouAreOffline": "Offline: Keine Verbindung zu einem Netzwerk.",
7273
"YouAreOnline": "Sie sind jetzt online",

resources/i18n/el.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
"DisMatchUserEmail": "Το email χρήστη δεν ταιριάζει",
6767
"MyEnvironments": "Τα περιβάλλοντα μου",
6868
"ResourcePolicy": "Πολιτική Πόρων",
69-
"FullNameUpdated": "Το πλήρες όνομα ενημερώθηκε με επιτυχία."
69+
"FullNameUpdated": "Το πλήρες όνομα ενημερώθηκε με επιτυχία.",
70+
"Chat": "Συνομιλία"
7071
},
7172
"YouAreOffline": "Offline: Δεν είναι συνδεδεμένος σε κανένα δίκτυο.",
7273
"YouAreOnline": "Είστε πλέον συνδεδεμένοι",

resources/i18n/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@
6565
"DisMatchUserEmail": "User email does not match",
6666
"MyEnvironments": "My Environments",
6767
"ResourcePolicy": "Resource Policy",
68-
"FullNameUpdated": "Full name is successfully updated."
68+
"FullNameUpdated": "Full name is successfully updated.",
69+
"Chat": "Chat"
6970
},
7071
"YouAreOffline": "Offline: Not connected to any networks.",
7172
"YouAreOnline": "You are now online",

resources/i18n/es.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,8 @@
16571657
"DisMatchUserEmail": "El correo electrónico del usuario no coincide",
16581658
"MyEnvironments": "Mis ambientes",
16591659
"ResourcePolicy": "Política de recursos",
1660-
"FullNameUpdated": "El nombre completo se ha actualizado correctamente."
1660+
"FullNameUpdated": "El nombre completo se ha actualizado correctamente.",
1661+
"Chat": "Chat"
16611662
},
16621663
"NetworkSoftTimeout": "El servidor está tardando más en responder. Por favor, espere un momento",
16631664
"NotFound": "<p>¡Oops!<br/>Página no encontrada...</p>",

resources/i18n/fi.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,8 @@
16571657
"DisMatchUserEmail": "Käyttäjän sähköpostiosoite ei täsmää",
16581658
"MyEnvironments": "Omat ympäristöt",
16591659
"ResourcePolicy": "Resurssipolitiikka",
1660-
"FullNameUpdated": "Koko nimi on päivitetty onnistuneesti."
1660+
"FullNameUpdated": "Koko nimi on päivitetty onnistuneesti.",
1661+
"Chat": "Chat"
16611662
},
16621663
"NetworkSoftTimeout": "Palvelimen vastaus kestää kauemmin. Odota hetki",
16631664
"NotFound": "<p>Oops!<br/>Sivua ei löydy...</p>",

resources/i18n/fr.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
"DisMatchUserEmail": "L'e-mail de l'utilisateur ne correspond pas",
6767
"MyEnvironments": "Mes environnements",
6868
"ResourcePolicy": "Politique des ressources",
69-
"FullNameUpdated": "Le nom complet a été mis à jour avec succès."
69+
"FullNameUpdated": "Le nom complet a été mis à jour avec succès.",
70+
"Chat": "Chat"
7071
},
7172
"YouAreOffline": "Hors ligne : N'est connecté à aucun réseau.",
7273
"YouAreOnline": "Vous êtes maintenant en ligne",

resources/i18n/id.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
"DisMatchUserEmail": "Email Pengguna tidak cocok",
6767
"MyEnvironments": "Lingkungan Saya",
6868
"ResourcePolicy": "Kebijakan Sumber Daya",
69-
"FullNameUpdated": "Nama lengkap berhasil diperbarui."
69+
"FullNameUpdated": "Nama lengkap berhasil diperbarui.",
70+
"Chat": "Mengobrol"
7071
},
7172
"YouAreOffline": "Offline: Tidak terhubung ke jaringan apa pun.",
7273
"YouAreOnline": "Anda sekarang online",

resources/i18n/it.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
"DisMatchUserEmail": "L'e-mail dell'utente non corrisponde",
6767
"MyEnvironments": "I miei ambienti",
6868
"ResourcePolicy": "Politica delle risorse",
69-
"FullNameUpdated": "Il nome completo è stato aggiornato con successo."
69+
"FullNameUpdated": "Il nome completo è stato aggiornato con successo.",
70+
"Chat": "Chat"
7071
},
7172
"YouAreOffline": "Non in linea: Non è collegato ad alcuna rete.",
7273
"YouAreOnline": "Ora sei online",

resources/i18n/ja.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
"DisMatchUserEmail": "ユーザーの電子メールが一致しません",
6767
"MyEnvironments": "私の環境",
6868
"ResourcePolicy": "リソースポリシー",
69-
"FullNameUpdated": "フルネームが正常に更新されました。"
69+
"FullNameUpdated": "フルネームが正常に更新されました。",
70+
"Chat": "チャット"
7071
},
7172
"YouAreOffline": "オフライン:どのネットワークにも接続されていない。",
7273
"YouAreOnline": "あなたは今オンラインです",

resources/i18n/ko.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
"DisMatchUserEmail": "사용자 이메일이 일치하지 않습니다.",
6767
"MyEnvironments": "나의 실행 환경",
6868
"ResourcePolicy": "자원 정책",
69-
"FullNameUpdated": "사용자 이름이 갱신되었습니다."
69+
"FullNameUpdated": "사용자 이름이 갱신되었습니다.",
70+
"Chat": "채팅"
7071
},
7172
"YouAreOffline": "오프라인: 네트워크에 연결되어 있지 않습니다.",
7273
"YouAreOnline": "온라인 상태가 되었습니다",

resources/i18n/mn.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
"DisMatchUserEmail": "Хэрэглэгчийн имэйл таарахгүй байна",
6767
"MyEnvironments": "Миний орчин",
6868
"ResourcePolicy": "Нөөцийн бодлого",
69-
"FullNameUpdated": "Бүтэн нэр амжилттай шинэчлэгдлээ."
69+
"FullNameUpdated": "Бүтэн нэр амжилттай шинэчлэгдлээ.",
70+
"Chat": "Яриа хөрөө"
7071
},
7172
"YouAreOffline": "Офлайн: Ямар ч сүлжээнд холбогдоогүй.",
7273
"YouAreOnline": "Та одоо онлайн байна",

0 commit comments

Comments
 (0)