This commit is contained in:
archer
2023-07-17 22:05:45 +08:00
parent 509ca92f0a
commit ecce182a20
16 changed files with 1395 additions and 1422 deletions

View File

@@ -89,6 +89,8 @@ export const streamFetch = ({
}); });
read(); read();
} catch (err: any) { } catch (err: any) {
console.log(111111111111111111);
if (err?.message === 'The user aborted a request.') { if (err?.message === 'The user aborted a request.') {
return resolve({ return resolve({
responseText, responseText,
@@ -102,7 +104,7 @@ export const streamFetch = ({
}; };
read(); read();
} catch (err: any) { } catch (err: any) {
console.log(err); console.log(err, 'fetch error');
reject(getErrText(err, '请求异常')); reject(getErrText(err, '请求异常'));
} }

View File

@@ -464,7 +464,7 @@ const ChatBox = (
source={item.value} source={item.value}
isChatting={index === chatHistory.length - 1 && isChatting} isChatting={index === chatHistory.length - 1 && isChatting}
/> />
{(item[quoteLenKey] || item[rawSearchKey]?.length) && ( {(!!item[quoteLenKey] || !!item[rawSearchKey]?.length) && (
<Button <Button
size={'xs'} size={'xs'}
variant={'base'} variant={'base'}

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689602517026" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5455" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M727.008 487.232l194.016-184.32a99.2 99.2 0 0 0 0-140.288l-48.416-48.416a99.2 99.2 0 0 0-138.464-1.76L544.64 292.384l-184.064-196.64-1.504-1.568a64.832 64.832 0 0 0-91.712-0.384L129.184 231.968a64.8 64.8 0 0 0-1.12 90.144l181.344 193.728-171.456 162.88a99.264 99.264 0 0 0-28.256 49.28l-28.992 123.744a65.632 65.632 0 0 0 82.4 77.92l119.296-35.136a99.744 99.744 0 0 0 40.32-23.232l169.056-160.608 203.616 217.536 1.504 1.568a64.832 64.832 0 0 0 91.712 0.384l138.176-138.176a64.8 64.8 0 0 0 1.12-90.144l-200.896-214.624zM319.424 786.176l-90.112-90.112a31.488 31.488 0 0 0-9.792-6.496L667.104 264.352l94.272 94.272c1.408 1.408 3.168 2.08 4.768 3.168L319.424 786.176zM778.208 158.784a35.2 35.2 0 0 1 49.12 0.64l48.416 48.416c13.76 13.76 13.76 36.032-0.64 50.4l-64.448 61.216c-1.28-2.08-2.24-4.288-4.064-6.112l-93.12-93.12 64.736-61.44zM288.512 399.904c8-0.128 16-3.168 22.112-9.28l48-48a31.968 31.968 0 1 0-45.248-45.248l-48 48a31.68 31.68 0 0 0-8.928 20.256L174.816 278.4c-0.512-0.512-0.512-1.024-0.352-1.152L312.64 139.04c0.128-0.128 0.672-0.128 1.248 0.416l184.384 196.992-142.432 135.328-67.328-71.872zM145.024 868.288a1.6 1.6 0 0 1-2.016-1.92l28.992-123.744c0.992-4.16 2.944-7.968 5.312-11.488a31.808 31.808 0 0 0 6.752 10.144l88.288 88.288a35.072 35.072 0 0 1-8 3.552l-119.328 35.168z m598.336 16.672c-0.128 0.128-0.672 0.128-1.248-0.416l-125.6-134.176a31.232 31.232 0 0 0 14.08-7.712l48-48a31.968 31.968 0 1 0-45.248-45.248l-48 48a31.68 31.68 0 0 0-7.296 11.904l-39.904-42.656 142.432-135.328 200.576 214.304c0.48 0.512 0.48 1.024 0.352 1.152l-138.144 138.176z" p-id="5456"></path></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -62,7 +62,8 @@ const map = {
csvImport: require('./icons/file/csv.svg').default, csvImport: require('./icons/file/csv.svg').default,
qaImport: require('./icons/file/qaImport.svg').default, qaImport: require('./icons/file/qaImport.svg').default,
uploadFile: require('./icons/file/uploadFile.svg').default, uploadFile: require('./icons/file/uploadFile.svg').default,
closeLight: require('./icons/light/close.svg').default closeLight: require('./icons/light/close.svg').default,
customTitle: require('./icons/light/customTitle.svg').default
}; };
export type IconName = keyof typeof map; export type IconName = keyof typeof map;

View File

@@ -21,7 +21,7 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
label: '应用', label: '应用',
icon: 'tabbarModel', icon: 'tabbarModel',
link: `/app/list`, link: `/app/list`,
activeLink: ['/app/list'], activeLink: ['/app/list', '/app/detail'],
unread: 0 unread: 0
}, },
{ {
@@ -64,7 +64,7 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
pt={1} pt={1}
px={3} px={3}
transform={'scale(0.9)'} transform={'scale(0.9)'}
{...(item.activeLink.includes(router.asPath) {...(item.activeLink.includes(router.pathname)
? { ? {
color: '#7089f1' color: '#7089f1'
} }
@@ -72,7 +72,7 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
color: 'myGray.500' color: 'myGray.500'
})} })}
_after={ _after={
item.activeLink.includes(router.asPath) item.activeLink.includes(router.pathname)
? { ? {
content: '""', content: '""',
position: 'absolute', position: 'absolute',

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,6 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@/service/response'; import { jsonRes } from '@/service/response';
import { authUser } from '@/service/utils/auth'; import { authUser } from '@/service/utils/auth';
import { connectToDatabase, App } from '@/service/mongo'; import { connectToDatabase, App } from '@/service/mongo';
import { appTemplates } from '@/constants/app';
import { rawSearchKey } from '@/constants/chat'; import { rawSearchKey } from '@/constants/chat';
const chatTemplate = ({ const chatTemplate = ({
@@ -85,7 +84,7 @@ const chatTemplate = ({
}, },
{ {
key: 'temperature', key: 'temperature',
type: 'slider', type: 'custom',
label: '温度', label: '温度',
value: temperature, value: temperature,
min: 0, min: 0,
@@ -105,10 +104,10 @@ const chatTemplate = ({
}, },
{ {
key: 'maxToken', key: 'maxToken',
type: 'slider', type: 'custom',
label: '回复上限', label: '回复上限',
value: maxToken, value: maxToken,
min: 0, min: 100,
max: 16000, max: 16000,
step: 50, step: 50,
markList: [ markList: [
@@ -328,8 +327,8 @@ const kbTemplate = ({
} }
], ],
position: { position: {
x: 211.58250540918442, x: -196.84632684738483,
y: 611.8700401034965 y: 797.3401378431948
}, },
moduleId: 'k9y3jm' moduleId: 'k9y3jm'
}, },
@@ -364,7 +363,7 @@ const kbTemplate = ({
}, },
{ {
key: 'temperature', key: 'temperature',
type: 'slider', type: 'custom',
label: '温度', label: '温度',
value: temperature, value: temperature,
min: 0, min: 0,
@@ -384,10 +383,10 @@ const kbTemplate = ({
}, },
{ {
key: 'maxToken', key: 'maxToken',
type: 'slider', type: 'custom',
label: '回复上限', label: '回复上限',
value: maxToken, value: maxToken,
min: 0, min: 100,
max: 16000, max: 16000,
step: 50, step: 50,
markList: [ markList: [
@@ -459,8 +458,8 @@ const kbTemplate = ({
} }
], ],
position: { position: {
x: 830.725790038998, x: 745.484449528062,
y: 201.0790739617387 y: 259.9361900288137
}, },
moduleId: 'qbf8td' moduleId: 'qbf8td'
}, },
@@ -482,7 +481,7 @@ const kbTemplate = ({
}, },
{ {
key: 'similarity', key: 'similarity',
type: 'slider', type: 'custom',
label: '相似度', label: '相似度',
value: searchSimilarity, value: searchSimilarity,
min: 0, min: 0,
@@ -502,8 +501,9 @@ const kbTemplate = ({
}, },
{ {
key: 'limit', key: 'limit',
type: 'slider', type: 'custom',
label: '单次搜索上限', label: '单次搜索上限',
description: '最多取 n 条记录作为本次问题引用',
value: searchLimit, value: searchLimit,
min: 1, min: 1,
max: 20, max: 20,
@@ -575,7 +575,7 @@ const kbTemplate = ({
}, },
moduleId: 'q9v14m' moduleId: 'q9v14m'
}, },
searchEmptyText ...(searchEmptyText
? [ ? [
{ {
logo: '/imgs/module/reply.png', logo: '/imgs/module/reply.png',
@@ -600,13 +600,13 @@ const kbTemplate = ({
], ],
outputs: [], outputs: [],
position: { position: {
x: 827.8570503787319, x: 673.6108151684664,
y: -63.837994077710675 y: -84.13355134221933
}, },
moduleId: 'w8av9y' moduleId: 'w8av9y'
} }
] ]
: [] : [])
]; ];
}; };
@@ -619,13 +619,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const apps = await App.find( const apps = await App.find(
{ {
chat: { $ne: null }, chat: { $ne: null },
modules: { $ne: null } modules: { $exists: false }
// userId: '63f9a14228d2a688d8dc9e1b'
}, },
'_id chat' '_id chat'
).limit(2); );
const result = await Promise.all( await Promise.all(
apps.map(async (app) => { apps.map(async (app) => {
if (!app.chat) return app;
const modules = (() => { const modules = (() => {
if (app.chat.relatedKbs.length === 0) { if (app.chat.relatedKbs.length === 0) {
return chatTemplate({ return chatTemplate({
@@ -650,17 +652,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
} }
})(); })();
await App.findByIdAndUpdate(app.id, {
modules
});
return modules; return modules;
}) })
); );
console.log(apps);
jsonRes(res, { jsonRes(res, {
data: { data: apps.length
apps,
result
}
}); });
} catch (error) { } catch (error) {
jsonRes(res, { jsonRes(res, {

View File

@@ -30,7 +30,7 @@ export type Props = {
export type Response = { [SpecificInputEnum.answerText]: string; totalTokens: number }; export type Response = { [SpecificInputEnum.answerText]: string; totalTokens: number };
export default async function handler(req: NextApiRequest, res: NextApiResponse) { export default async function handler(req: NextApiRequest, res: NextApiResponse) {
let { model, temperature = 0, stream } = req.body as Props; let { model, stream } = req.body as Props;
try { try {
await authUser({ req, authRoot: true }); await authUser({ req, authRoot: true });
@@ -54,7 +54,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
} }
} catch (err) { } catch (err) {
if (stream) { if (stream) {
res.status(500);
sseErrRes(res, err); sseErrRes(res, err);
res.end(); res.end();
} else { } else {

View File

@@ -9,6 +9,8 @@ import RenderOutput from './render/RenderOutput';
import { FlowOutputItemTypeEnum } from '@/constants/flow'; import { FlowOutputItemTypeEnum } from '@/constants/flow';
import MySelect from '@/components/Select'; import MySelect from '@/components/Select';
import { chatModelList } from '@/store/static'; import { chatModelList } from '@/store/static';
import MySlider from '@/components/Slider';
import { Box } from '@chakra-ui/react';
const NodeChat = ({ const NodeChat = ({
data: { moduleId, inputs, outputs, onChangeNode, ...props } data: { moduleId, inputs, outputs, onChangeNode, ...props }
@@ -47,7 +49,7 @@ const NodeChat = ({
key: 'maxToken', key: 'maxToken',
valueKey: 'markList', valueKey: 'markList',
value: [ value: [
{ label: '0', value: 0 }, { label: '100', value: 100 },
{ label: `${model.contextMaxToken}`, value: model.contextMaxToken } { label: `${model.contextMaxToken}`, value: model.contextMaxToken }
] ]
}); });
@@ -65,7 +67,35 @@ const NodeChat = ({
}); });
}} }}
/> />
) ),
maxToken: (inputItem) => {
const model = inputs.find((item) => item.key === 'model')?.value;
const modelData = chatModelList.find((item) => item.model === model);
const maxToken = modelData ? modelData.contextMaxToken : 4000;
const markList = [
{ label: '100', value: 100 },
{ label: `${maxToken}`, value: maxToken }
];
return (
<Box pt={5} pb={4} px={2}>
<MySlider
markList={markList}
width={'100%'}
min={inputItem.min || 100}
max={maxToken}
step={inputItem.step || 1}
value={inputItem.value}
onChange={(e) => {
onChangeNode({
moduleId,
key: inputItem.key,
value: e
});
}}
/>
</Box>
);
}
}} }}
/> />
</Container> </Container>

View File

@@ -84,6 +84,7 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => {
const { x, y, zoom } = useViewport(); const { x, y, zoom } = useViewport();
const [nodes, setNodes, onNodesChange] = useNodesState<FlowModuleItemType>([]); const [nodes, setNodes, onNodesChange] = useNodesState<FlowModuleItemType>([]);
const [edges, setEdges, onEdgesChange] = useEdgesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]);
const [loaded, setLoaded] = useState(false);
const { const {
isOpen: isOpenTemplate, isOpen: isOpenTemplate,
onOpen: onOpenTemplate, onOpen: onOpenTemplate,
@@ -255,6 +256,9 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => {
}) })
) )
); );
setLoaded(true);
onFixView();
}, },
[onDelConnect, setEdges, setNodes, onChangeNode, onDelNode] [onDelConnect, setEdges, setNodes, onChangeNode, onDelNode]
); );
@@ -377,14 +381,15 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => {
isOpenTemplate ? onCloseTemplate() : onOpenTemplate(); isOpenTemplate ? onCloseTemplate() : onOpenTemplate();
}} }}
/> />
<ReactFlow <ReactFlow
ref={reactFlowWrapper} ref={reactFlowWrapper}
className={styles.panel} className={styles.panel}
fitView
nodes={nodes} nodes={nodes}
edges={edges} edges={edges}
minZoom={0.4} minZoom={0.4}
maxZoom={1.5} maxZoom={1.5}
fitView
defaultEdgeOptions={edgeOptions} defaultEdgeOptions={edgeOptions}
connectionLineStyle={connectionLineStyle} connectionLineStyle={connectionLineStyle}
nodeTypes={nodeTypes} nodeTypes={nodeTypes}

View File

@@ -21,9 +21,8 @@ import { getErrText } from '@/utils/tools';
import { useToast } from '@/hooks/useToast'; import { useToast } from '@/hooks/useToast';
import { postCreateApp } from '@/api/app'; import { postCreateApp } from '@/api/app';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { appTemplates } from '@/constants/app'; import { appTemplates } from '@/constants/flow/ModuleTemplate';
import Avatar from '@/components/Avatar'; import Avatar from '@/components/Avatar';
import MyIcon from '@/components/Icon';
type FormType = { type FormType = {
avatar: string; avatar: string;

View File

@@ -30,7 +30,8 @@ const ChatHistorySlider = ({
activeHistoryId, activeHistoryId,
onChangeChat, onChangeChat,
onDelHistory, onDelHistory,
onSetHistoryTop onSetHistoryTop,
onUpdateTitle
}: { }: {
appId?: string; appId?: string;
appName: string; appName: string;
@@ -40,6 +41,7 @@ const ChatHistorySlider = ({
onChangeChat: (historyId?: string) => void; onChangeChat: (historyId?: string) => void;
onDelHistory: (historyId: string) => void; onDelHistory: (historyId: string) => void;
onSetHistoryTop?: (e: { historyId: string; top: boolean }) => void; onSetHistoryTop?: (e: { historyId: string; top: boolean }) => void;
onUpdateTitle?: (e: { historyId: string; title: string }) => void;
}) => { }) => {
const theme = useTheme(); const theme = useTheme();
const router = useRouter(); const router = useRouter();
@@ -159,6 +161,20 @@ const ChatHistorySlider = ({
{item.top ? '取消置顶' : '置顶'} {item.top ? '取消置顶' : '置顶'}
</MenuItem> </MenuItem>
)} )}
{/* {onUpdateTitle && (
<MenuItem
onClick={(e) => {
e.stopPropagation();
onUpdateTitle({
historyId: item.id,
title: '是是是'
});
}}
>
<MyIcon mr={2} name={'customTitle'} w={'16px'}></MyIcon>
自定义标题
</MenuItem>
)} */}
<MenuItem <MenuItem
_hover={{ color: 'red.500' }} _hover={{ color: 'red.500' }}
onClick={(e) => { onClick={(e) => {

View File

@@ -24,7 +24,7 @@ const ToolMenu = ({ history }: { history: ChatItemType[] }) => {
}, },
{ icon: 'pdf', label: 'PDF导出', onClick: () => onExportChat({ type: 'pdf', history }) } { icon: 'pdf', label: 'PDF导出', onClick: () => onExportChat({ type: 'pdf', history }) }
]); ]);
return ( return history.length > 0 ? (
<Menu autoSelect={false} isLazy> <Menu autoSelect={false} isLazy>
<MenuButton <MenuButton
_hover={{ bg: 'myWhite.600 ' }} _hover={{ bg: 'myWhite.600 ' }}
@@ -45,7 +45,7 @@ const ToolMenu = ({ history }: { history: ChatItemType[] }) => {
))} ))}
</MenuList> </MenuList>
</Menu> </Menu>
); ) : null;
}; };
export default ToolMenu; export default ToolMenu;

View File

@@ -260,6 +260,20 @@ const Chat = () => {
}); });
} catch (error) {} } catch (error) {}
}} }}
onUpdateTitle={async (e) => {
try {
await putChatHistory({
historyId: e.historyId,
customTitle: e.title
});
const historyItem = history.find((item) => item._id === e.historyId);
if (!historyItem) return;
updateHistory({
...historyItem,
title: e.title
});
} catch (error) {}
}}
/> />
)} )}
{/* chat container */} {/* chat container */}

View File

@@ -96,7 +96,7 @@ export const moduleFetch = ({ url, data, res }: Props) =>
data: JSON.stringify(data) data: JSON.stringify(data)
}); });
} else if (item.event === sseResponseEventEnum.error) { } else if (item.event === sseResponseEventEnum.error) {
return reject(getErrText(data, '流响应错误')); return reject(data);
} }
}); });
read(); read();