new framwork
@@ -1,35 +0,0 @@
|
|||||||
# 运行端口,如果不是 3000 口运行,需要改成其他的。注意:不是改了这个变量就会变成其他端口,而是因为改成其他端口,才用这个变量。
|
|
||||||
PORT=3000
|
|
||||||
# 代理
|
|
||||||
# AXIOS_PROXY_HOST=127.0.0.1
|
|
||||||
# AXIOS_PROXY_PORT=7890
|
|
||||||
# email
|
|
||||||
MY_MAIL=xxx@qq.com
|
|
||||||
MAILE_CODE=xxx
|
|
||||||
# ali ems
|
|
||||||
aliAccessKeyId=xxx
|
|
||||||
aliAccessKeySecret=xxx
|
|
||||||
aliSignName=xxx
|
|
||||||
aliTemplateCode=SMS_xxx
|
|
||||||
# token
|
|
||||||
TOKEN_KEY=xxx
|
|
||||||
# root key, 最高权限
|
|
||||||
ROOT_KEY=xxx
|
|
||||||
# 是否进行安全校验(1: 开启,0: 关闭)
|
|
||||||
SENSITIVE_CHECK=1
|
|
||||||
# openai
|
|
||||||
# OPENAI_BASE_URL=https://api.openai.com/v1
|
|
||||||
# OPENAI_BASE_URL_AUTH=可选的安全凭证(不需要的时候,记得去掉)
|
|
||||||
OPENAIKEY=sk-xxx # 对话用的key
|
|
||||||
OPENAI_TRAINING_KEY=sk-xxx # 训练用的key
|
|
||||||
GPT4KEY=sk-xxx
|
|
||||||
# claude
|
|
||||||
CLAUDE_BASE_URL=calude模型请求地址
|
|
||||||
CLAUDE_KEY=CLAUDE_KEY
|
|
||||||
# db
|
|
||||||
MONGODB_URI=mongodb://username:password@0.0.0.0:27017/test?authSource=admin
|
|
||||||
PG_HOST=0.0.0.0
|
|
||||||
PG_PORT=8100
|
|
||||||
PG_USER=xxx
|
|
||||||
PG_PASSWORD=xxx
|
|
||||||
PG_DB_NAME=xxx
|
|
20
.gitignore
vendored
@@ -1,19 +1,10 @@
|
|||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
node_modules/
|
||||||
/.pnp
|
|
||||||
.pnp.js
|
|
||||||
|
|
||||||
# testing
|
|
||||||
/coverage
|
|
||||||
|
|
||||||
# next.js
|
# next.js
|
||||||
/.next/
|
.next/
|
||||||
/out/
|
out/
|
||||||
|
|
||||||
# production
|
# production
|
||||||
/build
|
build/
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
@@ -34,6 +25,7 @@ yarn-error.log*
|
|||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
/.vscode/
|
|
||||||
platform.json
|
platform.json
|
||||||
testApi/
|
testApi/
|
||||||
|
local/
|
||||||
|
.husky/
|
@@ -1,6 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
. "$(dirname -- "$0")/_/husky.sh"
|
|
||||||
|
|
||||||
if command -v npx >/dev/null 2>&1; then
|
|
||||||
npx lint-staged
|
|
||||||
fi
|
|
7
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"editor.formatOnSave": true, //每次保存自动格式化
|
||||||
|
"editor.mouseWheelZoom": true,
|
||||||
|
"typescript.tsdk": "./client/node_modules/typescript/lib",
|
||||||
|
"prettier.prettierPath": "./node_modules/prettier"
|
||||||
|
|
||||||
|
}
|
47
Makefile
@@ -1,47 +0,0 @@
|
|||||||
SERVICE_NAME=fastgpt
|
|
||||||
# Image URL to use all building/pushing image targets
|
|
||||||
IMG ?= $(SERVICE_NAME):latest
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all: build
|
|
||||||
|
|
||||||
##@ General
|
|
||||||
|
|
||||||
# The help target prints out all targets with their descriptions organized
|
|
||||||
# beneath their categories. The categories are represented by '##@' and the
|
|
||||||
# target descriptions by '##'. The awk commands is responsible for reading the
|
|
||||||
# entire set of makefiles included in this invocation, looking for lines of the
|
|
||||||
# file as xyz: ## something, and then pretty-format the target and help. Then,
|
|
||||||
# if there's a line with ##@ something, that gets pretty-printed as a category.
|
|
||||||
# More info on the usage of ANSI control characters for terminal formatting:
|
|
||||||
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
|
|
||||||
# More info on the awk command:
|
|
||||||
# http://linuxcommand.org/lc3_adv_awk.php
|
|
||||||
|
|
||||||
.PHONY: help
|
|
||||||
help: ## Display this help.
|
|
||||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
|
||||||
|
|
||||||
##@ Build
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build: ## Build desktop-frontend binary.
|
|
||||||
pnpm run build
|
|
||||||
|
|
||||||
.PHONY: run
|
|
||||||
run: ## Run a dev service from host.
|
|
||||||
pnpm run start
|
|
||||||
|
|
||||||
.PHONY: docker-build
|
|
||||||
docker-build: ## Build docker image with the desktop-frontend.
|
|
||||||
docker build -t registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:latest . --network host --build-arg HTTP_PROXY=http://127.0.0.1:7890 --build-arg HTTPS_PROXY=http://127.0.0.1:7890
|
|
||||||
|
|
||||||
##@ Deployment
|
|
||||||
|
|
||||||
.PHONY: docker-run
|
|
||||||
docker-run: ## Push docker image.
|
|
||||||
docker run -d -p 8008:3000 --name fastgpt -v /web_project/yjl/fastgpt/logs:/app/.next/logs registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:latest
|
|
||||||
|
|
||||||
#TODO: add support of docker push
|
|
||||||
|
|
||||||
#TODO: add support of sealos apply
|
|
31
client/.gitignore
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
# next.js
|
||||||
|
.next/
|
||||||
|
out/
|
||||||
|
# production
|
||||||
|
build/
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
platform.json
|
||||||
|
testApi/
|
||||||
|
local/
|
||||||
|
.husky/
|
82
client/package.json
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"name": "fastgpt",
|
||||||
|
"version": "3.7",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "next lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@alicloud/dysmsapi20170525": "^2.0.23",
|
||||||
|
"@alicloud/openapi-client": "^0.4.5",
|
||||||
|
"@alicloud/tea-util": "^1.4.5",
|
||||||
|
"@chakra-ui/icons": "^2.0.17",
|
||||||
|
"@chakra-ui/react": "^2.5.1",
|
||||||
|
"@chakra-ui/system": "^2.5.5",
|
||||||
|
"@dqbd/tiktoken": "^1.0.6",
|
||||||
|
"@emotion/react": "^11.10.6",
|
||||||
|
"@emotion/styled": "^11.10.6",
|
||||||
|
"@next/font": "13.1.6",
|
||||||
|
"@tanstack/react-query": "^4.24.10",
|
||||||
|
"@types/nprogress": "^0.2.0",
|
||||||
|
"axios": "^1.3.3",
|
||||||
|
"cookie": "^0.5.0",
|
||||||
|
"crypto": "^1.0.1",
|
||||||
|
"dayjs": "^1.11.7",
|
||||||
|
"eventsource-parser": "^0.1.0",
|
||||||
|
"formidable": "^2.1.1",
|
||||||
|
"framer-motion": "^9.0.6",
|
||||||
|
"graphemer": "^1.4.0",
|
||||||
|
"hyperdown": "^2.4.29",
|
||||||
|
"immer": "^9.0.19",
|
||||||
|
"jsonwebtoken": "^9.0.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"mammoth": "^1.5.1",
|
||||||
|
"mongoose": "^6.10.0",
|
||||||
|
"nanoid": "^4.0.1",
|
||||||
|
"next": "13.1.6",
|
||||||
|
"nextjs-cors": "^2.1.2",
|
||||||
|
"nodemailer": "^6.9.1",
|
||||||
|
"nprogress": "^0.2.0",
|
||||||
|
"openai": "^3.2.1",
|
||||||
|
"papaparse": "^5.4.1",
|
||||||
|
"pg": "^8.10.0",
|
||||||
|
"react": "18.2.0",
|
||||||
|
"react-dom": "18.2.0",
|
||||||
|
"react-hook-form": "^7.43.1",
|
||||||
|
"react-markdown": "^8.0.5",
|
||||||
|
"react-syntax-highlighter": "^15.5.0",
|
||||||
|
"rehype-katex": "^6.0.2",
|
||||||
|
"remark-gfm": "^3.0.1",
|
||||||
|
"remark-math": "^5.1.1",
|
||||||
|
"request-ip": "^3.3.0",
|
||||||
|
"sass": "^1.58.3",
|
||||||
|
"tunnel": "^0.0.6",
|
||||||
|
"wxpay-v3": "^3.0.2",
|
||||||
|
"zustand": "^4.3.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@svgr/webpack": "^6.5.1",
|
||||||
|
"@types/cookie": "^0.5.1",
|
||||||
|
"@types/formidable": "^2.0.5",
|
||||||
|
"@types/jsonwebtoken": "^9.0.1",
|
||||||
|
"@types/lodash": "^4.14.191",
|
||||||
|
"@types/node": "18.14.0",
|
||||||
|
"@types/nodemailer": "^6.4.7",
|
||||||
|
"@types/papaparse": "^5.3.7",
|
||||||
|
"@types/pg": "^8.6.6",
|
||||||
|
"@types/react": "18.0.28",
|
||||||
|
"@types/react-dom": "18.0.11",
|
||||||
|
"@types/react-syntax-highlighter": "^15.5.6",
|
||||||
|
"@types/request-ip": "^0.0.37",
|
||||||
|
"@types/tunnel": "^0.0.3",
|
||||||
|
"eslint": "8.34.0",
|
||||||
|
"eslint-config-next": "13.1.6",
|
||||||
|
"typescript": "4.9.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
}
|
11742
client/pnpm-lock.yaml
generated
Normal file
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 201 KiB After Width: | Height: | Size: 201 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
67
client/src/api/fetch.ts
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import { GUIDE_PROMPT_HEADER, NEW_CHATID_HEADER, QUOTE_LEN_HEADER } from '@/constants/chat';
|
||||||
|
|
||||||
|
interface StreamFetchProps {
|
||||||
|
url: string;
|
||||||
|
data: any;
|
||||||
|
onMessage: (text: string) => void;
|
||||||
|
abortSignal: AbortController;
|
||||||
|
}
|
||||||
|
export const streamFetch = ({ url, data, onMessage, abortSignal }: StreamFetchProps) =>
|
||||||
|
new Promise<{
|
||||||
|
responseText: string;
|
||||||
|
newChatId: string;
|
||||||
|
systemPrompt: string;
|
||||||
|
quoteLen: number;
|
||||||
|
}>(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const res = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
signal: abortSignal.signal
|
||||||
|
});
|
||||||
|
const reader = res.body?.getReader();
|
||||||
|
if (!reader) return;
|
||||||
|
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
|
||||||
|
const newChatId = decodeURIComponent(res.headers.get(NEW_CHATID_HEADER) || '');
|
||||||
|
const systemPrompt = decodeURIComponent(res.headers.get(GUIDE_PROMPT_HEADER) || '').trim();
|
||||||
|
const quoteLen = res.headers.get(QUOTE_LEN_HEADER)
|
||||||
|
? Number(res.headers.get(QUOTE_LEN_HEADER))
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
let responseText = '';
|
||||||
|
|
||||||
|
const read = async () => {
|
||||||
|
try {
|
||||||
|
const { done, value } = await reader?.read();
|
||||||
|
if (done) {
|
||||||
|
if (res.status === 200) {
|
||||||
|
resolve({ responseText, newChatId, quoteLen, systemPrompt });
|
||||||
|
} else {
|
||||||
|
const parseError = JSON.parse(responseText);
|
||||||
|
reject(parseError?.message || '请求异常');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const text = decoder.decode(value);
|
||||||
|
responseText += text;
|
||||||
|
onMessage(text);
|
||||||
|
read();
|
||||||
|
} catch (err: any) {
|
||||||
|
if (err?.message === 'The user aborted a request.') {
|
||||||
|
return resolve({ responseText, newChatId, quoteLen, systemPrompt });
|
||||||
|
}
|
||||||
|
reject(typeof err === 'string' ? err : err?.message || '请求异常');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
read();
|
||||||
|
} catch (err: any) {
|
||||||
|
console.log(err, '====');
|
||||||
|
reject(typeof err === 'string' ? err : err?.message || '请求异常');
|
||||||
|
}
|
||||||
|
});
|
@@ -7,7 +7,12 @@ import {
|
|||||||
Response as PushDateResponse
|
Response as PushDateResponse
|
||||||
} from '@/pages/api/openapi/kb/pushData';
|
} from '@/pages/api/openapi/kb/pushData';
|
||||||
|
|
||||||
export type KbUpdateParams = { id: string; name: string; tags: string; avatar: string };
|
export type KbUpdateParams = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
tags: string;
|
||||||
|
avatar: string;
|
||||||
|
};
|
||||||
|
|
||||||
/* knowledge base */
|
/* knowledge base */
|
||||||
export const getKbList = () => GET<KbItemType[]>(`/plugins/kb/list`);
|
export const getKbList = () => GET<KbItemType[]>(`/plugins/kb/list`);
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 866 B After Width: | Height: | Size: 866 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 878 B After Width: | Height: | Size: 878 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 976 B After Width: | Height: | Size: 976 B |
Before Width: | Height: | Size: 810 B After Width: | Height: | Size: 810 B |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 1013 B After Width: | Height: | Size: 1013 B |
Before Width: | Height: | Size: 663 B After Width: | Height: | Size: 663 B |
Before Width: | Height: | Size: 694 B After Width: | Height: | Size: 694 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 823 B After Width: | Height: | Size: 823 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |