mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-16 08:01:18 +00:00
feat: pg vector 0.8.0;perf: app pdf enhance parse (#3962)
* perf: app pdf enhance parse * feat: pg vector 0.8.0 * update schema default * model sort and default image * perf: i18n * perf: ui tip
This commit is contained in:
@@ -7,8 +7,8 @@ version: '3.3'
|
|||||||
services:
|
services:
|
||||||
# db
|
# db
|
||||||
pg:
|
pg:
|
||||||
image: pgvector/pgvector:0.7.0-pg15 # docker hub
|
image: pgvector/pgvector:0.8.0-pg15 # docker hub
|
||||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/pgvector:v0.7.0 # 阿里云
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/pgvector:v0.8.0-pg15 # 阿里云
|
||||||
container_name: pg
|
container_name: pg
|
||||||
restart: always
|
restart: always
|
||||||
ports: # 生产环境建议不要暴露
|
ports: # 生产环境建议不要暴露
|
||||||
|
@@ -298,6 +298,8 @@ curl --location --request DELETE 'http://localhost:3000/api/core/dataset/delete?
|
|||||||
| datasetId | 知识库ID | ✅ |
|
| datasetId | 知识库ID | ✅ |
|
||||||
| parentId: | 父级ID,不填则默认为根目录 | |
|
| parentId: | 父级ID,不填则默认为根目录 | |
|
||||||
| trainingType | 数据处理方式。chunk: 按文本长度进行分割;qa: 问答对提取 | ✅ |
|
| trainingType | 数据处理方式。chunk: 按文本长度进行分割;qa: 问答对提取 | ✅ |
|
||||||
|
| autoIndexes | 是否自动生成索引(仅商业版支持) | |
|
||||||
|
| imageIndex | 是否自动生成图片索引(仅商业版支持) | |
|
||||||
| chunkSize | 预估块大小 | |
|
| chunkSize | 预估块大小 | |
|
||||||
| chunkSplitter | 自定义最高优先分割符号 | |
|
| chunkSplitter | 自定义最高优先分割符号 | |
|
||||||
| qaPrompt | qa拆分提示词 | |
|
| qaPrompt | qa拆分提示词 | |
|
||||||
|
@@ -19,6 +19,7 @@ weight: 803
|
|||||||
|
|
||||||
1. PDF增强解析交互添加到页面上。同时内嵌 Doc2x 服务,可直接使用 Doc2x 服务解析 PDF 文件。
|
1. PDF增强解析交互添加到页面上。同时内嵌 Doc2x 服务,可直接使用 Doc2x 服务解析 PDF 文件。
|
||||||
2. 图片自动标注,同时修改知识库文件上传部分数据逻辑和交互。
|
2. 图片自动标注,同时修改知识库文件上传部分数据逻辑和交互。
|
||||||
|
3. pg vector 插件升级 0.8.0 版本,引入迭代搜索,减少部分数据无法被检索的情况。
|
||||||
|
|
||||||
## ⚙️ 优化
|
## ⚙️ 优化
|
||||||
|
|
||||||
|
1
packages/global/core/app/type.d.ts
vendored
1
packages/global/core/app/type.d.ts
vendored
@@ -188,6 +188,7 @@ export type AppAutoExecuteConfigType = {
|
|||||||
// File
|
// File
|
||||||
export type AppFileSelectConfigType = {
|
export type AppFileSelectConfigType = {
|
||||||
canSelectFile: boolean;
|
canSelectFile: boolean;
|
||||||
|
customPdfParse?: boolean;
|
||||||
canSelectImg: boolean;
|
canSelectImg: boolean;
|
||||||
maxFiles: number;
|
maxFiles: number;
|
||||||
};
|
};
|
||||||
|
@@ -164,34 +164,22 @@ export class PgVectorCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// const explan: any = await PgClient.query(
|
|
||||||
// `BEGIN;
|
|
||||||
// SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
|
|
||||||
// EXPLAIN ANALYZE select id, collection_id, vector <#> '[${vector}]' AS score
|
|
||||||
// from ${DatasetVectorTableName}
|
|
||||||
// where team_id='${teamId}'
|
|
||||||
// AND dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
|
|
||||||
// ${forbidCollectionSql}
|
|
||||||
// order by score limit ${limit};
|
|
||||||
// COMMIT;`
|
|
||||||
// );
|
|
||||||
// console.log(explan[2].rows);
|
|
||||||
|
|
||||||
const results: any = await PgClient.query(
|
const results: any = await PgClient.query(
|
||||||
`
|
`BEGIN;
|
||||||
BEGIN;
|
|
||||||
SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
|
SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
|
||||||
select id, collection_id, vector <#> '[${vector}]' AS score
|
SET LOCAL hnsw.iterative_scan = relaxed_order;
|
||||||
from ${DatasetVectorTableName}
|
WITH relaxed_results AS MATERIALIZED (
|
||||||
where team_id='${teamId}'
|
select id, collection_id, vector <#> '[${vector}]' AS score
|
||||||
AND dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
|
from ${DatasetVectorTableName}
|
||||||
${filterCollectionIdSql}
|
where team_id='${teamId}'
|
||||||
${forbidCollectionSql}
|
AND dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
|
||||||
order by score limit ${limit};
|
${filterCollectionIdSql}
|
||||||
|
${forbidCollectionSql}
|
||||||
|
order by score limit ${limit}
|
||||||
|
) SELECT id, collection_id, score FROM relaxed_results ORDER BY score;
|
||||||
COMMIT;`
|
COMMIT;`
|
||||||
);
|
);
|
||||||
|
const rows = results?.[3]?.rows as PgSearchRawType[];
|
||||||
const rows = results?.[2]?.rows as PgSearchRawType[];
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
results: rows.map((item) => ({
|
results: rows.map((item) => ({
|
||||||
|
@@ -163,6 +163,13 @@ export const loadSystemModels = async (init = false) => {
|
|||||||
global.systemDefaultModel.rerank = Array.from(global.reRankModelMap.values())[0];
|
global.systemDefaultModel.rerank = Array.from(global.reRankModelMap.values())[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort model list
|
||||||
|
global.systemActiveModelList.sort((a, b) => {
|
||||||
|
const providerA = getModelProvider(a.provider);
|
||||||
|
const providerB = getModelProvider(b.provider);
|
||||||
|
return providerA.order - providerB.order;
|
||||||
|
});
|
||||||
|
|
||||||
console.log('Load models success', JSON.stringify(global.systemActiveModelList, null, 2));
|
console.log('Load models success', JSON.stringify(global.systemActiveModelList, null, 2));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Load models error', error);
|
console.error('Load models error', error);
|
||||||
|
@@ -45,8 +45,7 @@ const DatasetDataSchema = new Schema({
|
|||||||
{
|
{
|
||||||
// Abandon
|
// Abandon
|
||||||
defaultIndex: {
|
defaultIndex: {
|
||||||
type: Boolean,
|
type: Boolean
|
||||||
default: false
|
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@@ -11,6 +11,7 @@ import { addLog } from '../../../common/system/log';
|
|||||||
import { getCollectionWithDataset } from '../controller';
|
import { getCollectionWithDataset } from '../controller';
|
||||||
import { mongoSessionRun } from '../../../common/mongo/sessionRun';
|
import { mongoSessionRun } from '../../../common/mongo/sessionRun';
|
||||||
import { PushDataToTrainingQueueProps } from '@fastgpt/global/core/dataset/training/type';
|
import { PushDataToTrainingQueueProps } from '@fastgpt/global/core/dataset/training/type';
|
||||||
|
import { i18nT } from '../../../../web/i18n/utils';
|
||||||
|
|
||||||
export const lockTrainingDataByTeamId = async (teamId: string): Promise<any> => {
|
export const lockTrainingDataByTeamId = async (teamId: string): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
@@ -71,7 +72,7 @@ export async function pushDataListToTrainingQueue({
|
|||||||
if (mode === TrainingModeEnum.chunk) {
|
if (mode === TrainingModeEnum.chunk) {
|
||||||
const vectorModelData = getEmbeddingModel(vectorModel);
|
const vectorModelData = getEmbeddingModel(vectorModel);
|
||||||
if (!vectorModelData) {
|
if (!vectorModelData) {
|
||||||
return Promise.reject(`Vector model ${vectorModel} is inValid`);
|
return Promise.reject(i18nT('common:error_embedding_not_config'));
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
maxToken: vectorModelData.maxToken * 1.5,
|
maxToken: vectorModelData.maxToken * 1.5,
|
||||||
@@ -83,7 +84,7 @@ export async function pushDataListToTrainingQueue({
|
|||||||
if (mode === TrainingModeEnum.qa || mode === TrainingModeEnum.auto) {
|
if (mode === TrainingModeEnum.qa || mode === TrainingModeEnum.auto) {
|
||||||
const agentModelData = getLLMModel(agentModel);
|
const agentModelData = getLLMModel(agentModel);
|
||||||
if (!agentModelData) {
|
if (!agentModelData) {
|
||||||
return Promise.reject(`File model ${agentModel} is inValid`);
|
return Promise.reject(i18nT('common:error_llm_not_config'));
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
maxToken: agentModelData.maxContext * 0.8,
|
maxToken: agentModelData.maxContext * 0.8,
|
||||||
@@ -95,7 +96,7 @@ export async function pushDataListToTrainingQueue({
|
|||||||
if (mode === TrainingModeEnum.image) {
|
if (mode === TrainingModeEnum.image) {
|
||||||
const vllmModelData = getVlmModel(vlmModel);
|
const vllmModelData = getVlmModel(vlmModel);
|
||||||
if (!vllmModelData) {
|
if (!vllmModelData) {
|
||||||
return Promise.reject(`Vlm model ${vlmModel} is inValid`);
|
return Promise.reject(i18nT('common:error_vlm_not_config'));
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
maxToken: vllmModelData.maxContext * 0.8,
|
maxToken: vllmModelData.maxContext * 0.8,
|
||||||
|
@@ -104,6 +104,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
|||||||
histories: chatHistories,
|
histories: chatHistories,
|
||||||
requestOrigin,
|
requestOrigin,
|
||||||
maxFiles: chatConfig?.fileSelectConfig?.maxFiles || 20,
|
maxFiles: chatConfig?.fileSelectConfig?.maxFiles || 20,
|
||||||
|
customPdfParse: chatConfig?.fileSelectConfig?.customPdfParse,
|
||||||
fileLinks,
|
fileLinks,
|
||||||
inputFiles: globalFiles,
|
inputFiles: globalFiles,
|
||||||
hasReadFilesTool
|
hasReadFilesTool
|
||||||
@@ -295,6 +296,7 @@ const getMultiInput = async ({
|
|||||||
fileLinks,
|
fileLinks,
|
||||||
requestOrigin,
|
requestOrigin,
|
||||||
maxFiles,
|
maxFiles,
|
||||||
|
customPdfParse,
|
||||||
inputFiles,
|
inputFiles,
|
||||||
hasReadFilesTool
|
hasReadFilesTool
|
||||||
}: {
|
}: {
|
||||||
@@ -303,6 +305,7 @@ const getMultiInput = async ({
|
|||||||
fileLinks?: string[];
|
fileLinks?: string[];
|
||||||
requestOrigin?: string;
|
requestOrigin?: string;
|
||||||
maxFiles: number;
|
maxFiles: number;
|
||||||
|
customPdfParse?: boolean;
|
||||||
inputFiles: UserChatItemValueItemType['file'][];
|
inputFiles: UserChatItemValueItemType['file'][];
|
||||||
hasReadFilesTool: boolean;
|
hasReadFilesTool: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
@@ -330,6 +333,7 @@ const getMultiInput = async ({
|
|||||||
urls,
|
urls,
|
||||||
requestOrigin,
|
requestOrigin,
|
||||||
maxFiles,
|
maxFiles,
|
||||||
|
customPdfParse,
|
||||||
teamId: runningUserInfo.teamId,
|
teamId: runningUserInfo.teamId,
|
||||||
tmbId: runningUserInfo.tmbId
|
tmbId: runningUserInfo.tmbId
|
||||||
});
|
});
|
||||||
|
@@ -124,6 +124,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
|||||||
stringQuoteText,
|
stringQuoteText,
|
||||||
requestOrigin,
|
requestOrigin,
|
||||||
maxFiles: chatConfig?.fileSelectConfig?.maxFiles || 20,
|
maxFiles: chatConfig?.fileSelectConfig?.maxFiles || 20,
|
||||||
|
customPdfParse: chatConfig?.fileSelectConfig?.customPdfParse,
|
||||||
runningUserInfo
|
runningUserInfo
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
@@ -358,6 +359,7 @@ async function getMultiInput({
|
|||||||
stringQuoteText,
|
stringQuoteText,
|
||||||
requestOrigin,
|
requestOrigin,
|
||||||
maxFiles,
|
maxFiles,
|
||||||
|
customPdfParse,
|
||||||
runningUserInfo
|
runningUserInfo
|
||||||
}: {
|
}: {
|
||||||
histories: ChatItemType[];
|
histories: ChatItemType[];
|
||||||
@@ -366,6 +368,7 @@ async function getMultiInput({
|
|||||||
stringQuoteText?: string; // file quote
|
stringQuoteText?: string; // file quote
|
||||||
requestOrigin?: string;
|
requestOrigin?: string;
|
||||||
maxFiles: number;
|
maxFiles: number;
|
||||||
|
customPdfParse?: boolean;
|
||||||
runningUserInfo: ChatDispatchProps['runningUserInfo'];
|
runningUserInfo: ChatDispatchProps['runningUserInfo'];
|
||||||
}) {
|
}) {
|
||||||
// 旧版本适配====>
|
// 旧版本适配====>
|
||||||
@@ -403,6 +406,7 @@ async function getMultiInput({
|
|||||||
urls,
|
urls,
|
||||||
requestOrigin,
|
requestOrigin,
|
||||||
maxFiles,
|
maxFiles,
|
||||||
|
customPdfParse,
|
||||||
teamId: runningUserInfo.teamId,
|
teamId: runningUserInfo.teamId,
|
||||||
tmbId: runningUserInfo.tmbId
|
tmbId: runningUserInfo.tmbId
|
||||||
});
|
});
|
||||||
|
@@ -52,6 +52,7 @@ export const dispatchReadFiles = async (props: Props): Promise<Response> => {
|
|||||||
params: { fileUrlList = [] }
|
params: { fileUrlList = [] }
|
||||||
} = props;
|
} = props;
|
||||||
const maxFiles = chatConfig?.fileSelectConfig?.maxFiles || 20;
|
const maxFiles = chatConfig?.fileSelectConfig?.maxFiles || 20;
|
||||||
|
const customPdfParse = chatConfig?.fileSelectConfig?.customPdfParse || false;
|
||||||
|
|
||||||
// Get files from histories
|
// Get files from histories
|
||||||
const filesFromHistories = version !== '489' ? [] : getHistoryFileLinks(histories);
|
const filesFromHistories = version !== '489' ? [] : getHistoryFileLinks(histories);
|
||||||
@@ -62,7 +63,8 @@ export const dispatchReadFiles = async (props: Props): Promise<Response> => {
|
|||||||
requestOrigin,
|
requestOrigin,
|
||||||
maxFiles,
|
maxFiles,
|
||||||
teamId,
|
teamId,
|
||||||
tmbId
|
tmbId,
|
||||||
|
customPdfParse
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -107,13 +109,15 @@ export const getFileContentFromLinks = async ({
|
|||||||
requestOrigin,
|
requestOrigin,
|
||||||
maxFiles,
|
maxFiles,
|
||||||
teamId,
|
teamId,
|
||||||
tmbId
|
tmbId,
|
||||||
|
customPdfParse
|
||||||
}: {
|
}: {
|
||||||
urls: string[];
|
urls: string[];
|
||||||
requestOrigin?: string;
|
requestOrigin?: string;
|
||||||
maxFiles: number;
|
maxFiles: number;
|
||||||
teamId: string;
|
teamId: string;
|
||||||
tmbId: string;
|
tmbId: string;
|
||||||
|
customPdfParse?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const parseUrlList = urls
|
const parseUrlList = urls
|
||||||
// Remove invalid urls
|
// Remove invalid urls
|
||||||
@@ -210,7 +214,8 @@ export const getFileContentFromLinks = async ({
|
|||||||
teamId,
|
teamId,
|
||||||
tmbId,
|
tmbId,
|
||||||
buffer,
|
buffer,
|
||||||
encoding
|
encoding,
|
||||||
|
customPdfParse
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add to buffer
|
// Add to buffer
|
||||||
|
@@ -43,5 +43,7 @@
|
|||||||
"selected_model_empty": "Choose at least one model",
|
"selected_model_empty": "Choose at least one model",
|
||||||
"start_test": "Start testing {{num}} models",
|
"start_test": "Start testing {{num}} models",
|
||||||
"test_failed": "There are {{num}} models that report errors",
|
"test_failed": "There are {{num}} models that report errors",
|
||||||
|
"vlm_model": "Vlm",
|
||||||
|
"vlm_model_tip": "Used to generate additional indexing of images in a document in the knowledge base",
|
||||||
"waiting_test": "Waiting for testing"
|
"waiting_test": "Waiting for testing"
|
||||||
}
|
}
|
||||||
|
@@ -105,6 +105,9 @@
|
|||||||
"open_vision_function_tip": "Models with icon switches have image recognition capabilities. \nAfter being turned on, the model will parse the pictures in the file link and automatically parse the pictures in the user's question (user question ≤ 500 words).",
|
"open_vision_function_tip": "Models with icon switches have image recognition capabilities. \nAfter being turned on, the model will parse the pictures in the file link and automatically parse the pictures in the user's question (user question ≤ 500 words).",
|
||||||
"or_drag_JSON": "or drag in JSON file",
|
"or_drag_JSON": "or drag in JSON file",
|
||||||
"paste_config_or_drag": "Paste config or drag JSON file here",
|
"paste_config_or_drag": "Paste config or drag JSON file here",
|
||||||
|
"pdf_enhance_parse": "PDF enhancement analysis",
|
||||||
|
"pdf_enhance_parse_price": "{{price}}Points/page",
|
||||||
|
"pdf_enhance_parse_tips": "Calling PDF recognition model for parsing, you can convert it into Markdown and retain pictures in the document. At the same time, you can also identify scanned documents, which will take a long time to identify them.",
|
||||||
"permission.des.manage": "Based on write permissions, you can configure publishing channels, view conversation logs, and assign permissions to the application.",
|
"permission.des.manage": "Based on write permissions, you can configure publishing channels, view conversation logs, and assign permissions to the application.",
|
||||||
"permission.des.read": "Use the app to have conversations",
|
"permission.des.read": "Use the app to have conversations",
|
||||||
"permission.des.write": "Can view and edit apps",
|
"permission.des.write": "Can view and edit apps",
|
||||||
|
@@ -883,6 +883,9 @@
|
|||||||
"error.upload_image_error": "File upload failed",
|
"error.upload_image_error": "File upload failed",
|
||||||
"error.username_empty": "Account cannot be empty",
|
"error.username_empty": "Account cannot be empty",
|
||||||
"error_collection_not_exist": "The collection does not exist",
|
"error_collection_not_exist": "The collection does not exist",
|
||||||
|
"error_embedding_not_config": "Unconfigured index model",
|
||||||
|
"error_llm_not_config": "Unconfigured file understanding model",
|
||||||
|
"error_vlm_not_config": "Image comprehension model not configured",
|
||||||
"extraction_results": "Extraction Results",
|
"extraction_results": "Extraction Results",
|
||||||
"field_name": "Field Name",
|
"field_name": "Field Name",
|
||||||
"free": "Free",
|
"free": "Free",
|
||||||
|
@@ -76,7 +76,7 @@
|
|||||||
"params_setting": "Parameter settings",
|
"params_setting": "Parameter settings",
|
||||||
"pdf_enhance_parse": "PDF enhancement analysis",
|
"pdf_enhance_parse": "PDF enhancement analysis",
|
||||||
"pdf_enhance_parse_price": "{{price}} points/page",
|
"pdf_enhance_parse_price": "{{price}} points/page",
|
||||||
"pdf_enhance_parse_tips": "When parsing a PDF file, the PDF recognition model is called for recognition, which can be converted into Markdown and retained the pictures in the document, and can also identify the scanned files.",
|
"pdf_enhance_parse_tips": "Calling PDF recognition model for parsing, you can convert it into Markdown and retain pictures in the document. At the same time, you can also identify scanned documents, which will take a long time to identify them.",
|
||||||
"permission.des.manage": "Can manage the entire knowledge base data and information",
|
"permission.des.manage": "Can manage the entire knowledge base data and information",
|
||||||
"permission.des.read": "View knowledge base content",
|
"permission.des.read": "View knowledge base content",
|
||||||
"permission.des.write": "Ability to add and change knowledge base content",
|
"permission.des.write": "Ability to add and change knowledge base content",
|
||||||
|
@@ -43,5 +43,7 @@
|
|||||||
"selected_model_empty": "至少选择一个模型",
|
"selected_model_empty": "至少选择一个模型",
|
||||||
"start_test": "开始测试{{num}}个模型",
|
"start_test": "开始测试{{num}}个模型",
|
||||||
"test_failed": "有{{num}}个模型报错",
|
"test_failed": "有{{num}}个模型报错",
|
||||||
|
"vlm_model": "图片理解模型",
|
||||||
|
"vlm_model_tip": "用于知识库中对文档中的图片进行额外的索引生成",
|
||||||
"waiting_test": "等待测试"
|
"waiting_test": "等待测试"
|
||||||
}
|
}
|
||||||
|
@@ -105,6 +105,9 @@
|
|||||||
"open_vision_function_tip": "有图示开关的模型即拥有图片识别能力。若开启,模型会解析文件链接里的图片,并自动解析用户问题中的图片(用户问题≤500字时生效)。",
|
"open_vision_function_tip": "有图示开关的模型即拥有图片识别能力。若开启,模型会解析文件链接里的图片,并自动解析用户问题中的图片(用户问题≤500字时生效)。",
|
||||||
"or_drag_JSON": "或拖入JSON文件",
|
"or_drag_JSON": "或拖入JSON文件",
|
||||||
"paste_config_or_drag": "粘贴配置或拖入 JSON 文件",
|
"paste_config_or_drag": "粘贴配置或拖入 JSON 文件",
|
||||||
|
"pdf_enhance_parse": "PDF增强解析",
|
||||||
|
"pdf_enhance_parse_price": "{{price}}积分/页",
|
||||||
|
"pdf_enhance_parse_tips": "调用 PDF 识别模型进行解析,可以将其转换成 Markdown 并保留文档中的图片,同时也可以对扫描件进行识别,识别时间较长。",
|
||||||
"permission.des.manage": "写权限基础上,可配置发布渠道、查看对话日志、分配该应用权限",
|
"permission.des.manage": "写权限基础上,可配置发布渠道、查看对话日志、分配该应用权限",
|
||||||
"permission.des.read": "可使用该应用进行对话",
|
"permission.des.read": "可使用该应用进行对话",
|
||||||
"permission.des.write": "可查看和编辑应用",
|
"permission.des.write": "可查看和编辑应用",
|
||||||
|
@@ -886,6 +886,9 @@
|
|||||||
"error.upload_image_error": "上传文件失败",
|
"error.upload_image_error": "上传文件失败",
|
||||||
"error.username_empty": "账号不能为空",
|
"error.username_empty": "账号不能为空",
|
||||||
"error_collection_not_exist": "集合不存在",
|
"error_collection_not_exist": "集合不存在",
|
||||||
|
"error_embedding_not_config": "未配置索引模型",
|
||||||
|
"error_llm_not_config": "未配置文件理解模型",
|
||||||
|
"error_vlm_not_config": "未配置图片理解模型",
|
||||||
"extraction_results": "提取结果",
|
"extraction_results": "提取结果",
|
||||||
"field_name": "字段名",
|
"field_name": "字段名",
|
||||||
"free": "免费",
|
"free": "免费",
|
||||||
|
@@ -76,7 +76,7 @@
|
|||||||
"params_setting": "参数设置",
|
"params_setting": "参数设置",
|
||||||
"pdf_enhance_parse": "PDF增强解析",
|
"pdf_enhance_parse": "PDF增强解析",
|
||||||
"pdf_enhance_parse_price": "{{price}}积分/页",
|
"pdf_enhance_parse_price": "{{price}}积分/页",
|
||||||
"pdf_enhance_parse_tips": "解析 PDF 文件时,调用 PDF 识别模型进行识别,可以将其转换成 Markdown 并保留文档中的图片,同时也可以对扫描件进行识别。",
|
"pdf_enhance_parse_tips": "调用 PDF 识别模型进行解析,可以将其转换成 Markdown 并保留文档中的图片,同时也可以对扫描件进行识别,识别时间较长。",
|
||||||
"permission.des.manage": "可管理整个知识库数据和信息",
|
"permission.des.manage": "可管理整个知识库数据和信息",
|
||||||
"permission.des.read": "可查看知识库内容",
|
"permission.des.read": "可查看知识库内容",
|
||||||
"permission.des.write": "可增加和变更知识库内容",
|
"permission.des.write": "可增加和变更知识库内容",
|
||||||
|
@@ -41,5 +41,7 @@
|
|||||||
"selected_model_empty": "至少選擇一個模型",
|
"selected_model_empty": "至少選擇一個模型",
|
||||||
"start_test": "開始測試{{num}}個模型",
|
"start_test": "開始測試{{num}}個模型",
|
||||||
"test_failed": "有{{num}}個模型報錯",
|
"test_failed": "有{{num}}個模型報錯",
|
||||||
|
"vlm_model": "圖片理解模型",
|
||||||
|
"vlm_model_tip": "用於知識庫中對文檔中的圖片進行額外的索引生成",
|
||||||
"waiting_test": "等待測試"
|
"waiting_test": "等待測試"
|
||||||
}
|
}
|
||||||
|
@@ -105,6 +105,9 @@
|
|||||||
"open_vision_function_tip": "有圖示開關的模型即擁有圖片辨識功能。若開啟,模型會解析檔案連結中的圖片,並自動解析使用者問題中的圖片(使用者問題 ≤ 500 字時生效)。",
|
"open_vision_function_tip": "有圖示開關的模型即擁有圖片辨識功能。若開啟,模型會解析檔案連結中的圖片,並自動解析使用者問題中的圖片(使用者問題 ≤ 500 字時生效)。",
|
||||||
"or_drag_JSON": "或拖曳 JSON 檔案",
|
"or_drag_JSON": "或拖曳 JSON 檔案",
|
||||||
"paste_config_or_drag": "貼上配置或拖入 JSON 文件",
|
"paste_config_or_drag": "貼上配置或拖入 JSON 文件",
|
||||||
|
"pdf_enhance_parse": "PDF增強解析",
|
||||||
|
"pdf_enhance_parse_price": "{{price}}積分/頁",
|
||||||
|
"pdf_enhance_parse_tips": "調用 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文檔中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
|
||||||
"permission.des.manage": "在寫入權限基礎上,可以設定發布通道、檢視對話紀錄、分配這個應用程式的權限",
|
"permission.des.manage": "在寫入權限基礎上,可以設定發布通道、檢視對話紀錄、分配這個應用程式的權限",
|
||||||
"permission.des.read": "可以使用這個應用程式進行對話",
|
"permission.des.read": "可以使用這個應用程式進行對話",
|
||||||
"permission.des.write": "可以檢視和編輯應用程式",
|
"permission.des.write": "可以檢視和編輯應用程式",
|
||||||
|
@@ -883,6 +883,9 @@
|
|||||||
"error.upload_image_error": "上傳文件失敗",
|
"error.upload_image_error": "上傳文件失敗",
|
||||||
"error.username_empty": "帳號不能為空",
|
"error.username_empty": "帳號不能為空",
|
||||||
"error_collection_not_exist": "集合不存在",
|
"error_collection_not_exist": "集合不存在",
|
||||||
|
"error_embedding_not_config": "未配置索引模型",
|
||||||
|
"error_llm_not_config": "未配置文件理解模型",
|
||||||
|
"error_vlm_not_config": "未配置圖片理解模型",
|
||||||
"extraction_results": "提取結果",
|
"extraction_results": "提取結果",
|
||||||
"field_name": "欄位名稱",
|
"field_name": "欄位名稱",
|
||||||
"free": "免費",
|
"free": "免費",
|
||||||
|
@@ -76,7 +76,7 @@
|
|||||||
"params_setting": "參數設置",
|
"params_setting": "參數設置",
|
||||||
"pdf_enhance_parse": "PDF增強解析",
|
"pdf_enhance_parse": "PDF增強解析",
|
||||||
"pdf_enhance_parse_price": "{{price}}積分/頁",
|
"pdf_enhance_parse_price": "{{price}}積分/頁",
|
||||||
"pdf_enhance_parse_tips": "解析 PDF 文件時,調用 PDF 識別模型進行識別,可以將其轉換成 Markdown 並保留文檔中的圖片,同時也可以對掃描件進行識別。",
|
"pdf_enhance_parse_tips": "調用 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文檔中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
|
||||||
"permission.des.manage": "可管理整個資料集的資料和資訊",
|
"permission.des.manage": "可管理整個資料集的資料和資訊",
|
||||||
"permission.des.read": "可檢視資料集內容",
|
"permission.des.read": "可檢視資料集內容",
|
||||||
"permission.des.write": "可新增和變更資料集內容",
|
"permission.des.write": "可新增和變更資料集內容",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"version": "4.8.23",
|
"version": "4.9.0",
|
||||||
"private": false,
|
"private": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
@@ -51,13 +51,13 @@ export const navbarWidth = '64px';
|
|||||||
|
|
||||||
const Layout = ({ children }: { children: JSX.Element }) => {
|
const Layout = ({ children }: { children: JSX.Element }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { toast } = useToast();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { Loading } = useLoading();
|
const { Loading } = useLoading();
|
||||||
const { loading, feConfigs, notSufficientModalType, llmModelList, embeddingModelList } =
|
const { loading, feConfigs, notSufficientModalType, llmModelList, embeddingModelList } =
|
||||||
useSystemStore();
|
useSystemStore();
|
||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
const { userInfo, teamPlanStatus, isUpdateNotification, setIsUpdateNotification } =
|
const { userInfo, isUpdateNotification, setIsUpdateNotification } = useUserStore();
|
||||||
useUserStore();
|
|
||||||
const { setUserDefaultLng } = useI18nLng();
|
const { setUserDefaultLng } = useI18nLng();
|
||||||
|
|
||||||
const isChatPage = useMemo(
|
const isChatPage = useMemo(
|
||||||
@@ -87,7 +87,6 @@ const Layout = ({ children }: { children: JSX.Element }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Check model invalid
|
// Check model invalid
|
||||||
const { toast } = useToast();
|
|
||||||
useDebounceEffect(
|
useDebounceEffect(
|
||||||
() => {
|
() => {
|
||||||
if (userInfo?.username === 'root') {
|
if (userInfo?.username === 'root') {
|
||||||
|
@@ -110,7 +110,7 @@ const OneRowSelector = ({ list, onchange, disableTip, ...props }: Props) => {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) => {
|
const MultipleRowSelector = ({ list, onchange, disableTip, placeholder, ...props }: Props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList } =
|
const { llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList } =
|
||||||
useSystemStore();
|
useSystemStore();
|
||||||
@@ -124,7 +124,7 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) =>
|
|||||||
];
|
];
|
||||||
|
|
||||||
return list.map((item) => getModelFromList(allModels, item.value)!).filter(Boolean);
|
return list.map((item) => getModelFromList(allModels, item.value)!).filter(Boolean);
|
||||||
}, [llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList]);
|
}, [llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList, list]);
|
||||||
|
|
||||||
const [value, setValue] = useState<string[]>([]);
|
const [value, setValue] = useState<string[]>([]);
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return renderList.filter((item) => item.children.length > 0);
|
return renderList.filter((item) => item.children.length > 0);
|
||||||
}, [avatarSize, list, modelList]);
|
}, [avatarSize, list, modelList, t]);
|
||||||
|
|
||||||
const onSelect = useCallback(
|
const onSelect = useCallback(
|
||||||
(e: string[]) => {
|
(e: string[]) => {
|
||||||
@@ -184,7 +184,9 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
const SelectedModel = useMemo(() => {
|
const SelectedModel = useMemo(() => {
|
||||||
|
if (!props.value) return <>{t('common:not_model_config')}</>;
|
||||||
const modelData = getModelFromList(modelList, props.value);
|
const modelData = getModelFromList(modelList, props.value);
|
||||||
|
|
||||||
if (!modelData) return <>{t('common:not_model_config')}</>;
|
if (!modelData) return <>{t('common:not_model_config')}</>;
|
||||||
|
|
||||||
setValue([modelData.provider, props.value]);
|
setValue([modelData.provider, props.value]);
|
||||||
@@ -201,7 +203,7 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) =>
|
|||||||
<Box>{modelData?.name}</Box>
|
<Box>{modelData?.name}</Box>
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
}, [modelList, props.value, avatarSize]);
|
}, [modelList, props.value, t, avatarSize]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -217,6 +219,7 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) =>
|
|||||||
list={selectorList}
|
list={selectorList}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
value={value}
|
value={value}
|
||||||
|
placeholder={placeholder}
|
||||||
rowMinWidth="160px"
|
rowMinWidth="160px"
|
||||||
ButtonProps={{
|
ButtonProps={{
|
||||||
isDisabled: !!disableTip,
|
isDisabled: !!disableTip,
|
||||||
|
@@ -9,7 +9,8 @@ import {
|
|||||||
HStack,
|
HStack,
|
||||||
Switch,
|
Switch,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
BoxProps
|
BoxProps,
|
||||||
|
Checkbox
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
@@ -22,6 +23,8 @@ import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
|||||||
import { useMount } from 'ahooks';
|
import { useMount } from 'ahooks';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||||
|
import MyTag from '@fastgpt/web/components/common/Tag/index';
|
||||||
|
import MyDivider from '@fastgpt/web/components/common/MyDivider';
|
||||||
|
|
||||||
const FileSelect = ({
|
const FileSelect = ({
|
||||||
forbidVision = false,
|
forbidVision = false,
|
||||||
@@ -95,6 +98,42 @@ const FileSelect = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
{value.canSelectFile && feConfigs.showCustomPdfParse && (
|
||||||
|
<>
|
||||||
|
<HStack justifyContent={'end'} spacing={1} mt={2}>
|
||||||
|
<Checkbox
|
||||||
|
isChecked={value.customPdfParse}
|
||||||
|
onChange={(e) => {
|
||||||
|
onChange({
|
||||||
|
...value,
|
||||||
|
customPdfParse: e.target.checked
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FormLabel>{t('app:pdf_enhance_parse')}</FormLabel>
|
||||||
|
</Checkbox>
|
||||||
|
<QuestionTip label={t('app:pdf_enhance_parse_tips')} />
|
||||||
|
{feConfigs?.show_pay && (
|
||||||
|
<MyTag
|
||||||
|
type={'borderSolid'}
|
||||||
|
borderColor={'myGray.200'}
|
||||||
|
bg={'myGray.100'}
|
||||||
|
color={'primary.600'}
|
||||||
|
py={1.5}
|
||||||
|
borderRadius={'md'}
|
||||||
|
px={3}
|
||||||
|
whiteSpace={'wrap'}
|
||||||
|
ml={1}
|
||||||
|
>
|
||||||
|
{t('app:pdf_enhance_parse_price', {
|
||||||
|
price: feConfigs.customPdfParsePrice || 0
|
||||||
|
})}
|
||||||
|
</MyTag>
|
||||||
|
)}
|
||||||
|
</HStack>
|
||||||
|
<MyDivider my={2} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<HStack mt={6}>
|
<HStack mt={6}>
|
||||||
<FormLabel flex={'1 0 0'}>{t('app:image_upload')}</FormLabel>
|
<FormLabel flex={'1 0 0'}>{t('app:image_upload')}</FormLabel>
|
||||||
{forbidVision ? (
|
{forbidVision ? (
|
||||||
|
@@ -563,8 +563,10 @@ const DefaultModelModal = ({
|
|||||||
embeddingModelList,
|
embeddingModelList,
|
||||||
ttsModelList,
|
ttsModelList,
|
||||||
sttModelList,
|
sttModelList,
|
||||||
reRankModelList
|
reRankModelList,
|
||||||
|
getVlmModelList
|
||||||
} = useSystemStore();
|
} = useSystemStore();
|
||||||
|
const vlmModelList = useMemo(() => getVlmModelList(), [getVlmModelList]);
|
||||||
|
|
||||||
// Create a copy of defaultModels for local state management
|
// Create a copy of defaultModels for local state management
|
||||||
const [defaultData, setDefaultData] = useState(defaultModels);
|
const [defaultData, setDefaultData] = useState(defaultModels);
|
||||||
@@ -703,6 +705,28 @@ const DefaultModelModal = ({
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Flex mt={4} {...labelStyles} alignItems={'center'}>
|
||||||
|
<Box mr={0.5}>{t('account_model:vlm_model')}</Box>
|
||||||
|
<QuestionTip label={t('account_model:vlm_model_tip')} />
|
||||||
|
</Flex>
|
||||||
|
<Box flex={1}>
|
||||||
|
<AIModelSelector
|
||||||
|
bg="myGray.50"
|
||||||
|
value={defaultData.datasetImageLLM?.model}
|
||||||
|
list={vlmModelList.map((item) => ({
|
||||||
|
value: item.model,
|
||||||
|
label: item.name
|
||||||
|
}))}
|
||||||
|
onchange={(e) => {
|
||||||
|
setDefaultData((state) => ({
|
||||||
|
...state,
|
||||||
|
datasetImageLLM: vlmModelList.find((item) => item.model === e)
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant={'whiteBase'} mr={4} onClick={onClose}>
|
<Button variant={'whiteBase'} mr={4} onClick={onClose}>
|
||||||
|
@@ -35,21 +35,17 @@ import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
|||||||
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';
|
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';
|
||||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||||
import { shadowLight } from '@fastgpt/web/styles/theme';
|
import { shadowLight } from '@fastgpt/web/styles/theme';
|
||||||
import AIModelSelector from '@/components/Select/AIModelSelector';
|
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
||||||
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
|
|
||||||
function DataProcess() {
|
function DataProcess() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { feConfigs } = useSystemStore();
|
const { feConfigs } = useSystemStore();
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
const {
|
const { goToNext, processParamsForm, chunkSizeField, minChunkSize, maxChunkSize } =
|
||||||
goToNext,
|
useContextSelector(DatasetImportContext, (v) => v);
|
||||||
processParamsForm,
|
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
|
||||||
chunkSizeField,
|
|
||||||
minChunkSize,
|
|
||||||
maxChunkSize,
|
|
||||||
priceTip,
|
|
||||||
chunkSize
|
|
||||||
} = useContextSelector(DatasetImportContext, (v) => v);
|
|
||||||
const { getValues, setValue, register, watch } = processParamsForm;
|
const { getValues, setValue, register, watch } = processParamsForm;
|
||||||
const trainingType = watch('trainingType');
|
const trainingType = watch('trainingType');
|
||||||
const chunkSettingMode = watch('chunkSettingMode');
|
const chunkSettingMode = watch('chunkSettingMode');
|
||||||
@@ -177,9 +173,16 @@ function DataProcess() {
|
|||||||
<QuestionTip label={t('dataset:auto_indexes_tips')} />
|
<QuestionTip label={t('dataset:auto_indexes_tips')} />
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack flex={'1'} spacing={1}>
|
<HStack flex={'1'} spacing={1}>
|
||||||
<Checkbox {...register('imageIndex')}>
|
<MyTooltip
|
||||||
<FormLabel>{t('dataset:image_auto_parse')}</FormLabel>
|
label={!datasetDetail?.vlmModel ? t('common:error_vlm_not_config') : ''}
|
||||||
</Checkbox>
|
>
|
||||||
|
<Checkbox
|
||||||
|
isDisabled={!datasetDetail?.vlmModel}
|
||||||
|
{...register('imageIndex')}
|
||||||
|
>
|
||||||
|
<FormLabel>{t('dataset:image_auto_parse')}</FormLabel>
|
||||||
|
</Checkbox>
|
||||||
|
</MyTooltip>
|
||||||
<QuestionTip label={t('dataset:image_auto_parse_tips')} />
|
<QuestionTip label={t('dataset:image_auto_parse_tips')} />
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
@@ -37,7 +37,7 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { datasetDetail, loadDatasetDetail, updateDataset, rebuildingCount, trainingCount } =
|
const { datasetDetail, loadDatasetDetail, updateDataset, rebuildingCount, trainingCount } =
|
||||||
useContextSelector(DatasetPageContext, (v) => v);
|
useContextSelector(DatasetPageContext, (v) => v);
|
||||||
const { feConfigs, datasetModelList, embeddingModelList, getVllmModelList } = useSystemStore();
|
const { feConfigs, datasetModelList, embeddingModelList, getVlmModelList } = useSystemStore();
|
||||||
|
|
||||||
const [editedDataset, setEditedDataset] = useState<EditResourceInfoFormType>();
|
const [editedDataset, setEditedDataset] = useState<EditResourceInfoFormType>();
|
||||||
const [editedAPIDataset, setEditedAPIDataset] = useState<EditAPIDatasetInfoFormType>();
|
const [editedAPIDataset, setEditedAPIDataset] = useState<EditAPIDatasetInfoFormType>();
|
||||||
@@ -52,7 +52,7 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
|||||||
const vectorModel = watch('vectorModel');
|
const vectorModel = watch('vectorModel');
|
||||||
const agentModel = watch('agentModel');
|
const agentModel = watch('agentModel');
|
||||||
|
|
||||||
const vllmModelList = useMemo(() => getVllmModelList(), [getVllmModelList]);
|
const vllmModelList = useMemo(() => getVlmModelList(), [getVlmModelList]);
|
||||||
const vlmModel = watch('vlmModel');
|
const vlmModel = watch('vlmModel');
|
||||||
|
|
||||||
const { ConfirmModal: ConfirmDelModal } = useConfirm({
|
const { ConfirmModal: ConfirmDelModal } = useConfirm({
|
||||||
|
@@ -40,7 +40,7 @@ const CreateModal = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { feConfigs, defaultModels, embeddingModelList, datasetModelList, getVllmModelList } =
|
const { feConfigs, defaultModels, embeddingModelList, datasetModelList, getVlmModelList } =
|
||||||
useSystemStore();
|
useSystemStore();
|
||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ const CreateModal = ({
|
|||||||
|
|
||||||
const filterNotHiddenVectorModelList = embeddingModelList.filter((item) => !item.hidden);
|
const filterNotHiddenVectorModelList = embeddingModelList.filter((item) => !item.hidden);
|
||||||
|
|
||||||
const vllmModelList = useMemo(() => getVllmModelList(), [getVllmModelList]);
|
const vllmModelList = useMemo(() => getVlmModelList(), [getVlmModelList]);
|
||||||
|
|
||||||
const form = useForm<CreateDatasetParams>({
|
const form = useForm<CreateDatasetParams>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
|
@@ -5,6 +5,8 @@ import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection
|
|||||||
import { DatasetCollectionDataProcessModeEnum } from '@fastgpt/global/core/dataset/constants';
|
import { DatasetCollectionDataProcessModeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||||
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
|
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
|
||||||
import { DatasetDataIndexTypeEnum } from '@fastgpt/global/core/dataset/data/constants';
|
import { DatasetDataIndexTypeEnum } from '@fastgpt/global/core/dataset/data/constants';
|
||||||
|
import { PgClient } from '@fastgpt/service/common/vectorStore/pg';
|
||||||
|
import { PG_ADDRESS } from '@fastgpt/service/common/vectorStore/constants';
|
||||||
|
|
||||||
// 所有 trainingType=auto 的 collection,都改成 trainingType=chunk
|
// 所有 trainingType=auto 的 collection,都改成 trainingType=chunk
|
||||||
const updateCollections = async () => {
|
const updateCollections = async () => {
|
||||||
@@ -48,10 +50,19 @@ const updateData = async () => {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
const upgradePgVector = async () => {
|
||||||
|
if (!PG_ADDRESS) return;
|
||||||
|
await PgClient.query(`
|
||||||
|
ALTER EXTENSION vector UPDATE;
|
||||||
|
`);
|
||||||
|
};
|
||||||
|
|
||||||
async function handler(req: NextApiRequest, _res: NextApiResponse) {
|
async function handler(req: NextApiRequest, _res: NextApiResponse) {
|
||||||
await authCert({ req, authRoot: true });
|
await authCert({ req, authRoot: true });
|
||||||
|
|
||||||
|
console.log('升级 PG vector 插件');
|
||||||
|
await upgradePgVector();
|
||||||
|
|
||||||
console.log('变更所有 collection 的 trainingType 为 chunk');
|
console.log('变更所有 collection 的 trainingType 为 chunk');
|
||||||
await updateCollections();
|
await updateCollections();
|
||||||
|
|
||||||
|
@@ -53,7 +53,7 @@ type State = {
|
|||||||
defaultModels: SystemDefaultModelType;
|
defaultModels: SystemDefaultModelType;
|
||||||
llmModelList: LLMModelItemType[];
|
llmModelList: LLMModelItemType[];
|
||||||
datasetModelList: LLMModelItemType[];
|
datasetModelList: LLMModelItemType[];
|
||||||
getVllmModelList: () => LLMModelItemType[];
|
getVlmModelList: () => LLMModelItemType[];
|
||||||
embeddingModelList: EmbeddingModelItemType[];
|
embeddingModelList: EmbeddingModelItemType[];
|
||||||
ttsModelList: TTSModelType[];
|
ttsModelList: TTSModelType[];
|
||||||
reRankModelList: ReRankModelItemType[];
|
reRankModelList: ReRankModelItemType[];
|
||||||
@@ -135,7 +135,7 @@ export const useSystemStore = create<State>()(
|
|||||||
ttsModelList: [],
|
ttsModelList: [],
|
||||||
reRankModelList: [],
|
reRankModelList: [],
|
||||||
sttModelList: [],
|
sttModelList: [],
|
||||||
getVllmModelList: () => {
|
getVlmModelList: () => {
|
||||||
return get().llmModelList.filter((item) => item.vision);
|
return get().llmModelList.filter((item) => item.vision);
|
||||||
},
|
},
|
||||||
initStaticData(res) {
|
initStaticData(res) {
|
||||||
|
Reference in New Issue
Block a user