mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-08-11 13:12:18 +00:00
Merge branch 'new-page-framework' into dev_ty_06_end
This commit is contained in:
commit
16655e5f13
@ -11,14 +11,27 @@ const AgentPage = (props) => {
|
|||||||
ready: !!props.params?.agentId
|
ready: !!props.params?.agentId
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleChatSubmit, history } = useAgentChat({
|
const { history, handleChatSubmit } = useAgentChat({
|
||||||
queryAgentURL: `/v1/chat/completions`,
|
queryAgentURL: `http://30.183.154.8:5000/v1/chat/completions`,
|
||||||
queryBody: {}
|
queryBody: {
|
||||||
|
conv_uid: props.params?.agentId,
|
||||||
|
chat_mode: 'chat_normal'
|
||||||
|
},
|
||||||
|
initHistory: historyList?.data
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mx-auto flex h-full max-w-3xl flex-col gap-6 px-5 pt-6 sm:gap-8 xl:max-w-4xl'>
|
<div className='mx-auto flex h-full max-w-3xl flex-col gap-6 px-5 pt-6 sm:gap-8 xl:max-w-4xl'>
|
||||||
<ChatBoxComp messages={historyList?.data || []} onSubmit={handleChatSubmit}/>
|
<ChatBoxComp
|
||||||
|
initialMessage={historyList?.data ? (historyList?.data?.length <= 0 ? props.searchParams?.initMessage : undefined) : undefined}
|
||||||
|
clearIntialMessage={() => {
|
||||||
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
|
searchParams.delete('initMessage');
|
||||||
|
window.history.replaceState(null, null, `?${searchParams.toString()}`);
|
||||||
|
}}
|
||||||
|
messages={history || []}
|
||||||
|
onSubmit={handleChatSubmit}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Stack,
|
Stack,
|
||||||
Input,
|
Input,
|
||||||
|
Textarea,
|
||||||
Chip,
|
Chip,
|
||||||
styled
|
styled
|
||||||
} from '@/lib/mui'
|
} from '@/lib/mui'
|
||||||
@ -61,6 +62,8 @@ const Documents = () => {
|
|||||||
const [documents, setDocuments] = useState<any>([])
|
const [documents, setDocuments] = useState<any>([])
|
||||||
const [webPageUrl, setWebPageUrl] = useState<string>('')
|
const [webPageUrl, setWebPageUrl] = useState<string>('')
|
||||||
const [documentName, setDocumentName] = useState<any>('')
|
const [documentName, setDocumentName] = useState<any>('')
|
||||||
|
const [textSource, setTextSource] = useState<string>('');
|
||||||
|
const [text, setText] = useState<string>('');
|
||||||
const [originFileObj, setOriginFileObj] = useState<any>(null)
|
const [originFileObj, setOriginFileObj] = useState<any>(null)
|
||||||
const props: UploadProps = {
|
const props: UploadProps = {
|
||||||
name: 'file',
|
name: 'file',
|
||||||
@ -264,7 +267,6 @@ const Documents = () => {
|
|||||||
onChange={(e: any) => setDocumentName(e.target.value)}
|
onChange={(e: any) => setDocumentName(e.target.value)}
|
||||||
sx={{ marginBottom: '20px' }}
|
sx={{ marginBottom: '20px' }}
|
||||||
/>
|
/>
|
||||||
Web Page URL:
|
|
||||||
{documentType === 'webPage' ? (
|
{documentType === 'webPage' ? (
|
||||||
<>
|
<>
|
||||||
Web Page URL:
|
Web Page URL:
|
||||||
@ -293,7 +295,20 @@ const Documents = () => {
|
|||||||
</Dragger>
|
</Dragger>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<>
|
||||||
|
Text Source(Optional):
|
||||||
|
<Input
|
||||||
|
placeholder="Please input the text source"
|
||||||
|
onChange={(e: any) => setTextSource(e.target.value)}
|
||||||
|
sx={{ marginBottom: '20px' }}
|
||||||
|
/>
|
||||||
|
Text:
|
||||||
|
<Textarea
|
||||||
|
onChange={(e: any) => setText(e.target.value)}
|
||||||
|
minRows={4}
|
||||||
|
sx={{ marginBottom: '20px' }}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
<Button
|
<Button
|
||||||
@ -379,6 +394,47 @@ const Documents = () => {
|
|||||||
} else {
|
} else {
|
||||||
message.error(data.err_msg || 'failed')
|
message.error(data.err_msg || 'failed')
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (text === '') {
|
||||||
|
message.error('Please input the text')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const res = await fetch(
|
||||||
|
`http://localhost:8000/knowledge/${spaceName}/document/add`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
doc_name: documentName,
|
||||||
|
source: textSource,
|
||||||
|
content: text,
|
||||||
|
doc_type: 'TEXT'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const data = await res.json()
|
||||||
|
if (data.success) {
|
||||||
|
message.success('success')
|
||||||
|
setIsAddDocumentModalShow(false)
|
||||||
|
const res = await fetch(
|
||||||
|
`http://localhost:8000/knowledge/${spaceName}/document/list`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const data = await res.json()
|
||||||
|
if (data.success) {
|
||||||
|
setDocuments(data.data)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.error(data.err_msg || 'failed')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
Stack,
|
Stack,
|
||||||
Box,
|
Box,
|
||||||
Input,
|
Input,
|
||||||
|
Textarea,
|
||||||
styled
|
styled
|
||||||
} from '@/lib/mui'
|
} from '@/lib/mui'
|
||||||
|
|
||||||
@ -62,6 +63,8 @@ const Index = () => {
|
|||||||
const [knowledgeSpaceName, setKnowledgeSpaceName] = useState<string>('')
|
const [knowledgeSpaceName, setKnowledgeSpaceName] = useState<string>('')
|
||||||
const [webPageUrl, setWebPageUrl] = useState<string>('')
|
const [webPageUrl, setWebPageUrl] = useState<string>('')
|
||||||
const [documentName, setDocumentName] = useState<any>('')
|
const [documentName, setDocumentName] = useState<any>('')
|
||||||
|
const [textSource, setTextSource] = useState<string>('');
|
||||||
|
const [text, setText] = useState<string>('');
|
||||||
const [originFileObj, setOriginFileObj] = useState<any>(null)
|
const [originFileObj, setOriginFileObj] = useState<any>(null)
|
||||||
const props: UploadProps = {
|
const props: UploadProps = {
|
||||||
name: 'file',
|
name: 'file',
|
||||||
@ -304,7 +307,20 @@ const Index = () => {
|
|||||||
</Dragger>
|
</Dragger>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<>
|
||||||
|
Text Source(Optional):
|
||||||
|
<Input
|
||||||
|
placeholder="Please input the text source"
|
||||||
|
onChange={(e: any) => setTextSource(e.target.value)}
|
||||||
|
sx={{ marginBottom: '20px' }}
|
||||||
|
/>
|
||||||
|
Text:
|
||||||
|
<Textarea
|
||||||
|
onChange={(e: any) => setText(e.target.value)}
|
||||||
|
minRows={4}
|
||||||
|
sx={{ marginBottom: '20px' }}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
<Button
|
<Button
|
||||||
@ -362,6 +378,33 @@ const Index = () => {
|
|||||||
} else {
|
} else {
|
||||||
message.error(data.err_msg || 'failed')
|
message.error(data.err_msg || 'failed')
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (text === '') {
|
||||||
|
message.error('Please input the text')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const res = await fetch(
|
||||||
|
`http://localhost:8000/knowledge/${knowledgeSpaceName}/document/add`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
doc_name: documentName,
|
||||||
|
source: textSource,
|
||||||
|
content: text,
|
||||||
|
doc_type: 'TEXT'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const data = await res.json()
|
||||||
|
if (data.success) {
|
||||||
|
message.success('success')
|
||||||
|
setIsAddKnowledgeSpaceModalShow(false)
|
||||||
|
} else {
|
||||||
|
message.error(data.err_msg || 'failed')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -5,12 +5,12 @@ import LeftSider from '@/components/leftSider';
|
|||||||
import { CssVarsProvider, ThemeProvider } from '@mui/joy/styles';
|
import { CssVarsProvider, ThemeProvider } from '@mui/joy/styles';
|
||||||
import { joyTheme } from './defaultTheme';
|
import { joyTheme } from './defaultTheme';
|
||||||
import TopProgressBar from '@/components/topProgressBar';
|
import TopProgressBar from '@/components/topProgressBar';
|
||||||
|
function RootLayout({
|
||||||
export default function RootLayout({
|
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en" className="h-full font-sans">
|
<html lang="en" className="h-full font-sans">
|
||||||
<body className={`h-full font-sans`}>
|
<body className={`h-full font-sans`}>
|
||||||
@ -31,3 +31,5 @@ export default function RootLayout({
|
|||||||
</html>
|
</html>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default RootLayout;
|
@ -28,8 +28,7 @@ export default function Home() {
|
|||||||
chat_mode: 'chat_normal'
|
chat_mode: 'chat_normal'
|
||||||
});
|
});
|
||||||
if (res?.success && res?.data?.conv_uid) {
|
if (res?.success && res?.data?.conv_uid) {
|
||||||
// router.push(`/agents/${res?.data?.conv_uid}?newMessage=${query}`);
|
router.push(`/agents/${res?.data?.conv_uid}?initMessage=${query}`);
|
||||||
// await refreshDialogList();
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -17,8 +17,9 @@ type Props = {
|
|||||||
messages: Message[];
|
messages: Message[];
|
||||||
onSubmit: (message: string) => Promise<any>;
|
onSubmit: (message: string) => Promise<any>;
|
||||||
messageTemplates?: string[];
|
messageTemplates?: string[];
|
||||||
initialMessage?: Message;
|
initialMessage?: string;
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
|
clearIntialMessage?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Schema = z.object({ query: z.string().min(1) });
|
const Schema = z.object({ query: z.string().min(1) });
|
||||||
@ -29,6 +30,7 @@ const ChatBoxComp = ({
|
|||||||
messageTemplates,
|
messageTemplates,
|
||||||
initialMessage,
|
initialMessage,
|
||||||
readOnly,
|
readOnly,
|
||||||
|
clearIntialMessage
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const scrollableRef = React.useRef<HTMLDivElement>(null);
|
const scrollableRef = React.useRef<HTMLDivElement>(null);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
@ -52,6 +54,11 @@ const ChatBoxComp = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleInitMessage = async () => {
|
||||||
|
await submit({ query: (initialMessage as string) });
|
||||||
|
clearIntialMessage?.();
|
||||||
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!scrollableRef.current) {
|
if (!scrollableRef.current) {
|
||||||
return;
|
return;
|
||||||
@ -61,11 +68,9 @@ const ChatBoxComp = ({
|
|||||||
}, [messages?.length]);
|
}, [messages?.length]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setTimeout(() => {
|
if (initialMessage && messages.length <= 0) {
|
||||||
setFirstMsg(
|
handleInitMessage();
|
||||||
initialMessage ? initialMessage : undefined
|
}
|
||||||
);
|
|
||||||
}, 0);
|
|
||||||
}, [initialMessage]);
|
}, [initialMessage]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -116,7 +121,7 @@ const ChatBoxComp = ({
|
|||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{messages.map((each, index) => (
|
{messages.filter(item => ['ai', 'human'].includes(item.role)).map((each, index) => (
|
||||||
<Stack
|
<Stack
|
||||||
key={index}
|
key={index}
|
||||||
sx={{
|
sx={{
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React, { useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname, useSearchParams } from 'next/navigation';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { Box, List, ListItem, ListItemButton, ListItemDecorator, ListItemContent, Typography, Button, useColorScheme, Alert } from '@/lib/mui';
|
import { Box, List, ListItem, ListItemButton, ListItemDecorator, ListItemContent, Typography, Button, useColorScheme } from '@/lib/mui';
|
||||||
import SmartToyRoundedIcon from '@mui/icons-material/SmartToyRounded'; // Icons import
|
import SmartToyRoundedIcon from '@mui/icons-material/SmartToyRounded'; // Icons import
|
||||||
import StorageRoundedIcon from '@mui/icons-material/StorageRounded';
|
import StorageRoundedIcon from '@mui/icons-material/StorageRounded';
|
||||||
import DarkModeIcon from '@mui/icons-material/DarkMode';
|
import DarkModeIcon from '@mui/icons-material/DarkMode';
|
||||||
import WbSunnyIcon from '@mui/icons-material/WbSunny';
|
import WbSunnyIcon from '@mui/icons-material/WbSunny';
|
||||||
import HomeIcon from '@mui/icons-material/Home';
|
|
||||||
import MenuIcon from '@mui/icons-material/Menu';
|
import MenuIcon from '@mui/icons-material/Menu';
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
import { useQueryDialog } from '@/hooks/useQueryDialogue';
|
import { useQueryDialog } from '@/hooks/useQueryDialogue';
|
||||||
@ -16,16 +15,10 @@ import { useQueryDialog } from '@/hooks/useQueryDialogue';
|
|||||||
const LeftSider = () => {
|
const LeftSider = () => {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const { mode, setMode } = useColorScheme();
|
const { mode, setMode } = useColorScheme();
|
||||||
const [chatSelect, setChatSelect] = useState();
|
|
||||||
const { dialogueList } = useQueryDialog();
|
const { dialogueList } = useQueryDialog();
|
||||||
|
|
||||||
const menus = useMemo(() => {
|
const menus = useMemo(() => {
|
||||||
return [{
|
return [{
|
||||||
label: 'Home',
|
|
||||||
icon: <HomeIcon fontSize="small" />,
|
|
||||||
route: '/',
|
|
||||||
active: pathname === '/',
|
|
||||||
}, {
|
|
||||||
label: 'Agents',
|
label: 'Agents',
|
||||||
icon: <SmartToyRoundedIcon fontSize="small" />,
|
icon: <SmartToyRoundedIcon fontSize="small" />,
|
||||||
route: '/agents',
|
route: '/agents',
|
||||||
@ -53,7 +46,7 @@ const LeftSider = () => {
|
|||||||
<MenuIcon />
|
<MenuIcon />
|
||||||
</div>
|
</div>
|
||||||
<span className='truncate px-4'>New Chat</span>
|
<span className='truncate px-4'>New Chat</span>
|
||||||
<a href='javascript: void(0)' className='-mr-3 flex h-9 w-9 shrink-0 items-center justify-center'>
|
<a href='' className='-mr-3 flex h-9 w-9 shrink-0 items-center justify-center'>
|
||||||
<AddIcon />
|
<AddIcon />
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
@ -99,7 +92,9 @@ const LeftSider = () => {
|
|||||||
px: 2
|
px: 2
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Link href={`/`}>
|
||||||
<Button variant="outlined" color="primary" className='w-full'>+ 新建对话</Button>
|
<Button variant="outlined" color="primary" className='w-full'>+ 新建对话</Button>
|
||||||
|
</Link>
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -121,14 +116,13 @@ const LeftSider = () => {
|
|||||||
'& .JoyListItemButton-root': { p: '8px' },
|
'& .JoyListItemButton-root': { p: '8px' },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{dialogueList?.data?.map((each) => (
|
{dialogueList?.data?.map((each) => {
|
||||||
|
const isSelect = pathname === `/agents/${each.conv_uid}`;
|
||||||
|
return (
|
||||||
<ListItem key={each.conv_uid}>
|
<ListItem key={each.conv_uid}>
|
||||||
<ListItemButton
|
<ListItemButton
|
||||||
selected={chatSelect === each.conv_uid}
|
selected={isSelect}
|
||||||
variant={chatSelect === each.conv_uid ? 'soft' : 'plain'}
|
variant={isSelect ? 'soft' : 'plain'}
|
||||||
onClick={() => {
|
|
||||||
setChatSelect(each.conv_uid);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ListItemContent>
|
<ListItemContent>
|
||||||
<Link href={`/agents/${each.conv_uid}`}>
|
<Link href={`/agents/${each.conv_uid}`}>
|
||||||
@ -136,11 +130,11 @@ const LeftSider = () => {
|
|||||||
{each?.user_name || each?.user_input || 'undefined'}
|
{each?.user_name || each?.user_input || 'undefined'}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
</ListItemContent>
|
</ListItemContent>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
))}
|
)
|
||||||
|
})}
|
||||||
</List>
|
</List>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
@ -178,7 +172,6 @@ const LeftSider = () => {
|
|||||||
color="neutral"
|
color="neutral"
|
||||||
selected={each.active}
|
selected={each.active}
|
||||||
variant={each.active ? 'soft' : 'plain'}
|
variant={each.active ? 'soft' : 'plain'}
|
||||||
onClick={() => { setChatSelect(undefined); }}
|
|
||||||
>
|
>
|
||||||
<ListItemDecorator
|
<ListItemDecorator
|
||||||
sx={{
|
sx={{
|
||||||
|
@ -2,34 +2,30 @@ import {
|
|||||||
EventStreamContentType,
|
EventStreamContentType,
|
||||||
fetchEventSource,
|
fetchEventSource,
|
||||||
} from '@microsoft/fetch-event-source';
|
} from '@microsoft/fetch-event-source';
|
||||||
import { ApiError, ApiErrorType } from '@/utils/api-error';
|
|
||||||
import useStateReducer from './useStateReducer';
|
import useStateReducer from './useStateReducer';
|
||||||
import useVisitorId from './useVisitorId';
|
import { Message } from '@/types';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
queryAgentURL: string;
|
queryAgentURL: string;
|
||||||
queryHistoryURL?: string;
|
|
||||||
channel?: "dashboard" | "website" | "slack" | "crisp";
|
channel?: "dashboard" | "website" | "slack" | "crisp";
|
||||||
queryBody?: any;
|
queryBody?: any;
|
||||||
|
initHistory: Message[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const useAgentChat = ({
|
const useAgentChat = ({
|
||||||
queryAgentURL,
|
queryAgentURL,
|
||||||
queryHistoryURL,
|
|
||||||
channel,
|
channel,
|
||||||
queryBody,
|
queryBody,
|
||||||
|
initHistory
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [state, setState] = useStateReducer({
|
const [state, setState] = useStateReducer({
|
||||||
history: [{
|
history: (initHistory || []) as { role: 'human' | 'ai'; context: string; id?: string }[],
|
||||||
role: 'human',
|
|
||||||
context: 'hello',
|
|
||||||
}, {
|
|
||||||
role: 'agent',
|
|
||||||
context: 'Hello! How can I assist you today?',
|
|
||||||
}] as { role: 'human' | 'agent'; context: string; id?: string }[],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { visitorId } = useVisitorId();
|
useEffect(() => {
|
||||||
|
if (initHistory) setState({ history: initHistory });
|
||||||
|
}, [initHistory]);
|
||||||
|
|
||||||
const handleChatSubmit = async (context: string) => {
|
const handleChatSubmit = async (context: string) => {
|
||||||
if (!context) {
|
if (!context) {
|
||||||
@ -50,9 +46,6 @@ import {
|
|||||||
const ctrl = new AbortController();
|
const ctrl = new AbortController();
|
||||||
let buffer = '';
|
let buffer = '';
|
||||||
|
|
||||||
class RetriableError extends Error {}
|
|
||||||
class FatalError extends Error {}
|
|
||||||
|
|
||||||
await fetchEventSource(queryAgentURL, {
|
await fetchEventSource(queryAgentURL, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -60,9 +53,7 @@ import {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
...queryBody,
|
...queryBody,
|
||||||
streaming: true,
|
user_input: context,
|
||||||
query: context,
|
|
||||||
visitorId: visitorId,
|
|
||||||
channel,
|
channel,
|
||||||
}),
|
}),
|
||||||
signal: ctrl.signal,
|
signal: ctrl.signal,
|
||||||
@ -79,64 +70,59 @@ import {
|
|||||||
response.status !== 429
|
response.status !== 429
|
||||||
) {
|
) {
|
||||||
if (response.status === 402) {
|
if (response.status === 402) {
|
||||||
throw new ApiError(ApiErrorType.USAGE_LIMIT);
|
//throw new ApiError(ApiErrorType.USAGE_LIMIT);
|
||||||
}
|
}
|
||||||
throw new FatalError();
|
// client-side errors are usually non-retriable:
|
||||||
|
//throw new FatalError();
|
||||||
} else {
|
} else {
|
||||||
throw new RetriableError();
|
//throw new RetriableError();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onclose() {
|
onclose() {
|
||||||
throw new RetriableError();
|
// if the server closes the connection unexpectedly, retry:
|
||||||
|
console.log('onclose');
|
||||||
|
//throw new RetriableError();
|
||||||
},
|
},
|
||||||
onerror(err) {
|
onerror(err) {
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
// if (err instanceof FatalError) {
|
|
||||||
// ctrl.abort();
|
|
||||||
// throw new Error(); // rethrow to stop the operation
|
|
||||||
// } else if (err instanceof ApiError) {
|
|
||||||
// console.log('ApiError', ApiError);
|
|
||||||
// throw new Error();
|
|
||||||
// } else {
|
|
||||||
// throw new Error(err);
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
onmessage: (event) => {
|
onmessage: (event) => {
|
||||||
|
event.data = event.data.replaceAll('\\n', '\n');
|
||||||
console.log(event, 'event');
|
console.log(event, 'event');
|
||||||
if (event.data === '[DONE]') {
|
if (event.data === '[DONE]') {
|
||||||
ctrl.abort();
|
ctrl.abort();
|
||||||
} else if (event.data?.startsWith('[ERROR]')) {
|
} else if (event.data?.startsWith('[ERROR]')) {
|
||||||
ctrl.abort();
|
ctrl.abort();
|
||||||
|
|
||||||
setState({
|
setState({
|
||||||
history: [
|
history: [
|
||||||
...history,
|
...history,
|
||||||
{
|
{
|
||||||
role: 'agent',
|
role: 'ai',
|
||||||
context: event.data.replace('[ERROR]', ''),
|
context: event.data.replace('[ERROR]', ''),
|
||||||
} as any,
|
} as any,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
buffer += decodeURIComponent(event.data) as string;
|
|
||||||
const h = [...history];
|
const h = [...history];
|
||||||
|
if (event.data) {
|
||||||
if (h?.[nextIndex]) {
|
if (h?.[nextIndex]) {
|
||||||
h[nextIndex].context = `${buffer}`;
|
h[nextIndex].context = `${event.data}`;
|
||||||
} else {
|
} else {
|
||||||
h.push({ role: 'agent', context: buffer });
|
h.push({ role: 'ai', context: event.data });
|
||||||
}
|
}
|
||||||
setState({
|
setState({
|
||||||
history: h as any,
|
history: h as any,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('err', err);
|
|
||||||
setState({
|
setState({
|
||||||
history: [
|
history: [
|
||||||
...history,
|
...history,
|
||||||
{ role: 'agent', context: answer || '请求出错' as string },
|
{ role: 'ai', context: answer || '请求出错' as string },
|
||||||
] as any,
|
] as any,
|
||||||
});
|
});
|
||||||
// if (err instanceof ApiError) {
|
// if (err instanceof ApiError) {
|
||||||
@ -156,13 +142,12 @@ import {
|
|||||||
// setState({
|
// setState({
|
||||||
// history: [
|
// history: [
|
||||||
// ...history,
|
// ...history,
|
||||||
// { from: 'agent', message: answer as string },
|
// { from: 'ai', message: answer as string },
|
||||||
// ] as any,
|
// ] as any,
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleChatSubmit,
|
handleChatSubmit,
|
||||||
history: state.history,
|
history: state.history,
|
||||||
|
10
datacenter/hooks/useNewChat.ts
Normal file
10
datacenter/hooks/useNewChat.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export const useNewChat = () => {
|
||||||
|
const [message, setMessage] = useState<string | undefined>("hello");
|
||||||
|
|
||||||
|
return {
|
||||||
|
message,
|
||||||
|
setMessage
|
||||||
|
};
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { isPlainObject } from 'lodash';
|
import { isPlainObject } from 'lodash';
|
||||||
|
|
||||||
axios.defaults.baseURL = 'http://30.183.153.244:5000';
|
axios.defaults.baseURL = 'http://30.183.154.8:5000';
|
||||||
|
|
||||||
axios.defaults.timeout = 10000;
|
axios.defaults.timeout = 10000;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user