mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 13:03:50 +00:00
lock (#2063)
* lock * perf: init data * perf: vision model url * fix: chat index
This commit is contained in:
@@ -24,4 +24,6 @@ weight: 817
|
|||||||
2. 新增 - 应用搜索
|
2. 新增 - 应用搜索
|
||||||
3. 优化 - 对话框代码
|
3. 优化 - 对话框代码
|
||||||
4. 优化 - 升级 Dockerfile node 和 pnpm 版本
|
4. 优化 - 升级 Dockerfile node 和 pnpm 版本
|
||||||
5. 修复 - 简易模式无法变更全局变量
|
5. 优化 - local 域名部署,也可以正常使用 vision 模式
|
||||||
|
6. 修复 - 简易模式无法变更全局变量
|
||||||
|
7. 修复 - gpt4o 无法同时使用工具和图片
|
||||||
|
@@ -70,9 +70,3 @@ export type SystemEnvType = {
|
|||||||
oneapiUrl?: string;
|
oneapiUrl?: string;
|
||||||
chatApiKey?: string;
|
chatApiKey?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// declare global {
|
|
||||||
// var feConfigs: FastGPTFeConfigsType;
|
|
||||||
// var systemEnv: SystemEnvType;
|
|
||||||
// var systemInitd: boolean;
|
|
||||||
// }
|
|
||||||
|
@@ -56,7 +56,4 @@ export enum ChatStatusEnum {
|
|||||||
finish = 'finish'
|
finish = 'finish'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const IMG_BLOCK_KEY = 'img-block';
|
|
||||||
export const FILE_BLOCK_KEY = 'file-block';
|
|
||||||
|
|
||||||
export const MARKDOWN_QUOTE_SIGN = 'QUOTE SIGN';
|
export const MARKDOWN_QUOTE_SIGN = 'QUOTE SIGN';
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jschardet": "3.1.1",
|
"jschardet": "3.1.1",
|
||||||
"nanoid": "^4.0.1",
|
"nanoid": "^4.0.1",
|
||||||
"next": "14.2.3",
|
"next": "14.2.5",
|
||||||
"openai": "4.28.0",
|
"openai": "4.28.0",
|
||||||
"openapi-types": "^12.1.3",
|
"openapi-types": "^12.1.3",
|
||||||
"timezones-list": "^3.0.2"
|
"timezones-list": "^3.0.2"
|
||||||
|
@@ -63,6 +63,7 @@ const instance = axios.create({
|
|||||||
'Cache-Control': 'no-cache'
|
'Cache-Control': 'no-cache'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
export const serverRequestBaseUrl = `http://${SERVICE_LOCAL_HOST}`;
|
||||||
|
|
||||||
/* 请求拦截 */
|
/* 请求拦截 */
|
||||||
instance.interceptors.request.use(requestStart, (err) => Promise.reject(err));
|
instance.interceptors.request.use(requestStart, (err) => Promise.reject(err));
|
||||||
@@ -79,7 +80,7 @@ export function request(url: string, data: any, config: ConfigType, method: Meth
|
|||||||
|
|
||||||
return instance
|
return instance
|
||||||
.request({
|
.request({
|
||||||
baseURL: `http://${SERVICE_LOCAL_HOST}`,
|
baseURL: serverRequestBaseUrl,
|
||||||
url,
|
url,
|
||||||
method,
|
method,
|
||||||
data: ['POST', 'PUT'].includes(method) ? data : null,
|
data: ['POST', 'PUT'].includes(method) ? data : null,
|
||||||
|
@@ -64,10 +64,13 @@ export const getMongoModel = <T>(name: string, schema: mongoose.Schema) => {
|
|||||||
addCommonMiddleware(schema);
|
addCommonMiddleware(schema);
|
||||||
|
|
||||||
const model = connectionMongo.model<T>(name, schema);
|
const model = connectionMongo.model<T>(name, schema);
|
||||||
try {
|
|
||||||
model.syncIndexes();
|
if (process.env.SYNC_INDEX !== '0') {
|
||||||
} catch (error) {
|
try {
|
||||||
addLog.error('Create index error', error);
|
model.syncIndexes({ background: true });
|
||||||
|
} catch (error) {
|
||||||
|
addLog.error('Create index error', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { exit } from 'process';
|
||||||
import { addLog } from '../system/log';
|
import { addLog } from '../system/log';
|
||||||
import { connectionMongo } from './index';
|
import { connectionMongo } from './index';
|
||||||
import type { Mongoose } from 'mongoose';
|
import type { Mongoose } from 'mongoose';
|
||||||
@@ -56,9 +57,13 @@ export async function connectMongo({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
afterHook && (await afterHook());
|
if (!global.systemInited) {
|
||||||
|
global.systemInited = true;
|
||||||
|
afterHook && (await afterHook());
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addLog.error('mongo connect after hook error', error);
|
addLog.error('Mongo connect after hook error', error);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return connectionMongo;
|
return connectionMongo;
|
||||||
|
@@ -89,7 +89,7 @@ try {
|
|||||||
get chat logs;
|
get chat logs;
|
||||||
close custom feedback;
|
close custom feedback;
|
||||||
*/
|
*/
|
||||||
ChatItemSchema.index({ appId: 1, chatId: 1, dataId: 1 }, { background: true, unique: true });
|
ChatItemSchema.index({ appId: 1, chatId: 1, dataId: 1 }, { background: true });
|
||||||
// admin charts
|
// admin charts
|
||||||
ChatItemSchema.index({ time: -1, obj: 1 }, { background: true });
|
ChatItemSchema.index({ time: -1, obj: 1 }, { background: true });
|
||||||
// timer, clear history
|
// timer, clear history
|
||||||
|
@@ -85,7 +85,7 @@ try {
|
|||||||
// get user history
|
// get user history
|
||||||
ChatSchema.index({ tmbId: 1, appId: 1, top: -1, updateTime: -1 }, { background: true });
|
ChatSchema.index({ tmbId: 1, appId: 1, top: -1, updateTime: -1 }, { background: true });
|
||||||
// delete by appid; clear history; init chat; update chat; auth chat; get chat;
|
// delete by appid; clear history; init chat; update chat; auth chat; get chat;
|
||||||
ChatSchema.index({ appId: 1, chatId: 1 }, { background: true, unique: true });
|
ChatSchema.index({ appId: 1, chatId: 1 }, { background: true });
|
||||||
|
|
||||||
// get chat logs;
|
// get chat logs;
|
||||||
ChatSchema.index({ teamId: 1, appId: 1, updateTime: -1 }, { background: true });
|
ChatSchema.index({ teamId: 1, appId: 1, updateTime: -1 }, { background: true });
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
import { IMG_BLOCK_KEY } from '@fastgpt/global/core/chat/constants';
|
|
||||||
import { countGptMessagesTokens } from '../../common/string/tiktoken/index';
|
import { countGptMessagesTokens } from '../../common/string/tiktoken/index';
|
||||||
import type {
|
import type {
|
||||||
ChatCompletionContentPart,
|
ChatCompletionContentPart,
|
||||||
@@ -7,6 +6,8 @@ import type {
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/global/core/ai/constants';
|
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/global/core/ai/constants';
|
||||||
import { guessBase64ImageType } from '../../common/file/utils';
|
import { guessBase64ImageType } from '../../common/file/utils';
|
||||||
|
import { serverRequestBaseUrl } from '../../common/api/serverRequest';
|
||||||
|
import { cloneDeep } from 'lodash';
|
||||||
|
|
||||||
/* slice chat context by tokens */
|
/* slice chat context by tokens */
|
||||||
const filterEmptyMessages = (messages: ChatCompletionMessageParam[]) => {
|
const filterEmptyMessages = (messages: ChatCompletionMessageParam[]) => {
|
||||||
@@ -120,137 +121,64 @@ export const formatGPTMessagesInRequestBefore = (messages: ChatCompletionMessage
|
|||||||
.filter(Boolean) as ChatCompletionMessageParam[];
|
.filter(Boolean) as ChatCompletionMessageParam[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/* Load user chat content.
|
||||||
string to vision model. Follow the markdown code block rule for interception:
|
Img: to base 64
|
||||||
|
*/
|
||||||
@rule:
|
|
||||||
```img-block
|
|
||||||
{src:""}
|
|
||||||
{src:""}
|
|
||||||
```
|
|
||||||
```file-block
|
|
||||||
{name:"",src:""},
|
|
||||||
{name:"",src:""}
|
|
||||||
```
|
|
||||||
@example:
|
|
||||||
What’s in this image?
|
|
||||||
```img-block
|
|
||||||
{src:"https://1.png"}
|
|
||||||
```
|
|
||||||
@return
|
|
||||||
[
|
|
||||||
{ type: 'text', text: 'What’s in this image?' },
|
|
||||||
{
|
|
||||||
type: 'image_url',
|
|
||||||
image_url: {
|
|
||||||
url: 'https://1.png'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
*/
|
|
||||||
export async function formatStr2ChatContent(str: string) {
|
|
||||||
const content: ChatCompletionContentPart[] = [];
|
|
||||||
let lastIndex = 0;
|
|
||||||
const regex = new RegExp(`\`\`\`(${IMG_BLOCK_KEY})\\n([\\s\\S]*?)\`\`\``, 'g');
|
|
||||||
|
|
||||||
const imgKey: 'image_url' = 'image_url';
|
|
||||||
|
|
||||||
let match;
|
|
||||||
|
|
||||||
while ((match = regex.exec(str)) !== null) {
|
|
||||||
// add previous text
|
|
||||||
if (match.index > lastIndex) {
|
|
||||||
const text = str.substring(lastIndex, match.index).trim();
|
|
||||||
if (text) {
|
|
||||||
content.push({ type: 'text', text });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const blockType = match[1].trim();
|
|
||||||
|
|
||||||
if (blockType === IMG_BLOCK_KEY) {
|
|
||||||
const blockContentLines = match[2].trim().split('\n');
|
|
||||||
const jsonLines = blockContentLines.map((item) => {
|
|
||||||
try {
|
|
||||||
return JSON.parse(item) as { src: string };
|
|
||||||
} catch (error) {
|
|
||||||
return { src: '' };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const item of jsonLines) {
|
|
||||||
if (!item.src) throw new Error("image block's content error");
|
|
||||||
}
|
|
||||||
|
|
||||||
content.push(
|
|
||||||
...jsonLines.map((item) => ({
|
|
||||||
type: imgKey,
|
|
||||||
image_url: {
|
|
||||||
url: item.src
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastIndex = regex.lastIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add remaining text
|
|
||||||
if (lastIndex < str.length) {
|
|
||||||
const remainingText = str.substring(lastIndex).trim();
|
|
||||||
if (remainingText) {
|
|
||||||
content.push({ type: 'text', text: remainingText });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continuous text type content, if type=text, merge them
|
|
||||||
for (let i = 0; i < content.length - 1; i++) {
|
|
||||||
const currentContent = content[i];
|
|
||||||
const nextContent = content[i + 1];
|
|
||||||
if (currentContent.type === 'text' && nextContent.type === 'text') {
|
|
||||||
currentContent.text += nextContent.text;
|
|
||||||
content.splice(i + 1, 1);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content.length === 1 && content[0].type === 'text') {
|
|
||||||
return content[0].text;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!content) return null;
|
|
||||||
// load img to base64
|
|
||||||
for await (const item of content) {
|
|
||||||
if (item.type === imgKey && item[imgKey]?.url) {
|
|
||||||
const response = await axios.get(item[imgKey].url, {
|
|
||||||
responseType: 'arraybuffer'
|
|
||||||
});
|
|
||||||
const base64 = Buffer.from(response.data).toString('base64');
|
|
||||||
item[imgKey].url = `data:${response.headers['content-type']};base64,${base64}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return content ? content : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const loadChatImgToBase64 = async (content: string | ChatCompletionContentPart[]) => {
|
export const loadChatImgToBase64 = async (content: string | ChatCompletionContentPart[]) => {
|
||||||
if (typeof content === 'string') {
|
if (typeof content === 'string') {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
content.map(async (item) => {
|
content.map(async (item) => {
|
||||||
if (item.type === 'text') return item;
|
if (item.type === 'text') return item;
|
||||||
// load image
|
|
||||||
const response = await axios.get(item.image_url.url, {
|
if (!item.image_url.url) return item;
|
||||||
responseType: 'arraybuffer'
|
|
||||||
});
|
/*
|
||||||
const base64 = Buffer.from(response.data).toString('base64');
|
1. From db: Get it from db
|
||||||
let imageType = response.headers['content-type'];
|
2. From web: Not update
|
||||||
if (imageType === undefined) {
|
*/
|
||||||
imageType = guessBase64ImageType(base64);
|
if (item.image_url.url.startsWith('/')) {
|
||||||
|
const response = await axios.get(item.image_url.url, {
|
||||||
|
baseURL: serverRequestBaseUrl,
|
||||||
|
responseType: 'arraybuffer'
|
||||||
|
});
|
||||||
|
const base64 = Buffer.from(response.data).toString('base64');
|
||||||
|
let imageType = response.headers['content-type'];
|
||||||
|
if (imageType === undefined) {
|
||||||
|
imageType = guessBase64ImageType(base64);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
image_url: {
|
||||||
|
...item.image_url,
|
||||||
|
url: `data:${imageType};base64,${base64}`
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
item.image_url.url = `data:${imageType};base64,${base64}`;
|
|
||||||
return item;
|
return item;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
export const loadRequestMessages = async (messages: ChatCompletionMessageParam[]) => {
|
||||||
|
if (messages.length === 0) {
|
||||||
|
return Promise.reject('core.chat.error.Messages empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadMessages = await Promise.all(
|
||||||
|
messages.map(async (item) => {
|
||||||
|
if (item.role === ChatCompletionRequestMessageRoleEnum.User) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
content: await loadChatImgToBase64(item.content)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return loadMessages;
|
||||||
|
};
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||||
import { getAIApi } from '../../../../ai/config';
|
import { getAIApi } from '../../../../ai/config';
|
||||||
import { filterGPTMessageByMaxTokens } from '../../../../chat/utils';
|
import { filterGPTMessageByMaxTokens, loadRequestMessages } from '../../../../chat/utils';
|
||||||
import {
|
import {
|
||||||
ChatCompletion,
|
ChatCompletion,
|
||||||
StreamChatType,
|
StreamChatType,
|
||||||
@@ -88,6 +88,7 @@ export const runToolWithFunctionCall = async (
|
|||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
|
const requestMessages = await loadRequestMessages(formativeMessages);
|
||||||
|
|
||||||
/* Run llm */
|
/* Run llm */
|
||||||
const ai = getAIApi({
|
const ai = getAIApi({
|
||||||
@@ -99,7 +100,7 @@ export const runToolWithFunctionCall = async (
|
|||||||
model: toolModel.model,
|
model: toolModel.model,
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
stream,
|
stream,
|
||||||
messages: formativeMessages,
|
messages: requestMessages,
|
||||||
functions,
|
functions,
|
||||||
function_call: 'auto'
|
function_call: 'auto'
|
||||||
},
|
},
|
||||||
|
@@ -12,6 +12,7 @@ import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
|||||||
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||||
import {
|
import {
|
||||||
GPTMessages2Chats,
|
GPTMessages2Chats,
|
||||||
|
chatValue2RuntimePrompt,
|
||||||
chats2GPTMessages,
|
chats2GPTMessages,
|
||||||
getSystemPrompt,
|
getSystemPrompt,
|
||||||
runtimePrompt2ChatsValue
|
runtimePrompt2ChatsValue
|
||||||
@@ -29,10 +30,11 @@ type Response = DispatchNodeResultType<{
|
|||||||
|
|
||||||
export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<Response> => {
|
export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<Response> => {
|
||||||
const {
|
const {
|
||||||
node: { nodeId, name, outputs },
|
node: { nodeId, name },
|
||||||
runtimeNodes,
|
runtimeNodes,
|
||||||
runtimeEdges,
|
runtimeEdges,
|
||||||
histories,
|
histories,
|
||||||
|
query,
|
||||||
params: { model, systemPrompt, userChatInput, history = 6 }
|
params: { model, systemPrompt, userChatInput, history = 6 }
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
@@ -65,7 +67,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
|||||||
obj: ChatRoleEnum.Human,
|
obj: ChatRoleEnum.Human,
|
||||||
value: runtimePrompt2ChatsValue({
|
value: runtimePrompt2ChatsValue({
|
||||||
text: userChatInput,
|
text: userChatInput,
|
||||||
files: []
|
files: chatValue2RuntimePrompt(query).files
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||||
import { getAIApi } from '../../../../ai/config';
|
import { getAIApi } from '../../../../ai/config';
|
||||||
import { filterGPTMessageByMaxTokens } from '../../../../chat/utils';
|
import { filterGPTMessageByMaxTokens, loadRequestMessages } from '../../../../chat/utils';
|
||||||
import {
|
import {
|
||||||
ChatCompletion,
|
ChatCompletion,
|
||||||
StreamChatType,
|
StreamChatType,
|
||||||
@@ -87,6 +87,8 @@ export const runToolWithPromptCall = async (
|
|||||||
messages,
|
messages,
|
||||||
maxTokens: toolModel.maxContext - 500 // filter token. not response maxToken
|
maxTokens: toolModel.maxContext - 500 // filter token. not response maxToken
|
||||||
});
|
});
|
||||||
|
const requestMessages = await loadRequestMessages(filterMessages);
|
||||||
|
|
||||||
// console.log(JSON.stringify(filterMessages, null, 2));
|
// console.log(JSON.stringify(filterMessages, null, 2));
|
||||||
/* Run llm */
|
/* Run llm */
|
||||||
const ai = getAIApi({
|
const ai = getAIApi({
|
||||||
@@ -98,7 +100,7 @@ export const runToolWithPromptCall = async (
|
|||||||
model: toolModel.model,
|
model: toolModel.model,
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
stream,
|
stream,
|
||||||
messages: filterMessages
|
messages: requestMessages
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||||
import { getAIApi } from '../../../../ai/config';
|
import { getAIApi } from '../../../../ai/config';
|
||||||
import { filterGPTMessageByMaxTokens } from '../../../../chat/utils';
|
import { filterGPTMessageByMaxTokens, loadRequestMessages } from '../../../../chat/utils';
|
||||||
import {
|
import {
|
||||||
ChatCompletion,
|
ChatCompletion,
|
||||||
ChatCompletionMessageToolCall,
|
ChatCompletionMessageToolCall,
|
||||||
@@ -99,6 +99,8 @@ export const runToolWithToolChoice = async (
|
|||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
|
const requestMessages = await loadRequestMessages(formativeMessages);
|
||||||
|
|
||||||
// console.log(
|
// console.log(
|
||||||
// JSON.stringify(
|
// JSON.stringify(
|
||||||
// {
|
// {
|
||||||
@@ -106,7 +108,7 @@ export const runToolWithToolChoice = async (
|
|||||||
// model: toolModel.model,
|
// model: toolModel.model,
|
||||||
// temperature: 0,
|
// temperature: 0,
|
||||||
// stream,
|
// stream,
|
||||||
// messages: formativeMessages,
|
// messages: requestMessages,
|
||||||
// tools,
|
// tools,
|
||||||
// tool_choice: 'auto'
|
// tool_choice: 'auto'
|
||||||
// },
|
// },
|
||||||
@@ -124,7 +126,7 @@ export const runToolWithToolChoice = async (
|
|||||||
model: toolModel.model,
|
model: toolModel.model,
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
stream,
|
stream,
|
||||||
messages: formativeMessages,
|
messages: requestMessages,
|
||||||
tools,
|
tools,
|
||||||
tool_choice: 'auto'
|
tool_choice: 'auto'
|
||||||
},
|
},
|
||||||
|
@@ -2,7 +2,7 @@ import type { NextApiResponse } from 'next';
|
|||||||
import {
|
import {
|
||||||
filterGPTMessageByMaxTokens,
|
filterGPTMessageByMaxTokens,
|
||||||
formatGPTMessagesInRequestBefore,
|
formatGPTMessagesInRequestBefore,
|
||||||
loadChatImgToBase64
|
loadRequestMessages
|
||||||
} from '../../../chat/utils';
|
} from '../../../chat/utils';
|
||||||
import type { ChatItemType, UserChatItemValueItemType } from '@fastgpt/global/core/chat/type.d';
|
import type { ChatItemType, UserChatItemValueItemType } from '@fastgpt/global/core/chat/type.d';
|
||||||
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||||
@@ -151,22 +151,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
|||||||
...formatGPTMessagesInRequestBefore(filterMessages)
|
...formatGPTMessagesInRequestBefore(filterMessages)
|
||||||
] as ChatCompletionMessageParam[];
|
] as ChatCompletionMessageParam[];
|
||||||
|
|
||||||
if (concatMessages.length === 0) {
|
const requestMessages = await loadRequestMessages(concatMessages);
|
||||||
return Promise.reject('core.chat.error.Messages empty');
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadMessages = await Promise.all(
|
|
||||||
concatMessages.map(async (item) => {
|
|
||||||
if (item.role === ChatCompletionRequestMessageRoleEnum.User) {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
content: await loadChatImgToBase64(item.content)
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const requestBody = {
|
const requestBody = {
|
||||||
...modelConstantsData?.defaultConfig,
|
...modelConstantsData?.defaultConfig,
|
||||||
@@ -174,7 +159,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
|||||||
temperature,
|
temperature,
|
||||||
max_tokens,
|
max_tokens,
|
||||||
stream,
|
stream,
|
||||||
messages: loadMessages
|
messages: requestMessages
|
||||||
};
|
};
|
||||||
const response = await ai.chat.completions.create(requestBody, {
|
const response = await ai.chat.completions.create(requestBody, {
|
||||||
headers: {
|
headers: {
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
"mammoth": "^1.6.0",
|
"mammoth": "^1.6.0",
|
||||||
"mongoose": "^7.0.2",
|
"mongoose": "^7.0.2",
|
||||||
"multer": "1.4.5-lts.1",
|
"multer": "1.4.5-lts.1",
|
||||||
"next": "14.2.3",
|
"next": "14.2.5",
|
||||||
"nextjs-cors": "^2.2.0",
|
"nextjs-cors": "^2.2.0",
|
||||||
"node-cron": "^3.0.3",
|
"node-cron": "^3.0.3",
|
||||||
"node-xlsx": "^0.23.0",
|
"node-xlsx": "^0.23.0",
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import MyPopover from './index';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import MyIcon from '../Icon';
|
import MyIcon from '../Icon';
|
||||||
import { useRequest2 } from '../../../hooks/useRequest';
|
import { useRequest2 } from '../../../hooks/useRequest';
|
||||||
|
1163
pnpm-lock.yaml
generated
1163
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@
|
|||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mermaid": "^10.2.3",
|
"mermaid": "^10.2.3",
|
||||||
"nanoid": "^4.0.1",
|
"nanoid": "^4.0.1",
|
||||||
"next": "14.2.3",
|
"next": "14.2.5",
|
||||||
"json5": "^2.2.3",
|
"json5": "^2.2.3",
|
||||||
"nextjs-node-loader": "^1.1.5",
|
"nextjs-node-loader": "^1.1.5",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
"@types/js-yaml": "^4.0.9",
|
"@types/js-yaml": "^4.0.9",
|
||||||
"@types/jsonwebtoken": "^9.0.3",
|
"@types/jsonwebtoken": "^9.0.3",
|
||||||
"@types/lodash": "^4.14.191",
|
"@types/lodash": "^4.14.191",
|
||||||
"@types/node": "20.14.0",
|
"@types/node": "^20.14.2",
|
||||||
"@types/react": "18.3.1",
|
"@types/react": "18.3.1",
|
||||||
"@types/react-dom": "18.3.0",
|
"@types/react-dom": "18.3.0",
|
||||||
"@types/react-syntax-highlighter": "^15.5.6",
|
"@types/react-syntax-highlighter": "^15.5.6",
|
||||||
|
@@ -86,7 +86,7 @@ const ChatInput = ({
|
|||||||
});
|
});
|
||||||
updateFile(fileIndex, {
|
updateFile(fileIndex, {
|
||||||
...file,
|
...file,
|
||||||
url: `${location.origin}${url}`
|
url
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
removeFile(fileIndex);
|
removeFile(fileIndex);
|
||||||
|
@@ -6,16 +6,15 @@ import type { InitDateResponse } from '@/global/common/api/systemRes';
|
|||||||
import type { FastGPTConfigFileType } from '@fastgpt/global/common/system/types/index.d';
|
import type { FastGPTConfigFileType } from '@fastgpt/global/common/system/types/index.d';
|
||||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||||
import { getFastGPTConfigFromDB } from '@fastgpt/service/common/system/config/controller';
|
import { getFastGPTConfigFromDB } from '@fastgpt/service/common/system/config/controller';
|
||||||
import { connectToDatabase } from '@/service/mongo';
|
|
||||||
import { PluginTemplateType } from '@fastgpt/global/core/plugin/type';
|
import { PluginTemplateType } from '@fastgpt/global/core/plugin/type';
|
||||||
import { readConfigData } from '@/service/common/system';
|
import { readConfigData } from '@/service/common/system';
|
||||||
import { exit } from 'process';
|
|
||||||
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
|
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
|
||||||
import { initFastGPTConfig } from '@fastgpt/service/common/system/tools';
|
import { initFastGPTConfig } from '@fastgpt/service/common/system/tools';
|
||||||
import json5 from 'json5';
|
import json5 from 'json5';
|
||||||
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
|
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
|
||||||
|
import { connectToDatabase } from '@/service/mongo';
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
await getInitConfig();
|
await getInitConfig();
|
||||||
|
|
||||||
jsonRes<InitDateResponse>(res, {
|
jsonRes<InitDateResponse>(res, {
|
||||||
@@ -37,6 +36,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default handler;
|
||||||
|
|
||||||
const defaultFeConfigs: FastGPTFeConfigsType = {
|
const defaultFeConfigs: FastGPTFeConfigsType = {
|
||||||
show_emptyChat: true,
|
show_emptyChat: true,
|
||||||
show_git: true,
|
show_git: true,
|
||||||
@@ -55,29 +56,18 @@ const defaultFeConfigs: FastGPTFeConfigsType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export async function getInitConfig() {
|
export async function getInitConfig() {
|
||||||
if (global.systemInitd) return;
|
// First request
|
||||||
global.systemInitd = true;
|
if (!global.systemInited) {
|
||||||
|
|
||||||
try {
|
|
||||||
await connectToDatabase();
|
await connectToDatabase();
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
initSystemConfig(),
|
|
||||||
// getSimpleModeTemplates(),
|
|
||||||
getSystemVersion(),
|
|
||||||
getSystemPlugin(),
|
|
||||||
|
|
||||||
// abandon
|
|
||||||
getSystemPluginV1()
|
|
||||||
]);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Load init config error', error);
|
|
||||||
global.systemInitd = false;
|
|
||||||
|
|
||||||
if (!global.feConfigs) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return Promise.all([
|
||||||
|
initSystemConfig(),
|
||||||
|
getSystemVersion(),
|
||||||
|
getSystemPlugin(),
|
||||||
|
|
||||||
|
// abandon
|
||||||
|
getSystemPluginV1()
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function initSystemConfig() {
|
export async function initSystemConfig() {
|
||||||
|
@@ -33,8 +33,6 @@ async function handler(req: NextApiRequest) {
|
|||||||
await authDataset({ req, authToken: true, datasetId: id, per: WritePermissionVal });
|
await authDataset({ req, authToken: true, datasetId: id, per: WritePermissionVal });
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('update dataset', req.body);
|
|
||||||
|
|
||||||
await MongoDataset.findOneAndUpdate(
|
await MongoDataset.findOneAndUpdate(
|
||||||
{
|
{
|
||||||
_id: id
|
_id: id
|
||||||
|
@@ -1,114 +0,0 @@
|
|||||||
import { SERVICE_LOCAL_HOST } from '@fastgpt/service/common/system/tools';
|
|
||||||
import axios, { Method, InternalAxiosRequestConfig, AxiosResponse } from 'axios';
|
|
||||||
|
|
||||||
interface ConfigType {
|
|
||||||
headers?: { [key: string]: string };
|
|
||||||
hold?: boolean;
|
|
||||||
timeout?: number;
|
|
||||||
}
|
|
||||||
interface ResponseDataType {
|
|
||||||
code: number;
|
|
||||||
message: string;
|
|
||||||
data: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 请求开始
|
|
||||||
*/
|
|
||||||
function requestStart(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 请求成功,检查请求头
|
|
||||||
*/
|
|
||||||
function responseSuccess(response: AxiosResponse<ResponseDataType>) {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 响应数据检查
|
|
||||||
*/
|
|
||||||
function checkRes(data: ResponseDataType) {
|
|
||||||
if (data === undefined) {
|
|
||||||
console.log('error->', data, 'data is empty');
|
|
||||||
return Promise.reject('服务器异常');
|
|
||||||
} else if (data?.code && (data.code < 200 || data.code >= 400)) {
|
|
||||||
return Promise.reject(data);
|
|
||||||
}
|
|
||||||
return data.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 响应错误
|
|
||||||
*/
|
|
||||||
function responseError(err: any) {
|
|
||||||
if (!err) {
|
|
||||||
return Promise.reject({ message: '未知错误' });
|
|
||||||
}
|
|
||||||
if (typeof err === 'string') {
|
|
||||||
return Promise.reject({ message: err });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err?.response?.data) {
|
|
||||||
return Promise.reject(err?.response?.data);
|
|
||||||
}
|
|
||||||
return Promise.reject(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 创建请求实例 */
|
|
||||||
const instance = axios.create({
|
|
||||||
timeout: 60000, // 超时时间
|
|
||||||
headers: {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
'Cache-Control': 'no-cache'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/* 请求拦截 */
|
|
||||||
instance.interceptors.request.use(requestStart, (err) => Promise.reject(err));
|
|
||||||
/* 响应拦截 */
|
|
||||||
instance.interceptors.response.use(responseSuccess, (err) => Promise.reject(err));
|
|
||||||
|
|
||||||
export function request(url: string, data: any, config: ConfigType, method: Method): any {
|
|
||||||
/* 去空 */
|
|
||||||
for (const key in data) {
|
|
||||||
if (data[key] === null || data[key] === undefined) {
|
|
||||||
delete data[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance
|
|
||||||
.request({
|
|
||||||
baseURL: `http://${SERVICE_LOCAL_HOST}`,
|
|
||||||
url,
|
|
||||||
method,
|
|
||||||
data: ['POST', 'PUT'].includes(method) ? data : null,
|
|
||||||
params: !['POST', 'PUT'].includes(method) ? data : null,
|
|
||||||
...config // custom config
|
|
||||||
})
|
|
||||||
.then((res) => checkRes(res.data))
|
|
||||||
.catch((err) => responseError(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* api请求方式
|
|
||||||
* @param {String} url
|
|
||||||
* @param {Any} params
|
|
||||||
* @param {Object} config
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function GET<T = undefined>(url: string, params = {}, config: ConfigType = {}): Promise<T> {
|
|
||||||
return request(url, params, config, 'GET');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function POST<T = undefined>(url: string, data = {}, config: ConfigType = {}): Promise<T> {
|
|
||||||
return request(url, data, config, 'POST');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function PUT<T = undefined>(url: string, data = {}, config: ConfigType = {}): Promise<T> {
|
|
||||||
return request(url, data, config, 'PUT');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function DELETE<T = undefined>(url: string, data = {}, config: ConfigType = {}): Promise<T> {
|
|
||||||
return request(url, data, config, 'DELETE');
|
|
||||||
}
|
|
@@ -22,10 +22,6 @@ export function connectToDatabase() {
|
|||||||
initGlobal();
|
initGlobal();
|
||||||
},
|
},
|
||||||
afterHook: async () => {
|
afterHook: async () => {
|
||||||
if (global.systemInitd) return;
|
|
||||||
|
|
||||||
global.systemInitd = true;
|
|
||||||
|
|
||||||
systemStartCb();
|
systemStartCb();
|
||||||
|
|
||||||
//init system config;init vector database;init root user
|
//init system config;init vector database;init root user
|
||||||
|
2
projects/app/src/types/index.d.ts
vendored
2
projects/app/src/types/index.d.ts
vendored
@@ -20,8 +20,6 @@ export type PagingData<T> = {
|
|||||||
export type RequestPaging = { pageNum: number; pageSize: number; [key]: any };
|
export type RequestPaging = { pageNum: number; pageSize: number; [key]: any };
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
var systemInitd: boolean;
|
|
||||||
|
|
||||||
var qaQueueLen: number;
|
var qaQueueLen: number;
|
||||||
var vectorQueueLen: number;
|
var vectorQueueLen: number;
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
"@nestjs/schematics": "^10.0.0",
|
"@nestjs/schematics": "^10.0.0",
|
||||||
"@nestjs/testing": "^10.0.0",
|
"@nestjs/testing": "^10.0.0",
|
||||||
"@types/jest": "^29.5.2",
|
"@types/jest": "^29.5.2",
|
||||||
"@types/node": "20.14.0",
|
"@types/node": "^20.14.2",
|
||||||
"@types/supertest": "^6.0.0",
|
"@types/supertest": "^6.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||||
"@typescript-eslint/parser": "^6.0.0",
|
"@typescript-eslint/parser": "^6.0.0",
|
||||||
|
Reference in New Issue
Block a user