mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-08-14 22:43:49 +00:00
Merge remote-tracking branch 'origin/new-page-framework' into llm_framework
This commit is contained in:
commit
9c8265d3a4
@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
import { useRequest } from 'ahooks';
|
||||
import { useState } from 'react';
|
||||
import { Button, Input, useColorScheme, Box, buttonClasses } from '@/lib/mui';
|
||||
import { Button, Input, Box, buttonClasses } from '@/lib/mui';
|
||||
import IconButton from '@mui/joy/IconButton';
|
||||
import SendRoundedIcon from '@mui/icons-material/SendRounded';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
@ -13,7 +13,6 @@ import { useRouter } from 'next/navigation';
|
||||
export default function Home() {
|
||||
const Schema = z.object({ query: z.string().min(1) });
|
||||
const router = useRouter();
|
||||
const { mode } = useColorScheme();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const methods = useForm<z.infer<typeof Schema>>({
|
||||
resolver: zodResolver(Schema),
|
||||
@ -29,7 +28,7 @@ export default function Home() {
|
||||
chat_mode: 'chat_normal'
|
||||
});
|
||||
if (res?.success && res?.data?.conv_uid) {
|
||||
router.push(`/agents/${res?.data?.conv_uid}?initMessage=${query}`);
|
||||
router.push(`/chat?id=${res?.data?.conv_uid}&initMessage=${query}`);
|
||||
}
|
||||
} catch (err) {
|
||||
} finally {
|
||||
@ -67,7 +66,7 @@ export default function Home() {
|
||||
chat_mode: scene['chat_scene']
|
||||
});
|
||||
if (res?.success && res?.data?.conv_uid) {
|
||||
router.push(`/agents/${res?.data?.conv_uid}?scene=${scene['chat_scene']}`);
|
||||
router.push(`/chat?id=${res?.data?.conv_uid}&scene=${scene['chat_scene']}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
@ -2,14 +2,12 @@
|
||||
import { useRequest } from 'ahooks';
|
||||
import { sendGetRequest, sendPostRequest } from '@/utils/request';
|
||||
import useAgentChat from '@/hooks/useAgentChat';
|
||||
import ChatBoxComp from '@/components/chatBox';
|
||||
import ChatBoxComp from '@/components/chatBoxTemp';
|
||||
import { useDialogueContext } from '@/app/context/dialogue';
|
||||
|
||||
const AgentPage = (props: {
|
||||
params: {
|
||||
agentId?: string;
|
||||
},
|
||||
searchParams: {
|
||||
id?: string;
|
||||
scene?: string;
|
||||
initMessage?: string;
|
||||
}
|
||||
@ -17,26 +15,28 @@ const AgentPage = (props: {
|
||||
const { refreshDialogList } = useDialogueContext();
|
||||
|
||||
const { data: historyList } = useRequest(async () => await sendGetRequest('/v1/chat/dialogue/messages/history', {
|
||||
con_uid: props.params?.agentId
|
||||
con_uid: props.searchParams?.id
|
||||
}), {
|
||||
ready: !!props.params?.agentId
|
||||
ready: !!props.searchParams?.id,
|
||||
refreshDeps: [props.searchParams?.id]
|
||||
});
|
||||
|
||||
const { data: paramsList } = useRequest(async () => await sendPostRequest(`/v1/chat/mode/params/list?chat_mode=${props.searchParams?.scene}`), {
|
||||
ready: !!props.searchParams?.scene
|
||||
ready: !!props.searchParams?.scene,
|
||||
refreshDeps: [props.searchParams?.scene]
|
||||
});
|
||||
|
||||
const { history, handleChatSubmit } = useAgentChat({
|
||||
queryAgentURL: `/v1/chat/completions`,
|
||||
queryBody: {
|
||||
conv_uid: props.params?.agentId,
|
||||
conv_uid: props.searchParams?.id,
|
||||
chat_mode: props.searchParams?.scene || 'chat_normal',
|
||||
},
|
||||
initHistory: historyList?.data
|
||||
});
|
||||
|
||||
return (
|
||||
<div className='mx-auto flex h-full max-w-3xl flex-col gap-6 px-5 py-6 sm:gap-8 xl:max-w-5xl '>
|
||||
<>
|
||||
<ChatBoxComp
|
||||
initialMessage={historyList?.data ? (historyList?.data?.length <= 0 ? props.searchParams?.initMessage : undefined) : undefined}
|
||||
clearIntialMessage={async () => {
|
||||
@ -46,7 +46,7 @@ const AgentPage = (props: {
|
||||
onSubmit={handleChatSubmit}
|
||||
paramsList={paramsList?.data}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ const ChatBoxComp = ({
|
||||
}, [paramsList]);
|
||||
|
||||
return (
|
||||
<div className='mx-auto flex h-full max-w-3xl flex-col gap-6 px-5 py-6 sm:gap-8 xl:max-w-5xl'>
|
||||
<Stack
|
||||
direction={'column'}
|
||||
gap={2}
|
||||
@ -258,6 +259,8 @@ const ChatBoxComp = ({
|
||||
</form>
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
252
datacenter/components/chatBoxTemp.tsx
Normal file
252
datacenter/components/chatBoxTemp.tsx
Normal file
@ -0,0 +1,252 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import SendRoundedIcon from '@mui/icons-material/SendRounded';
|
||||
import { Card, CircularProgress, IconButton, Input, Stack, Select, Option, Tooltip, Box, useColorScheme } from '@/lib/mui';
|
||||
import React, { useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
import { Message } from '@/types';
|
||||
import FaceRetouchingNaturalOutlinedIcon from '@mui/icons-material/FaceRetouchingNaturalOutlined';
|
||||
import SmartToyOutlinedIcon from '@mui/icons-material/SmartToyOutlined';
|
||||
import Markdown from 'markdown-to-jsx';
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import { okaidia } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
||||
|
||||
type Props = {
|
||||
messages: Message[];
|
||||
onSubmit: (message: string, otherQueryBody?: any) => Promise<any>;
|
||||
initialMessage?: string;
|
||||
readOnly?: boolean;
|
||||
paramsList?: { [key: string]: string };
|
||||
clearIntialMessage?: () => void;
|
||||
};
|
||||
|
||||
const Schema = z.object({ query: z.string().min(1) });
|
||||
|
||||
const ChatBoxComp = ({
|
||||
messages,
|
||||
onSubmit,
|
||||
initialMessage,
|
||||
readOnly,
|
||||
paramsList,
|
||||
clearIntialMessage
|
||||
}: Props) => {
|
||||
const { mode } = useColorScheme();
|
||||
const scrollableRef = React.useRef<HTMLDivElement>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [currentParam, setCurrentParam] = useState<string | undefined | null>();
|
||||
|
||||
const methods = useForm<z.infer<typeof Schema>>({
|
||||
resolver: zodResolver(Schema),
|
||||
defaultValues: {},
|
||||
});
|
||||
|
||||
const submit = async ({ query }: z.infer<typeof Schema>) => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
methods.reset();
|
||||
await onSubmit(query, {
|
||||
select_param: paramsList?.[currentParam]
|
||||
});
|
||||
} catch (err) {
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleInitMessage = async () => {
|
||||
try {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
searchParams.delete('initMessage');
|
||||
window.history.replaceState(null, null, `?${searchParams.toString()}`);
|
||||
await submit({ query: (initialMessage as string) });
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
} finally {
|
||||
clearIntialMessage?.();
|
||||
}
|
||||
}
|
||||
|
||||
const options = {
|
||||
overrides: {
|
||||
code: ({ children }) => (
|
||||
<SyntaxHighlighter language="javascript" style={okaidia}>
|
||||
{children}
|
||||
</SyntaxHighlighter>
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!scrollableRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
scrollableRef.current.scrollTo(0, scrollableRef.current.scrollHeight);
|
||||
}, [messages?.length]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (initialMessage && messages.length <= 0) {
|
||||
handleInitMessage();
|
||||
}
|
||||
}, [initialMessage]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (paramsList && Object.keys(paramsList || {})?.length > 0) {
|
||||
setCurrentParam(Object.keys(paramsList || {})?.[0]);
|
||||
}
|
||||
}, [paramsList]);
|
||||
|
||||
return (
|
||||
<div className='w-full h-full'>
|
||||
<Stack
|
||||
className="w-full h-full"
|
||||
sx={{
|
||||
background: mode === 'light' ? '#fefefe' : '#212121',
|
||||
'table': {
|
||||
borderCollapse: 'collapse',
|
||||
border: '1px solid #ccc',
|
||||
},
|
||||
'th, td': {
|
||||
border: '1px solid #ccc',
|
||||
padding: '10px',
|
||||
textAlign: 'center'
|
||||
},
|
||||
|
||||
}}
|
||||
>
|
||||
<Stack
|
||||
ref={scrollableRef}
|
||||
direction={'column'}
|
||||
sx={{
|
||||
overflowY: 'auto',
|
||||
maxHeight: '100%',
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
{messages.filter(item => ['view', 'human'].includes(item.role))?.map((each, index) => {
|
||||
return (
|
||||
<Stack
|
||||
key={index}
|
||||
>
|
||||
<Card
|
||||
size="sm"
|
||||
variant={'outlined'}
|
||||
color={each.role === 'view' ? 'primary' : 'neutral'}
|
||||
sx={(theme) => ({
|
||||
background: each.role === 'view' ? 'var(--joy-palette-primary-softBg, var(--joy-palette-primary-100, #DDF1FF))': 'unset',
|
||||
border: 'unset',
|
||||
borderRadius: 'unset',
|
||||
padding: '24px 0 26px 0',
|
||||
lineHeight: '24px',
|
||||
})}
|
||||
>
|
||||
<Box sx={{ width: '76%', margin: '0 auto' }} className="flex flex-row">
|
||||
<div className='mr-3 inline'>
|
||||
{each.role === 'view' ? (
|
||||
<SmartToyOutlinedIcon />
|
||||
) : (
|
||||
<FaceRetouchingNaturalOutlinedIcon />
|
||||
)}
|
||||
</div>
|
||||
<div className='inline align-middle mt-0.5'>
|
||||
<Markdown options={options}>
|
||||
{each.context?.replaceAll('\\n', '\n')}
|
||||
</Markdown>
|
||||
</div>
|
||||
</Box>
|
||||
</Card>
|
||||
</Stack>
|
||||
)
|
||||
})}
|
||||
{isLoading && (
|
||||
<CircularProgress
|
||||
variant="soft"
|
||||
color="neutral"
|
||||
size="sm"
|
||||
sx={{ mx: 'auto', my: 2 }}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
{!readOnly && (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'relative',
|
||||
background: mode === 'light' ? '#fefefe' : '#212121',
|
||||
'&::before': {
|
||||
content: '" "',
|
||||
position: 'absolute',
|
||||
top: '-18px',
|
||||
left: '0',
|
||||
right: '0',
|
||||
width: '100%',
|
||||
margin: '0 auto',
|
||||
height: '20px',
|
||||
background: mode === 'light' ? '#fefefe' : '#212121',
|
||||
filter: 'blur(10px)',
|
||||
zIndex: 2,
|
||||
}
|
||||
}}
|
||||
>
|
||||
<form
|
||||
style={{
|
||||
maxWidth: '100%',
|
||||
width: '76%',
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
marginTop: 'auto',
|
||||
overflow: 'visible',
|
||||
background: 'none',
|
||||
justifyContent: 'center',
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
flexDirection: 'column',
|
||||
gap: '12px',
|
||||
paddingBottom: '58px',
|
||||
paddingTop: '20px'
|
||||
}}
|
||||
onSubmit={(e) => {
|
||||
e.stopPropagation();
|
||||
methods.handleSubmit(submit)(e);
|
||||
}}
|
||||
>
|
||||
{(Object.keys(paramsList || {}).length > 0) && (
|
||||
<div className='flex items-center gap-3'>
|
||||
<Select
|
||||
value={currentParam}
|
||||
onChange={(e, newValue) => {
|
||||
setCurrentParam(newValue);
|
||||
}}
|
||||
sx={{ maxWidth: '100%' }}
|
||||
>
|
||||
{Object.keys(paramsList || {}).map(paramItem => (
|
||||
<Option
|
||||
key={paramItem}
|
||||
value={paramItem}
|
||||
>
|
||||
{paramItem}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Input
|
||||
className='w-full h-12'
|
||||
variant="outlined"
|
||||
endDecorator={
|
||||
<IconButton type="submit" disabled={isLoading}>
|
||||
<SendRoundedIcon />
|
||||
</IconButton>
|
||||
}
|
||||
{...methods.register('query')}
|
||||
/>
|
||||
</form>
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChatBoxComp;
|
@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { usePathname, useRouter } from 'next/navigation';
|
||||
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { Modal } from 'antd';
|
||||
import { Box, List, ListItem, ListItemButton, ListItemDecorator, ListItemContent, Typography, Button, useColorScheme, IconButton } from '@/lib/mui';
|
||||
@ -15,6 +15,7 @@ import { sendPostRequest } from '@/utils/request';
|
||||
|
||||
const LeftSider = () => {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const router = useRouter();
|
||||
const { dialogueList, queryDialogueList, refreshDialogList } = useDialogueContext();
|
||||
const { mode, setMode } = useColorScheme();
|
||||
@ -44,7 +45,7 @@ const LeftSider = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav className='flex h-12 items-center justify-between border-b bg-gray-50 px-4 dark:border-gray-800 dark:bg-gray-800/70 md:hidden'>
|
||||
<nav className='flex h-12 items-center justify-between border-b px-4 dark:border-gray-800 dark:bg-gray-800/70 md:hidden'>
|
||||
<div>
|
||||
<MenuIcon />
|
||||
</div>
|
||||
@ -114,7 +115,7 @@ const LeftSider = () => {
|
||||
}}
|
||||
>
|
||||
{dialogueList?.data?.map((each) => {
|
||||
const isSelect = pathname === `/agents/${each.conv_uid}`;
|
||||
const isSelect = pathname === `/chat` && searchParams.get('id') === each.conv_uid;
|
||||
return (
|
||||
<ListItem key={each.conv_uid}>
|
||||
<ListItemButton
|
||||
@ -127,7 +128,7 @@ const LeftSider = () => {
|
||||
}}
|
||||
>
|
||||
<ListItemContent>
|
||||
<Link href={`/agents/${each.conv_uid}?scene=${each?.chat_mode}`} className="flex items-center justify-between">
|
||||
<Link href={`/chat?id=${each.conv_uid}&scene=${each?.chat_mode}`} className="flex items-center justify-between">
|
||||
<Typography fontSize={14} noWrap={true}>
|
||||
<SmsOutlinedIcon className='mr-2' />
|
||||
{each?.user_name || each?.user_input || 'undefined'}
|
||||
@ -147,7 +148,7 @@ const LeftSider = () => {
|
||||
async onOk() {
|
||||
await sendPostRequest(`v1/chat/dialogue/delete?con_uid=${each.conv_uid}`);
|
||||
await refreshDialogList();
|
||||
if (pathname === `/agents/${each.conv_uid}`) {
|
||||
if (pathname === `/chat` && searchParams.get('id') === each.conv_uid) {
|
||||
router.push('/');
|
||||
}
|
||||
}
|
||||
|
@ -25,26 +25,34 @@ export const joyTheme = extendTheme({
|
||||
surface: '#fff'
|
||||
},
|
||||
text: {
|
||||
primary: '#505050'
|
||||
primary: '#505050',
|
||||
},
|
||||
},
|
||||
},
|
||||
dark: {
|
||||
palette: {
|
||||
mode: 'light',
|
||||
primary: {
|
||||
...colors.grey,
|
||||
softBg: '#353539',
|
||||
softHoverBg: '#35353978',
|
||||
softDisabledBg: '#353539'
|
||||
},
|
||||
neutral: {
|
||||
plainColor: '#D8D8DF',
|
||||
plainHoverColor: '#F7F7F8',
|
||||
plainHoverBg: '#25252D',
|
||||
plainHoverBg: '#353539',
|
||||
plainActiveBg: '#434356',
|
||||
plainDisabledColor: '#434356'
|
||||
plainDisabledColor: '#434356',
|
||||
outlinedBorder: '#353539',
|
||||
outlinedHoverBorder: '#454651'
|
||||
},
|
||||
text: {
|
||||
primary: '#EBEBEF'
|
||||
},
|
||||
background: {
|
||||
body: '#0f172a',
|
||||
surface: '#1e293b40'
|
||||
body: '#212121',
|
||||
surface: '#525262',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -8,7 +8,7 @@ const nextConfig = {
|
||||
ignoreBuildErrors: true
|
||||
},
|
||||
env: {
|
||||
API_BASE_URL: process.env.API_BASE_URL || 'http://30.183.154.76:5000'
|
||||
API_BASE_URL: process.env.API_BASE_URL || 'https://u158074-879a-d00019a9.westa.seetacloud.com:8443'
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user