4.6.5- CoreferenceResolution Module (#631)

This commit is contained in:
Archer
2023-12-22 10:47:31 +08:00
committed by GitHub
parent 41115a96c0
commit cd682d4275
112 changed files with 4163 additions and 2700 deletions

View File

@@ -6,9 +6,9 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type.d';
import type { ModuleItemType } from '@fastgpt/global/core/module/type';
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/module/node/constant';
import { FormatForm2ModulesProps } from '@fastgpt/global/core/app/api';
import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constant';
import { getExtractModel } from '@/service/core/ai/model';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -31,13 +31,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
}
}
function simpleChatTemplate({
formData,
maxToken
}: {
formData: AppSimpleEditFormType;
maxToken: number;
}): ModuleItemType[] {
type Props = { formData: AppSimpleEditFormType; maxToken: number };
function simpleChatTemplate({ formData, maxToken }: Props): ModuleItemType[] {
return [
{
moduleId: 'userChatInput',
@@ -52,7 +48,10 @@ function simpleChatTemplate({
{
key: 'userChatInput',
type: 'systemInput',
valueType: 'string',
label: '用户问题',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
}
],
@@ -87,6 +86,8 @@ function simpleChatTemplate({
type: 'target',
label: 'core.module.input.label.switch',
valueType: 'any',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
@@ -94,6 +95,9 @@ function simpleChatTemplate({
type: 'selectChatModel',
label: '对话模型',
required: true,
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.model,
connected: false
},
@@ -102,6 +106,7 @@ function simpleChatTemplate({
type: 'hidden',
label: '温度',
value: 1,
valueType: 'number',
min: 0,
max: 10,
step: 1,
@@ -115,6 +120,8 @@ function simpleChatTemplate({
value: 10
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
@@ -122,6 +129,7 @@ function simpleChatTemplate({
type: 'hidden',
label: '回复上限',
value: maxToken,
valueType: 'number',
min: 100,
max: 4000,
step: 50,
@@ -135,14 +143,18 @@ function simpleChatTemplate({
value: 4000
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'isResponseAnswerText',
type: 'hidden',
label: '返回AI内容',
valueType: 'boolean',
value: true,
valueType: 'boolean',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
@@ -150,6 +162,9 @@ function simpleChatTemplate({
type: 'hidden',
label: '引用内容模板',
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.quoteTemplate,
connected: false
},
{
@@ -157,12 +172,18 @@ function simpleChatTemplate({
type: 'hidden',
label: '引用内容提示词',
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.quotePrompt,
connected: false
},
{
key: 'aiSettings',
type: 'aiSettings',
label: '',
valueType: 'any',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
@@ -175,31 +196,42 @@ function simpleChatTemplate({
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
placeholder:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
showTargetInApp: true,
showTargetInPlugin: true,
value: formData.aiSettings.systemPrompt,
connected: false
},
{
key: 'history',
type: 'numberInput',
label: 'core.module.input.label.chat history',
required: true,
min: 0,
max: 30,
valueType: 'chatHistory',
value: 8,
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
description: "对象数组格式,结构:\n [{q:'问题',a:'回答'}]",
valueType: 'datasetQuote',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'history',
type: 'target',
label: 'core.module.input.label.chat history',
valueType: 'chatHistory',
connected: false,
value: 8
},
{
key: 'userChatInput',
type: 'target',
label: 'core.module.input.label.user question',
required: true,
valueType: 'string',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
}
],
@@ -232,29 +264,26 @@ function simpleChatTemplate({
}
];
}
function datasetTemplate({
formData,
maxToken
}: {
formData: AppSimpleEditFormType;
maxToken: number;
}): ModuleItemType[] {
return [
function datasetTemplate({ formData, maxToken }: Props): ModuleItemType[] {
const modules: ModuleItemType[] = [
{
moduleId: 'userChatInput',
name: '用户问题(对话入口)',
avatar: '/imgs/module/userChatInput.png',
flowType: 'questionInput',
position: {
x: 464.32198615344566,
y: 1602.2698463081606
x: 324.81436595478294,
y: 1527.0012457753612
},
inputs: [
{
key: 'userChatInput',
type: 'systemInput',
valueType: 'string',
label: '用户问题',
connected: true
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
}
],
outputs: [
@@ -265,11 +294,11 @@ function datasetTemplate({
valueType: 'string',
targets: [
{
moduleId: 'chatModule',
moduleId: 'vuc92c',
key: 'userChatInput'
},
{
moduleId: 'datasetSearch',
moduleId: 'chatModule',
key: 'userChatInput'
}
]
@@ -283,43 +312,65 @@ function datasetTemplate({
flowType: 'datasetSearchNode',
showStatus: true,
position: {
x: 956.0838440206068,
y: 887.462827870246
x: 1351.5043753345153,
y: 947.0780385418003
},
inputs: [
{
key: 'switch',
type: 'target',
label: 'core.module.input.label.switch',
valueType: 'any',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'datasets',
value: formData.dataset.datasets,
type: FlowNodeInputTypeEnum.custom,
type: 'selectDataset',
label: '关联的知识库',
value: formData.dataset.datasets,
valueType: 'selectDataset',
list: [],
required: true,
showTargetInApp: false,
showTargetInPlugin: true,
connected: false
},
{
key: 'similarity',
value: 0.1,
type: FlowNodeInputTypeEnum.slider,
label: '相关度',
type: 'hidden',
label: '最低相关性',
value: 0.15,
valueType: 'number',
min: 0,
max: 1,
step: 0.01,
markList: [
{
label: '0',
value: 0
},
{
label: '1',
value: 1
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'limit',
type: 'hidden',
label: '引用上限',
description: '单次搜索最大的 Tokens 数量中文约1字=1.7Tokens英文约1字=1Tokens',
value: 2000,
type: FlowNodeInputTypeEnum.slider,
label: '单次搜索上限',
valueType: 'number',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'switch',
type: FlowNodeInputTypeEnum.target,
label: '触发器',
connected: false
},
{
key: 'userChatInput',
type: FlowNodeInputTypeEnum.target,
label: '用户问题',
connected: true
},
{
key: 'searchMode',
type: 'hidden',
@@ -334,10 +385,20 @@ function datasetTemplate({
key: 'datasetParamsModal',
type: 'selectDatasetParamsModal',
label: '',
connected: false,
valueType: 'any',
showTargetInApp: false,
showTargetInPlugin: false
showTargetInPlugin: false,
connected: false
},
{
key: 'userChatInput',
type: 'target',
label: 'core.module.input.label.user question',
required: true,
valueType: 'string',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
}
],
outputs: [
@@ -386,8 +447,8 @@ function datasetTemplate({
flowType: 'chatNode',
showStatus: true,
position: {
x: 1551.71405495818,
y: 977.4911578918461
x: 2022.7264786978908,
y: 1006.3102431257475
},
inputs: [
{
@@ -395,6 +456,8 @@ function datasetTemplate({
type: 'target',
label: 'core.module.input.label.switch',
valueType: 'any',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
@@ -402,6 +465,9 @@ function datasetTemplate({
type: 'selectChatModel',
label: '对话模型',
required: true,
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.model,
connected: false
},
@@ -410,6 +476,7 @@ function datasetTemplate({
type: 'hidden',
label: '温度',
value: 0,
valueType: 'number',
min: 0,
max: 10,
step: 1,
@@ -423,6 +490,8 @@ function datasetTemplate({
value: 10
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
@@ -430,6 +499,7 @@ function datasetTemplate({
type: 'hidden',
label: '回复上限',
value: maxToken,
valueType: 'number',
min: 100,
max: 4000,
step: 50,
@@ -443,14 +513,18 @@ function datasetTemplate({
value: 4000
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'isResponseAnswerText',
type: 'hidden',
label: '返回AI内容',
valueType: 'boolean',
value: true,
valueType: 'boolean',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
@@ -458,6 +532,9 @@ function datasetTemplate({
type: 'hidden',
label: '引用内容模板',
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: '',
connected: false
},
{
@@ -465,12 +542,18 @@ function datasetTemplate({
type: 'hidden',
label: '引用内容提示词',
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: '',
connected: false
},
{
key: 'aiSettings',
type: 'aiSettings',
label: '',
valueType: 'any',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
@@ -483,31 +566,42 @@ function datasetTemplate({
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
placeholder:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
showTargetInApp: true,
showTargetInPlugin: true,
value: formData.aiSettings.systemPrompt,
connected: false
},
{
key: 'history',
type: 'numberInput',
label: 'core.module.input.label.chat history',
required: true,
min: 0,
max: 30,
valueType: 'chatHistory',
value: 6,
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
description: "对象数组格式,结构:\n [{q:'问题',a:'回答'}]",
valueType: 'datasetQuote',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
},
{
key: 'history',
type: 'target',
label: 'core.module.input.label.chat history',
valueType: 'chatHistory',
connected: false,
value: 8
},
{
key: 'userChatInput',
type: 'target',
label: 'core.module.input.label.user question',
required: true,
valueType: 'string',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
}
],
@@ -537,6 +631,91 @@ function datasetTemplate({
targets: []
}
]
},
{
moduleId: 'vuc92c',
name: 'core.module.template.cfr',
avatar: '/imgs/module/cfr.svg',
flowType: 'cfr',
showStatus: true,
position: {
x: 758.2985382279098,
y: 1124.6527309337314
},
inputs: [
{
key: 'switch',
type: 'target',
label: 'core.module.input.label.switch',
valueType: 'any',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'model',
type: 'selectExtractModel',
label: 'core.module.input.label.aiModel',
required: true,
valueType: 'string',
value: getExtractModel().model,
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'systemPrompt',
type: 'textarea',
label: 'core.module.input.label.cfr background',
max: 300,
value: formData.cfr.background,
valueType: 'string',
description: 'core.module.input.description.cfr background',
placeholder: 'core.module.input.placeholder.cfr background',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'history',
type: 'numberInput',
label: 'core.module.input.label.chat history',
required: true,
min: 0,
max: 30,
valueType: 'chatHistory',
value: 6,
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'userChatInput',
type: 'target',
label: 'core.module.input.label.user question',
required: true,
valueType: 'string',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
}
],
outputs: [
{
key: 'system_text',
label: 'core.module.output.label.cfr result',
valueType: 'string',
type: 'source',
targets: [
{
moduleId: 'datasetSearch',
key: 'userChatInput'
}
]
}
]
}
];
return modules;
}

View File

@@ -6,15 +6,12 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type.d';
import type { ModuleItemType } from '@fastgpt/global/core/module/type';
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
import { ModuleIOValueTypeEnum } from '@fastgpt/global/core/module/constants';
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
import type { FlowNodeInputItemType } from '@fastgpt/global/core/module/node/type.d';
import { FormatForm2ModulesProps } from '@fastgpt/global/core/app/api';
import { getExtractModel } from '@/service/core/ai/model';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
const { formData, chatModelList } = req.body as FormatForm2ModulesProps;
const { formData } = req.body as FormatForm2ModulesProps;
const modules =
formData.dataset.datasets.length > 0
@@ -32,100 +29,34 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
}
}
function chatModelInput(formData: AppSimpleEditFormType): FlowNodeInputItemType[] {
return [
{
key: 'model',
value: formData.aiSettings.model,
type: 'custom',
label: '对话模型',
connected: false
},
{
key: 'temperature',
value: formData.aiSettings.temperature,
type: 'slider',
label: '温度',
connected: false
},
{
key: 'maxToken',
value: formData.aiSettings.maxToken,
type: 'custom',
label: '回复上限',
connected: false
},
{
key: 'systemPrompt',
value: formData.aiSettings.systemPrompt || '',
type: 'textarea',
label: '系统提示词',
connected: false
},
{
key: ModuleInputKeyEnum.aiChatIsResponseText,
value: true,
type: 'hidden',
label: '返回AI内容',
connected: false
},
{
key: 'quoteTemplate',
value: formData.aiSettings.quoteTemplate || '',
type: 'hidden',
label: '引用内容模板',
connected: false
},
{
key: 'quotePrompt',
value: formData.aiSettings.quotePrompt || '',
type: 'hidden',
label: '引用内容提示词',
connected: false
},
{
key: 'switch',
type: 'target',
label: '触发器',
connected: formData.dataset.datasets.length > 0 && !!formData.dataset.searchEmptyText
},
{
key: 'history',
type: 'target',
label: 'core.module.input.label.chat history',
connected: false,
value: 6
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
connected: formData.dataset.datasets.length > 0
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
connected: true
}
];
}
function simpleChatTemplate(formData: AppSimpleEditFormType): ModuleItemType[] {
return [
{
moduleId: 'userChatInput',
name: '用户问题(对话入口)',
flowType: FlowNodeTypeEnum.questionInput,
avatar: '/imgs/module/userChatInput.png',
flowType: 'questionInput',
position: {
x: 464.32198615344566,
y: 1602.2698463081606
},
inputs: [
{
key: 'userChatInput',
connected: false,
type: 'systemInput',
valueType: 'string',
label: '用户问题',
type: 'systemInput'
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
}
],
outputs: [
{
key: 'userChatInput',
label: '用户问题',
type: 'source',
valueType: 'string',
targets: [
{
moduleId: 'chatModule',
@@ -133,115 +64,309 @@ function simpleChatTemplate(formData: AppSimpleEditFormType): ModuleItemType[] {
}
]
}
],
position: {
x: 464.32198615344566,
y: 1602.2698463081606
},
moduleId: 'userChatInput'
]
},
{
moduleId: 'chatModule',
name: 'AI 对话',
flowType: FlowNodeTypeEnum.chatNode,
inputs: chatModelInput(formData),
avatar: '/imgs/module/AI.png',
flowType: 'chatNode',
showStatus: true,
outputs: [
{
key: 'answerText',
label: 'AI回复',
description: '直接响应,无需配置',
type: 'hidden',
targets: []
},
{
key: 'finish',
label: '回复结束',
description: 'AI 回复完成后触发',
valueType: 'boolean',
type: 'source',
targets: []
}
],
position: {
x: 981.9682828103937,
y: 890.014595014464
},
moduleId: 'chatModule'
inputs: [
{
key: 'switch',
type: 'target',
label: 'core.module.input.label.switch',
valueType: 'any',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'model',
type: 'selectChatModel',
label: '对话模型',
required: true,
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.model,
connected: false
},
{
key: 'temperature',
type: 'hidden',
label: '温度',
value: formData.aiSettings.temperature,
valueType: 'number',
min: 0,
max: 10,
step: 1,
markList: [
{
label: '严谨',
value: 0
},
{
label: '发散',
value: 10
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'maxToken',
type: 'hidden',
label: '回复上限',
value: formData.aiSettings.maxToken,
valueType: 'number',
min: 100,
max: 4000,
step: 50,
markList: [
{
label: '100',
value: 100
},
{
label: '4000',
value: 4000
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'isResponseAnswerText',
type: 'hidden',
label: '返回AI内容',
value: true,
valueType: 'boolean',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'quoteTemplate',
type: 'hidden',
label: '引用内容模板',
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.quoteTemplate,
connected: false
},
{
key: 'quotePrompt',
type: 'hidden',
label: '引用内容提示词',
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.quotePrompt,
connected: false
},
{
key: 'aiSettings',
type: 'aiSettings',
label: '',
valueType: 'any',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'systemPrompt',
type: 'textarea',
label: '系统提示词',
max: 300,
valueType: 'string',
description:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
placeholder:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
showTargetInApp: true,
showTargetInPlugin: true,
value: formData.aiSettings.systemPrompt,
connected: false
},
{
key: 'history',
type: 'numberInput',
label: 'core.module.input.label.chat history',
required: true,
min: 0,
max: 30,
valueType: 'chatHistory',
value: 6,
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
description: "对象数组格式,结构:\n [{q:'问题',a:'回答'}]",
valueType: 'datasetQuote',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'userChatInput',
type: 'target',
label: 'core.module.input.label.user question',
required: true,
valueType: 'string',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
}
],
outputs: [
{
key: 'answerText',
label: 'AI回复',
description: '将在 stream 回复完毕后触发',
valueType: 'string',
type: 'source',
targets: []
},
{
key: 'finish',
label: 'core.module.output.label.running done',
description: 'core.module.output.description.running done',
valueType: 'boolean',
type: 'source',
targets: []
},
{
key: 'history',
label: '新的上下文',
description: '将本次回复内容拼接上历史记录,作为新的上下文返回',
valueType: 'chatHistory',
type: 'source',
targets: []
}
]
}
];
}
function datasetTemplate(formData: AppSimpleEditFormType): ModuleItemType[] {
return [
const modules: ModuleItemType[] = [
{
moduleId: 'userChatInput',
name: '用户问题(对话入口)',
flowType: FlowNodeTypeEnum.questionInput,
avatar: '/imgs/module/userChatInput.png',
flowType: 'questionInput',
position: {
x: 324.81436595478294,
y: 1527.0012457753612
},
inputs: [
{
key: 'userChatInput',
label: '用户问题',
type: 'systemInput',
valueType: 'string',
label: '用户问题',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
}
],
outputs: [
{
key: 'userChatInput',
label: '用户问题',
type: 'source',
valueType: 'string',
targets: [
{
moduleId: 'chatModule',
moduleId: 'vuc92c',
key: 'userChatInput'
},
{
moduleId: 'datasetSearch',
moduleId: 'chatModule',
key: 'userChatInput'
}
]
}
],
position: {
x: 464.32198615344566,
y: 1602.2698463081606
},
moduleId: 'userChatInput'
]
},
{
moduleId: 'datasetSearch',
name: '知识库搜索',
flowType: FlowNodeTypeEnum.datasetSearchNode,
avatar: '/imgs/module/db.png',
flowType: 'datasetSearchNode',
showStatus: true,
position: {
x: 1351.5043753345153,
y: 947.0780385418003
},
inputs: [
{
key: 'switch',
type: 'target',
label: 'core.module.input.label.switch',
valueType: 'any',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'datasets',
value: formData.dataset.datasets,
type: FlowNodeInputTypeEnum.custom,
type: 'selectDataset',
label: '关联的知识库',
value: formData.dataset.datasets,
valueType: 'selectDataset',
list: [],
required: true,
showTargetInApp: false,
showTargetInPlugin: true,
connected: false
},
{
key: 'similarity',
type: 'hidden',
label: '最低相关性',
value: formData.dataset.similarity,
type: FlowNodeInputTypeEnum.slider,
label: '相关度',
valueType: 'number',
min: 0,
max: 1,
step: 0.01,
markList: [
{
label: '0',
value: 0
},
{
label: '1',
value: 1
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'limit',
type: 'hidden',
label: '引用上限',
description: '单次搜索最大的 Tokens 数量中文约1字=1.7Tokens英文约1字=1Tokens',
value: formData.dataset.limit,
type: FlowNodeInputTypeEnum.slider,
label: '单次搜索上限',
valueType: 'number',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'switch',
type: FlowNodeInputTypeEnum.target,
label: '触发器',
connected: false
},
{
key: 'userChatInput',
type: FlowNodeInputTypeEnum.target,
label: '用户问题',
connected: true
},
{
key: 'searchMode',
type: 'hidden',
@@ -256,19 +381,32 @@ function datasetTemplate(formData: AppSimpleEditFormType): ModuleItemType[] {
key: 'datasetParamsModal',
type: 'selectDatasetParamsModal',
label: '',
connected: false,
valueType: 'any',
showTargetInApp: false,
showTargetInPlugin: false
showTargetInPlugin: false,
connected: false
},
{
key: 'userChatInput',
type: 'target',
label: 'core.module.input.label.user question',
required: true,
valueType: 'string',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
}
],
outputs: [
{
key: 'isEmpty',
label: '搜索结果为空',
type: 'source',
valueType: 'boolean',
targets: formData.dataset.searchEmptyText
? [
{
moduleId: 'emptyText',
moduleId: '6dtsvu',
key: 'switch'
}
]
@@ -276,6 +414,9 @@ function datasetTemplate(formData: AppSimpleEditFormType): ModuleItemType[] {
},
{
key: 'unEmpty',
label: '搜索结果不为空',
type: 'source',
valueType: 'boolean',
targets: formData.dataset.searchEmptyText
? [
{
@@ -287,77 +428,352 @@ function datasetTemplate(formData: AppSimpleEditFormType): ModuleItemType[] {
},
{
key: 'quoteQA',
label: '引用内容',
description:
'始终返回数组,如果希望搜索结果为空时执行额外操作,需要用到上面的两个输入以及目标模块的触发器',
type: 'source',
valueType: 'datasetQuote',
targets: [
{
moduleId: 'chatModule',
key: 'quoteQA'
}
]
}
],
position: {
x: 956.0838440206068,
y: 887.462827870246
},
moduleId: 'datasetSearch'
},
...(formData.dataset.searchEmptyText
? [
{
name: '指定回复',
flowType: FlowNodeTypeEnum.answerNode,
inputs: [
{
key: ModuleInputKeyEnum.switch,
type: FlowNodeInputTypeEnum.target,
label: '触发器',
connected: true
},
{
key: ModuleInputKeyEnum.answerText,
value: formData.dataset.searchEmptyText,
type: FlowNodeInputTypeEnum.textarea,
valueType: ModuleIOValueTypeEnum.string,
label: '回复的内容',
connected: false
}
],
outputs: [],
position: {
x: 1553.5815811529146,
y: 637.8753731306779
},
moduleId: 'emptyText'
}
]
: []),
{
name: 'AI 对话',
flowType: FlowNodeTypeEnum.chatNode,
inputs: chatModelInput(formData),
showStatus: true,
outputs: [
{
key: 'answerText',
label: 'AI回复',
description: '直接响应,无需配置',
type: 'hidden',
targets: []
},
{
key: 'finish',
label: '回复结束',
description: 'AI 回复完成后触发',
label: 'core.module.output.label.running done',
description: 'core.module.output.description.running done',
valueType: 'boolean',
type: 'source',
targets: []
}
],
]
},
{
moduleId: 'chatModule',
name: 'AI 对话',
avatar: '/imgs/module/AI.png',
flowType: 'chatNode',
showStatus: true,
position: {
x: 1551.71405495818,
y: 977.4911578918461
x: 2022.7264786978908,
y: 1006.3102431257475
},
moduleId: 'chatModule'
inputs: [
{
key: 'switch',
type: 'target',
label: 'core.module.input.label.switch',
valueType: 'any',
showTargetInApp: true,
showTargetInPlugin: true,
connected: !!formData.dataset?.searchEmptyText
},
{
key: 'model',
type: 'selectChatModel',
label: '对话模型',
required: true,
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.model,
connected: false
},
{
key: 'temperature',
type: 'hidden',
label: '温度',
value: formData.aiSettings.temperature,
valueType: 'number',
min: 0,
max: 10,
step: 1,
markList: [
{
label: '严谨',
value: 0
},
{
label: '发散',
value: 10
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'maxToken',
type: 'hidden',
label: '回复上限',
value: formData.aiSettings.maxToken,
valueType: 'number',
min: 100,
max: 4000,
step: 50,
markList: [
{
label: '100',
value: 100
},
{
label: '4000',
value: 4000
}
],
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'isResponseAnswerText',
type: 'hidden',
label: '返回AI内容',
value: true,
valueType: 'boolean',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'quoteTemplate',
type: 'hidden',
label: '引用内容模板',
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.quoteTemplate,
connected: false
},
{
key: 'quotePrompt',
type: 'hidden',
label: '引用内容提示词',
valueType: 'string',
showTargetInApp: false,
showTargetInPlugin: false,
value: formData.aiSettings.quotePrompt,
connected: false
},
{
key: 'aiSettings',
type: 'aiSettings',
label: '',
valueType: 'any',
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'systemPrompt',
type: 'textarea',
label: '系统提示词',
max: 300,
valueType: 'string',
description:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
placeholder:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
showTargetInApp: true,
showTargetInPlugin: true,
value: formData.aiSettings.systemPrompt,
connected: false
},
{
key: 'history',
type: 'numberInput',
label: 'core.module.input.label.chat history',
required: true,
min: 0,
max: 30,
valueType: 'chatHistory',
value: 6,
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
description: "对象数组格式,结构:\n [{q:'问题',a:'回答'}]",
valueType: 'datasetQuote',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
},
{
key: 'userChatInput',
type: 'target',
label: 'core.module.input.label.user question',
required: true,
valueType: 'string',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
}
],
outputs: [
{
key: 'answerText',
label: 'AI回复',
description: '将在 stream 回复完毕后触发',
valueType: 'string',
type: 'source',
targets: []
},
{
key: 'finish',
label: 'core.module.output.label.running done',
description: 'core.module.output.description.running done',
valueType: 'boolean',
type: 'source',
targets: []
},
{
key: 'history',
label: '新的上下文',
description: '将本次回复内容拼接上历史记录,作为新的上下文返回',
valueType: 'chatHistory',
type: 'source',
targets: []
}
]
},
{
moduleId: 'vuc92c',
name: 'core.module.template.cfr',
avatar: '/imgs/module/cfr.svg',
flowType: 'cfr',
showStatus: true,
position: {
x: 758.2985382279098,
y: 1124.6527309337314
},
inputs: [
{
key: 'switch',
type: 'target',
label: 'core.module.input.label.switch',
valueType: 'any',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'model',
type: 'selectExtractModel',
label: 'core.module.input.label.aiModel',
required: true,
valueType: 'string',
value: getExtractModel().model,
showTargetInApp: false,
showTargetInPlugin: false,
connected: false
},
{
key: 'systemPrompt',
type: 'textarea',
label: 'core.module.input.label.cfr background',
max: 300,
value: formData.cfr.background,
valueType: 'string',
description: 'core.module.input.description.cfr background',
placeholder: 'core.module.input.placeholder.cfr background',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'history',
type: 'numberInput',
label: 'core.module.input.label.chat history',
required: true,
min: 0,
max: 30,
valueType: 'chatHistory',
value: 6,
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
},
{
key: 'userChatInput',
type: 'target',
label: 'core.module.input.label.user question',
required: true,
valueType: 'string',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
}
],
outputs: [
{
key: 'system_text',
label: 'core.module.output.label.cfr result',
valueType: 'string',
type: 'source',
targets: [
{
moduleId: 'datasetSearch',
key: 'userChatInput'
}
]
}
]
}
];
if (formData.dataset?.searchEmptyText) {
modules.push({
moduleId: '6dtsvu',
name: '指定回复',
avatar: '/imgs/module/reply.png',
flowType: 'answerNode',
position: {
x: 2018.2744321961648,
y: 616.1220817209096
},
inputs: [
{
key: 'switch',
type: 'target',
label: 'core.module.input.label.switch',
valueType: 'any',
showTargetInApp: true,
showTargetInPlugin: true,
connected: true
},
{
key: 'text',
type: 'textarea',
value: formData.dataset.searchEmptyText,
valueType: 'any',
label: '回复的内容',
description:
'可以使用 \\n 来实现连续换行。\n可以通过外部模块输入实现回复外部模块输入时会覆盖当前填写的内容。\n如传入非字符串类型数据将会自动转成字符串',
placeholder:
'可以使用 \\n 来实现连续换行。\n可以通过外部模块输入实现回复外部模块输入时会覆盖当前填写的内容。\n如传入非字符串类型数据将会自动转成字符串',
showTargetInApp: true,
showTargetInPlugin: true,
connected: false
}
],
outputs: [
{
key: 'finish',
label: 'core.module.output.label.running done',
description: 'core.module.output.description.running done',
valueType: 'boolean',
type: 'source',
targets: []
}
]
});
}
return modules;
}

View File

@@ -58,6 +58,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
/* start process */
const { responseData } = await dispatchModules({
res,
mode: 'test',
teamId,
tmbId,
user,
@@ -101,6 +102,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
export const config = {
api: {
bodyParser: {
sizeLimit: '10mb'
},
responseLimit: '20mb'
}
};

View File

@@ -9,6 +9,7 @@ import { pushGenerateVectorBill } from '@/service/support/wallet/bill/push';
import { searchDatasetData } from '@/service/core/dataset/data/pg';
import { updateApiKeyUsage } from '@fastgpt/service/support/openapi/tools';
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
import { searchQueryExtension } from '@fastgpt/service/core/ai/functions/queryExtension';
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -33,8 +34,15 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
// auth balance
await authTeamBalance(teamId);
// query extension
// const { queries } = await searchQueryExtension({
// query: text,
// model: global.chatModels[0].model
// });
const { searchRes, tokenLen } = await searchDatasetData({
text,
rawQuery: text,
queries: [text],
model: dataset.vectorModel,
limit: Math.min(limit * 800, 30000),
datasetIds: [datasetId],

View File

@@ -19,6 +19,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
const result = (() => {
if (typeof input === 'string') {
const defaultReg: any[] = [
'',
undefined,
'undefined',
null,

View File

@@ -2,12 +2,14 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { request } from '@fastgpt/service/common/api/plusRequest';
import type { Method } from 'axios';
import { connectToDatabase } from '@/service/mongo';
import { setCookie } from '@fastgpt/service/support/permission/controller';
import { getInitConfig } from '../system/getInitData';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
if (!global.systemEnv?.pluginBaseUrl) {
await getInitConfig();
}
const method = (req.method || 'POST') as Method;
const { path = [], ...query } = req.query as any;

View File

@@ -1,4 +1,4 @@
import type { FeConfigsType, SystemEnvType } from '@fastgpt/global/common/system/types/index.d';
import type { FeConfigsType } from '@fastgpt/global/common/system/types/index.d';
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { readFileSync, readdirSync } from 'fs';
@@ -6,23 +6,14 @@ import type { ConfigFileType, InitDateResponse } from '@/global/common/api/syste
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
import { getTikTokenEnc } from '@fastgpt/global/common/string/tiktoken';
import { initHttpAgent } from '@fastgpt/service/common/middle/httpAgent';
import {
defaultChatModels,
defaultQAModels,
defaultCQModels,
defaultExtractModels,
defaultQGModels,
defaultVectorModels,
defaultAudioSpeechModels,
defaultWhisperModel,
defaultReRankModels
} from '@fastgpt/global/core/ai/model';
import { SimpleModeTemplate_FastGPT_Universal } from '@/global/core/app/constants';
import { getSimpleTemplatesFromPlus } from '@/service/core/app/utils';
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
import { getFastGPTFeConfig } from '@fastgpt/service/common/system/config/controller';
import { connectToDatabase } from '@/service/mongo';
import { PluginTemplateType } from '@fastgpt/global/core/plugin/type';
import { readConfigData } from '@/service/common/system';
import { exit } from 'process';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
await getInitConfig();
@@ -48,18 +39,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
}
const defaultSystemEnv: SystemEnvType = {
vectorMaxProcess: 15,
qaMaxProcess: 15,
pgHNSWEfSearch: 100
};
const defaultFeConfigs: FeConfigsType = {
show_emptyChat: true,
show_git: true,
show_register: false,
docUrl: 'https://doc.fastgpt.in',
openAPIDocUrl: 'https://doc.fastgpt.in/docs/development/openapi',
systemTitle: 'FastGPT',
concatMd:
'* 项目开源地址: [FastGPT GitHub](https://github.com/labring/FastGPT)\n* 交流群: ![](https://doc.fastgpt.in/wechat-fastgpt.webp)',
limit: {
exportLimitMinutes: 0
},
@@ -73,24 +60,45 @@ export async function getInitConfig() {
await connectToDatabase();
initGlobal();
const filename =
process.env.NODE_ENV === 'development' ? 'data/config.local.json' : '/app/data/config.json';
const res = JSON.parse(readFileSync(filename, 'utf-8')) as ConfigFileType;
// load config
const [dbConfig, fileConfig] = await Promise.all([
getFastGPTFeConfig(),
readConfigData('config.json')
]);
const fileRes = JSON.parse(fileConfig) as ConfigFileType;
// get config from database
const dbFeConfig = await getFastGPTFeConfig();
const concatConfig: ConfigFileType = {
...res,
const config: ConfigFileType = {
...fileRes,
FeConfig: {
...res.FeConfig,
...dbFeConfig
...defaultFeConfigs,
...fileRes.FeConfig,
...dbConfig
}
};
setDefaultData(concatConfig);
// set config
global.feConfigs = {
isPlus: !!config.SystemParams.pluginBaseUrl,
concatMd: config.FeConfig.show_git ? config.FeConfig.concatMd : '',
...config.FeConfig
};
global.systemEnv = config.SystemParams;
global.chatModels = config.ChatModels;
global.qaModels = config.QAModels;
global.cqModels = config.CQModels;
global.extractModels = config.ExtractModels;
global.qgModels = config.QGModels;
global.vectorModels = config.VectorModels;
global.reRankModels = config.ReRankModels;
global.audioSpeechModels = config.AudioSpeechModels;
global.whisperModel = config.WhisperModel;
global.priceMd = '';
} catch (error) {
setDefaultData();
console.log('get init config error, set default', error);
console.error('Load init config error', error);
exit(1);
}
await getSimpleModeTemplates();
@@ -117,45 +125,13 @@ export async function getInitConfig() {
}
export function initGlobal() {
// init tikToken
getTikTokenEnc();
initHttpAgent();
global.communityPlugins = [];
global.simpleModeTemplates = [];
global.qaQueueLen = global.qaQueueLen ?? 0;
global.vectorQueueLen = global.vectorQueueLen ?? 0;
}
export function setDefaultData(res?: ConfigFileType) {
global.systemEnv = res?.SystemParams
? { ...defaultSystemEnv, ...res.SystemParams }
: defaultSystemEnv;
global.feConfigs = res?.FeConfig
? {
concatMd: res?.FeConfig?.show_git
? '* 项目开源地址: [FastGPT GitHub](https://github.com/labring/FastGPT)\n* 交流群: ![](https://doc.fastgpt.in/wechat-fastgpt.webp)'
: '',
...defaultFeConfigs,
...res.FeConfig,
isPlus: !!res.SystemParams?.pluginBaseUrl
}
: defaultFeConfigs;
global.chatModels = res?.ChatModels || defaultChatModels;
global.qaModels = res?.QAModels || defaultQAModels;
global.cqModels = res?.CQModels || defaultCQModels;
global.extractModels = res?.ExtractModels || defaultExtractModels;
global.qgModels = res?.QGModels || defaultQGModels;
global.vectorModels = res?.VectorModels || defaultVectorModels;
global.reRankModels = res?.ReRankModels || defaultReRankModels;
global.audioSpeechModels = res?.AudioSpeechModels || defaultAudioSpeechModels;
global.whisperModel = res?.WhisperModel || defaultWhisperModel;
global.priceMd = '';
// init tikToken
getTikTokenEnc();
initHttpAgent();
}
export function getSystemVersion() {
@@ -209,9 +185,7 @@ async function getSimpleModeTemplates() {
try {
const basePath =
process.env.NODE_ENV === 'development'
? 'public/simpleTemplates'
: '/app/projects/app/public/simpleTemplates';
process.env.NODE_ENV === 'development' ? 'data/simpleTemplates' : '/app/data/simpleTemplates';
// read data/simpleTemplates directory, get all json file
const files = readdirSync(basePath);
// filter json file
@@ -243,9 +217,7 @@ function getSystemPlugin() {
if (global.communityPlugins && global.communityPlugins.length > 0) return;
const basePath =
process.env.NODE_ENV === 'development'
? 'public/pluginTemplates'
: '/app/projects/app/public/pluginTemplates';
process.env.NODE_ENV === 'development' ? 'data/pluginTemplates' : '/app/data/pluginTemplates';
// read data/pluginTemplates directory, get all json file
const files = readdirSync(basePath);
// filter json file

View File

@@ -200,13 +200,14 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
/* start flow controller */
const { responseData, answerText } = await dispatchModules({
res,
mode: 'chat',
user,
teamId: String(user.team.teamId),
tmbId: String(user.team.tmbId),
appId: String(app._id),
chatId,
responseChatItemId,
modules: app.modules,
user,
teamId: user.team.teamId,
tmbId: user.team.tmbId,
variables,
histories: concatHistories,
startParams: {