diff --git a/.gitignore b/.gitignore
index 5de60dd48..2892820b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,5 +28,4 @@ next-env.d.ts
platform.json
testApi/
local/
-.husky/
dist/
\ No newline at end of file
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 000000000..12cc5e1ce
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,6 @@
+#!/usr/bin/env sh
+. "$(dirname -- "$0")/_/husky.sh"
+
+if command -v npx >/dev/null 2>&1; then
+ npx lint-staged
+fi
\ No newline at end of file
diff --git a/client/src/components/Layout/navbar.tsx b/client/src/components/Layout/navbar.tsx
index 75114791e..88e648b30 100644
--- a/client/src/components/Layout/navbar.tsx
+++ b/client/src/components/Layout/navbar.tsx
@@ -27,7 +27,7 @@ const Navbar = ({ unread }: { unread: number }) => {
activeLink: ['/chat']
},
{
- label: '我的应用',
+ label: '应用',
icon: 'model',
link: `/model?modelId=${lastModelId}`,
activeLink: ['/model']
@@ -39,7 +39,7 @@ const Navbar = ({ unread }: { unread: number }) => {
activeLink: ['/kb']
},
{
- label: '应用市场',
+ label: '市场',
icon: 'appStore',
link: '/model/share',
activeLink: ['/model/share']
@@ -61,14 +61,15 @@ const Navbar = ({ unread }: { unread: number }) => {
);
const itemStyles: any = {
- mb: 3,
+ my: 3,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
- w: '60px',
- h: '45px',
+ w: '54px',
+ h: '54px',
+ borderRadius: 'md',
_hover: {
color: '#ffffff'
}
@@ -79,7 +80,7 @@ const Navbar = ({ unread }: { unread: number }) => {
flexDirection={'column'}
alignItems={'center'}
pt={6}
- backgroundColor={'#465069'}
+ backgroundImage={'linear-gradient(to bottom right,#465069,#000000)'}
h={'100%'}
w={'100%'}
boxShadow={'4px 0px 4px 0px rgba(43, 45, 55, 0.01)'}
@@ -99,30 +100,26 @@ const Navbar = ({ unread }: { unread: number }) => {
{/* 导航列表 */}
{navbarList.map((item) => (
-
-
-
-
-
+
+
+ {item.label}
+
+
))}
{unread > 0 && (
diff --git a/client/src/constants/theme.ts b/client/src/constants/theme.ts
index c8db64557..bf9d192db 100644
--- a/client/src/constants/theme.ts
+++ b/client/src/constants/theme.ts
@@ -232,6 +232,10 @@ export const theme = extendTheme({
xl: '1800px',
'2xl': '2100px'
},
+ active: {
+ activeBlueGradient: 'linear-gradient(120deg, #d6e8ff 0%, #f0f7ff 100%)',
+ hoverBlueGradient: 'linear-gradient(60deg, #f0f7ff 0%, #d6e8ff 100%)'
+ },
components: {
Modal: ModalTheme,
Button,
diff --git a/client/src/constants/user.ts b/client/src/constants/user.ts
index c4edb6c1c..4386331e2 100644
--- a/client/src/constants/user.ts
+++ b/client/src/constants/user.ts
@@ -40,3 +40,8 @@ export const InformTypeMap = {
label: '系统通知'
}
};
+
+export enum MyModelsTypeEnum {
+ my = 'my',
+ collection = 'collection'
+}
diff --git a/client/src/pages/api/openapi/kb/pushData.ts b/client/src/pages/api/openapi/kb/pushData.ts
index bcffda278..fab40ba25 100644
--- a/client/src/pages/api/openapi/kb/pushData.ts
+++ b/client/src/pages/api/openapi/kb/pushData.ts
@@ -7,6 +7,7 @@ import { withNextCors } from '@/service/utils/tools';
import { TrainingModeEnum } from '@/constants/plugin';
import { startQueue } from '@/service/utils/tools';
import { PgClient } from '@/service/pg';
+import { modelToolMap } from '@/utils/plugin';
type DateItemType = { a: string; q: string; source?: string };
@@ -21,6 +22,11 @@ export type Response = {
insertLen: number;
};
+const modeMaxToken = {
+ [TrainingModeEnum.index]: 700,
+ [TrainingModeEnum.qa]: 3300
+};
+
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { kbId, data, mode, prompt } = req.body as Props;
@@ -68,7 +74,15 @@ export async function pushDataToKb({
data.forEach((item) => {
const text = item.q + item.a;
- if (!set.has(text)) {
+
+ // count token
+ const token = modelToolMap['gpt-3.5-turbo'].countTokens({
+ messages: [{ obj: 'System', value: item.q }]
+ });
+
+ if (mode === TrainingModeEnum.qa && token > modeMaxToken[TrainingModeEnum.qa]) {
+ console.log('q is too long');
+ } else if (!set.has(text)) {
filterData.push(item);
set.add(text);
}
diff --git a/client/src/pages/chat/components/History.tsx b/client/src/pages/chat/components/History.tsx
index b5521c752..9a000be7a 100644
--- a/client/src/pages/chat/components/History.tsx
+++ b/client/src/pages/chat/components/History.tsx
@@ -146,31 +146,26 @@ const PcSliderBar = ({
)}
)}
-
{/* chat history */}
-
+
{history.map((item) => (
{
if (item._id === chatId) return;
diff --git a/client/src/pages/kb/components/KbList.tsx b/client/src/pages/kb/components/KbList.tsx
index 5f10d71d9..f9b254786 100644
--- a/client/src/pages/kb/components/KbList.tsx
+++ b/client/src/pages/kb/components/KbList.tsx
@@ -87,7 +87,7 @@ const KbList = ({ kbId }: { kbId: string }) => {
/>
-
+
{kbs.map((item) => (
{
mb={[2, 0]}
cursor={'pointer'}
transition={'background-color .2s ease-in'}
- borderLeft={['', '5px solid transparent']}
_hover={{
- backgroundColor: ['', '#dee0e3']
+ backgroundImage: ['', theme.active.hoverBlueGradient]
}}
{...(kbId === item._id
? {
- backgroundColor: '#eff0f1',
- borderLeftColor: 'myBlue.600 !important'
+ backgroundImage: `${theme.active.activeBlueGradient} !important`
}
: {})}
onClick={() => {
diff --git a/client/src/pages/model/components/ModelList.tsx b/client/src/pages/model/components/ModelList.tsx
index 3bf74cb78..8fa9a36af 100644
--- a/client/src/pages/model/components/ModelList.tsx
+++ b/client/src/pages/model/components/ModelList.tsx
@@ -1,5 +1,15 @@
-import React, { useCallback, useMemo, useState } from 'react';
-import { Box, Flex, useTheme, Input, IconButton, Tooltip } from '@chakra-ui/react';
+import React, { useCallback, useMemo, useRef, useState } from 'react';
+import {
+ Box,
+ Flex,
+ Input,
+ IconButton,
+ Tooltip,
+ Tabs,
+ TabList,
+ Tab,
+ useTheme
+} from '@chakra-ui/react';
import { AddIcon } from '@chakra-ui/icons';
import { useRouter } from 'next/router';
import MyIcon from '@/components/Icon';
@@ -9,8 +19,15 @@ import { useToast } from '@/hooks/useToast';
import { useQuery } from '@tanstack/react-query';
import { useUserStore } from '@/store/user';
import Avatar from '@/components/Avatar';
+import { MyModelsTypeEnum } from '@/constants/user';
const ModelList = ({ modelId }: { modelId: string }) => {
+ const tabs = useRef([
+ { label: '我的', value: MyModelsTypeEnum.my },
+ { label: '收藏', value: MyModelsTypeEnum.collection }
+ ]);
+ const [currentTab, setCurrentTab] = useState(MyModelsTypeEnum.my);
+
const theme = useTheme();
const router = useRouter();
const { toast } = useToast();
@@ -42,29 +59,23 @@ const ModelList = ({ modelId }: { modelId: string }) => {
setIsLoading(false);
}, [myModels.length, refreshModel, router, setIsLoading, toast]);
- const models = useMemo(
- () =>
- [
- {
- label: '我的',
- list: myModels.filter((item) =>
- new RegExp(searchText, 'ig').test(item.name + item.systemPrompt)
- )
- },
- {
- label: '收藏',
- list: myCollectionModels.filter((item) =>
- new RegExp(searchText, 'ig').test(item.name + item.systemPrompt)
- )
- }
- ].filter((item) => item.list.length > 0),
- [myCollectionModels, myModels, searchText]
- );
-
- const totalModels = useMemo(
- () => models.reduce((sum, item) => sum + item.list.length, 0),
- [models]
- );
+ const currentModels = useMemo(() => {
+ const map = {
+ [MyModelsTypeEnum.my]: {
+ list: myModels.filter((item) =>
+ new RegExp(searchText, 'ig').test(item.name + item.systemPrompt)
+ ),
+ emptyText: '还没有 AI 应用~\n快来创建一个吧'
+ },
+ [MyModelsTypeEnum.collection]: {
+ list: myCollectionModels.filter((item) =>
+ new RegExp(searchText, 'ig').test(item.name + item.systemPrompt)
+ ),
+ emptyText: '收藏的 AI 应用为空~\n快去市场找一个吧'
+ }
+ };
+ return map[currentTab];
+ }, [currentTab, myCollectionModels, myModels, searchText]);
return (
{
/>
-
- {models.map((item) => (
-
-
- {item.label}
-
- {item.list.map((item) => (
- {
- if (item._id === modelId) return;
- router.push(`/model?modelId=${item._id}`);
- }}
+
+
+ item.value === currentTab)}
+ onChange={(i) => setCurrentTab(tabs.current[i].value)}
+ >
+
+ {tabs.current.map((item) => (
+
-
-
-
- {item.name}
-
-
- {item.systemPrompt || '这个 应用 没有设置提示词~'}
-
-
-
+ {item.label}
+
))}
-
+
+
+
+
+ {currentModels.list.map((item) => (
+ {
+ if (item._id === modelId) return;
+ router.push(`/model?modelId=${item._id}`);
+ }}
+ >
+
+
+
+ {item.name}
+
+
+ {item.systemPrompt || '这个 应用 没有设置提示词~'}
+
+
+
))}
-
- {!isFetching && totalModels === 0 && (
+ {!isFetching && currentModels.list.length === 0 && (
- 还没有 AI 应用~
+ {currentModels.emptyText}
)}
diff --git a/client/src/styles/reset.scss b/client/src/styles/reset.scss
index 8de5ad988..13864a54d 100644
--- a/client/src/styles/reset.scss
+++ b/client/src/styles/reset.scss
@@ -44,7 +44,7 @@ svg {
div {
&::-webkit-scrollbar-thumb {
background: transparent !important;
- transition: 1s;
+ transition: background 1s;
}
&:hover {
&::-webkit-scrollbar-thumb {
diff --git a/package.json b/package.json
index 8df2a2fd9..63f578a58 100644
--- a/package.json
+++ b/package.json
@@ -6,14 +6,13 @@
"prepare": "husky install",
"format": "prettier --config \"./.prettierrc.js\" --write \"./**/src/**/*.{ts,tsx,scss}\""
},
- "dependencies": {},
"devDependencies": {
"husky": "^8.0.3",
"lint-staged": "^13.2.1",
"prettier": "^2.8.7"
},
"lint-staged": {
- "./**/*.{ts,tsx,scss}": "npm run format"
+ "./**/**/*.{ts,tsx,scss}": "npm run format"
},
"engines": {
"node": ">=18.0.0"