v4.6.2-alpah (#511)
@ -20,7 +20,7 @@ export const splitText2Chunks = (props: { text: string; maxLen: number; overlapL
|
|||||||
|
|
||||||
4: /(\n\n)/g,
|
4: /(\n\n)/g,
|
||||||
5: /([\n])/g,
|
5: /([\n])/g,
|
||||||
6: /[。]|(?!<[^a-zA-Z])\.\s/g,
|
6: /([。]|(?!<[^a-zA-Z])\.\s)/g,
|
||||||
7: /([!?]|!\s|\?\s)/g,
|
7: /([!?]|!\s|\?\s)/g,
|
||||||
8: /([;]|;\s)/g,
|
8: /([;]|;\s)/g,
|
||||||
9: /([,]|,\s)/g
|
9: /([,]|,\s)/g
|
||||||
@ -55,10 +55,15 @@ export const splitText2Chunks = (props: { text: string; maxLen: number; overlapL
|
|||||||
}
|
}
|
||||||
|
|
||||||
// split text by special char
|
// split text by special char
|
||||||
const splitTexts = text
|
const splitTexts = (() => {
|
||||||
|
if (!reg.test(text)) {
|
||||||
|
return [text];
|
||||||
|
}
|
||||||
|
return text
|
||||||
.replace(reg, isMarkdownSplit ? `${tempMarker}$1` : `$1${tempMarker}`)
|
.replace(reg, isMarkdownSplit ? `${tempMarker}$1` : `$1${tempMarker}`)
|
||||||
.split(`${tempMarker}`)
|
.split(`${tempMarker}`)
|
||||||
.filter((part) => part);
|
.filter((part) => part);
|
||||||
|
})();
|
||||||
|
|
||||||
let chunks: string[] = [];
|
let chunks: string[] = [];
|
||||||
for (let i = 0; i < splitTexts.length; i++) {
|
for (let i = 0; i < splitTexts.length; i++) {
|
||||||
|
|||||||
10
packages/global/core/app/api.d.ts
vendored
@ -1,5 +1,6 @@
|
|||||||
|
import type { ChatModelItemType } from '../ai/model.d';
|
||||||
import { AppTypeEnum } from './constants';
|
import { AppTypeEnum } from './constants';
|
||||||
import { AppSchema } from './type';
|
import { AppSchema, AppSimpleEditFormType } from './type';
|
||||||
|
|
||||||
export type CreateAppParams = {
|
export type CreateAppParams = {
|
||||||
name?: string;
|
name?: string;
|
||||||
@ -11,8 +12,15 @@ export type CreateAppParams = {
|
|||||||
export interface AppUpdateParams {
|
export interface AppUpdateParams {
|
||||||
name?: string;
|
name?: string;
|
||||||
type?: `${AppTypeEnum}`;
|
type?: `${AppTypeEnum}`;
|
||||||
|
simpleTemplateId?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
intro?: string;
|
intro?: string;
|
||||||
modules?: AppSchema['modules'];
|
modules?: AppSchema['modules'];
|
||||||
permission?: AppSchema['permission'];
|
permission?: AppSchema['permission'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type FormatForm2ModulesProps = {
|
||||||
|
formData: AppSimpleEditFormType;
|
||||||
|
chatModelMaxToken: number;
|
||||||
|
chatModelList: ChatModelItemType[];
|
||||||
|
};
|
||||||
|
|||||||
@ -1,4 +1,12 @@
|
|||||||
export enum AppTypeEnum {
|
export enum AppTypeEnum {
|
||||||
basic = 'basic',
|
simple = 'simple',
|
||||||
advanced = 'advanced'
|
advanced = 'advanced'
|
||||||
}
|
}
|
||||||
|
export const AppTypeMap = {
|
||||||
|
[AppTypeEnum.simple]: {
|
||||||
|
label: 'simple'
|
||||||
|
},
|
||||||
|
[AppTypeEnum.advanced]: {
|
||||||
|
label: 'advanced'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
90
packages/global/core/app/type.d.ts
vendored
@ -1,6 +1,9 @@
|
|||||||
import { ModuleItemType } from '../module/type';
|
import type { AppTTSConfigType, ModuleItemType, VariableItemType } from '../module/type.d';
|
||||||
import { AppTypeEnum } from './constants';
|
import { AppTypeEnum } from './constants';
|
||||||
import { PermissionTypeEnum } from '../../support/permission/constant';
|
import { PermissionTypeEnum } from '../../support/permission/constant';
|
||||||
|
import type { AIChatModuleProps, DatasetModuleProps } from '../module/node/type.d';
|
||||||
|
import { VariableInputEnum } from '../module/constants';
|
||||||
|
import { SelectedDatasetType } from '../module/api';
|
||||||
|
|
||||||
export interface AppSchema {
|
export interface AppSchema {
|
||||||
_id: string;
|
_id: string;
|
||||||
@ -9,6 +12,7 @@ export interface AppSchema {
|
|||||||
tmbId: string;
|
tmbId: string;
|
||||||
name: string;
|
name: string;
|
||||||
type: `${AppTypeEnum}`;
|
type: `${AppTypeEnum}`;
|
||||||
|
simpleTemplateId: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
intro: string;
|
intro: string;
|
||||||
updateTime: number;
|
updateTime: number;
|
||||||
@ -29,3 +33,87 @@ export type AppDetailType = AppSchema & {
|
|||||||
isOwner: boolean;
|
isOwner: boolean;
|
||||||
canWrite: boolean;
|
canWrite: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// export type AppSimpleEditFormType = {
|
||||||
|
// aiSettings: AIChatModuleProps;
|
||||||
|
// dataset: DatasetModuleProps & {
|
||||||
|
// searchEmptyText: string;
|
||||||
|
// };
|
||||||
|
// userGuide: {
|
||||||
|
// welcomeText: string;
|
||||||
|
// variables: VariableItemType[];
|
||||||
|
// questionGuide: boolean;
|
||||||
|
// tts: AppTTSConfigType;
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
// Since useform cannot infer enumeration types, all enumeration keys can only be undone manually
|
||||||
|
export type AppSimpleEditFormType = {
|
||||||
|
templateId: string;
|
||||||
|
aiSettings: {
|
||||||
|
model: string;
|
||||||
|
systemPrompt?: string | undefined;
|
||||||
|
temperature: number;
|
||||||
|
maxToken: number;
|
||||||
|
isResponseAnswerText: boolean;
|
||||||
|
quoteTemplate?: string | undefined;
|
||||||
|
quotePrompt?: string | undefined;
|
||||||
|
};
|
||||||
|
dataset: {
|
||||||
|
datasets: SelectedDatasetType;
|
||||||
|
similarity: number;
|
||||||
|
limit: number;
|
||||||
|
rerank: boolean;
|
||||||
|
searchEmptyText: string;
|
||||||
|
};
|
||||||
|
userGuide: {
|
||||||
|
welcomeText: string;
|
||||||
|
variables: {
|
||||||
|
id: string;
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
type: `${VariableInputEnum}`;
|
||||||
|
required: boolean;
|
||||||
|
maxLen: number;
|
||||||
|
enums: {
|
||||||
|
value: string;
|
||||||
|
}[];
|
||||||
|
}[];
|
||||||
|
questionGuide: boolean;
|
||||||
|
tts: {
|
||||||
|
type: 'none' | 'web' | 'model';
|
||||||
|
model?: string | undefined;
|
||||||
|
voice?: string | undefined;
|
||||||
|
speed?: number | undefined;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* simple mode template*/
|
||||||
|
export type AppSimpleEditConfigTemplateType = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
desc: string;
|
||||||
|
systemForm: {
|
||||||
|
aiSettings?: {
|
||||||
|
model?: boolean;
|
||||||
|
systemPrompt?: boolean;
|
||||||
|
temperature?: boolean;
|
||||||
|
maxToken?: boolean;
|
||||||
|
quoteTemplate?: boolean;
|
||||||
|
quotePrompt?: boolean;
|
||||||
|
};
|
||||||
|
dataset?: {
|
||||||
|
datasets?: boolean;
|
||||||
|
similarity?: boolean;
|
||||||
|
limit?: boolean;
|
||||||
|
rerank?: boolean;
|
||||||
|
searchEmptyText?: boolean;
|
||||||
|
};
|
||||||
|
userGuide?: {
|
||||||
|
welcomeText?: boolean;
|
||||||
|
variables?: boolean;
|
||||||
|
questionGuide?: boolean;
|
||||||
|
tts?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
123
packages/global/core/app/utils.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import type { AppSimpleEditFormType } from '../app/type';
|
||||||
|
import { FlowNodeTypeEnum } from '../module/node/constant';
|
||||||
|
import { ModuleOutputKeyEnum, ModuleInputKeyEnum } from '../module/constants';
|
||||||
|
import type { FlowNodeInputItemType } from '../module/node/type.d';
|
||||||
|
import { getGuideModule, splitGuideModule } from '../module/utils';
|
||||||
|
import { defaultChatModels } from '../ai/model';
|
||||||
|
import { ModuleItemType } from '../module/type.d';
|
||||||
|
|
||||||
|
export const getDefaultAppForm = (templateId = 'fastgpt-universal'): AppSimpleEditFormType => {
|
||||||
|
const defaultChatModel = defaultChatModels[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
templateId,
|
||||||
|
aiSettings: {
|
||||||
|
model: defaultChatModel?.model,
|
||||||
|
systemPrompt: '',
|
||||||
|
temperature: 0,
|
||||||
|
isResponseAnswerText: true,
|
||||||
|
quotePrompt: '',
|
||||||
|
quoteTemplate: '',
|
||||||
|
maxToken: defaultChatModel ? defaultChatModel.maxResponse / 2 : 4000
|
||||||
|
},
|
||||||
|
dataset: {
|
||||||
|
datasets: [],
|
||||||
|
similarity: 0.4,
|
||||||
|
limit: 5,
|
||||||
|
searchEmptyText: '',
|
||||||
|
rerank: false
|
||||||
|
},
|
||||||
|
userGuide: {
|
||||||
|
welcomeText: '',
|
||||||
|
variables: [],
|
||||||
|
questionGuide: false,
|
||||||
|
tts: {
|
||||||
|
type: 'web'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* format app modules to edit form */
|
||||||
|
export const appModules2Form = ({
|
||||||
|
templateId,
|
||||||
|
modules
|
||||||
|
}: {
|
||||||
|
modules: ModuleItemType[];
|
||||||
|
templateId: string;
|
||||||
|
}) => {
|
||||||
|
const defaultAppForm = getDefaultAppForm(templateId);
|
||||||
|
|
||||||
|
const findInputValueByKey = (inputs: FlowNodeInputItemType[], key: string) => {
|
||||||
|
return inputs.find((item) => item.key === key)?.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
modules.forEach((module) => {
|
||||||
|
if (module.flowType === FlowNodeTypeEnum.chatNode) {
|
||||||
|
defaultAppForm.aiSettings.model = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.aiModel
|
||||||
|
);
|
||||||
|
defaultAppForm.aiSettings.systemPrompt = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.aiSystemPrompt
|
||||||
|
);
|
||||||
|
defaultAppForm.aiSettings.temperature = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.aiChatTemperature
|
||||||
|
);
|
||||||
|
defaultAppForm.aiSettings.maxToken = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.aiChatMaxToken
|
||||||
|
);
|
||||||
|
defaultAppForm.aiSettings.quoteTemplate = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.aiChatQuoteTemplate
|
||||||
|
);
|
||||||
|
defaultAppForm.aiSettings.quotePrompt = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.aiChatQuoteTemplate
|
||||||
|
);
|
||||||
|
} else if (module.flowType === FlowNodeTypeEnum.datasetSearchNode) {
|
||||||
|
defaultAppForm.dataset.datasets = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.datasetSelectList
|
||||||
|
);
|
||||||
|
defaultAppForm.dataset.similarity = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.datasetSimilarity
|
||||||
|
);
|
||||||
|
defaultAppForm.dataset.limit = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.datasetLimit
|
||||||
|
);
|
||||||
|
defaultAppForm.dataset.rerank = findInputValueByKey(
|
||||||
|
module.inputs,
|
||||||
|
ModuleInputKeyEnum.datasetStartReRank
|
||||||
|
);
|
||||||
|
|
||||||
|
// empty text
|
||||||
|
const emptyOutputs =
|
||||||
|
module.outputs.find((item) => item.key === ModuleOutputKeyEnum.datasetIsEmpty)?.targets ||
|
||||||
|
[];
|
||||||
|
const emptyOutput = emptyOutputs[0];
|
||||||
|
if (emptyOutput) {
|
||||||
|
const target = modules.find((item) => item.moduleId === emptyOutput.moduleId);
|
||||||
|
defaultAppForm.dataset.searchEmptyText =
|
||||||
|
target?.inputs?.find((item) => item.key === ModuleInputKeyEnum.answerText)?.value || '';
|
||||||
|
}
|
||||||
|
} else if (module.flowType === FlowNodeTypeEnum.userGuide) {
|
||||||
|
const { welcomeText, variableModules, questionGuide, ttsConfig } = splitGuideModule(
|
||||||
|
getGuideModule(modules)
|
||||||
|
);
|
||||||
|
defaultAppForm.userGuide = {
|
||||||
|
welcomeText: welcomeText,
|
||||||
|
variables: variableModules,
|
||||||
|
questionGuide: questionGuide,
|
||||||
|
tts: ttsConfig
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return defaultAppForm;
|
||||||
|
};
|
||||||
1
packages/global/core/chat/api.d.ts
vendored
@ -30,5 +30,4 @@ export type InitChatResponse = {
|
|||||||
export type ChatHistoryItemResType = moduleDispatchResType & {
|
export type ChatHistoryItemResType = moduleDispatchResType & {
|
||||||
moduleType: `${FlowNodeTypeEnum}`;
|
moduleType: `${FlowNodeTypeEnum}`;
|
||||||
moduleName: string;
|
moduleName: string;
|
||||||
moduleLogo?: string;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,12 +6,6 @@ export enum ChatRoleEnum {
|
|||||||
Tool = 'Tool'
|
Tool = 'Tool'
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TaskResponseKeyEnum {
|
|
||||||
'answerText' = 'answerText', // answer module text key
|
|
||||||
'responseData' = 'responseData',
|
|
||||||
'history' = 'history'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ChatRoleMap = {
|
export const ChatRoleMap = {
|
||||||
[ChatRoleEnum.System]: {
|
[ChatRoleEnum.System]: {
|
||||||
name: '系统提示词'
|
name: '系统提示词'
|
||||||
|
|||||||
16
packages/global/core/chat/type.d.ts
vendored
@ -1,8 +1,9 @@
|
|||||||
import { ClassifyQuestionAgentItemType } from '../module/type';
|
import { ClassifyQuestionAgentItemType } from '../module/type';
|
||||||
import { SearchDataResponseItemType } from '../dataset/type';
|
import { SearchDataResponseItemType } from '../dataset/type';
|
||||||
import { ChatRoleEnum, ChatSourceEnum, TaskResponseKeyEnum } from './constants';
|
import { ChatRoleEnum, ChatSourceEnum } from './constants';
|
||||||
import { FlowNodeTypeEnum } from '../module/node/constant';
|
import { FlowNodeTypeEnum } from '../module/node/constant';
|
||||||
import { AppSchema } from 'core/app/type';
|
import { ModuleOutputKeyEnum } from '../module/constants';
|
||||||
|
import { AppSchema } from '../app/type';
|
||||||
|
|
||||||
export type ChatSchema = {
|
export type ChatSchema = {
|
||||||
_id: string;
|
_id: string;
|
||||||
@ -38,7 +39,7 @@ export type ChatItemSchema = {
|
|||||||
value: string;
|
value: string;
|
||||||
userFeedback?: string;
|
userFeedback?: string;
|
||||||
adminFeedback?: AdminFbkType;
|
adminFeedback?: AdminFbkType;
|
||||||
[TaskResponseKeyEnum.responseData]?: ChatHistoryItemResType[];
|
[ModuleOutputKeyEnum.responseData]?: ChatHistoryItemResType[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AdminFbkType = {
|
export type AdminFbkType = {
|
||||||
@ -55,14 +56,14 @@ export type ChatItemType = {
|
|||||||
value: any;
|
value: any;
|
||||||
userFeedback?: string;
|
userFeedback?: string;
|
||||||
adminFeedback?: ChatItemSchema['feedback'];
|
adminFeedback?: ChatItemSchema['feedback'];
|
||||||
[TaskResponseKeyEnum.responseData]?: ChatItemSchema[TaskResponseKeyEnum.responseData];
|
[ModuleOutputKeyEnum.responseData]?: ChatHistoryItemResType[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ChatSiteItemType = {
|
export type ChatSiteItemType = ChatItemType & {
|
||||||
status: 'loading' | 'running' | 'finish';
|
status: 'loading' | 'running' | 'finish';
|
||||||
moduleName?: string;
|
moduleName?: string;
|
||||||
ttsBuffer?: Uint8Array;
|
ttsBuffer?: Uint8Array;
|
||||||
} & ChatItemType;
|
};
|
||||||
|
|
||||||
export type HistoryItemType = {
|
export type HistoryItemType = {
|
||||||
chatId: string;
|
chatId: string;
|
||||||
@ -77,13 +78,14 @@ export type ChatHistoryItemType = HistoryItemType & {
|
|||||||
|
|
||||||
// response data
|
// response data
|
||||||
export type moduleDispatchResType = {
|
export type moduleDispatchResType = {
|
||||||
|
moduleLogo?: string;
|
||||||
price: number;
|
price: number;
|
||||||
runningTime?: number;
|
runningTime?: number;
|
||||||
tokens?: number;
|
tokens?: number;
|
||||||
model?: string;
|
model?: string;
|
||||||
|
query?: string;
|
||||||
|
|
||||||
// chat
|
// chat
|
||||||
question?: string;
|
|
||||||
temperature?: number;
|
temperature?: number;
|
||||||
maxToken?: number;
|
maxToken?: number;
|
||||||
quoteList?: SearchDataResponseItemType[];
|
quoteList?: SearchDataResponseItemType[];
|
||||||
|
|||||||
102
packages/global/core/module/constants.ts
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
export enum ModuleTemplateTypeEnum {
|
||||||
|
userGuide = 'userGuide',
|
||||||
|
systemInput = 'systemInput',
|
||||||
|
textAnswer = 'textAnswer',
|
||||||
|
dataset = 'dataset',
|
||||||
|
functionCall = 'functionCall',
|
||||||
|
externalCall = 'externalCall',
|
||||||
|
|
||||||
|
personalPlugin = 'personalPlugin',
|
||||||
|
communityPlugin = 'communityPlugin',
|
||||||
|
commercialPlugin = 'commercialPlugin',
|
||||||
|
|
||||||
|
other = 'other'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ModuleDataTypeEnum {
|
||||||
|
string = 'string',
|
||||||
|
number = 'number',
|
||||||
|
boolean = 'boolean',
|
||||||
|
chatHistory = 'chatHistory',
|
||||||
|
datasetQuote = 'datasetQuote',
|
||||||
|
any = 'any',
|
||||||
|
|
||||||
|
// plugin special type
|
||||||
|
selectApp = 'selectApp',
|
||||||
|
selectDataset = 'selectDataset'
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reg: modulename key */
|
||||||
|
export enum ModuleInputKeyEnum {
|
||||||
|
// old
|
||||||
|
welcomeText = 'welcomeText',
|
||||||
|
variables = 'variables',
|
||||||
|
switch = 'switch', // a trigger switch
|
||||||
|
history = 'history',
|
||||||
|
userChatInput = 'userChatInput',
|
||||||
|
questionGuide = 'questionGuide',
|
||||||
|
tts = 'tts',
|
||||||
|
answerText = 'text',
|
||||||
|
agents = 'agents', // cq agent key
|
||||||
|
|
||||||
|
// latest
|
||||||
|
// common
|
||||||
|
aiModel = 'model',
|
||||||
|
aiSystemPrompt = 'systemPrompt',
|
||||||
|
description = 'description',
|
||||||
|
|
||||||
|
// history
|
||||||
|
historyMaxAmount = 'maxContext',
|
||||||
|
|
||||||
|
// ai chat
|
||||||
|
aiChatTemperature = 'temperature',
|
||||||
|
aiChatMaxToken = 'maxToken',
|
||||||
|
aiChatSettingModal = 'aiSettings',
|
||||||
|
aiChatIsResponseText = 'isResponseAnswerText',
|
||||||
|
aiChatQuoteTemplate = 'quoteTemplate',
|
||||||
|
aiChatQuotePrompt = 'quotePrompt',
|
||||||
|
aiChatDatasetQuote = 'quoteQA',
|
||||||
|
|
||||||
|
// dataset
|
||||||
|
datasetSelectList = 'datasets',
|
||||||
|
datasetSimilarity = 'similarity',
|
||||||
|
datasetLimit = 'limit',
|
||||||
|
datasetStartReRank = 'rerank',
|
||||||
|
|
||||||
|
// context extract
|
||||||
|
contextExtractInput = 'content',
|
||||||
|
extractKeys = 'extractKeys',
|
||||||
|
|
||||||
|
// http
|
||||||
|
httpUrl = 'url',
|
||||||
|
|
||||||
|
// app
|
||||||
|
runAppSelectApp = 'app',
|
||||||
|
|
||||||
|
// plugin
|
||||||
|
pluginId = 'pluginId'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ModuleOutputKeyEnum {
|
||||||
|
// common
|
||||||
|
userChatInput = 'userChatInput',
|
||||||
|
finish = 'finish',
|
||||||
|
responseData = 'responseData',
|
||||||
|
history = 'history',
|
||||||
|
answerText = 'answerText', // answer module text key
|
||||||
|
success = 'success',
|
||||||
|
failed = 'failed',
|
||||||
|
|
||||||
|
// dataset
|
||||||
|
datasetIsEmpty = 'isEmpty',
|
||||||
|
datasetUnEmpty = 'unEmpty',
|
||||||
|
datasetQuoteQA = 'quoteQA',
|
||||||
|
|
||||||
|
// context extract
|
||||||
|
contextExtractFields = 'fields'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum VariableInputEnum {
|
||||||
|
input = 'input',
|
||||||
|
select = 'select'
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
export enum FlowNodeInputTypeEnum {
|
export enum FlowNodeInputTypeEnum {
|
||||||
systemInput = 'systemInput', // history, userChatInput, variableInput
|
systemInput = 'systemInput', // history, userChatInput, variableInput
|
||||||
|
|
||||||
input = 'input', // one line input
|
input = 'input', // one line input
|
||||||
textarea = 'textarea',
|
textarea = 'textarea',
|
||||||
numberInput = 'numberInput',
|
numberInput = 'numberInput',
|
||||||
@ -8,11 +9,10 @@ export enum FlowNodeInputTypeEnum {
|
|||||||
custom = 'custom',
|
custom = 'custom',
|
||||||
target = 'target', // data input
|
target = 'target', // data input
|
||||||
switch = 'switch',
|
switch = 'switch',
|
||||||
chatInput = 'chatInput',
|
|
||||||
selectApp = 'selectApp',
|
selectApp = 'selectApp',
|
||||||
// chat special input
|
// chat special input
|
||||||
aiSettings = 'aiSettings',
|
aiSettings = 'aiSettings',
|
||||||
maxToken = 'maxToken',
|
// maxToken = 'maxToken',
|
||||||
selectChatModel = 'selectChatModel',
|
selectChatModel = 'selectChatModel',
|
||||||
// dataset special input
|
// dataset special input
|
||||||
selectDataset = 'selectDataset',
|
selectDataset = 'selectDataset',
|
||||||
@ -44,18 +44,3 @@ export enum FlowNodeTypeEnum {
|
|||||||
// abandon
|
// abandon
|
||||||
variable = 'variable'
|
variable = 'variable'
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum FlowNodeSpecialInputKeyEnum {
|
|
||||||
'answerText' = 'text',
|
|
||||||
'agents' = 'agents', // cq agent key
|
|
||||||
'pluginId' = 'pluginId'
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum FlowNodeValTypeEnum {
|
|
||||||
'string' = 'string',
|
|
||||||
'number' = 'number',
|
|
||||||
'boolean' = 'boolean',
|
|
||||||
'chatHistory' = 'chatHistory',
|
|
||||||
'datasetQuote' = 'datasetQuote',
|
|
||||||
'any' = 'any'
|
|
||||||
}
|
|
||||||
|
|||||||
61
packages/global/core/module/node/type.d.ts
vendored
@ -1,9 +1,6 @@
|
|||||||
import {
|
import { FlowNodeInputTypeEnum, FlowNodeOutputTypeEnum, FlowNodeTypeEnum } from './constant';
|
||||||
FlowNodeInputTypeEnum,
|
import { ModuleDataTypeEnum, ModuleInputKeyEnum, ModuleOutputKeyEnum } from '../constants';
|
||||||
FlowNodeOutputTypeEnum,
|
import { SelectedDatasetType } from '../api';
|
||||||
FlowNodeValTypeEnum,
|
|
||||||
FlowNodeTypeEnum
|
|
||||||
} from './constant';
|
|
||||||
|
|
||||||
export type FlowNodeChangeProps = {
|
export type FlowNodeChangeProps = {
|
||||||
moduleId: string;
|
moduleId: string;
|
||||||
@ -23,24 +20,27 @@ export type FlowNodeChangeProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type FlowNodeInputItemType = {
|
export type FlowNodeInputItemType = {
|
||||||
key: string; // 字段名
|
key: `${ModuleInputKeyEnum}`;
|
||||||
|
type: `${FlowNodeInputTypeEnum}`; // Decide on a render style
|
||||||
value?: any;
|
value?: any;
|
||||||
valueType?: `${FlowNodeValTypeEnum}`;
|
valueType?: `${ModuleDataTypeEnum}`; // data type
|
||||||
type: `${FlowNodeInputTypeEnum}`;
|
|
||||||
label: string;
|
label: string;
|
||||||
edit?: boolean;
|
|
||||||
connected?: boolean;
|
|
||||||
description?: string;
|
description?: string;
|
||||||
placeholder?: string;
|
required?: boolean;
|
||||||
plusField?: boolean;
|
edit?: boolean; // Whether to allow editing
|
||||||
|
connected?: boolean; // unConnected field will be deleted
|
||||||
|
|
||||||
|
showTargetInApp?: boolean;
|
||||||
|
showTargetInPlugin?: boolean;
|
||||||
|
|
||||||
|
placeholder?: string; // input,textarea
|
||||||
|
list?: { label: string; value: any }[]; // select
|
||||||
|
step?: number; // slider max?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
min?: number;
|
min?: number;
|
||||||
step?: number;
|
markList?: { label: string; value: any }[]; // slider
|
||||||
required?: boolean;
|
|
||||||
list?: { label: string; value: any }[];
|
plusField?: boolean; // plus system will show
|
||||||
markList?: { label: string; value: any }[];
|
|
||||||
customData?: () => any;
|
|
||||||
valueCheck?: (value: any) => boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FlowNodeOutputTargetItemType = {
|
export type FlowNodeOutputTargetItemType = {
|
||||||
@ -48,11 +48,30 @@ export type FlowNodeOutputTargetItemType = {
|
|||||||
key: string;
|
key: string;
|
||||||
};
|
};
|
||||||
export type FlowNodeOutputItemType = {
|
export type FlowNodeOutputItemType = {
|
||||||
key: string; // 字段名
|
key: `${ModuleOutputKeyEnum}` | string;
|
||||||
label?: string;
|
label?: string;
|
||||||
edit?: boolean;
|
edit?: boolean;
|
||||||
description?: string;
|
description?: string;
|
||||||
valueType?: `${FlowNodeValTypeEnum}`;
|
valueType?: `${ModuleDataTypeEnum}`;
|
||||||
type?: `${FlowNodeOutputTypeEnum}`;
|
type?: `${FlowNodeOutputTypeEnum}`;
|
||||||
targets: FlowNodeOutputTargetItemType[];
|
targets: FlowNodeOutputTargetItemType[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ------------- item type --------------- */
|
||||||
|
/* ai chat modules props */
|
||||||
|
export type AIChatModuleProps = {
|
||||||
|
[ModuleInputKeyEnum.aiModel]: string;
|
||||||
|
[ModuleInputKeyEnum.aiSystemPrompt]?: string;
|
||||||
|
[ModuleInputKeyEnum.aiChatTemperature]: number;
|
||||||
|
[ModuleInputKeyEnum.aiChatMaxToken]: number;
|
||||||
|
[ModuleInputKeyEnum.aiChatIsResponseText]: boolean;
|
||||||
|
[ModuleInputKeyEnum.aiChatQuoteTemplate]?: string;
|
||||||
|
[ModuleInputKeyEnum.aiChatQuotePrompt]?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DatasetModuleProps = {
|
||||||
|
[ModuleInputKeyEnum.datasetSelectList]: SelectedDatasetType;
|
||||||
|
[ModuleInputKeyEnum.datasetSimilarity]: number;
|
||||||
|
[ModuleInputKeyEnum.datasetLimit]: number;
|
||||||
|
[ModuleInputKeyEnum.datasetStartReRank]: boolean;
|
||||||
|
};
|
||||||
|
|||||||
32
packages/global/core/module/template/input.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import type { FlowNodeInputItemType } from '../node/type.d';
|
||||||
|
import { ModuleInputKeyEnum } from '../constants';
|
||||||
|
import { FlowNodeInputTypeEnum } from '../node/constant';
|
||||||
|
import { ModuleDataTypeEnum } from '../constants';
|
||||||
|
|
||||||
|
export const Input_Template_TFSwitch: FlowNodeInputItemType = {
|
||||||
|
key: ModuleInputKeyEnum.switch,
|
||||||
|
type: FlowNodeInputTypeEnum.target,
|
||||||
|
label: 'core.module.input.label.switch',
|
||||||
|
valueType: ModuleDataTypeEnum.any,
|
||||||
|
showTargetInApp: true,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Input_Template_History: FlowNodeInputItemType = {
|
||||||
|
key: ModuleInputKeyEnum.history,
|
||||||
|
type: FlowNodeInputTypeEnum.target,
|
||||||
|
label: 'core.module.input.label.chat history',
|
||||||
|
valueType: ModuleDataTypeEnum.chatHistory,
|
||||||
|
showTargetInApp: true,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Input_Template_UserChatInput: FlowNodeInputItemType = {
|
||||||
|
key: ModuleInputKeyEnum.userChatInput,
|
||||||
|
type: FlowNodeInputTypeEnum.target,
|
||||||
|
label: 'core.module.input.label.user question',
|
||||||
|
required: true,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
showTargetInApp: true,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
};
|
||||||
13
packages/global/core/module/template/output.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import type { FlowNodeOutputItemType } from '../node/type';
|
||||||
|
import { ModuleOutputKeyEnum } from '../constants';
|
||||||
|
import { FlowNodeOutputTypeEnum } from '../node/constant';
|
||||||
|
import { ModuleDataTypeEnum } from '../constants';
|
||||||
|
|
||||||
|
export const Output_Template_Finish: FlowNodeOutputItemType = {
|
||||||
|
key: ModuleOutputKeyEnum.finish,
|
||||||
|
label: 'core.module.output.label.running done',
|
||||||
|
description: 'core.module.output.description.running done',
|
||||||
|
valueType: ModuleDataTypeEnum.boolean,
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
};
|
||||||
157
packages/global/core/module/template/system/aiChat.ts
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import {
|
||||||
|
FlowNodeInputTypeEnum,
|
||||||
|
FlowNodeOutputTypeEnum,
|
||||||
|
FlowNodeTypeEnum
|
||||||
|
} from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import {
|
||||||
|
ModuleDataTypeEnum,
|
||||||
|
ModuleInputKeyEnum,
|
||||||
|
ModuleOutputKeyEnum,
|
||||||
|
ModuleTemplateTypeEnum
|
||||||
|
} from '../../constants';
|
||||||
|
import {
|
||||||
|
Input_Template_History,
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
Input_Template_UserChatInput
|
||||||
|
} from '../input';
|
||||||
|
import { chatNodeSystemPromptTip } from '../tip';
|
||||||
|
import { Output_Template_Finish } from '../output';
|
||||||
|
|
||||||
|
export const AiChatModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.chatNode,
|
||||||
|
templateType: ModuleTemplateTypeEnum.textAnswer,
|
||||||
|
flowType: FlowNodeTypeEnum.chatNode,
|
||||||
|
avatar: '/imgs/module/AI.png',
|
||||||
|
name: 'AI 对话',
|
||||||
|
intro: 'AI 大模型对话',
|
||||||
|
showStatus: true,
|
||||||
|
inputs: [
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiModel,
|
||||||
|
type: FlowNodeInputTypeEnum.selectChatModel,
|
||||||
|
label: '对话模型',
|
||||||
|
required: true,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
// --- settings modal
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiChatTemperature,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden, // Set in the pop-up window
|
||||||
|
label: '温度',
|
||||||
|
value: 0,
|
||||||
|
valueType: ModuleDataTypeEnum.number,
|
||||||
|
min: 0,
|
||||||
|
max: 10,
|
||||||
|
step: 1,
|
||||||
|
markList: [
|
||||||
|
{ label: '严谨', value: 0 },
|
||||||
|
{ label: '发散', value: 10 }
|
||||||
|
],
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiChatMaxToken,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden, // Set in the pop-up window
|
||||||
|
label: '回复上限',
|
||||||
|
value: 2000,
|
||||||
|
valueType: ModuleDataTypeEnum.number,
|
||||||
|
min: 100,
|
||||||
|
max: 4000,
|
||||||
|
step: 50,
|
||||||
|
markList: [
|
||||||
|
{ label: '100', value: 100 },
|
||||||
|
{
|
||||||
|
label: `${4000}`,
|
||||||
|
value: 4000
|
||||||
|
}
|
||||||
|
],
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiChatIsResponseText,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden,
|
||||||
|
label: '返回AI内容',
|
||||||
|
value: true,
|
||||||
|
valueType: ModuleDataTypeEnum.boolean,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiChatQuoteTemplate,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden,
|
||||||
|
label: '引用内容模板',
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
value: '',
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiChatQuotePrompt,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden,
|
||||||
|
label: '引用内容提示词',
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
value: '',
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiChatSettingModal,
|
||||||
|
type: FlowNodeInputTypeEnum.aiSettings,
|
||||||
|
label: '',
|
||||||
|
connected: false,
|
||||||
|
valueType: ModuleDataTypeEnum.any,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
// settings modal ---
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiSystemPrompt,
|
||||||
|
type: FlowNodeInputTypeEnum.textarea,
|
||||||
|
label: '系统提示词',
|
||||||
|
max: 300,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
description: chatNodeSystemPromptTip,
|
||||||
|
placeholder: chatNodeSystemPromptTip,
|
||||||
|
value: '',
|
||||||
|
showTargetInApp: true,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiChatDatasetQuote,
|
||||||
|
type: FlowNodeInputTypeEnum.target,
|
||||||
|
label: '引用内容',
|
||||||
|
description: "对象数组格式,结构:\n [{q:'问题',a:'回答'}]",
|
||||||
|
valueType: ModuleDataTypeEnum.datasetQuote,
|
||||||
|
connected: false,
|
||||||
|
showTargetInApp: true,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
},
|
||||||
|
Input_Template_History,
|
||||||
|
Input_Template_UserChatInput
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.history,
|
||||||
|
label: '新的上下文',
|
||||||
|
description: '将本次回复内容拼接上历史记录,作为新的上下文返回',
|
||||||
|
valueType: ModuleDataTypeEnum.chatHistory,
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.answerText,
|
||||||
|
label: 'AI回复',
|
||||||
|
description: '将在 stream 回复完毕后触发',
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
Output_Template_Finish
|
||||||
|
]
|
||||||
|
};
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import { ModuleDataTypeEnum, ModuleInputKeyEnum, ModuleTemplateTypeEnum } from '../../constants';
|
||||||
|
import { Input_Template_TFSwitch } from '../input';
|
||||||
|
import { Output_Template_Finish } from '../output';
|
||||||
|
|
||||||
|
export const AssignedAnswerModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.answerNode,
|
||||||
|
templateType: ModuleTemplateTypeEnum.textAnswer,
|
||||||
|
flowType: FlowNodeTypeEnum.answerNode,
|
||||||
|
avatar: '/imgs/module/reply.png',
|
||||||
|
name: '指定回复',
|
||||||
|
intro: '该模块可以直接回复一段指定的内容。常用于引导、提示',
|
||||||
|
inputs: [
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.answerText,
|
||||||
|
type: FlowNodeInputTypeEnum.textarea,
|
||||||
|
valueType: ModuleDataTypeEnum.any,
|
||||||
|
value: '',
|
||||||
|
label: '回复的内容',
|
||||||
|
description:
|
||||||
|
'可以使用 \\n 来实现连续换行。\n\n可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容。\n\n如传入非字符串类型数据将会自动转成字符串',
|
||||||
|
showTargetInApp: true,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outputs: [Output_Template_Finish]
|
||||||
|
};
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
import {
|
||||||
|
FlowNodeInputTypeEnum,
|
||||||
|
FlowNodeOutputTypeEnum,
|
||||||
|
FlowNodeTypeEnum
|
||||||
|
} from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import { ModuleDataTypeEnum, ModuleInputKeyEnum, ModuleTemplateTypeEnum } from '../../constants';
|
||||||
|
import {
|
||||||
|
Input_Template_History,
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
Input_Template_UserChatInput
|
||||||
|
} from '../input';
|
||||||
|
|
||||||
|
export const ClassifyQuestionModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.classifyQuestion,
|
||||||
|
templateType: ModuleTemplateTypeEnum.functionCall,
|
||||||
|
flowType: FlowNodeTypeEnum.classifyQuestion,
|
||||||
|
avatar: '/imgs/module/cq.png',
|
||||||
|
name: '问题分类',
|
||||||
|
intro:
|
||||||
|
'根据用户的历史记录和当前问题判断该次提问的类型。可以添加多组问题类型,下面是一个模板例子:\n类型1: 打招呼\n类型2: 关于 laf 通用问题\n类型3: 关于 laf 代码问题\n类型4: 其他问题',
|
||||||
|
showStatus: true,
|
||||||
|
inputs: [
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiModel,
|
||||||
|
type: FlowNodeInputTypeEnum.selectChatModel,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
label: '分类模型',
|
||||||
|
required: true,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.aiSystemPrompt,
|
||||||
|
type: FlowNodeInputTypeEnum.textarea,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
value: '',
|
||||||
|
label: '背景知识',
|
||||||
|
description:
|
||||||
|
'你可以添加一些特定内容的介绍,从而更好的识别用户的问题类型。这个内容通常是给模型介绍一个它不知道的内容。',
|
||||||
|
placeholder: '例如: \n1. Laf 是一个云函数开发平台……\n2. Sealos 是一个集群操作系统',
|
||||||
|
showTargetInApp: true,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
},
|
||||||
|
Input_Template_History,
|
||||||
|
Input_Template_UserChatInput,
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.agents,
|
||||||
|
type: FlowNodeInputTypeEnum.custom,
|
||||||
|
valueType: ModuleDataTypeEnum.any,
|
||||||
|
label: '',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
value: '打招呼',
|
||||||
|
key: 'fasw'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '关于 xxx 的问题',
|
||||||
|
key: 'fqsw'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '其他问题',
|
||||||
|
key: 'fesw'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
// custom output
|
||||||
|
{
|
||||||
|
key: 'fasw',
|
||||||
|
label: '',
|
||||||
|
type: FlowNodeOutputTypeEnum.hidden,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fqsw',
|
||||||
|
label: '',
|
||||||
|
type: FlowNodeOutputTypeEnum.hidden,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fesw',
|
||||||
|
label: '',
|
||||||
|
type: FlowNodeOutputTypeEnum.hidden,
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
import {
|
||||||
|
FlowNodeInputTypeEnum,
|
||||||
|
FlowNodeOutputTypeEnum,
|
||||||
|
FlowNodeTypeEnum
|
||||||
|
} from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import {
|
||||||
|
ModuleDataTypeEnum,
|
||||||
|
ModuleInputKeyEnum,
|
||||||
|
ModuleOutputKeyEnum,
|
||||||
|
ModuleTemplateTypeEnum
|
||||||
|
} from '../../constants';
|
||||||
|
import { Input_Template_History, Input_Template_TFSwitch } from '../input';
|
||||||
|
|
||||||
|
export const ContextExtractModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.contentExtract,
|
||||||
|
templateType: ModuleTemplateTypeEnum.functionCall,
|
||||||
|
flowType: FlowNodeTypeEnum.contentExtract,
|
||||||
|
avatar: '/imgs/module/extract.png',
|
||||||
|
name: '文本内容提取',
|
||||||
|
intro: '可从文本中提取指定的数据,例如:sql语句、搜索关键词、代码等',
|
||||||
|
showStatus: true,
|
||||||
|
inputs: [
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.description,
|
||||||
|
type: FlowNodeInputTypeEnum.textarea,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
value: '',
|
||||||
|
label: '提取要求描述',
|
||||||
|
description: '写一段提取要求,告诉 AI 需要提取哪些内容',
|
||||||
|
required: true,
|
||||||
|
placeholder:
|
||||||
|
'例如: \n1. 你是一个实验室预约助手。根据用户问题,提取出姓名、实验室号和预约时间',
|
||||||
|
showTargetInApp: true,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
},
|
||||||
|
Input_Template_History,
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.contextExtractInput,
|
||||||
|
type: FlowNodeInputTypeEnum.target,
|
||||||
|
label: '需要提取的文本',
|
||||||
|
required: true,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
showTargetInApp: true,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.extractKeys,
|
||||||
|
type: FlowNodeInputTypeEnum.custom,
|
||||||
|
label: '目标字段',
|
||||||
|
valueType: ModuleDataTypeEnum.any,
|
||||||
|
description: "由 '描述' 和 'key' 组成一个目标字段,可提取多个目标字段",
|
||||||
|
value: [], // {desc: string; key: string; required: boolean;}[]
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.success,
|
||||||
|
label: '字段完全提取',
|
||||||
|
valueType: ModuleDataTypeEnum.boolean,
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.failed,
|
||||||
|
label: '提取字段缺失',
|
||||||
|
valueType: ModuleDataTypeEnum.boolean,
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.contextExtractFields,
|
||||||
|
label: '完整提取结果',
|
||||||
|
description: '一个 JSON 字符串,例如:{"name:":"YY","Time":"2023/7/2 18:00"}',
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
109
packages/global/core/module/template/system/datasetSearch.ts
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import {
|
||||||
|
FlowNodeInputTypeEnum,
|
||||||
|
FlowNodeOutputTypeEnum,
|
||||||
|
FlowNodeTypeEnum
|
||||||
|
} from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import {
|
||||||
|
ModuleDataTypeEnum,
|
||||||
|
ModuleInputKeyEnum,
|
||||||
|
ModuleOutputKeyEnum,
|
||||||
|
ModuleTemplateTypeEnum
|
||||||
|
} from '../../constants';
|
||||||
|
import { Input_Template_TFSwitch, Input_Template_UserChatInput } from '../input';
|
||||||
|
import { Output_Template_Finish } from '../output';
|
||||||
|
|
||||||
|
export const DatasetSearchModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.datasetSearchNode,
|
||||||
|
templateType: ModuleTemplateTypeEnum.dataset,
|
||||||
|
flowType: FlowNodeTypeEnum.datasetSearchNode,
|
||||||
|
avatar: '/imgs/module/db.png',
|
||||||
|
name: '知识库搜索',
|
||||||
|
intro: '去知识库中搜索对应的答案。可作为 AI 对话引用参考。',
|
||||||
|
showStatus: true,
|
||||||
|
inputs: [
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.datasetSelectList,
|
||||||
|
type: FlowNodeInputTypeEnum.selectDataset,
|
||||||
|
label: '关联的知识库',
|
||||||
|
value: [],
|
||||||
|
valueType: ModuleDataTypeEnum.selectDataset,
|
||||||
|
list: [],
|
||||||
|
required: true,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.datasetSimilarity,
|
||||||
|
type: FlowNodeInputTypeEnum.slider,
|
||||||
|
label: '最低相关性',
|
||||||
|
value: 0.4,
|
||||||
|
valueType: ModuleDataTypeEnum.number,
|
||||||
|
min: 0,
|
||||||
|
max: 1,
|
||||||
|
step: 0.01,
|
||||||
|
markList: [
|
||||||
|
{ label: '0', value: 0 },
|
||||||
|
{ label: '1', value: 1 }
|
||||||
|
],
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.datasetLimit,
|
||||||
|
type: FlowNodeInputTypeEnum.slider,
|
||||||
|
label: '单次搜索上限',
|
||||||
|
description: '最多取 n 条记录作为本次问题引用',
|
||||||
|
value: 5,
|
||||||
|
valueType: ModuleDataTypeEnum.number,
|
||||||
|
min: 1,
|
||||||
|
max: 20,
|
||||||
|
step: 1,
|
||||||
|
markList: [
|
||||||
|
{ label: '1', value: 1 },
|
||||||
|
{ label: '20', value: 20 }
|
||||||
|
],
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.datasetStartReRank,
|
||||||
|
type: FlowNodeInputTypeEnum.switch,
|
||||||
|
label: '结果重排',
|
||||||
|
description: '将召回的结果进行进一步重排,可增加召回率',
|
||||||
|
plusField: true,
|
||||||
|
value: false,
|
||||||
|
valueType: ModuleDataTypeEnum.boolean,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
Input_Template_UserChatInput
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.datasetIsEmpty,
|
||||||
|
label: '搜索结果为空',
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
valueType: ModuleDataTypeEnum.boolean,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.datasetUnEmpty,
|
||||||
|
label: '搜索结果不为空',
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
valueType: ModuleDataTypeEnum.boolean,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.datasetQuoteQA,
|
||||||
|
label: '引用内容',
|
||||||
|
description:
|
||||||
|
'始终返回数组,如果希望搜索结果为空时执行额外操作,需要用到上面的两个输入以及目标模块的触发器',
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
valueType: ModuleDataTypeEnum.datasetQuote,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
Output_Template_Finish
|
||||||
|
]
|
||||||
|
};
|
||||||
14
packages/global/core/module/template/system/empty.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { ModuleTemplateTypeEnum } from '../../constants';
|
||||||
|
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
|
||||||
|
export const EmptyModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.empty,
|
||||||
|
templateType: ModuleTemplateTypeEnum.other,
|
||||||
|
flowType: FlowNodeTypeEnum.empty,
|
||||||
|
avatar: '/imgs/module/cq.png',
|
||||||
|
name: '该模块已被移除',
|
||||||
|
intro: '',
|
||||||
|
inputs: [],
|
||||||
|
outputs: []
|
||||||
|
};
|
||||||
46
packages/global/core/module/template/system/history.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import {
|
||||||
|
FlowNodeInputTypeEnum,
|
||||||
|
FlowNodeOutputTypeEnum,
|
||||||
|
FlowNodeTypeEnum
|
||||||
|
} from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import { ModuleDataTypeEnum, ModuleInputKeyEnum, ModuleTemplateTypeEnum } from '../../constants';
|
||||||
|
|
||||||
|
export const HistoryModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.historyNode,
|
||||||
|
templateType: ModuleTemplateTypeEnum.systemInput,
|
||||||
|
flowType: FlowNodeTypeEnum.historyNode,
|
||||||
|
avatar: '/imgs/module/history.png',
|
||||||
|
name: '聊天记录',
|
||||||
|
intro: '用户输入的内容。该模块通常作为应用的入口,用户在发送消息后会首先执行该模块。',
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.historyMaxAmount,
|
||||||
|
type: FlowNodeInputTypeEnum.numberInput,
|
||||||
|
label: '最长记录数',
|
||||||
|
value: 6,
|
||||||
|
valueType: ModuleDataTypeEnum.number,
|
||||||
|
min: 0,
|
||||||
|
max: 50,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.history,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden,
|
||||||
|
valueType: ModuleDataTypeEnum.chatHistory,
|
||||||
|
label: '聊天记录',
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.history,
|
||||||
|
label: '聊天记录',
|
||||||
|
valueType: ModuleDataTypeEnum.chatHistory,
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
31
packages/global/core/module/template/system/http.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import { ModuleDataTypeEnum, ModuleInputKeyEnum, ModuleTemplateTypeEnum } from '../../constants';
|
||||||
|
import { Input_Template_TFSwitch } from '../input';
|
||||||
|
import { Output_Template_Finish } from '../output';
|
||||||
|
|
||||||
|
export const HttpModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.httpRequest,
|
||||||
|
templateType: ModuleTemplateTypeEnum.externalCall,
|
||||||
|
flowType: FlowNodeTypeEnum.httpRequest,
|
||||||
|
avatar: '/imgs/module/http.png',
|
||||||
|
name: 'HTTP模块',
|
||||||
|
intro: '可以发出一个 HTTP POST 请求,实现更为复杂的操作(联网搜索、数据库查询等)',
|
||||||
|
showStatus: true,
|
||||||
|
inputs: [
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.httpUrl,
|
||||||
|
value: '',
|
||||||
|
type: FlowNodeInputTypeEnum.input,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
label: '请求地址',
|
||||||
|
description: '请求目标地址',
|
||||||
|
placeholder: 'https://api.fastgpt.run/getInventory',
|
||||||
|
required: true,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outputs: [Output_Template_Finish]
|
||||||
|
};
|
||||||
15
packages/global/core/module/template/system/pluginInput.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { ModuleTemplateTypeEnum } from '../../constants';
|
||||||
|
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
|
||||||
|
export const PluginInputModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.pluginInput,
|
||||||
|
templateType: ModuleTemplateTypeEnum.systemInput,
|
||||||
|
flowType: FlowNodeTypeEnum.pluginInput,
|
||||||
|
avatar: '/imgs/module/input.png',
|
||||||
|
name: '定义插件输入',
|
||||||
|
intro: '自定义配置外部输入,使用插件时,仅暴露自定义配置的输入',
|
||||||
|
showStatus: false,
|
||||||
|
inputs: [],
|
||||||
|
outputs: []
|
||||||
|
};
|
||||||
15
packages/global/core/module/template/system/pluginOutput.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { ModuleTemplateTypeEnum } from '../../constants';
|
||||||
|
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
|
||||||
|
export const PluginOutputModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.pluginOutput,
|
||||||
|
templateType: ModuleTemplateTypeEnum.systemInput,
|
||||||
|
flowType: FlowNodeTypeEnum.pluginOutput,
|
||||||
|
avatar: '/imgs/module/output.png',
|
||||||
|
name: '定义插件输出',
|
||||||
|
intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出',
|
||||||
|
showStatus: false,
|
||||||
|
inputs: [],
|
||||||
|
outputs: []
|
||||||
|
};
|
||||||
62
packages/global/core/module/template/system/runApp.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import {
|
||||||
|
FlowNodeInputTypeEnum,
|
||||||
|
FlowNodeOutputTypeEnum,
|
||||||
|
FlowNodeTypeEnum
|
||||||
|
} from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import {
|
||||||
|
ModuleDataTypeEnum,
|
||||||
|
ModuleInputKeyEnum,
|
||||||
|
ModuleOutputKeyEnum,
|
||||||
|
ModuleTemplateTypeEnum
|
||||||
|
} from '../../constants';
|
||||||
|
import {
|
||||||
|
Input_Template_History,
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
Input_Template_UserChatInput
|
||||||
|
} from '../input';
|
||||||
|
import { Output_Template_Finish } from '../output';
|
||||||
|
|
||||||
|
export const RunAppModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.runApp,
|
||||||
|
templateType: ModuleTemplateTypeEnum.externalCall,
|
||||||
|
flowType: FlowNodeTypeEnum.runApp,
|
||||||
|
avatar: '/imgs/module/app.png',
|
||||||
|
name: '应用调用',
|
||||||
|
intro: '可以选择一个其他应用进行调用',
|
||||||
|
showStatus: true,
|
||||||
|
inputs: [
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.runAppSelectApp,
|
||||||
|
type: FlowNodeInputTypeEnum.selectApp,
|
||||||
|
valueType: ModuleDataTypeEnum.selectApp,
|
||||||
|
label: '选择一个应用',
|
||||||
|
description: '选择一个其他应用进行调用',
|
||||||
|
required: true,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
Input_Template_History,
|
||||||
|
Input_Template_UserChatInput
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.history,
|
||||||
|
label: '新的上下文',
|
||||||
|
description: '将该应用回复内容拼接到历史记录中,作为新的上下文返回',
|
||||||
|
valueType: ModuleDataTypeEnum.chatHistory,
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.answerText,
|
||||||
|
label: 'AI回复',
|
||||||
|
description: '将在应用完全结束后触发',
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
Output_Template_Finish
|
||||||
|
]
|
||||||
|
};
|
||||||
15
packages/global/core/module/template/system/runPlugin.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { ModuleTemplateTypeEnum } from '../../constants';
|
||||||
|
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
|
||||||
|
export const RunPluginModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.pluginModule,
|
||||||
|
templateType: ModuleTemplateTypeEnum.externalCall,
|
||||||
|
flowType: FlowNodeTypeEnum.pluginModule,
|
||||||
|
avatar: '/imgs/module/custom.png',
|
||||||
|
intro: '',
|
||||||
|
name: '自定义模块',
|
||||||
|
showStatus: false,
|
||||||
|
inputs: [], // [{key:'pluginId'},...]
|
||||||
|
outputs: []
|
||||||
|
};
|
||||||
49
packages/global/core/module/template/system/userGuide.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import { userGuideTip } from '../tip';
|
||||||
|
import { ModuleDataTypeEnum, ModuleInputKeyEnum, ModuleTemplateTypeEnum } from '../../constants';
|
||||||
|
|
||||||
|
export const UserGuideModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.userGuide,
|
||||||
|
templateType: ModuleTemplateTypeEnum.userGuide,
|
||||||
|
flowType: FlowNodeTypeEnum.userGuide,
|
||||||
|
avatar: '/imgs/module/userGuide.png',
|
||||||
|
name: '用户引导',
|
||||||
|
intro: userGuideTip,
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.welcomeText,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
label: '开场白',
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.variables,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden,
|
||||||
|
valueType: ModuleDataTypeEnum.any,
|
||||||
|
label: '对话框变量',
|
||||||
|
value: [],
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.questionGuide,
|
||||||
|
valueType: ModuleDataTypeEnum.boolean,
|
||||||
|
type: FlowNodeInputTypeEnum.switch,
|
||||||
|
label: '问题引导',
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.tts,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden,
|
||||||
|
valueType: ModuleDataTypeEnum.any,
|
||||||
|
label: '语音播报',
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outputs: []
|
||||||
|
};
|
||||||
40
packages/global/core/module/template/system/userInput.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import {
|
||||||
|
FlowNodeInputTypeEnum,
|
||||||
|
FlowNodeOutputTypeEnum,
|
||||||
|
FlowNodeTypeEnum
|
||||||
|
} from '../../node/constant';
|
||||||
|
import { FlowModuleTemplateType } from '../../type.d';
|
||||||
|
import {
|
||||||
|
ModuleDataTypeEnum,
|
||||||
|
ModuleInputKeyEnum,
|
||||||
|
ModuleOutputKeyEnum,
|
||||||
|
ModuleTemplateTypeEnum
|
||||||
|
} from '../../constants';
|
||||||
|
|
||||||
|
export const UserInputModule: FlowModuleTemplateType = {
|
||||||
|
id: FlowNodeTypeEnum.questionInput,
|
||||||
|
templateType: ModuleTemplateTypeEnum.systemInput,
|
||||||
|
flowType: FlowNodeTypeEnum.questionInput,
|
||||||
|
avatar: '/imgs/module/userChatInput.png',
|
||||||
|
name: '用户问题(入口)',
|
||||||
|
intro: '用户输入的内容。该模块通常作为应用的入口,用户在发送消息后会首先执行该模块。',
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
key: ModuleInputKeyEnum.userChatInput,
|
||||||
|
type: FlowNodeInputTypeEnum.systemInput,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
label: '用户问题',
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
key: ModuleOutputKeyEnum.userChatInput,
|
||||||
|
label: '用户问题',
|
||||||
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
7
packages/global/core/module/template/tip.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export const chatNodeSystemPromptTip =
|
||||||
|
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}';
|
||||||
|
export const userGuideTip = '可以在对话前设置引导语,设置全局变量,设置下一步指引';
|
||||||
|
export const welcomeTextTip =
|
||||||
|
'每次对话开始前,发送一个初始内容。支持标准 Markdown 语法,可使用的额外标记:\n[快捷按键]: 用户点击后可以直接发送该问题';
|
||||||
|
export const variableTip =
|
||||||
|
'可以在对话开始前,要求用户填写一些内容作为本轮对话的特定变量。该模块位于开场引导之后。\n变量可以通过 {{变量key}} 的形式注入到其他模块 string 类型的输入中,例如:提示词、限定词等';
|
||||||
32
packages/global/core/module/type.d.ts
vendored
@ -1,13 +1,14 @@
|
|||||||
import { FlowNodeTypeEnum, FlowNodeValTypeEnum } from './node/constant';
|
import { FlowNodeTypeEnum } from './node/constant';
|
||||||
|
import { ModuleDataTypeEnum, ModuleTemplateTypeEnum, VariableInputEnum } from './constants';
|
||||||
import { FlowNodeInputItemType, FlowNodeOutputItemType } from './node/type';
|
import { FlowNodeInputItemType, FlowNodeOutputItemType } from './node/type';
|
||||||
|
|
||||||
export type FlowModuleTemplateType = {
|
export type FlowModuleTemplateType = {
|
||||||
id: string;
|
id: string;
|
||||||
|
templateType: `${ModuleTemplateTypeEnum}`;
|
||||||
flowType: `${FlowNodeTypeEnum}`; // unique
|
flowType: `${FlowNodeTypeEnum}`; // unique
|
||||||
logo?: string;
|
avatar?: string;
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
intro: string; // template list intro
|
||||||
intro?: string;
|
|
||||||
showStatus?: boolean; // chatting response step status
|
showStatus?: boolean; // chatting response step status
|
||||||
inputs: FlowNodeInputItemType[];
|
inputs: FlowNodeInputItemType[];
|
||||||
outputs: FlowNodeOutputItemType[];
|
outputs: FlowNodeOutputItemType[];
|
||||||
@ -15,16 +16,17 @@ export type FlowModuleTemplateType = {
|
|||||||
export type FlowModuleItemType = FlowModuleTemplateType & {
|
export type FlowModuleItemType = FlowModuleTemplateType & {
|
||||||
moduleId: string;
|
moduleId: string;
|
||||||
};
|
};
|
||||||
export type SystemModuleTemplateType = {
|
export type moduleTemplateListType = {
|
||||||
|
type: `${ModuleTemplateTypeEnum}`;
|
||||||
label: string;
|
label: string;
|
||||||
list: FlowModuleTemplateType[];
|
list: FlowModuleTemplateType[];
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
|
// store module type
|
||||||
export type ModuleItemType = {
|
export type ModuleItemType = {
|
||||||
name: string;
|
name: string;
|
||||||
logo?: string;
|
logo?: string;
|
||||||
intro?: string;
|
intro?: string;
|
||||||
description?: string;
|
|
||||||
moduleId: string;
|
moduleId: string;
|
||||||
position?: {
|
position?: {
|
||||||
x: number;
|
x: number;
|
||||||
@ -37,6 +39,24 @@ export type ModuleItemType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* function type */
|
/* function type */
|
||||||
|
// variable
|
||||||
|
export type VariableItemType = {
|
||||||
|
id: string;
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
type: `${VariableInputEnum}`;
|
||||||
|
required: boolean;
|
||||||
|
maxLen: number;
|
||||||
|
enums: { value: string }[];
|
||||||
|
};
|
||||||
|
// tts
|
||||||
|
export type AppTTSConfigType = {
|
||||||
|
type: 'none' | 'web' | 'model';
|
||||||
|
model?: string;
|
||||||
|
voice?: string;
|
||||||
|
speed?: number;
|
||||||
|
};
|
||||||
|
|
||||||
export type SelectAppItemType = {
|
export type SelectAppItemType = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@ -1,28 +1,54 @@
|
|||||||
import {
|
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from './node/constant';
|
||||||
FlowNodeInputTypeEnum,
|
import { ModuleDataTypeEnum, ModuleInputKeyEnum } from './constants';
|
||||||
FlowNodeSpecialInputKeyEnum,
|
|
||||||
FlowNodeTypeEnum
|
|
||||||
} from './node/constant';
|
|
||||||
import { FlowNodeInputItemType, FlowNodeOutputItemType } from './node/type';
|
import { FlowNodeInputItemType, FlowNodeOutputItemType } from './node/type';
|
||||||
import { ModuleItemType } from './type';
|
import { AppTTSConfigType, ModuleItemType, VariableItemType } from './type';
|
||||||
|
|
||||||
|
export const getGuideModule = (modules: ModuleItemType[]) =>
|
||||||
|
modules.find((item) => item.flowType === FlowNodeTypeEnum.userGuide);
|
||||||
|
|
||||||
|
export const splitGuideModule = (guideModules?: ModuleItemType) => {
|
||||||
|
const welcomeText: string =
|
||||||
|
guideModules?.inputs?.find((item) => item.key === ModuleInputKeyEnum.welcomeText)?.value || '';
|
||||||
|
|
||||||
|
const variableModules: VariableItemType[] =
|
||||||
|
guideModules?.inputs.find((item) => item.key === ModuleInputKeyEnum.variables)?.value || [];
|
||||||
|
|
||||||
|
const questionGuide: boolean =
|
||||||
|
!!guideModules?.inputs?.find((item) => item.key === ModuleInputKeyEnum.questionGuide)?.value ||
|
||||||
|
false;
|
||||||
|
|
||||||
|
const ttsConfig: AppTTSConfigType = guideModules?.inputs?.find(
|
||||||
|
(item) => item.key === ModuleInputKeyEnum.tts
|
||||||
|
)?.value || { type: 'web' };
|
||||||
|
|
||||||
export function getPluginTemplatePluginIdInput(pluginId: string) {
|
|
||||||
return {
|
return {
|
||||||
key: FlowNodeSpecialInputKeyEnum.pluginId,
|
welcomeText,
|
||||||
type: FlowNodeInputTypeEnum.hidden,
|
variableModules,
|
||||||
label: 'pluginId',
|
questionGuide,
|
||||||
value: pluginId,
|
ttsConfig
|
||||||
connected: true
|
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export function formatPluginIOModules(
|
export function formatPluginToPreviewModule(
|
||||||
pluginId: string,
|
pluginId: string,
|
||||||
modules: ModuleItemType[]
|
modules: ModuleItemType[]
|
||||||
): {
|
): {
|
||||||
inputs: FlowNodeInputItemType[];
|
inputs: FlowNodeInputItemType[];
|
||||||
outputs: FlowNodeOutputItemType[];
|
outputs: FlowNodeOutputItemType[];
|
||||||
} {
|
} {
|
||||||
|
function getPluginTemplatePluginIdInput(pluginId: string): FlowNodeInputItemType {
|
||||||
|
return {
|
||||||
|
key: ModuleInputKeyEnum.pluginId,
|
||||||
|
type: FlowNodeInputTypeEnum.hidden,
|
||||||
|
label: 'pluginId',
|
||||||
|
value: pluginId,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
connected: true,
|
||||||
|
showTargetInApp: false,
|
||||||
|
showTargetInPlugin: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const pluginInput = modules.find((module) => module.flowType === FlowNodeTypeEnum.pluginInput);
|
const pluginInput = modules.find((module) => module.flowType === FlowNodeTypeEnum.pluginInput);
|
||||||
const customOutput = modules.find((module) => module.flowType === FlowNodeTypeEnum.pluginOutput);
|
const customOutput = modules.find((module) => module.flowType === FlowNodeTypeEnum.pluginOutput);
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
|
import { ModuleTemplateTypeEnum } from '../module/constants';
|
||||||
import { ModuleItemType } from '../module/type';
|
import { ModuleItemType } from '../module/type';
|
||||||
|
|
||||||
export const defaultModules: ModuleItemType[] = [
|
export const defaultModules: ModuleItemType[] = [
|
||||||
{
|
{
|
||||||
moduleId: 'fph4s3',
|
moduleId: 'custom-output',
|
||||||
name: '自定义输出',
|
name: '自定义输出',
|
||||||
flowType: 'pluginOutput',
|
flowType: 'pluginOutput',
|
||||||
showStatus: false,
|
showStatus: false,
|
||||||
@ -14,7 +15,7 @@ export const defaultModules: ModuleItemType[] = [
|
|||||||
outputs: []
|
outputs: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
moduleId: 'w09v30',
|
moduleId: 'custom-input',
|
||||||
name: '自定义输入',
|
name: '自定义输入',
|
||||||
flowType: 'pluginInput',
|
flowType: 'pluginInput',
|
||||||
showStatus: false,
|
showStatus: false,
|
||||||
@ -26,3 +27,14 @@ export const defaultModules: ModuleItemType[] = [
|
|||||||
outputs: []
|
outputs: []
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export enum PluginTypeEnum {
|
||||||
|
personal = 'personal',
|
||||||
|
community = 'community',
|
||||||
|
commercial = 'commercial'
|
||||||
|
}
|
||||||
|
export const PluginType2TemplateTypeMap = {
|
||||||
|
[PluginTypeEnum.personal]: ModuleTemplateTypeEnum.personalPlugin,
|
||||||
|
[PluginTypeEnum.community]: ModuleTemplateTypeEnum.communityPlugin,
|
||||||
|
[PluginTypeEnum.commercial]: ModuleTemplateTypeEnum.commercialPlugin
|
||||||
|
};
|
||||||
|
|||||||
13
packages/global/core/plugin/type.d.ts
vendored
@ -1,4 +1,6 @@
|
|||||||
|
import { ModuleTemplateTypeEnum } from 'core/module/constants';
|
||||||
import type { ModuleItemType } from '../module/type.d';
|
import type { ModuleItemType } from '../module/type.d';
|
||||||
|
import { PluginTypeEnum } from './constants';
|
||||||
|
|
||||||
export type PluginItemSchema = {
|
export type PluginItemSchema = {
|
||||||
_id: string;
|
_id: string;
|
||||||
@ -11,3 +13,14 @@ export type PluginItemSchema = {
|
|||||||
updateTime: Date;
|
updateTime: Date;
|
||||||
modules: ModuleItemType[];
|
modules: ModuleItemType[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* plugin template */
|
||||||
|
export type PluginTemplateType = {
|
||||||
|
id: string;
|
||||||
|
type: `${PluginTypeEnum}`;
|
||||||
|
name: string;
|
||||||
|
avatar: string;
|
||||||
|
intro: string;
|
||||||
|
modules: ModuleItemType[];
|
||||||
|
templateType?: `${ModuleTemplateTypeEnum}`;
|
||||||
|
};
|
||||||
|
|||||||
5
packages/global/support/user/api.d.ts
vendored
@ -13,3 +13,8 @@ export type OauthLoginProps = {
|
|||||||
inviterId?: string;
|
inviterId?: string;
|
||||||
tmbId?: string;
|
tmbId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type FastLoginProps = {
|
||||||
|
token: string;
|
||||||
|
code: string;
|
||||||
|
};
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { AppTypeMap } from '@fastgpt/global/core/app/constants';
|
||||||
import { connectionMongo, type Model } from '../../common/mongo';
|
import { connectionMongo, type Model } from '../../common/mongo';
|
||||||
const { Schema, model, models } = connectionMongo;
|
const { Schema, model, models } = connectionMongo;
|
||||||
import type { AppSchema as AppType } from '@fastgpt/global/core/app/type.d';
|
import type { AppSchema as AppType } from '@fastgpt/global/core/app/type.d';
|
||||||
@ -31,7 +32,11 @@ const AppSchema = new Schema({
|
|||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'advanced',
|
default: 'advanced',
|
||||||
enum: ['basic', 'advanced']
|
enum: Object.keys(AppTypeMap)
|
||||||
|
},
|
||||||
|
simpleTemplateId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
},
|
},
|
||||||
avatar: {
|
avatar: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -61,6 +66,7 @@ const AppSchema = new Schema({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
AppSchema.index({ updateTime: -1 });
|
AppSchema.index({ updateTime: -1 });
|
||||||
|
AppSchema.index({ teamId: 1 });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { connectionMongo, type Model } from '../../common/mongo';
|
import { connectionMongo, type Model } from '../../common/mongo';
|
||||||
const { Schema, model, models } = connectionMongo;
|
const { Schema, model, models } = connectionMongo;
|
||||||
import { ChatItemSchema as ChatItemType } from '@fastgpt/global/core/chat/type';
|
import { ChatItemSchema as ChatItemType } from '@fastgpt/global/core/chat/type';
|
||||||
import { ChatRoleMap, TaskResponseKeyEnum } from '@fastgpt/global/core/chat/constants';
|
import { ChatRoleMap } from '@fastgpt/global/core/chat/constants';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24);
|
||||||
import {
|
import {
|
||||||
@ -10,6 +10,7 @@ import {
|
|||||||
} from '@fastgpt/global/support/user/team/constant';
|
} from '@fastgpt/global/support/user/team/constant';
|
||||||
import { appCollectionName } from '../app/schema';
|
import { appCollectionName } from '../app/schema';
|
||||||
import { userCollectionName } from '../../support/user/schema';
|
import { userCollectionName } from '../../support/user/schema';
|
||||||
|
import { ModuleOutputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||||
|
|
||||||
const ChatItemSchema = new Schema({
|
const ChatItemSchema = new Schema({
|
||||||
dataId: {
|
dataId: {
|
||||||
@ -65,7 +66,7 @@ const ChatItemSchema = new Schema({
|
|||||||
a: String
|
a: String
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[TaskResponseKeyEnum.responseData]: {
|
[ModuleOutputKeyEnum.responseData]: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: []
|
default: []
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,13 @@
|
|||||||
import { connectionMongo, type Model } from '../../common/mongo';
|
import { connectionMongo, type Model } from '../../common/mongo';
|
||||||
const { Schema, model, models } = connectionMongo;
|
const { Schema, model, models } = connectionMongo;
|
||||||
import { ChatSchema as ChatType } from '@fastgpt/global/core/chat/type.d';
|
import { ChatSchema as ChatType } from '@fastgpt/global/core/chat/type.d';
|
||||||
import {
|
import { ChatRoleMap, ChatSourceMap } from '@fastgpt/global/core/chat/constants';
|
||||||
ChatRoleMap,
|
|
||||||
ChatSourceMap,
|
|
||||||
TaskResponseKeyEnum
|
|
||||||
} from '@fastgpt/global/core/chat/constants';
|
|
||||||
import {
|
import {
|
||||||
TeamCollectionName,
|
TeamCollectionName,
|
||||||
TeamMemberCollectionName
|
TeamMemberCollectionName
|
||||||
} from '@fastgpt/global/support/user/team/constant';
|
} from '@fastgpt/global/support/user/team/constant';
|
||||||
import { appCollectionName } from '../app/schema';
|
import { appCollectionName } from '../app/schema';
|
||||||
|
import { ModuleOutputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||||
|
|
||||||
export const chatCollectionName = 'chat';
|
export const chatCollectionName = 'chat';
|
||||||
|
|
||||||
@ -81,7 +78,7 @@ const ChatSchema = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
[TaskResponseKeyEnum.responseData]: {
|
[ModuleOutputKeyEnum.responseData]: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: []
|
default: []
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,14 @@ const DatasetDataSchema = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
|
qToken: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
aToken: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
indexes: {
|
indexes: {
|
||||||
type: [
|
type: [
|
||||||
{
|
{
|
||||||
@ -70,9 +78,11 @@ const DatasetDataSchema = new Schema({
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DatasetDataSchema.index({ userId: 1 });
|
DatasetDataSchema.index({ teamId: 1 });
|
||||||
DatasetDataSchema.index({ datasetId: 1 });
|
DatasetDataSchema.index({ datasetId: 1 });
|
||||||
DatasetDataSchema.index({ collectionId: 1 });
|
DatasetDataSchema.index({ collectionId: 1 });
|
||||||
|
// full text index
|
||||||
|
DatasetDataSchema.index({ qToken: 'text', aToken: 'text' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +1,100 @@
|
|||||||
import { MongoPlugin } from './schema';
|
import { MongoPlugin } from './schema';
|
||||||
import { FlowModuleTemplateType } from '@fastgpt/global/core/module/type';
|
import { FlowModuleTemplateType } from '@fastgpt/global/core/module/type';
|
||||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
import { FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||||
import { formatPluginIOModules } from '@fastgpt/global/core/module/utils';
|
import { formatPluginToPreviewModule } from '@fastgpt/global/core/module/utils';
|
||||||
|
import { PluginType2TemplateTypeMap, PluginTypeEnum } from '@fastgpt/global/core/plugin/constants';
|
||||||
|
import type { PluginTemplateType } from '@fastgpt/global/core/plugin/type.d';
|
||||||
|
|
||||||
/* plugin templates */
|
/*
|
||||||
export async function getUserPlugins2Templates({
|
plugin id rule:
|
||||||
teamId
|
personal: id
|
||||||
}: {
|
community: community-id
|
||||||
teamId: string;
|
commercial: commercial-id
|
||||||
}): Promise<FlowModuleTemplateType[]> {
|
*/
|
||||||
const plugins = await MongoPlugin.find({ teamId }).lean();
|
|
||||||
|
|
||||||
return plugins.map((plugin) => ({
|
export async function splitCombinePluginId(id: string) {
|
||||||
id: String(plugin._id),
|
const splitRes = id.split('-');
|
||||||
flowType: FlowNodeTypeEnum.pluginModule,
|
if (splitRes.length === 1 && id.length === 24) {
|
||||||
logo: plugin.avatar,
|
return {
|
||||||
name: plugin.name,
|
type: PluginTypeEnum.personal,
|
||||||
description: plugin.intro,
|
pluginId: id
|
||||||
intro: plugin.intro,
|
};
|
||||||
showStatus: false,
|
}
|
||||||
inputs: [],
|
|
||||||
outputs: []
|
const [type, pluginId] = id.split('-') as [`${PluginTypeEnum}`, string];
|
||||||
}));
|
if (!type || !pluginId) return Promise.reject('pluginId not found');
|
||||||
|
|
||||||
|
return { type, pluginId: id };
|
||||||
}
|
}
|
||||||
/* one plugin 2 module detail */
|
/* format plugin modules to plugin preview module */
|
||||||
export async function getPluginModuleDetail({ id }: { id: string }) {
|
export async function getPluginPreviewModule({
|
||||||
const plugin = await MongoPlugin.findById(id);
|
id
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
}): Promise<FlowModuleTemplateType> {
|
||||||
|
// classify
|
||||||
|
const { type, pluginId } = await splitCombinePluginId(id);
|
||||||
|
|
||||||
|
const plugin = await (async () => {
|
||||||
|
if (type === PluginTypeEnum.community) {
|
||||||
|
return global.communityPlugins?.find((plugin) => plugin.id === pluginId);
|
||||||
|
}
|
||||||
|
if (type === PluginTypeEnum.personal) {
|
||||||
|
const item = await MongoPlugin.findById(id);
|
||||||
|
if (!item) return undefined;
|
||||||
|
return {
|
||||||
|
id: String(item._id),
|
||||||
|
name: item.name,
|
||||||
|
avatar: item.avatar,
|
||||||
|
intro: item.intro,
|
||||||
|
type: PluginTypeEnum.personal,
|
||||||
|
modules: item.modules
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
if (!plugin) return Promise.reject('plugin not found');
|
if (!plugin) return Promise.reject('plugin not found');
|
||||||
return {
|
return {
|
||||||
id: String(plugin._id),
|
id: plugin.id,
|
||||||
|
templateType: PluginType2TemplateTypeMap[plugin.type],
|
||||||
flowType: FlowNodeTypeEnum.pluginModule,
|
flowType: FlowNodeTypeEnum.pluginModule,
|
||||||
logo: plugin.avatar,
|
avatar: plugin.avatar,
|
||||||
name: plugin.name,
|
name: plugin.name,
|
||||||
description: plugin.intro,
|
|
||||||
intro: plugin.intro,
|
intro: plugin.intro,
|
||||||
showStatus: false,
|
showStatus: true,
|
||||||
...formatPluginIOModules(String(plugin._id), plugin.modules)
|
...formatPluginToPreviewModule(plugin.id, plugin.modules)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getPluginRuntimeById(id: string): Promise<PluginTemplateType> {
|
||||||
|
const { type, pluginId } = await splitCombinePluginId(id);
|
||||||
|
|
||||||
|
const plugin = await (async () => {
|
||||||
|
if (type === PluginTypeEnum.community) {
|
||||||
|
return global.communityPlugins?.find((plugin) => plugin.id === pluginId);
|
||||||
|
}
|
||||||
|
if (type === PluginTypeEnum.personal) {
|
||||||
|
const item = await MongoPlugin.findById(id);
|
||||||
|
if (!item) return undefined;
|
||||||
|
return {
|
||||||
|
id: String(item._id),
|
||||||
|
name: item.name,
|
||||||
|
avatar: item.avatar,
|
||||||
|
intro: item.intro,
|
||||||
|
type: PluginTypeEnum.personal,
|
||||||
|
modules: item.modules
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (!plugin) return Promise.reject('plugin not found');
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: plugin.id,
|
||||||
|
type: plugin.type,
|
||||||
|
name: plugin.name,
|
||||||
|
avatar: plugin.avatar,
|
||||||
|
intro: plugin.intro,
|
||||||
|
modules: plugin.modules
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import {
|
|||||||
TeamMemberCollectionName
|
TeamMemberCollectionName
|
||||||
} from '@fastgpt/global/support/user/team/constant';
|
} from '@fastgpt/global/support/user/team/constant';
|
||||||
|
|
||||||
export const ModuleCollectionName = 'plugins';
|
export const PluginCollectionName = 'plugins';
|
||||||
|
|
||||||
const PluginSchema = new Schema({
|
const PluginSchema = new Schema({
|
||||||
userId: {
|
userId: {
|
||||||
@ -52,5 +52,5 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const MongoPlugin: Model<PluginItemSchema> =
|
export const MongoPlugin: Model<PluginItemSchema> =
|
||||||
models[ModuleCollectionName] || model(ModuleCollectionName, PluginSchema);
|
models[PluginCollectionName] || model(PluginCollectionName, PluginSchema);
|
||||||
MongoPlugin.syncIndexes();
|
MongoPlugin.syncIndexes();
|
||||||
|
|||||||
31
packages/service/core/plugin/store/schema.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { connectionMongo, type Model } from '../../../common/mongo';
|
||||||
|
const { Schema, model, models } = connectionMongo;
|
||||||
|
import type { PluginItemSchema } from '@fastgpt/global/core/plugin/type.d';
|
||||||
|
|
||||||
|
import { PluginCollectionName } from '../schema';
|
||||||
|
|
||||||
|
export const ModuleCollectionName = 'plugins';
|
||||||
|
|
||||||
|
const PluginStoreSchema = new Schema({
|
||||||
|
pluginId: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: PluginCollectionName,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
price: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
updateTime: {
|
||||||
|
type: Date,
|
||||||
|
default: () => new Date()
|
||||||
|
},
|
||||||
|
modules: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const MongoPluginStore: Model<PluginItemSchema> =
|
||||||
|
models[ModuleCollectionName] || model(ModuleCollectionName, PluginStoreSchema);
|
||||||
|
MongoPluginStore.syncIndexes();
|
||||||
5
packages/service/core/plugin/type.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { PluginTemplateType } from '@fastgpt/global/core/plugin/type.d';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
var communityPlugins: PluginTemplateType[];
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { AuthResponseType } from '@fastgpt/global/support/permission/type';
|
import { AuthResponseType } from '@fastgpt/global/support/permission/type';
|
||||||
import { AuthModeType } from '../type';
|
import { AuthModeType } from '../type';
|
||||||
import type { ChatSchema, ChatWithAppSchema } from '@fastgpt/global/core/chat/type';
|
import type { ChatWithAppSchema } from '@fastgpt/global/core/chat/type';
|
||||||
import { parseHeaderCert } from '../controller';
|
import { parseHeaderCert } from '../controller';
|
||||||
import { MongoChat } from '../../../core/chat/chatSchema';
|
import { MongoChat } from '../../../core/chat/chatSchema';
|
||||||
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
|
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
|
||||||
@ -16,7 +16,7 @@ export async function authChat({
|
|||||||
chatId: string;
|
chatId: string;
|
||||||
}): Promise<
|
}): Promise<
|
||||||
AuthResponseType & {
|
AuthResponseType & {
|
||||||
chat: ChatSchema;
|
chat: ChatWithAppSchema;
|
||||||
}
|
}
|
||||||
> {
|
> {
|
||||||
const { userId, teamId, tmbId } = await parseHeaderCert(props);
|
const { userId, teamId, tmbId } = await parseHeaderCert(props);
|
||||||
|
|||||||
@ -15,19 +15,17 @@ import { getFileById } from '../../../common/file/gridfs/controller';
|
|||||||
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||||
import { getTeamInfoByTmbId } from '../../user/team/controller';
|
import { getTeamInfoByTmbId } from '../../user/team/controller';
|
||||||
|
|
||||||
export async function authDataset({
|
export async function authDatasetByTmbId({
|
||||||
|
teamId,
|
||||||
|
tmbId,
|
||||||
datasetId,
|
datasetId,
|
||||||
per = 'owner',
|
per
|
||||||
...props
|
}: {
|
||||||
}: AuthModeType & {
|
teamId: string;
|
||||||
|
tmbId: string;
|
||||||
datasetId: string;
|
datasetId: string;
|
||||||
}): Promise<
|
per: AuthModeType['per'];
|
||||||
AuthResponseType & {
|
}) {
|
||||||
dataset: DatasetSchemaType;
|
|
||||||
}
|
|
||||||
> {
|
|
||||||
const result = await parseHeaderCert(props);
|
|
||||||
const { teamId, tmbId } = result;
|
|
||||||
const { role } = await getTeamInfoByTmbId({ tmbId });
|
const { role } = await getTeamInfoByTmbId({ tmbId });
|
||||||
|
|
||||||
const { dataset, isOwner, canWrite } = await (async () => {
|
const { dataset, isOwner, canWrite } = await (async () => {
|
||||||
@ -58,6 +56,32 @@ export async function authDataset({
|
|||||||
return { dataset, isOwner, canWrite };
|
return { dataset, isOwner, canWrite };
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
return {
|
||||||
|
dataset,
|
||||||
|
isOwner,
|
||||||
|
canWrite
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export async function authDataset({
|
||||||
|
datasetId,
|
||||||
|
per = 'owner',
|
||||||
|
...props
|
||||||
|
}: AuthModeType & {
|
||||||
|
datasetId: string;
|
||||||
|
}): Promise<
|
||||||
|
AuthResponseType & {
|
||||||
|
dataset: DatasetSchemaType;
|
||||||
|
}
|
||||||
|
> {
|
||||||
|
const result = await parseHeaderCert(props);
|
||||||
|
const { teamId, tmbId } = result;
|
||||||
|
const { dataset, isOwner, canWrite } = await authDatasetByTmbId({
|
||||||
|
teamId,
|
||||||
|
tmbId,
|
||||||
|
datasetId,
|
||||||
|
per
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...result,
|
...result,
|
||||||
dataset,
|
dataset,
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
|
|||||||
import { MongoPlugin } from '../../../core/plugin/schema';
|
import { MongoPlugin } from '../../../core/plugin/schema';
|
||||||
import { PluginErrEnum } from '@fastgpt/global/common/error/code/plugin';
|
import { PluginErrEnum } from '@fastgpt/global/common/error/code/plugin';
|
||||||
import { PluginItemSchema } from '@fastgpt/global/core/plugin/type';
|
import { PluginItemSchema } from '@fastgpt/global/core/plugin/type';
|
||||||
|
import { splitCombinePluginId } from '../../../core/plugin/controller';
|
||||||
|
import { PluginTypeEnum } from '@fastgpt/global/core/plugin/constants';
|
||||||
|
|
||||||
export async function authPluginCrud({
|
export async function authPluginCrud({
|
||||||
id,
|
id,
|
||||||
@ -54,3 +56,29 @@ export async function authPluginCrud({
|
|||||||
canWrite
|
canWrite
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function authPluginCanUse({
|
||||||
|
id,
|
||||||
|
teamId,
|
||||||
|
tmbId
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
teamId: string;
|
||||||
|
tmbId: string;
|
||||||
|
}) {
|
||||||
|
const { type, pluginId } = await splitCombinePluginId(id);
|
||||||
|
|
||||||
|
if (type === PluginTypeEnum.community) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === PluginTypeEnum.personal) {
|
||||||
|
const { role } = await getTeamInfoByTmbId({ tmbId });
|
||||||
|
const plugin = await MongoPlugin.findOne({ _id: pluginId, teamId });
|
||||||
|
if (!plugin) {
|
||||||
|
return Promise.reject(PluginErrEnum.unExist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
1
projects/app/public/imgs/modal/badAnswer.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700745147176" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="25531" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M551.706122 909.061224c-25.6 0-49.632653-8.359184-65.306122-24.555102-25.6-26.122449-36.571429-70.530612-47.542857-117.028571-6.269388-26.122449-13.583673-55.902041-21.420408-68.963265-20.897959-35.526531-65.828571-54.334694-78.367347-59.036735H266.971429c-25.6 0-47.020408-20.897959-47.020409-47.020408V215.771429c0-25.6 20.897959-47.020408 47.020409-47.020409h67.918367C364.146939 153.6 447.738776 114.938776 543.346939 114.938776h181.812245c29.779592 0 92.473469 10.971429 117.55102 53.289795 23.510204 39.183673 63.216327 344.293878 63.216327 370.416327 0 56.946939-53.812245 101.355102-100.310204 101.355102h-119.640817c-4.179592 0-6.791837 2.089796-7.836734 3.657143-1.044898 1.567347-2.612245 4.179592-2.089796 8.359184 4.179592 20.37551 13.583673 73.665306 6.791836 130.612244-7.314286 57.991837-41.795918 102.922449-92.473469 120.163266-12.016327 4.179592-25.6 6.269388-38.661225 6.269387z" fill="#16C4AF" p-id="25532"></path><path d="M132.179592 623.281633c-10.971429 0-19.853061-8.881633-19.853061-19.853062V196.440816c0-10.971429 8.881633-19.853061 19.853061-19.853061s19.853061 8.881633 19.853061 19.853061v406.987755c0 10.971429-8.881633 19.853061-19.853061 19.853062z" fill="#16C4AF" p-id="25533"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
1
projects/app/public/imgs/modal/bill.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700746245397" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="43680" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M0 0m178.086957 0l667.826086 0q178.086957 0 178.086957 178.086957l0 667.826086q0 178.086957-178.086957 178.086957l-667.826086 0q-178.086957 0-178.086957-178.086957l0-667.826086q0-178.086957 178.086957-178.086957Z" fill="#8973E6" p-id="43681"></path><path d="M570.813217 258.782609a77.534609 77.534609 0 0 1 77.534609 77.534608v350.987131a77.913043 77.913043 0 0 0 74.017391 77.824l3.895653 0.089043H316.838957a77.534609 77.534609 0 0 1-77.534609-77.534608V336.317217a77.534609 77.534609 0 0 1 77.534609-77.534608h253.996521zM456.43687 589.913043h-122.61287a16.606609 16.606609 0 0 0-16.606609 16.606609v5.743305c0 9.171478 7.43513 16.606609 16.606609 16.606608h122.61287a16.606609 16.606609 0 0 0 16.606608-16.606608v-5.743305a16.606609 16.606609 0 0 0-16.606608-16.606609z m77.913043-116.869565h-200.525913a16.606609 16.606609 0 0 0-16.606609 16.606609v5.743304c0 9.171478 7.43513 16.606609 16.606609 16.606609h200.525913a16.606609 16.606609 0 0 0 16.606609-16.606609v-5.743304a16.606609 16.606609 0 0 0-16.606609-16.606609z m0-116.869565h-200.525913a16.606609 16.606609 0 0 0-16.606609 16.606609v5.743304c0 9.171478 7.43513 16.606609 16.606609 16.606609h200.525913a16.606609 16.606609 0 0 0 16.606609-16.606609v-5.743304a16.606609 16.606609 0 0 0-16.606609-16.606609z" fill="#FFFFFF" p-id="43682"></path><path d="M628.869565 570.434783h155.826087v116.869565a77.913043 77.913043 0 0 1-155.826087 0v-116.869565z" fill="#FFFFFF" opacity=".6" p-id="43683"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
1
projects/app/public/imgs/modal/chatHistory.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700627014976" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9004" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M749.57747 338.71354a28.03513 28.03513 0 0 1-1.921508-56.00726l167.832777-11.875555-5.355025-146.507178a28.03513 28.03513 0 0 1 56.038759-2.047509l5.607026 153.43721a48.730726 48.730726 0 0 1-45.45471 50.589234l-174.762809 12.348057c-0.630003 0.063-1.291506 0.063-1.98451 0.063001z m166.16327-60.952783z" fill="#2E3138" p-id="9005"></path><path d="M585.461711 1004.878624a484.125741 484.125741 0 0 0-190.544383-929.254302H285.13932l-94.815439 74.466344-152.775707 469.761675L395.35833 996.153084s131.607609 33.799656 190.103381 8.72554z" fill="#56E5BE" p-id="9006"></path><path d="M769.202061 559.781563a484.220242 484.220242 0 0 1-290.179343 443.648054c-59.346275 25.98762-339.06757-61.173283-369.559711-198.450919-63.630295-286.651327-5.071523-729.133876 175.644813-729.133875a484.031241 484.031241 0 0 1 484.094241 483.93674z" fill="#50DDB8" p-id="9007"></path><path d="M279.658295 87.342376a484.220242 484.220242 0 0 1 103.950481 908.810708l-233.101079-144.900671-112.802022-242.551123 8.851541-229.258062 107.100495-210.389474z" fill="#42D3AD" p-id="9008"></path><path d="M512.727874 1023.999212a512.003371 512.003371 0 0 1-426.921477-227.998055C-70.780828 561.041569-6.993032 242.480594 227.998056 85.798869S781.424118-6.87456 938.105843 228.085028a28.06663 28.06663 0 0 1-46.683216 31.122144 455.964611 455.964611 0 0 0-632.333927-126.630587C49.864731 271.996231-6.961532 555.655044 132.521114 764.910513s423.046959 266.050232 632.333927 126.599086a458.925625 458.925625 0 0 0 198.954921-441.821045 28.04458 28.04458 0 1 1 55.566258-7.623036 515.342386 515.342386 0 0 1-223.462035 496.127297 509.451859 509.451859 0 0 1-283.186311 85.806397z" fill="#2E3138" p-id="9009"></path><path d="M729.543378 657.558016h-2.236511l-186.354862-14.553067a47.029718 47.029718 0 0 1-43.0292-46.746217v-211.77548a28.03513 28.03513 0 0 1 56.07026 0v203.17594l177.818323 13.891565a28.03513 28.03513 0 0 1-2.14201 56.007259z" fill="#2E3138" p-id="9010"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
1
projects/app/public/imgs/modal/concat.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700745458924" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="30191" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M0 512a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" fill="#EFF2FF" p-id="30192"></path><path d="M682.666667 682.666667c9.898667 9.841778-9.841778-9.841778 0 0zM338.488889 685.511111l5.688889-5.688889c-1.080889 0.682667-2.161778 2.104889-2.844445 2.844445a10.752 10.752 0 0 0-2.844444 2.844444z" fill="#000000" p-id="30193"></path><path d="M784.896 740.693333c23.324444-40.504889 10.410667-71.68-30.947556-102.798222-48.696889-36.579556-96.199111-61.212444-130.389333-21.788444 0 0-36.295111 43.064889-143.075555-57.685334C356.352 440.490667 408.462222 398.677333 408.462222 398.677333c43.178667-43.235556 15.701333-75.548444-20.48-124.416-36.238222-48.924444-72.817778-64.341333-125.326222-22.300444-101.262222 81.009778 41.528889 271.189333 113.607111 345.144889 0 0 109.738667 113.095111 178.801778 150.755555l36.920889 20.593778c52.906667 27.079111 112.469333 39.480889 154.339555 14.336 0 0 20.195556-10.353778 38.570667-42.097778z" fill="#4D4DEE" p-id="30194"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
1
projects/app/public/imgs/modal/edit.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700634007483" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19559" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M65.361 856H967v160H65.361zM65.531 805.062l2.295-188.972L676.402 7.515 863.078 194.19 254.503 802.766 65.53 805.062z m50.726-169.52l-1.46 120.254 120.254-1.46L116.257 635.54z m507.147-507.147L742.198 247.19l52.163-52.163L675.567 76.232l-52.163 52.163z" fill="#1AA5FF" p-id="19560"></path></svg>
|
||||||
|
After Width: | Height: | Size: 628 B |
1
projects/app/public/imgs/modal/folder.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700746526624" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="53489" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M300.053794 0h423.892412c200.032053 0 300.053794 100.021741 300.053794 300.053794v423.892412c0 200.032053-100.021741 300.053794-300.053794 300.053794H300.053794C100.021741 1023.988572 0 923.966831 0 723.934778v-423.880984C0 100.021741 100.021741 0 300.053794 0z" fill="#598BFC" opacity=".15" p-id="53490"></path><path d="M709.900648 336.864812h-191.883572c-7.017065 0-13.542706-3.645674-17.211237-9.62275l-43.725226-41.828105a34.641899 34.641899 0 0 0-29.508242-16.479816h-110.695908c-43.725226 0-79.164831 35.416748-79.16483 79.09626v310.876531c0 42.136673 34.182476 76.296291 76.364862 76.30772h395.835582c42.170958 0 76.364862-34.171047 76.364862-76.30772V413.172532c0-42.136673-34.193904-76.30772-76.376291-76.30772z" fill="#598BFC" p-id="53491"></path><path d="M335.436256 437.800828h353.116059c13.336994 0 20.011205 6.857066 20.011205 20.571199s-6.674211 20.571199-20.011205 20.571199H335.436256c-13.336994 0-20.011205-6.857066-20.011205-20.571199s6.674211-20.571199 20.011205-20.571199z" fill="#FFFFFF" p-id="53492"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
1
projects/app/public/imgs/modal/import.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700746705101" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="61761" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M906.5472 756.8384H632.9344c-23.04 0-43.2128-20.1728-43.2128-43.2128s20.1728-43.2128 43.2128-43.2128h273.6128c23.04 0 43.2128 20.1728 43.2128 43.2128s-20.1728 43.2128-43.2128 43.2128z" fill="#409EFF" p-id="61762"></path><path d="M631.296 756.8384c-11.5712 0-23.04-2.8672-28.7744-11.5712-17.3056-17.3056-17.3056-43.2128 0-60.5184L732.16 555.2128c17.3056-17.3056 43.2128-17.3056 60.5184 0s17.3056 43.2128 0 60.5184L663.04 745.3696c-11.5712 8.6016-23.04 11.4688-31.744 11.4688z" fill="#409EFF" p-id="61763"></path><path d="M761.4464 886.3744c-11.5712 0-23.04-2.8672-28.7744-11.5712L603.0336 745.3696c-17.3056-17.3056-17.3056-43.2128 0-60.5184s43.2128-17.3056 60.5184 0l129.6384 129.536c17.3056 17.3056 17.3056 43.2128 0 60.5184-8.704 5.7344-20.2752 11.4688-31.744 11.4688z" fill="#409EFF" p-id="61764"></path><path d="M851.8656 932.4544a126.65856 126.65856 0 0 1-89.2928 37.4784c-34.6112 0-63.3856-11.5712-89.2928-37.4784L546.5088 802.9184c-17.3056-17.3056-28.7744-40.3456-34.6112-63.3856-2.8672-8.6016-2.8672-17.3056-2.8672-25.9072s0-17.3056 2.8672-25.9072c5.7344-23.04 17.3056-46.08 34.6112-63.3856L676.0448 494.592c48.4352-49.3568 127.6928-49.9712 177.0496-1.536l1.536 1.536c17.6128 17.6128 52.0192 62.1568 67.2768 82.1248 1.4336 1.8432 4.096 2.2528 5.9392 0.8192 1.024-0.8192 1.6384-2.048 1.6384-3.3792V280.064c0-65.6384-53.76-119.3984-119.3984-119.3984H314.5728c-65.6384 0-119.3984 53.76-119.3984 119.3984v573.3376c0 65.6384 53.76 119.3984 119.3984 119.3984h492.6464c65.6384 0 119.3984-53.76 119.3984-119.3984 0-2.3552-1.8432-4.1984-4.1984-4.1984a3.9936 3.9936 0 0 0-3.3792 1.7408c-14.7456 20.1728-47.616 64.1024-67.1744 81.5104z" fill="#409EFF" p-id="61765"></path><path d="M131.7888 823.0912V212.48c0-66.2528 54.6816-120.9344 120.9344-120.9344h524.1856C756.8384 68.5056 725.0944 51.2 690.5856 51.2H189.44C126.0544 51.2 74.24 103.0144 74.24 166.4v584.6016c0 43.2128 23.04 80.5888 60.5184 100.7616-2.9696-11.4688-2.9696-20.0704-2.9696-28.672z" fill="#409EFF" p-id="61766"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
1
projects/app/public/imgs/modal/key.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700745751866" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="36975" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M220.150923 700.501366l167.543301-167.5433a73.062148 73.062148 0 0 1 103.327242 103.327242l-365.310741 365.310741a73.062148 73.062148 0 1 1-103.327242-103.286288l94.481152-94.481152-64.257012-64.257013a73.062148 73.062148 0 1 1 103.327242-103.286288l64.216058 64.216058z" fill="#CCDAFF" p-id="36976"></path><path d="M475.909397 49.003242a365.310741 365.310741 0 1 1 365.310741 632.782092 365.310741 365.310741 0 0 1-365.310741-632.741138z m118.685036 205.589677a127.981622 127.981622 0 1 0 127.981622 221.643692 127.981622 127.981622 0 0 0-127.981622-221.684646z" fill="#244DD5" p-id="36977"></path></svg>
|
||||||
|
After Width: | Height: | Size: 939 B |
1
projects/app/public/imgs/modal/move.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700746780241" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="67557" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M768 320v128H576V256h128L512 64 320 256h128v192H256V320L64 512l64 64 128 128V576h192v192H320l192 192 64-64 128-128H576V576h192v128l192-192-192-192z" p-id="67558" fill="#13227a"></path></svg>
|
||||||
|
After Width: | Height: | Size: 524 B |
1
projects/app/public/imgs/modal/network.svg
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
1
projects/app/public/imgs/modal/openai.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700746289796" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="44851" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M939.795692 421.415385a248.832 248.832 0 0 0-21.385846-204.386462 251.667692 251.667692 0 0 0-271.064615-120.753231 248.832 248.832 0 0 0-187.687385-83.672615 251.687385 251.687385 0 0 0-240.088615 174.257231 248.910769 248.910769 0 0 0-166.4 120.713846 251.707077 251.707077 0 0 0 30.956307 295.108923 248.832 248.832 0 0 0 21.385847 204.386461 251.687385 251.687385 0 0 0 271.064615 120.753231 248.832 248.832 0 0 0 187.687385 83.672616 251.687385 251.687385 0 0 0 240.167384-174.355693 248.910769 248.910769 0 0 0 166.4-120.713846A251.707077 251.707077 0 0 0 939.795692 421.415385zM564.342154 946.195692a186.663385 186.663385 0 0 1-119.827692-43.323077c1.516308-0.827077 4.174769-2.284308 5.907692-3.347692l198.892308-114.884923a32.334769 32.334769 0 0 0 16.344615-28.297846V475.943385l84.066461 48.541538a2.993231 2.993231 0 0 1 1.634462 2.304v232.211692a187.431385 187.431385 0 0 1-187.017846 187.195077z m-402.195692-171.776a186.564923 186.564923 0 0 1-22.331077-125.44c1.476923 0.886154 4.056615 2.461538 5.907692 3.524923l198.892308 114.884923a32.374154 32.374154 0 0 0 32.669538 0l242.825846-140.20923v97.083077a3.012923 3.012923 0 0 1-1.201231 2.579692l-201.058461 116.086154a187.392 187.392 0 0 1-255.704615-68.509539z m-52.322462-434.195692a186.505846 186.505846 0 0 1 97.437538-82.077538c0 1.713231-0.098462 4.745846-0.098461 6.852923v229.769846a32.315077 32.315077 0 0 0 16.324923 28.278154L466.313846 663.236923l-84.066461 48.541539a3.012923 3.012923 0 0 1-2.835693 0.256l-201.078154-116.184616a187.392 187.392 0 0 1-68.509538-255.625846z m690.688 160.728615l-242.825846-140.20923 84.066461-48.521847a3.012923 3.012923 0 0 1 2.835693-0.256l201.078154 116.086154a187.234462 187.234462 0 0 1-28.928 337.821539V529.230769a32.295385 32.295385 0 0 0-16.226462-28.278154zM884.184615 375.020308c-1.476923-0.905846-4.056615-2.461538-5.907692-3.524923l-198.892308-114.884923a32.413538 32.413538 0 0 0-32.669538 0l-242.825846 140.20923v-97.083077a3.012923 3.012923 0 0 1 1.201231-2.579692l201.058461-115.987692A187.214769 187.214769 0 0 1 884.184615 375.020308z m-526.00123 173.036307l-84.086154-48.541538a2.993231 2.993231 0 0 1-1.634462-2.304V264.999385a187.214769 187.214769 0 0 1 307.003077-143.753847c-1.516308 0.827077-4.155077 2.284308-5.907692 3.347693l-198.892308 114.884923a32.315077 32.315077 0 0 0-16.344615 28.278154z m45.666461-98.461538L512 387.131077l108.150154 62.424615v124.888616L512 636.868923l-108.150154-62.424615z" fill="#202123" p-id="44852"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.8 KiB |
1
projects/app/public/imgs/modal/params.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700626300526" class="icon" viewBox="0 0 1050 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5944" xmlns:xlink="http://www.w3.org/1999/xlink" width="131.25" height="128"><path d="M877.714286 29.404164H173.484566c-72.53027 0-131.338598 58.808327-131.338598 131.338597V864.972481c0 72.53027 58.808327 131.338598 131.338598 131.338598h704.22972c72.53027 0 131.338598-58.808327 131.338597-131.338598V160.742761C1008.807849 88.212491 949.999521 29.404164 877.714286 29.404164zM857.621441 760.832735h-113.941135c-19.112706 39.695621-59.543431 67.384542-106.590093 67.384542s-87.477387-27.443886-106.590093-67.384542h-318.545107c-27.933955 0-50.722182-22.788227-50.722182-50.722182 0-27.933955 22.788227-50.722182 50.722182-50.722183h318.790141c19.112706-39.695621 59.543431-67.384542 106.590094-67.384541s87.477387 27.443886 106.590093 67.384541H857.621441c27.933955 0 50.722182 22.788227 50.722182 50.722183 0.245035 28.17899-22.543192 50.722182-50.722182 50.722182z m0-394.750897H523.149079c-19.112706 39.695621-59.543431 67.384542-106.590094 67.384542s-87.477387-27.443886-106.590093-67.384542h-98.013879c-27.933955 0-50.722182-22.788227-50.722182-50.722183 0-27.933955 22.788227-50.722182 50.722182-50.722182h98.258914c19.112706-39.695621 59.543431-67.384542 106.590093-67.384542s87.477387 27.443886 106.590093 67.384542H857.621441c27.933955 0 50.722182 22.788227 50.722182 50.722182 0.245035 27.933955-22.543192 50.722182-50.722182 50.722183z" p-id="5945" fill="#1296db"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
1
projects/app/public/imgs/modal/password.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700746389208" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="49701" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M128 0h768C981.357714 0 1024 42.642286 1024 128v768c0 85.357714-42.642286 128-128 128H128C42.642286 1024 0 981.357714 0 896V128C0 42.642286 42.642286 0 128 0z" fill="#4C84FF" p-id="49702"></path><path d="M704 398.189714h-31.963429v-64.950857c0-89.746286-71.68-162.596571-160.036571-162.596571-88.283429 0-159.963429 72.850286-159.963429 162.596571v64.950857h-32.036571c-35.181714 0-64 29.257143-64 65.097143v282.331429c0 35.766857 28.818286 65.097143 64 65.097143h384c35.181714 0 64-29.257143 64-65.097143v-282.331429a64.731429 64.731429 0 0 0-64-65.097143zM512 682.715429a85.577143 85.577143 0 0 1-85.357714-85.357715A85.577143 85.577143 0 0 1 512 512a85.577143 85.577143 0 0 1 85.357714 85.357714A85.577143 85.577143 0 0 1 512 682.642286z m-95.963429-284.525715v-64.950857c0-53.979429 42.861714-97.572571 95.963429-97.572571 53.101714 0 96.036571 43.52 96.036571 97.572571v64.950857H416.036571z" fill="#FFFFFF" p-id="49703"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
1
projects/app/public/imgs/modal/pay.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700746345419" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="47618" width="128" height="128" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M885 409.2c-28.2 1.4-53.9-18.2-59.4-46.8l-29-150.5-585 112.6c-8.4 1.6-15.8 6.5-20.7 13.8-4.9 7.3-6.7 15.9-5.1 24.3 6 31.3-14.5 61.6-45.8 67.6-31.3 6.1-61.6-14.5-67.6-45.8-7.4-38.7 0.7-78.1 22.9-110.9 22.2-32.8 55.8-54.9 94.5-62.4L781.4 97.4c28.5-5.5 57.5 0.5 81.6 16.8 24.1 16.3 40.4 41 45.9 69.5l30.2 157c6 31.3-14.5 61.6-45.8 67.6-2.8 0.5-5.5 0.8-8.3 0.9z" fill="#00EFEF" p-id="47619"></path><path d="M861.6 281.7H162.1c-54.6 0-99 44.4-99 99V817c0 54.6 44.4 99.1 99 99.1h699.5c54.5 0 99-44.4 99-99.1V380.7c0-54.6-44.5-99-99-99zM178.5 397.1h666.6v60.1H178.5v-60.1z m666.6 403.5H178.5V570h666.6v230.6z" fill="#52A9FF" p-id="47620"></path><path d="M446.7 682.8H251.1c-20.7 0-37.6-16.9-37.6-37.6 0-20.7 16.9-37.6 37.6-37.6h195.5c20.7 0 37.6 16.9 37.6 37.6 0.1 20.7-16.9 37.6-37.5 37.6z" fill="#00EFEF" p-id="47621"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
1
projects/app/public/imgs/modal/preview.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700747053101" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="69471" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M512 853.333333c-263.9872 0-477.866667-284.672-477.866667-341.230933C34.133333 471.3472 248.0128 170.666667 512 170.666667c263.918933 0 477.866667 303.445333 477.866667 341.435733C989.7984 568.900267 775.850667 853.333333 512 853.333333z m-6.144-521.1136c-127.658667 0-276.5824 60.279467-276.5824 187.938134s148.8896 174.318933 276.548267 174.318933 279.005867-46.660267 279.005866-174.318933-151.3472-187.938133-279.005866-187.938134z m2.594133 93.7984a79.325867 79.325867 0 0 0 79.223467 79.291734c10.376533 0 19.968-2.1504 29.013333-5.563734 0.341333 3.6864 1.297067 7.202133 1.297067 11.0592a113.220267 113.220267 0 1 1-226.542933 0 113.322667 113.322667 0 0 1 113.220266-113.3568c3.1744 0 6.178133 0.7168 9.216 0.989867-3.345067 8.6016-5.4272 17.749333-5.4272 27.579733z" fill="#85C2FF" p-id="69472"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
1
projects/app/public/imgs/modal/prompt.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700745656774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="34698" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M683.776 164.352a55.808 55.808 0 1 0-105.984-34.9184L336.9984 859.648a55.808 55.808 0 1 0 105.984 34.9184L683.8272 164.352zM179.712 327.168l-66.9184-36.5568a33.4848 33.4848 0 0 1 0-58.88L179.712 195.072a9.472 9.472 0 0 0 3.7888-3.7888l36.608-66.9184a33.4848 33.4848 0 0 1 58.88 0l37.9392 69.3248 69.376 37.9392a33.4848 33.4848 0 0 1 0 58.88l-66.9184 36.6592a9.472 9.472 0 0 0-3.7888 3.7376l-36.608 66.9184a33.4848 33.4848 0 0 1-58.88 0l-36.608-66.9184a9.472 9.472 0 0 0-3.7888-3.7376z m591.4624 302.8992l-57.5488-31.488a28.8256 28.8256 0 0 1 0-50.688l57.5488-31.488a8.192 8.192 0 0 0 3.2768-3.2256l31.488-57.6a28.8256 28.8256 0 0 1 50.688 0l32.6144 59.6992 59.648 32.6144a28.7744 28.7744 0 0 1 0 50.688l-57.5488 31.488a8.192 8.192 0 0 0-3.2768 3.2256l-31.488 57.6a28.8256 28.8256 0 0 1-50.688 0l-31.4368-57.6a8.192 8.192 0 0 0-3.2768-3.2256z" p-id="34699" fill="#13227a"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
1
projects/app/public/imgs/modal/quote.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700627067306" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10812" xmlns:xlink="http://www.w3.org/1999/xlink" width="128.125" height="128"><path d="M448 838.4c0 67.2-52.8 121.6-118.4 121.6H118.4C52.8 960 0 905.6 0 838.4v-448C0 209.6 140.8 64 315.2 64h40c20.8 0 40 19.2 40 40v81.6c0 22.4-17.6 40-40 40h-40c-86.4 0-156.8 73.6-156.8 163.2v20.8c0 33.6 27.2 60.8 59.2 60.8h113.6c65.6 0 118.4 54.4 118.4 121.6v246.4z m576 0c0 67.2-52.8 121.6-118.4 121.6H694.4c-65.6 0-118.4-54.4-118.4-121.6v-448C576 209.6 716.8 64 891.2 64h40c20.8 0 40 19.2 40 40v81.6c0 22.4-17.6 40-40 40h-40c-86.4 0-156.8 73.6-156.8 163.2v20.8c0 33.6 27.2 60.8 59.2 60.8h113.6c65.6 0 118.4 54.4 118.4 121.6v246.4z" p-id="10813" fill="#E67E22"></path></svg>
|
||||||
|
After Width: | Height: | Size: 910 B |
1
projects/app/public/imgs/modal/readFeedback.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700745264665" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="27472" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M826 957H342.1c-74.3 0-135-60.8-135-135V338.1c0-74.3 60.8-135 135-135H826c74.3 0 135 60.8 135 135V822c0 74.3-60.8 135-135 135z" fill="#BAD4FF" p-id="27473"></path><path d="M901 452.9c-16.4 0-25.3 13.5-25.3 30v300.4c0 49.7-40.5 94.6-84.6 94.6H230.4c-44.2 0-84.6-46-84.6-95.7V242.7c0-49.7 40.5-94.6 84.6-94.6h313.3c16.5 0 29.8-9 29.8-25.5S560.2 97 543.7 97H230.4c-77.1 0-135.2 62.9-135.2 145.7v540.6c0 82.8 58.2 145.7 135.2 145.7h560.7c77 0 136.3-62.8 136.3-145.7V483c0-16.6-9.9-30.1-26.4-30.1z" fill="#0081FF" p-id="27474"></path><path d="M426.4 441.9l3.1 125.6c0.6 15.5 13 28 28.5 28.8l125.2 2.4h1.3c7.9 0 15.5-3.2 21-8.8L919 275.1c11.6-11.7 10.8-30-0.8-41.7L791.6 105.5c-11.1-11.3-30.9-11.3-42.1 0l-314.3 314c-5.9 5.9-9.1 14-8.8 22.4z m344.2-291.8l105.3 104.5-296.8 296.2-100.7-3.9-4.5-100.6c-0.1 0 296.7-296.2 296.7-296.2z" fill="#0081FF" p-id="27475"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
1
projects/app/public/imgs/modal/shareLight.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1690507057466" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2581" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M816 416a174.816 174.816 0 0 1-133.6-62.624l-219.616 104.672a222.944 222.944 0 0 1-1.216 174.656l173.696 89.984A179.84 179.84 0 1 1 611.2 784l-185.056-96a224 224 0 1 1 2.912-284.8l221.44-105.6A175.552 175.552 0 1 1 816 416z" fill="#3399FF" p-id="2582"></path></svg>
|
||||||
|
After Width: | Height: | Size: 596 B |
1
projects/app/public/imgs/modal/team.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700746143520" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="41570" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M593.9 619.6l-45-45c-17.7 7.1-33.7 15-48.2 23.6v233.4h54.6l38.6-212z" fill="#FFDB69" p-id="41571"></path><path d="M629.3 352.9m-147.8 0a147.8 147.8 0 1 0 295.6 0 147.8 147.8 0 1 0-295.6 0Z" fill="#FFECB6" p-id="41572"></path><path d="M709.6 574.7l-45 45 38.6 212.1H896c0-0.1 6.4-180-186.4-257.1z" fill="#FFDB69" p-id="41573"></path><path d="M629.3 619.6l-32.9-32.9h65.8zM629.3 619.6l-32.2 154.3 32.2 57.8 32.1-57.8zM603.6 510.4c-88.6 0-160.7-72.1-160.7-160.7 0-44.5 14.3-66.4 21.9-78.1l1.6-2.5c2.8-4.5 8.8-5.8 13.3-3s5.8 8.8 3 13.3l-1.7 2.7c-7 10.8-18.8 28.8-18.8 67.6 0 78 63.4 141.4 141.4 141.4S745 427.7 745 349.7s-63.4-141.4-141.4-141.4c-44.8 0-68.5 13.8-90.2 34.4-3.9 3.7-10 3.5-13.6-0.4-3.7-3.9-3.5-10 0.4-13.6 21.7-20.6 49.3-39.7 103.5-39.7 88.6 0 160.7 72.1 160.7 160.7s-72.2 160.7-160.8 160.7z" fill="#F7931E" p-id="41574"></path><path d="M870.3 834.9c-5.3 0-9.6-4.3-9.6-9.6 0-141.7-115.3-257.1-257.1-257.1-39.1 0-72.3 5.7-101.7 17.6-5 2-10.6-0.4-12.5-5.3-2-4.9 0.4-10.6 5.3-12.5 31.7-12.8 67.3-19 108.9-19 152.4 0 276.3 124 276.3 276.3 0 5.3-4.3 9.6-9.6 9.6z" fill="#F7931E" p-id="41575"></path><path d="M430 352.9m-147.8 0a147.8 147.8 0 1 0 295.6 0 147.8 147.8 0 1 0-295.6 0Z" fill="#FFECB6" p-id="41576"></path><path d="M349.7 574.7l45 45-38.6 212.1H163.3c0-0.1-6.4-180 186.4-257.1zM510.4 574.7l-45 45 38.6 212h192.8s6.4-179.9-186.4-257z" fill="#F4BA64" p-id="41577"></path><path d="M430 619.6l-32.9-32.9H463zM430 619.6l-32.1 154.3 32.1 57.8 32.2-57.8z" fill="#F7931E" p-id="41578"></path><path d="M404.3 510.4c-88.6 0-160.7-72.1-160.7-160.7 0-44.5 14.3-66.4 21.9-78.1l1.6-2.5c2.9-4.5 8.8-5.8 13.3-3s5.8 8.8 3 13.3l-1.7 2.7c-7 10.8-18.8 28.8-18.8 67.6 0 78 63.4 141.4 141.4 141.4s141.4-63.4 141.4-141.4-63.4-141.4-141.4-141.4c-44.8 0-68.5 13.8-90.2 34.4-3.9 3.7-10 3.5-13.6-0.4-3.7-3.9-3.5-10 0.4-13.6 21.7-20.6 49.3-39.7 103.5-39.7 88.6 0 160.7 72.1 160.7 160.7s-72.2 160.7-160.8 160.7zM671 834.9c-5.3 0-9.6-4.3-9.6-9.6 0-141.7-115.3-257.1-257.1-257.1-68.4 0-121.2 18.1-161.5 55.3-3.9 3.6-10 3.4-13.6-0.5-3.6-3.9-3.4-10 0.5-13.6 44-40.7 101.1-60.4 174.6-60.4 152.4 0 276.3 124 276.3 276.3 0.1 5.3-4.2 9.6-9.6 9.6z" fill="" p-id="41579"></path><path d="M137.6 834.9c-5.3 0-9.6-4.3-9.6-9.6 0-74.6 19.3-129.1 62.6-176.7 3.6-3.9 9.7-4.2 13.6-0.7 3.9 3.6 4.2 9.7 0.7 13.6-40.4 44.5-57.6 93.4-57.6 163.8 0 5.3-4.3 9.6-9.7 9.6z" fill="" p-id="41580"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.6 KiB |
1
projects/app/public/imgs/modal/txt.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700746633907" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="59866" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M384.8192 785.6128c20.7872-25.8048 45.2608-49.4592 68.5056-73.1136 63.2832-64.4096 126.6688-128.9216 189.952-193.3312 59.0848-60.1088 118.1696-120.2176 177.152-180.3264 13.2096-13.4144 25.8048-29.7984 40.5504-41.472 15.36-12.0832 25.6-4.5056 37.5808 7.7824 10.5472 10.8544 20.7872 22.016 31.1296 32.9728 2.3552 2.56 15.9744 13.2096 15.9744 16.896 0 0-0.3072-258.4576-0.3072-258.4576 0-38.6048-31.4368-70.0416-70.0416-70.0416L135.7824 26.5216c-38.6048 0-70.0416 31.4368-70.0416 70.0416l0 812.6464c0 38.6048 31.4368 70.0416 70.0416 70.0416l183.7056 0.9216 36.4544-136.704C356.0448 843.4688 364.544 810.8032 384.8192 785.6128zM461.2096 432.2304 207.36 432.2304c-11.9808 0-21.7088-9.728-21.7088-21.7088 0-11.9808 9.728-21.7088 21.7088-21.7088l253.8496 0c11.9808 0 21.7088 9.728 21.7088 21.7088C483.0208 422.5024 473.1904 432.2304 461.2096 432.2304zM637.952 317.6448 207.36 317.6448c-11.9808 0-21.7088-9.728-21.7088-21.7088 0-11.9808 9.728-21.7088 21.7088-21.7088L637.952 274.2272c11.9808 0 21.7088 9.728 21.7088 21.7088C659.6608 307.9168 649.9328 317.6448 637.952 317.6448zM758.1696 202.9568 207.36 202.9568c-11.9808 0-21.7088-9.728-21.7088-21.7088 0-11.9808 9.728-21.7088 21.7088-21.7088l550.8096 0c11.9808 0 21.7088 9.728 21.7088 21.7088C779.8784 193.2288 770.1504 202.9568 758.1696 202.9568z" fill="#FF9000" p-id="59867"></path><path d="M992.5632 501.4528 891.4944 400.384c-10.752-10.752-29.5936-10.752-40.3456 0L428.2368 823.0912c-1.7408 1.7408-3.072 3.9936-3.6864 6.3488l-42.2912 151.6544c-1.3312 4.8128-0.1024 10.0352 3.2768 13.7216 2.7648 2.9696 6.656 4.7104 10.6496 4.7104 0.9216 0 1.7408-0.1024 2.6624-0.2048L562.176 968.704c2.8672-0.512 5.5296-1.9456 7.5776-3.9936l422.912-422.8096C1003.7248 530.7392 1003.7248 512.6144 992.5632 501.4528zM927.1296 585.3184c-5.4272 5.4272-13.9264 5.7344-19.0464 0.6144l-100.864-100.864c-5.12-5.12-4.8128-13.6192 0.6144-19.0464 5.4272-5.4272 14.0288-5.7344 19.0464-0.6144l100.864 100.864C932.864 571.2896 932.5568 579.8912 927.1296 585.3184z" fill="#FF9000" p-id="59868"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
1
projects/app/public/imgs/modal/wholeRecord.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700705708636" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23671" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M179.5 890.1C116.4 890.1 65 838.7 65 775.6V371.4c0-63.1 51.4-114.5 114.5-114.5h561.6c63.1 0 114.5 51.4 114.5 114.5v404.2c0 63.1-51.4 114.5-114.5 114.5H179.5z m0-584.6c-36.4 0-65.9 29.6-65.9 65.9v404.2c0 36.4 29.6 65.9 65.9 65.9h561.6c36.4 0 66-29.6 66-65.9V371.4c0-36.4-29.6-65.9-66-65.9H179.5z" fill="#6B400D" p-id="23672"></path><path d="M521.3 511H195.2c-1.6 0-2.8-1.3-2.8-2.8v-44.1c0-1.6 1.3-2.8 2.8-2.8h326.1c1.6 0 2.8 1.3 2.8 2.8v44.1c0 1.6-1.2 2.8-2.8 2.8zM521.3 685.7H195.2c-1.6 0-2.8-1.3-2.8-2.8v-44.1c0-1.6 1.3-2.8 2.8-2.8h326.1c1.6 0 2.8 1.3 2.8 2.8v44.1c0 1.5-1.2 2.8-2.8 2.8zM625 547.1c-4.9 0-9.4-1.9-12.9-5.4l-48.6-48.8c-7.1-7.1-7.1-18.7 0-25.8 3.4-3.4 8-5.3 12.9-5.3s9.4 1.9 12.9 5.3l35.8 35.9 72.2-72.5c3.4-3.5 8-5.3 12.9-5.3s9.4 1.9 12.9 5.3c7.1 7.1 7.1 18.7 0 25.8L638 541.7c-3.6 3.5-8.2 5.4-13 5.4zM625 721.8c-4.9 0-9.4-1.9-12.9-5.4l-48.6-48.8c-7.1-7.1-7.1-18.7 0-25.8 3.4-3.4 8-5.3 12.9-5.3s9.4 1.9 12.9 5.3l35.8 35.9 72.2-72.5c3.4-3.5 8-5.3 12.9-5.3s9.4 1.9 12.9 5.3c7.1 7.1 7.1 18.7 0 25.8L638 716.4c-3.6 3.5-8.2 5.4-13 5.4z" fill="#6B400D" p-id="23673"></path><path d="M853.5 371.4c0-62-50.4-112.4-112.4-112.4H179.5c-2.7 0-5.4 0.2-8.1 0.4l-1.1 0.1-0.3-1.1v-4.9c0-63.1 51.4-114.5 114.5-114.5h561.6c63.1 0 114.5 51.4 114.5 114.5v404.2c0 59.5-46.5 109.6-105.9 114.1l-1.1 0.1V371.4z" fill="#6B400D" p-id="23674"></path><path d="M846.1 186.5H284.5c-36.9 0-67 30-67 67v4.5H741c62.6 0 113.5 50.9 113.5 113.5v352.3c32.9-4.2 58.5-32.1 58.5-66.1V253.5c0-37-30-67-66.9-67z" fill="#FFD524" p-id="23675"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
BIN
projects/app/public/imgs/module/templates.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
@ -31,9 +31,8 @@
|
|||||||
"Export Config Successful": "The configuration has been copied. Please check for important data",
|
"Export Config Successful": "The configuration has been copied. Please check for important data",
|
||||||
"Export Configs": "Export Configs",
|
"Export Configs": "Export Configs",
|
||||||
"Feedback Count": "User Feedback",
|
"Feedback Count": "User Feedback",
|
||||||
"Import Config": "Import Config",
|
|
||||||
"Import Config Failed": "Failed to import the configuration, please ensure that the configuration is normal!",
|
|
||||||
"Import Configs": "Import Configs",
|
"Import Configs": "Import Configs",
|
||||||
|
"Import Configs Failed": "Failed to import the configuration, please ensure that the configuration is normal!",
|
||||||
"Input Field Settings": "Input Field Settings",
|
"Input Field Settings": "Input Field Settings",
|
||||||
"Logs Empty": "Logs is empty",
|
"Logs Empty": "Logs is empty",
|
||||||
"Logs Message Total": "Message Count",
|
"Logs Message Total": "Message Count",
|
||||||
@ -54,15 +53,7 @@
|
|||||||
"My Modules": "My Custom Modules",
|
"My Modules": "My Custom Modules",
|
||||||
"No Modules": "No module",
|
"No Modules": "No module",
|
||||||
"System Module": "System Module",
|
"System Module": "System Module",
|
||||||
"type": "{{type}}\n{{example}}",
|
"type": "{{type}}\n{{example}}"
|
||||||
"valueType": {
|
|
||||||
"any": "any",
|
|
||||||
"boolean": "boolean",
|
|
||||||
"chatHistory": "Chat History",
|
|
||||||
"datasetQuote": "Dataset Quote",
|
|
||||||
"number": "number",
|
|
||||||
"string": "string"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
"Title is required": "Title is required"
|
"Title is required": "Title is required"
|
||||||
@ -115,9 +106,11 @@
|
|||||||
"module model": "Model",
|
"module model": "Model",
|
||||||
"module name": "Name",
|
"module name": "Name",
|
||||||
"module price": "Price",
|
"module price": "Price",
|
||||||
|
"module query": "Question/Query",
|
||||||
"module question": "Question",
|
"module question": "Question",
|
||||||
"module quoteList": "Quotes",
|
"module quoteList": "Quotes",
|
||||||
"module runningTime": "Time",
|
"module runningTime": "Time",
|
||||||
|
"module search query": "Query",
|
||||||
"module search response": "Search Result",
|
"module search response": "Search Result",
|
||||||
"module similarity": "Similarity",
|
"module similarity": "Similarity",
|
||||||
"module temperature": "Temperature",
|
"module temperature": "Temperature",
|
||||||
@ -129,12 +122,14 @@
|
|||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"Add": "Add",
|
"Add": "Add",
|
||||||
|
"Add New": "Add",
|
||||||
"Back": "Back",
|
"Back": "Back",
|
||||||
"Beta": "Beta",
|
"Beta": "Beta",
|
||||||
"Business edition features": "This is the commercial version function ~",
|
"Business edition features": "This is the commercial version function ~",
|
||||||
"Choose": "Choose",
|
"Choose": "Choose",
|
||||||
"Close": "Close",
|
"Close": "Close",
|
||||||
"Collect": "Collect",
|
"Collect": "Collect",
|
||||||
|
"Confirm": "Confirm",
|
||||||
"Confirm Create": "Create",
|
"Confirm Create": "Create",
|
||||||
"Confirm Move": "Move here",
|
"Confirm Move": "Move here",
|
||||||
"Confirm Update": "Update",
|
"Confirm Update": "Update",
|
||||||
@ -174,6 +169,7 @@
|
|||||||
"Rename Failed": "Rename Failed",
|
"Rename Failed": "Rename Failed",
|
||||||
"Rename Success": "Rename Success",
|
"Rename Success": "Rename Success",
|
||||||
"Request Error": "Request Error",
|
"Request Error": "Request Error",
|
||||||
|
"Require Input": "Required",
|
||||||
"Save Failed": "Save Failed",
|
"Save Failed": "Save Failed",
|
||||||
"Save Success": "Save Success",
|
"Save Success": "Save Success",
|
||||||
"Search": "Search",
|
"Search": "Search",
|
||||||
@ -222,6 +218,11 @@
|
|||||||
"Select TTS": "Select TTS",
|
"Select TTS": "Select TTS",
|
||||||
"TTS": "Audio Speech",
|
"TTS": "Audio Speech",
|
||||||
"TTS Tip": "After this function is enabled, the voice playback function can be used after each conversation. Use of this feature may incur additional charges.",
|
"TTS Tip": "After this function is enabled, the voice playback function can be used after each conversation. Use of this feature may incur additional charges.",
|
||||||
|
"create app": "Create App",
|
||||||
|
"setting": "App Setting",
|
||||||
|
"simple": {
|
||||||
|
"mode template select": "Template"
|
||||||
|
},
|
||||||
"tts": {
|
"tts": {
|
||||||
"Close": "NoUse",
|
"Close": "NoUse",
|
||||||
"Model alloy": "Female - Alloy",
|
"Model alloy": "Female - Alloy",
|
||||||
@ -249,6 +250,7 @@
|
|||||||
},
|
},
|
||||||
"dataset": {
|
"dataset": {
|
||||||
"Choose Dataset": "Choose Dataset",
|
"Choose Dataset": "Choose Dataset",
|
||||||
|
"Create dataset": "Create Dataset",
|
||||||
"Dataset": "Dataset",
|
"Dataset": "Dataset",
|
||||||
"Go Dataset": "To Dataset",
|
"Go Dataset": "To Dataset",
|
||||||
"Quote Length": "Quote Length",
|
"Quote Length": "Quote Length",
|
||||||
@ -260,6 +262,65 @@
|
|||||||
"Edit": "Edit Data",
|
"Edit": "Edit Data",
|
||||||
"id": "Data ID"
|
"id": "Data ID"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"module": {
|
||||||
|
"Data Type": "Data Type",
|
||||||
|
"Field Description": "Description",
|
||||||
|
"Field Name": "Name",
|
||||||
|
"Field Type": "Type",
|
||||||
|
"Field key": "Key",
|
||||||
|
"Input Type": "Input Type",
|
||||||
|
"Plugin output must connect": "Custom outputs must all be connected",
|
||||||
|
"Variable": "Variable",
|
||||||
|
"Variable Setting": "Variable Setting",
|
||||||
|
"input": {
|
||||||
|
"label": {
|
||||||
|
"chat history": "",
|
||||||
|
"switch": "",
|
||||||
|
"user question": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inputType": {
|
||||||
|
"input": "Input",
|
||||||
|
"selectApp": "App Selector",
|
||||||
|
"selectChatModel": "Select Chat Model",
|
||||||
|
"selectDataset": "Dataset Selector",
|
||||||
|
"switch": "Switch",
|
||||||
|
"target": "Target Data",
|
||||||
|
"textarea": "Textarea"
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"description": {
|
||||||
|
"running done": "running done"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"running done": "running done"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"valueType": {
|
||||||
|
"any": "Any",
|
||||||
|
"boolean": "Boolean",
|
||||||
|
"chatHistory": "History",
|
||||||
|
"datasetQuote": "Dataset Quote",
|
||||||
|
"number": "Number",
|
||||||
|
"selectApp": "Select App",
|
||||||
|
"selectDataset": "Select Dataset",
|
||||||
|
"string": "String"
|
||||||
|
},
|
||||||
|
"variable": {
|
||||||
|
"add option": "Add Option",
|
||||||
|
"key": "Key",
|
||||||
|
"key is required": "variable key is required",
|
||||||
|
"select type": "Select",
|
||||||
|
"text max length": "Max Length",
|
||||||
|
"text type": "Text",
|
||||||
|
"variable key is required": "",
|
||||||
|
"variable name": "Name",
|
||||||
|
"variable name is required": "variable name is required",
|
||||||
|
"variable option is required": "Variable option is required",
|
||||||
|
"variable option is value is required": "Variable option is value is required",
|
||||||
|
"variable options": "Options"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dataset": {
|
"dataset": {
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
"app": {
|
"app": {
|
||||||
"AI Advanced Settings": "AI 高级配置",
|
"AI Advanced Settings": "AI 高级配置",
|
||||||
"AI Settings": "AI 配置",
|
"AI Settings": "AI 配置",
|
||||||
"Advance App TestTip": "当前应用为高级编排模式\n如需切换为【简易模式】请点击左侧保存按键",
|
"Advance App TestTip": "当前应用可能为高级编排模式\n如需切换为【简易模式】请点击左侧保存按键",
|
||||||
"App Detail": "应用详情",
|
"App Detail": "应用详情",
|
||||||
"Basic Settings": "基本信息",
|
"Basic Settings": "基本信息",
|
||||||
"Chat Debug": "调试预览",
|
"Chat Debug": "调试预览",
|
||||||
@ -31,9 +31,8 @@
|
|||||||
"Export Config Successful": "已复制配置,请注意检查是否有重要数据",
|
"Export Config Successful": "已复制配置,请注意检查是否有重要数据",
|
||||||
"Export Configs": "导出配置",
|
"Export Configs": "导出配置",
|
||||||
"Feedback Count": "用户反馈",
|
"Feedback Count": "用户反馈",
|
||||||
"Import Config": "导入配置",
|
|
||||||
"Import Config Failed": "导入配置失败,请确保配置正常!",
|
|
||||||
"Import Configs": "导入配置",
|
"Import Configs": "导入配置",
|
||||||
|
"Import Configs Failed": "导入配置失败,请确保配置正常!",
|
||||||
"Input Field Settings": "输入字段编辑",
|
"Input Field Settings": "输入字段编辑",
|
||||||
"Logs Empty": "还没有日志噢~",
|
"Logs Empty": "还没有日志噢~",
|
||||||
"Logs Message Total": "消息总数",
|
"Logs Message Total": "消息总数",
|
||||||
@ -54,15 +53,7 @@
|
|||||||
"My Modules": "",
|
"My Modules": "",
|
||||||
"No Modules": "还没有模块~",
|
"No Modules": "还没有模块~",
|
||||||
"System Module": "系统模块",
|
"System Module": "系统模块",
|
||||||
"type": "\"{{type}}\"类型\n{{example}}",
|
"type": "\"{{type}}\"类型\n{{example}}"
|
||||||
"valueType": {
|
|
||||||
"any": "任意",
|
|
||||||
"boolean": "布尔",
|
|
||||||
"chatHistory": "聊天记录",
|
|
||||||
"datasetQuote": "引用内容",
|
|
||||||
"number": "数字",
|
|
||||||
"string": "字符串"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
"Title is required": "模块名不能为空"
|
"Title is required": "模块名不能为空"
|
||||||
@ -115,9 +106,11 @@
|
|||||||
"module model": "模型",
|
"module model": "模型",
|
||||||
"module name": "模型名",
|
"module name": "模型名",
|
||||||
"module price": "计费",
|
"module price": "计费",
|
||||||
|
"module query": "问题/检索词",
|
||||||
"module question": "问题",
|
"module question": "问题",
|
||||||
"module quoteList": "引用内容",
|
"module quoteList": "引用内容",
|
||||||
"module runningTime": "运行时长",
|
"module runningTime": "运行时长",
|
||||||
|
"module search query": "检索词",
|
||||||
"module search response": "搜索结果",
|
"module search response": "搜索结果",
|
||||||
"module similarity": "相似度",
|
"module similarity": "相似度",
|
||||||
"module temperature": "温度",
|
"module temperature": "温度",
|
||||||
@ -129,12 +122,14 @@
|
|||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"Add": "添加",
|
"Add": "添加",
|
||||||
|
"Add New": "新增",
|
||||||
"Back": "返回",
|
"Back": "返回",
|
||||||
"Beta": "实验版",
|
"Beta": "实验版",
|
||||||
"Business edition features": "这是商业版功能~",
|
"Business edition features": "这是商业版功能~",
|
||||||
"Choose": "选择",
|
"Choose": "选择",
|
||||||
"Close": "关闭",
|
"Close": "关闭",
|
||||||
"Collect": "收藏",
|
"Collect": "收藏",
|
||||||
|
"Confirm": "确认",
|
||||||
"Confirm Create": "确认创建",
|
"Confirm Create": "确认创建",
|
||||||
"Confirm Move": "移动到这",
|
"Confirm Move": "移动到这",
|
||||||
"Confirm Update": "确认更新",
|
"Confirm Update": "确认更新",
|
||||||
@ -174,6 +169,7 @@
|
|||||||
"Rename Failed": "重命名失败",
|
"Rename Failed": "重命名失败",
|
||||||
"Rename Success": "重命名成功",
|
"Rename Success": "重命名成功",
|
||||||
"Request Error": "请求异常",
|
"Request Error": "请求异常",
|
||||||
|
"Require Input": "必填",
|
||||||
"Save Failed": "保存失败",
|
"Save Failed": "保存失败",
|
||||||
"Save Success": "保存成功",
|
"Save Success": "保存成功",
|
||||||
"Search": "搜索",
|
"Search": "搜索",
|
||||||
@ -222,6 +218,11 @@
|
|||||||
"Select TTS": "选择语音播放模式",
|
"Select TTS": "选择语音播放模式",
|
||||||
"TTS": "语音播报",
|
"TTS": "语音播报",
|
||||||
"TTS Tip": "开启后,每次对话后可使用语音播放功能。使用该功能可能产生额外费用。",
|
"TTS Tip": "开启后,每次对话后可使用语音播放功能。使用该功能可能产生额外费用。",
|
||||||
|
"create app": "创建属于你的 AI 应用",
|
||||||
|
"setting": "应用信息设置",
|
||||||
|
"simple": {
|
||||||
|
"mode template select": "简易模板"
|
||||||
|
},
|
||||||
"tts": {
|
"tts": {
|
||||||
"Close": "不使用",
|
"Close": "不使用",
|
||||||
"Model alloy": "女声 - Alloy",
|
"Model alloy": "女声 - Alloy",
|
||||||
@ -249,6 +250,7 @@
|
|||||||
},
|
},
|
||||||
"dataset": {
|
"dataset": {
|
||||||
"Choose Dataset": "关联知识库",
|
"Choose Dataset": "关联知识库",
|
||||||
|
"Create dataset": "创建一个知识库",
|
||||||
"Dataset": "知识库",
|
"Dataset": "知识库",
|
||||||
"Go Dataset": "前往知识库",
|
"Go Dataset": "前往知识库",
|
||||||
"Quote Length": "引用内容长度",
|
"Quote Length": "引用内容长度",
|
||||||
@ -260,6 +262,65 @@
|
|||||||
"Edit": "编辑数据",
|
"Edit": "编辑数据",
|
||||||
"id": "数据ID"
|
"id": "数据ID"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"module": {
|
||||||
|
"Data Type": "数据类型",
|
||||||
|
"Field Description": "字段描述",
|
||||||
|
"Field Name": "字段名",
|
||||||
|
"Field Type": "字段类型",
|
||||||
|
"Field key": "字段 Key",
|
||||||
|
"Input Type": "输入类型",
|
||||||
|
"Plugin output must connect": "自定义输出必须全部连接",
|
||||||
|
"Variable": "参数变量",
|
||||||
|
"Variable Setting": "变量设置",
|
||||||
|
"input": {
|
||||||
|
"label": {
|
||||||
|
"chat history": "聊天记录",
|
||||||
|
"switch": "触发器",
|
||||||
|
"user question": "用户问题"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inputType": {
|
||||||
|
"input": "输入框",
|
||||||
|
"selectApp": "应用选择",
|
||||||
|
"selectChatModel": "对话模型选择",
|
||||||
|
"selectDataset": "知识库选择",
|
||||||
|
"switch": "开关",
|
||||||
|
"target": "外部数据",
|
||||||
|
"textarea": "段落输入"
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"description": {
|
||||||
|
"running done": "模块调用结束时触发"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"running done": "模块调用结束"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"valueType": {
|
||||||
|
"any": "任意",
|
||||||
|
"boolean": "布尔",
|
||||||
|
"chatHistory": "聊天记录",
|
||||||
|
"datasetQuote": "引用内容",
|
||||||
|
"number": "数字",
|
||||||
|
"selectApp": "应用选择",
|
||||||
|
"selectDataset": "知识库选择",
|
||||||
|
"string": "字符串"
|
||||||
|
},
|
||||||
|
"variable": {
|
||||||
|
"add option": "添加选项",
|
||||||
|
"key": "变量 key",
|
||||||
|
"key is required": "",
|
||||||
|
"select type": "下拉单选",
|
||||||
|
"text max length": "最大长度",
|
||||||
|
"text type": "文本",
|
||||||
|
"variable key is required": "变量 key 不能为空",
|
||||||
|
"variable name": "变量名",
|
||||||
|
"variable name is required": "变量名不能为空",
|
||||||
|
"variable option is required": "选项不能全空",
|
||||||
|
"variable option is value is required": "选项内容不能为空",
|
||||||
|
"variable options": "选项"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dataset": {
|
"dataset": {
|
||||||
|
|||||||
27
projects/app/public/simpleTemplates/fastgpt-simple.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "极简模板",
|
||||||
|
"desc": "极简模板\n已内置参数细节",
|
||||||
|
"systemForm": {
|
||||||
|
"aiSettings": {
|
||||||
|
"model": true,
|
||||||
|
"systemPrompt": true,
|
||||||
|
"temperature": false,
|
||||||
|
"maxToken": false,
|
||||||
|
"quoteTemplate": false,
|
||||||
|
"quotePrompt": false
|
||||||
|
},
|
||||||
|
"dataset": {
|
||||||
|
"datasets": true,
|
||||||
|
"similarity": false,
|
||||||
|
"limit": false,
|
||||||
|
"rerank": false,
|
||||||
|
"searchEmptyText": false
|
||||||
|
},
|
||||||
|
"userGuide": {
|
||||||
|
"welcomeText": true,
|
||||||
|
"variables": false,
|
||||||
|
"questionGuide": false,
|
||||||
|
"tts": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,7 +3,7 @@ import { Image } from '@chakra-ui/react';
|
|||||||
import type { ImageProps } from '@chakra-ui/react';
|
import type { ImageProps } from '@chakra-ui/react';
|
||||||
import { LOGO_ICON } from '@fastgpt/global/core/chat/constants';
|
import { LOGO_ICON } from '@fastgpt/global/core/chat/constants';
|
||||||
|
|
||||||
const Avatar = ({ w = '30px', ...props }: ImageProps) => {
|
const Avatar = ({ w = '30px', src, ...props }: ImageProps) => {
|
||||||
return (
|
return (
|
||||||
<Image
|
<Image
|
||||||
fallbackSrc={LOGO_ICON}
|
fallbackSrc={LOGO_ICON}
|
||||||
@ -14,6 +14,7 @@ const Avatar = ({ w = '30px', ...props }: ImageProps) => {
|
|||||||
w={w}
|
w={w}
|
||||||
h={w}
|
h={w}
|
||||||
p={'1px'}
|
p={'1px'}
|
||||||
|
src={src || LOGO_ICON}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ModalBody, Box, useTheme } from '@chakra-ui/react';
|
import { ModalBody, Box, useTheme, Flex, Image } from '@chakra-ui/react';
|
||||||
import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
||||||
import MyModal from '../MyModal';
|
import MyModal from '../MyModal';
|
||||||
|
|
||||||
@ -16,13 +16,13 @@ const ContextModal = ({
|
|||||||
<MyModal
|
<MyModal
|
||||||
isOpen={true}
|
isOpen={true}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
|
iconSrc="/imgs/modal/chatHistory.svg"
|
||||||
title={`完整对话记录(${context.length}条)`}
|
title={`完整对话记录(${context.length}条)`}
|
||||||
h={['90vh', '80vh']}
|
h={['90vh', '80vh']}
|
||||||
minW={['90vw', '600px']}
|
minW={['90vw', '600px']}
|
||||||
isCentered
|
isCentered
|
||||||
>
|
>
|
||||||
<ModalBody
|
<ModalBody
|
||||||
pt={0}
|
|
||||||
whiteSpace={'pre-wrap'}
|
whiteSpace={'pre-wrap'}
|
||||||
textAlign={'justify'}
|
textAlign={'justify'}
|
||||||
wordBreak={'break-all'}
|
wordBreak={'break-all'}
|
||||||
|
|||||||
@ -33,7 +33,12 @@ const FeedbackModal = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen={true} onClose={onClose} title={t('chat.Feedback Modal')}>
|
<MyModal
|
||||||
|
isOpen={true}
|
||||||
|
onClose={onClose}
|
||||||
|
iconSrc="/imgs/modal/badAnswer.svg"
|
||||||
|
title={t('chat.Feedback Modal')}
|
||||||
|
>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Textarea
|
<Textarea
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import { ModalBody, Box, useTheme, Flex, Progress, Link } from '@chakra-ui/react';
|
import { ModalBody, Box, useTheme, Flex, Progress, Link, Image } from '@chakra-ui/react';
|
||||||
import { getDatasetDataItemById } from '@/web/core/dataset/api';
|
import { getDatasetDataItemById } from '@/web/core/dataset/api';
|
||||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||||
import { useToast } from '@/web/common/hooks/useToast';
|
import { useToast } from '@/web/common/hooks/useToast';
|
||||||
@ -68,6 +68,7 @@ const QuoteModal = ({
|
|||||||
h={['90vh', '80vh']}
|
h={['90vh', '80vh']}
|
||||||
isCentered
|
isCentered
|
||||||
minW={['90vw', '600px']}
|
minW={['90vw', '600px']}
|
||||||
|
iconSrc="/imgs/modal/quote.svg"
|
||||||
title={
|
title={
|
||||||
<Box>
|
<Box>
|
||||||
知识库引用({rawSearch.length}条)
|
知识库引用({rawSearch.length}条)
|
||||||
@ -77,7 +78,7 @@ const QuoteModal = ({
|
|||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ModalBody pt={0} whiteSpace={'pre-wrap'} textAlign={'justify'} wordBreak={'break-all'}>
|
<ModalBody whiteSpace={'pre-wrap'} textAlign={'justify'} wordBreak={'break-all'}>
|
||||||
{rawSearch.map((item, i) => (
|
{rawSearch.map((item, i) => (
|
||||||
<Box
|
<Box
|
||||||
key={i}
|
key={i}
|
||||||
|
|||||||
@ -36,7 +36,12 @@ const ReadFeedbackModal = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen={true} onClose={onClose} title={t('chat.Feedback Modal')}>
|
<MyModal
|
||||||
|
isOpen={true}
|
||||||
|
onClose={onClose}
|
||||||
|
iconSrc="/imgs/modal/readFeedback.svg"
|
||||||
|
title={t('chat.Feedback Modal')}
|
||||||
|
>
|
||||||
<ModalBody>{content}</ModalBody>
|
<ModalBody>{content}</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button mr={2} isLoading={isLoading} variant={'base'} onClick={mutate}>
|
<Button mr={2} isLoading={isLoading} variant={'base'} onClick={mutate}>
|
||||||
|
|||||||
@ -35,7 +35,7 @@ const SelectMarkCollection = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const [selectedDatasetId, setSelectedDatasetId] = useState<string>();
|
const [selectedDatasetId, setSelectedDatasetId] = useState<string>();
|
||||||
const [selectedDatasetCollectionIds, setSelectedDatasetCollectionIds] = useState<string[]>([]);
|
const [selectedDatasetCollectionIds, setSelectedDatasetCollectionIds] = useState<string[]>([]);
|
||||||
const { paths, parentId, setParentId, datasets, isLoading } = useDatasetSelect();
|
const { paths, parentId, setParentId, datasets, isFetching } = useDatasetSelect();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -107,7 +107,7 @@ const SelectMarkCollection = ({
|
|||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button
|
<Button
|
||||||
isLoading={isLoading}
|
isLoading={isFetching}
|
||||||
isDisabled={!selectedDatasetId}
|
isDisabled={!selectedDatasetId}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setAdminMarkData({ ...adminMarkData, datasetId: selectedDatasetId });
|
setAdminMarkData({ ...adminMarkData, datasetId: selectedDatasetId });
|
||||||
|
|||||||
@ -2,31 +2,33 @@ import React, { useMemo, useState } from 'react';
|
|||||||
import { Box, useTheme, Flex, Image } from '@chakra-ui/react';
|
import { Box, useTheme, Flex, Image } from '@chakra-ui/react';
|
||||||
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/api.d';
|
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/api.d';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { ModuleTemplatesFlat } from '@/constants/flow/ModuleTemplate';
|
import { moduleTemplatesFlat } from '@/web/core/modules/template/system';
|
||||||
import Tabs from '../Tabs';
|
import Tabs from '../Tabs';
|
||||||
|
|
||||||
import MyModal from '../MyModal';
|
import MyModal from '../MyModal';
|
||||||
import MyTooltip from '../MyTooltip';
|
import MyTooltip from '../MyTooltip';
|
||||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||||
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
|
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
|
||||||
|
import Markdown from '../Markdown';
|
||||||
|
|
||||||
function Row({ label, value }: { label: string; value?: string | number | React.ReactNode }) {
|
function Row({ label, value }: { label: string; value?: string | number }) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
const strValue = `${value}`;
|
||||||
|
const isCodeBlock = strValue.startsWith('~~~json');
|
||||||
|
|
||||||
return value !== undefined && value !== '' && value !== 'undefined' ? (
|
return value !== undefined && value !== '' && value !== 'undefined' ? (
|
||||||
<Box mb={2}>
|
<Box mb={3}>
|
||||||
<Box fontSize={['sm', 'md']} mb={1} flex={'0 0 90px'}>
|
<Box fontSize={['sm', 'md']} mb={isCodeBlock ? 0 : 1} flex={'0 0 90px'}>
|
||||||
{label}:
|
{label}:
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
borderRadius={'lg'}
|
borderRadius={'md'}
|
||||||
border={theme.borders.base}
|
|
||||||
px={3}
|
|
||||||
py={1}
|
|
||||||
position={'relative'}
|
|
||||||
whiteSpace={'pre-wrap'}
|
|
||||||
fontSize={'sm'}
|
fontSize={'sm'}
|
||||||
|
{...(isCodeBlock
|
||||||
|
? { transform: 'translateY(-3px)' }
|
||||||
|
: { px: 3, py: 1, border: theme.borders.base })}
|
||||||
>
|
>
|
||||||
{value}
|
<Markdown source={strValue} />
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
) : null;
|
) : null;
|
||||||
@ -39,7 +41,6 @@ const WholeResponseModal = ({
|
|||||||
response: ChatHistoryItemResType[];
|
response: ChatHistoryItemResType[];
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme();
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const list = useMemo(
|
const list = useMemo(
|
||||||
@ -51,7 +52,8 @@ const WholeResponseModal = ({
|
|||||||
mr={2}
|
mr={2}
|
||||||
src={
|
src={
|
||||||
item.moduleLogo ||
|
item.moduleLogo ||
|
||||||
ModuleTemplatesFlat.find((template) => item.moduleType === template.flowType)?.logo
|
moduleTemplatesFlat.find((template) => item.moduleType === template.flowType)
|
||||||
|
?.avatar
|
||||||
}
|
}
|
||||||
alt={''}
|
alt={''}
|
||||||
w={['14px', '16px']}
|
w={['14px', '16px']}
|
||||||
@ -75,6 +77,7 @@ const WholeResponseModal = ({
|
|||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
h={['90vh', '80vh']}
|
h={['90vh', '80vh']}
|
||||||
w={['90vw', '500px']}
|
w={['90vw', '500px']}
|
||||||
|
iconSrc="/imgs/modal/wholeRecord.svg"
|
||||||
title={
|
title={
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
{t('chat.Complete Response')}
|
{t('chat.Complete Response')}
|
||||||
@ -102,37 +105,26 @@ const WholeResponseModal = ({
|
|||||||
/>
|
/>
|
||||||
<Row label={t('chat.response.module tokens')} value={`${activeModule?.tokens}`} />
|
<Row label={t('chat.response.module tokens')} value={`${activeModule?.tokens}`} />
|
||||||
<Row label={t('chat.response.module model')} value={activeModule?.model} />
|
<Row label={t('chat.response.module model')} value={activeModule?.model} />
|
||||||
|
<Row label={t('chat.response.module query')} value={activeModule?.query} />
|
||||||
|
|
||||||
{/* ai chat */}
|
{/* ai chat */}
|
||||||
<Row label={t('chat.response.module question')} value={activeModule?.question} />
|
|
||||||
<Row label={t('chat.response.module temperature')} value={activeModule?.temperature} />
|
<Row label={t('chat.response.module temperature')} value={activeModule?.temperature} />
|
||||||
<Row label={t('chat.response.module maxToken')} value={activeModule?.maxToken} />
|
<Row label={t('chat.response.module maxToken')} value={activeModule?.maxToken} />
|
||||||
<Row
|
|
||||||
label={t('chat.response.module quoteList')}
|
|
||||||
value={(() => {
|
|
||||||
try {
|
|
||||||
JSON.stringify(activeModule.quoteList, null, 2);
|
|
||||||
} catch (error) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
})()}
|
|
||||||
/>
|
|
||||||
<Row
|
<Row
|
||||||
label={t('chat.response.module historyPreview')}
|
label={t('chat.response.module historyPreview')}
|
||||||
value={(() => {
|
value={(() => {
|
||||||
if (!activeModule?.historyPreview) return '';
|
if (!activeModule?.historyPreview) return '';
|
||||||
return (
|
return activeModule.historyPreview
|
||||||
<>
|
.map((item, i) => `**${item.obj}**\n${item.value}`)
|
||||||
{activeModule.historyPreview.map((item, i) => (
|
.join('\n---\n');
|
||||||
<Box key={i} _notLast={{ mb: 3, borderBottom: theme.borders.base }} pb={3}>
|
|
||||||
<Box fontWeight={'bold'}>{item.obj}</Box>
|
|
||||||
<Box>{item.value}</Box>
|
|
||||||
</Box>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
})()}
|
})()}
|
||||||
/>
|
/>
|
||||||
|
{activeModule.quoteList && activeModule.quoteList.length > 0 && (
|
||||||
|
<Row
|
||||||
|
label={t('chat.response.module quoteList')}
|
||||||
|
value={`~~~json\n${JSON.stringify(activeModule.quoteList, null, 2)}`}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* dataset search */}
|
{/* dataset search */}
|
||||||
<Row label={t('chat.response.module similarity')} value={activeModule?.similarity} />
|
<Row label={t('chat.response.module similarity')} value={activeModule?.similarity} />
|
||||||
@ -143,15 +135,7 @@ const WholeResponseModal = ({
|
|||||||
label={t('chat.response.module cq')}
|
label={t('chat.response.module cq')}
|
||||||
value={(() => {
|
value={(() => {
|
||||||
if (!activeModule?.cqList) return '';
|
if (!activeModule?.cqList) return '';
|
||||||
return (
|
return activeModule.cqList.map((item) => `* ${item.value}`).join('\n');
|
||||||
<Box as={'ol'} px={3}>
|
|
||||||
{activeModule.cqList.map((item) => (
|
|
||||||
<Box key={item.key} as={'li'}>
|
|
||||||
{item.value}
|
|
||||||
</Box>
|
|
||||||
))}
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
})()}
|
})()}
|
||||||
/>
|
/>
|
||||||
<Row label={t('chat.response.module cq result')} value={activeModule?.cqResult} />
|
<Row label={t('chat.response.module cq result')} value={activeModule?.cqResult} />
|
||||||
@ -161,50 +145,34 @@ const WholeResponseModal = ({
|
|||||||
label={t('chat.response.module extract description')}
|
label={t('chat.response.module extract description')}
|
||||||
value={activeModule?.extractDescription}
|
value={activeModule?.extractDescription}
|
||||||
/>
|
/>
|
||||||
|
{activeModule?.extractResult && (
|
||||||
<Row
|
<Row
|
||||||
label={t('chat.response.module extract result')}
|
label={t('chat.response.module extract result')}
|
||||||
value={(() => {
|
value={`~~~json\n${JSON.stringify(activeModule?.extractResult, null, 2)}`}
|
||||||
try {
|
|
||||||
return JSON.stringify(activeModule?.extractResult, null, 2);
|
|
||||||
} catch (error) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
})()}
|
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* http */}
|
{/* http */}
|
||||||
|
{activeModule?.body && (
|
||||||
<Row
|
<Row
|
||||||
label={t('chat.response.module http body')}
|
label={t('chat.response.module http body')}
|
||||||
value={(() => {
|
value={`~~~json\n${JSON.stringify(activeModule?.body, null, 2)}`}
|
||||||
try {
|
|
||||||
return JSON.stringify(activeModule?.body, null, 2);
|
|
||||||
} catch (error) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
})()}
|
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{activeModule?.httpResult && (
|
||||||
<Row
|
<Row
|
||||||
label={t('chat.response.module http result')}
|
label={t('chat.response.module http result')}
|
||||||
value={(() => {
|
value={`~~~json\n${JSON.stringify(activeModule?.httpResult, null, 2)}`}
|
||||||
try {
|
|
||||||
return JSON.stringify(activeModule?.httpResult, null, 2);
|
|
||||||
} catch (error) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
})()}
|
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* plugin */}
|
{/* plugin */}
|
||||||
|
{activeModule?.pluginOutput && (
|
||||||
<Row
|
<Row
|
||||||
label={t('chat.response.plugin output')}
|
label={t('chat.response.plugin output')}
|
||||||
value={(() => {
|
value={`~~~json\n${JSON.stringify(activeModule?.pluginOutput, null, 2)}`}
|
||||||
try {
|
|
||||||
return JSON.stringify(activeModule?.pluginOutput, null, 2);
|
|
||||||
} catch (error) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
})()}
|
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</MyModal>
|
</MyModal>
|
||||||
|
|||||||
@ -33,14 +33,13 @@ import { eventBus } from '@/web/common/utils/eventbus';
|
|||||||
import { adaptChat2GptMessages } from '@fastgpt/global/core/chat/adapt';
|
import { adaptChat2GptMessages } from '@fastgpt/global/core/chat/adapt';
|
||||||
import { useMarkdown } from '@/web/common/hooks/useMarkdown';
|
import { useMarkdown } from '@/web/common/hooks/useMarkdown';
|
||||||
import { ModuleItemType } from '@fastgpt/global/core/module/type.d';
|
import { ModuleItemType } from '@fastgpt/global/core/module/type.d';
|
||||||
import { VariableInputEnum } from '@/constants/app';
|
import { VariableInputEnum } from '@fastgpt/global/core/module/constants';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import type { ChatMessageItemType } from '@fastgpt/global/core/ai/type.d';
|
import type { ChatMessageItemType } from '@fastgpt/global/core/ai/type.d';
|
||||||
import { fileDownload } from '@/web/common/file/utils';
|
import { fileDownload } from '@/web/common/file/utils';
|
||||||
import { htmlTemplate } from '@/constants/common';
|
import { htmlTemplate } from '@/constants/common';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
import { TaskResponseKeyEnum } from '@fastgpt/global/core/chat/constants';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
import { adminUpdateChatFeedback, userUpdateChatFeedback } from '@/web/core/chat/api';
|
import { adminUpdateChatFeedback, userUpdateChatFeedback } from '@/web/core/chat/api';
|
||||||
@ -60,9 +59,10 @@ const SelectMarkCollection = dynamic(() => import('./SelectMarkCollection'));
|
|||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
import { postQuestionGuide } from '@/web/core/ai/api';
|
import { postQuestionGuide } from '@/web/core/ai/api';
|
||||||
import { splitGuideModule } from '@/global/core/app/modules/utils';
|
import { splitGuideModule } from '@fastgpt/global/core/module/utils';
|
||||||
import { AppTTSConfigType } from '@/types/app';
|
import type { AppTTSConfigType } from '@fastgpt/global/core/module/type.d';
|
||||||
import MessageInput from './MessageInput';
|
import MessageInput from './MessageInput';
|
||||||
|
import { ModuleOutputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||||
|
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24);
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ type Props = {
|
|||||||
onUpdateVariable?: (e: Record<string, any>) => void;
|
onUpdateVariable?: (e: Record<string, any>) => void;
|
||||||
onStartChat?: (e: StartChatFnProps) => Promise<{
|
onStartChat?: (e: StartChatFnProps) => Promise<{
|
||||||
responseText: string;
|
responseText: string;
|
||||||
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType[];
|
[ModuleOutputKeyEnum.responseData]: ChatHistoryItemResType[];
|
||||||
isNewChat?: boolean;
|
isNewChat?: boolean;
|
||||||
}>;
|
}>;
|
||||||
onDelMessage?: (e: { contentId?: string; index: number }) => void;
|
onDelMessage?: (e: { contentId?: string; index: number }) => void;
|
||||||
@ -760,6 +760,9 @@ const ChatBox = (
|
|||||||
variant={'outline'}
|
variant={'outline'}
|
||||||
colorScheme={'gray'}
|
colorScheme={'gray'}
|
||||||
size={'xs'}
|
size={'xs'}
|
||||||
|
whiteSpace={'pre-wrap'}
|
||||||
|
h={'auto'}
|
||||||
|
py={1}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
resetInputVal(item);
|
resetInputVal(item);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -13,7 +13,12 @@ const md = `
|
|||||||
const CommunityModal = ({ onClose }: { onClose: () => void }) => {
|
const CommunityModal = ({ onClose }: { onClose: () => void }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen={true} onClose={onClose} title={t('home.Community')}>
|
<MyModal
|
||||||
|
isOpen={true}
|
||||||
|
onClose={onClose}
|
||||||
|
iconSrc="/imgs/modal/concat.svg"
|
||||||
|
title={t('home.Community')}
|
||||||
|
>
|
||||||
<ModalBody textAlign={'center'}>
|
<ModalBody textAlign={'center'}>
|
||||||
<Markdown source={md} />
|
<Markdown source={md} />
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|||||||
@ -8,6 +8,7 @@ const unAuthPage: { [key: string]: boolean } = {
|
|||||||
'/': true,
|
'/': true,
|
||||||
'/login': true,
|
'/login': true,
|
||||||
'/login/provider': true,
|
'/login/provider': true,
|
||||||
|
'/login/fastlogin': true,
|
||||||
'/appStore': true,
|
'/appStore': true,
|
||||||
'/chat/share': true
|
'/chat/share': true
|
||||||
};
|
};
|
||||||
|
|||||||
@ -22,6 +22,7 @@ const pcUnShowLayoutRoute: Record<string, boolean> = {
|
|||||||
'/': true,
|
'/': true,
|
||||||
'/login': true,
|
'/login': true,
|
||||||
'/login/provider': true,
|
'/login/provider': true,
|
||||||
|
'/login/fastlogin': true,
|
||||||
'/chat/share': true,
|
'/chat/share': true,
|
||||||
'/app/edit': true,
|
'/app/edit': true,
|
||||||
'/chat': true
|
'/chat': true
|
||||||
@ -30,6 +31,7 @@ const phoneUnShowLayoutRoute: Record<string, boolean> = {
|
|||||||
'/': true,
|
'/': true,
|
||||||
'/login': true,
|
'/login': true,
|
||||||
'/login/provider': true,
|
'/login/provider': true,
|
||||||
|
'/login/fastlogin': true,
|
||||||
'/chat/share': true
|
'/chat/share': true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -6,10 +6,12 @@ import {
|
|||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalCloseButton,
|
ModalCloseButton,
|
||||||
ModalContentProps,
|
ModalContentProps,
|
||||||
Box
|
Box,
|
||||||
|
Image
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
interface Props extends ModalContentProps {
|
interface Props extends ModalContentProps {
|
||||||
|
iconSrc?: string;
|
||||||
title?: any;
|
title?: any;
|
||||||
isCentered?: boolean;
|
isCentered?: boolean;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -19,6 +21,7 @@ interface Props extends ModalContentProps {
|
|||||||
const MyModal = ({
|
const MyModal = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
onClose,
|
onClose,
|
||||||
|
iconSrc,
|
||||||
title,
|
title,
|
||||||
children,
|
children,
|
||||||
isCentered,
|
isCentered,
|
||||||
@ -51,8 +54,9 @@ const MyModal = ({
|
|||||||
background={'#FBFBFC'}
|
background={'#FBFBFC'}
|
||||||
borderBottom={'1px solid #F4F6F8'}
|
borderBottom={'1px solid #F4F6F8'}
|
||||||
roundedTop={'lg'}
|
roundedTop={'lg'}
|
||||||
py={3}
|
py={'10px'}
|
||||||
>
|
>
|
||||||
|
{iconSrc && <Image mr={3} objectFit={'contain'} alt="" src={iconSrc} w={'20px'} />}
|
||||||
{title}
|
{title}
|
||||||
<Box flex={1} />
|
<Box flex={1} />
|
||||||
{onClose && <ModalCloseButton position={'relative'} top={0} right={0} />}
|
{onClose && <ModalCloseButton position={'relative'} top={0} right={0} />}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ const PromptTemplate = ({
|
|||||||
const [selectTemplateTitle, setSelectTemplateTitle] = useState<PromptTemplateItem>();
|
const [selectTemplateTitle, setSelectTemplateTitle] = useState<PromptTemplateItem>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen title={title} onClose={onClose} isCentered>
|
<MyModal isOpen title={title} onClose={onClose} iconSrc="/imgs/modal/prompt.svg">
|
||||||
<ModalBody h="100%" w={'600px'} maxW={'90vw'} overflowY={'auto'}>
|
<ModalBody h="100%" w={'600px'} maxW={'90vw'} overflowY={'auto'}>
|
||||||
<Grid gridTemplateColumns={['1fr', '1fr 1fr']} gridGap={4}>
|
<Grid gridTemplateColumns={['1fr', '1fr 1fr']} gridGap={4}>
|
||||||
{templates.map((item) => (
|
{templates.map((item) => (
|
||||||
|
|||||||
@ -4,8 +4,7 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import React, { Dispatch, useMemo, useState } from 'react';
|
import React, { Dispatch, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
import { Box, Flex, ModalHeader } from '@chakra-ui/react';
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
import MyIcon from '@/components/Icon';
|
|
||||||
import ParentPaths from '@/components/common/ParentPaths';
|
import ParentPaths from '@/components/common/ParentPaths';
|
||||||
|
|
||||||
type PathItemType = {
|
type PathItemType = {
|
||||||
@ -29,12 +28,12 @@ const DatasetSelectContainer = ({
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { isPc } = useSystemStore();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen={isOpen} onClose={onClose} w={'100%'} maxW={['90vw', '900px']} isCentered>
|
<MyModal
|
||||||
<Flex flexDirection={'column'} h={'90vh'}>
|
iconSrc="/imgs/module/db.png"
|
||||||
<ModalHeader fontWeight={'normal'}>
|
title={
|
||||||
|
<Box fontWeight={'normal'}>
|
||||||
<ParentPaths
|
<ParentPaths
|
||||||
paths={paths.map((path, i) => ({
|
paths={paths.map((path, i) => ({
|
||||||
parentId: path.parentId,
|
parentId: path.parentId,
|
||||||
@ -50,7 +49,15 @@ const DatasetSelectContainer = ({
|
|||||||
{tips}
|
{tips}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</ModalHeader>
|
</Box>
|
||||||
|
}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
w={'100%'}
|
||||||
|
maxW={['90vw', '900px']}
|
||||||
|
isCentered
|
||||||
|
>
|
||||||
|
<Flex flexDirection={'column'} h={'90vh'}>
|
||||||
<Box flex={'1 0 0'}>{children}</Box>
|
<Box flex={'1 0 0'}>{children}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</MyModal>
|
</MyModal>
|
||||||
@ -58,10 +65,9 @@ const DatasetSelectContainer = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function useDatasetSelect() {
|
export function useDatasetSelect() {
|
||||||
const { t } = useTranslation();
|
const [parentId, setParentId] = useState<string>('');
|
||||||
const [parentId, setParentId] = useState<string>();
|
|
||||||
|
|
||||||
const { data, isLoading } = useQuery(['loadDatasetData', parentId], () =>
|
const { data, isFetching } = useQuery(['loadDatasetData', parentId], () =>
|
||||||
Promise.all([getDatasets({ parentId }), getDatasetPaths(parentId)])
|
Promise.all([getDatasets({ parentId }), getDatasetPaths(parentId)])
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -72,7 +78,7 @@ export function useDatasetSelect() {
|
|||||||
setParentId,
|
setParentId,
|
||||||
datasets: data?.[0] || [],
|
datasets: data?.[0] || [],
|
||||||
paths,
|
paths,
|
||||||
isLoading
|
isFetching
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import MyModal from '@/components/MyModal';
|
import MyModal from '@/components/MyModal';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { EditFormType } from '@/web/core/app/basicSettings';
|
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
BoxProps,
|
BoxProps,
|
||||||
Button,
|
Button,
|
||||||
Flex,
|
Flex,
|
||||||
|
Image,
|
||||||
Link,
|
Link,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
@ -19,9 +19,12 @@ import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
|||||||
import { Prompt_QuotePromptList, Prompt_QuoteTemplateList } from '@/global/core/prompt/AIChat';
|
import { Prompt_QuotePromptList, Prompt_QuoteTemplateList } from '@/global/core/prompt/AIChat';
|
||||||
import { chatModelList, feConfigs } from '@/web/common/system/staticData';
|
import { chatModelList, feConfigs } from '@/web/common/system/staticData';
|
||||||
import MySlider from '@/components/Slider';
|
import MySlider from '@/components/Slider';
|
||||||
import { SystemInputEnum } from '@/constants/app';
|
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { PromptTemplateItem } from '@fastgpt/global/core/ai/type.d';
|
import { PromptTemplateItem } from '@fastgpt/global/core/ai/type.d';
|
||||||
|
import type { AIChatModuleProps } from '@fastgpt/global/core/module/node/type.d';
|
||||||
|
import type { AppSimpleEditConfigTemplateType } from '@fastgpt/global/core/app/type.d';
|
||||||
|
import { SimpleModeTemplate_FastGPT_Universal } from '@/global/core/app/constants';
|
||||||
|
|
||||||
const PromptTemplate = dynamic(() => import('@/components/PromptTemplate'));
|
const PromptTemplate = dynamic(() => import('@/components/PromptTemplate'));
|
||||||
|
|
||||||
@ -29,12 +32,14 @@ const AIChatSettingsModal = ({
|
|||||||
isAdEdit,
|
isAdEdit,
|
||||||
onClose,
|
onClose,
|
||||||
onSuccess,
|
onSuccess,
|
||||||
defaultData
|
defaultData,
|
||||||
|
simpleModeTemplate = SimpleModeTemplate_FastGPT_Universal
|
||||||
}: {
|
}: {
|
||||||
isAdEdit?: boolean;
|
isAdEdit?: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSuccess: (e: EditFormType['chatModel']) => void;
|
onSuccess: (e: AIChatModuleProps) => void;
|
||||||
defaultData: EditFormType['chatModel'];
|
defaultData: AIChatModuleProps;
|
||||||
|
simpleModeTemplate?: AppSimpleEditConfigTemplateType;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
@ -49,7 +54,10 @@ const AIChatSettingsModal = ({
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const tokenLimit = useMemo(() => {
|
const tokenLimit = useMemo(() => {
|
||||||
return chatModelList.find((item) => item.model === getValues('model'))?.maxResponse || 4000;
|
return (
|
||||||
|
chatModelList.find((item) => item.model === getValues(ModuleInputKeyEnum.aiModel))
|
||||||
|
?.maxResponse || 4000
|
||||||
|
);
|
||||||
}, [getValues, refresh]);
|
}, [getValues, refresh]);
|
||||||
|
|
||||||
const LabelStyles: BoxProps = {
|
const LabelStyles: BoxProps = {
|
||||||
@ -63,8 +71,9 @@ const AIChatSettingsModal = ({
|
|||||||
return (
|
return (
|
||||||
<MyModal
|
<MyModal
|
||||||
isOpen
|
isOpen
|
||||||
|
iconSrc="/imgs/module/AI.png"
|
||||||
title={
|
title={
|
||||||
<Flex alignItems={'flex-end'}>
|
<>
|
||||||
{t('app.AI Advanced Settings')}
|
{t('app.AI Advanced Settings')}
|
||||||
{feConfigs?.docUrl && (
|
{feConfigs?.docUrl && (
|
||||||
<Link
|
<Link
|
||||||
@ -78,13 +87,13 @@ const AIChatSettingsModal = ({
|
|||||||
查看说明
|
查看说明
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</>
|
||||||
}
|
}
|
||||||
isCentered
|
isCentered
|
||||||
w={'700px'}
|
w={'700px'}
|
||||||
h={['90vh', 'auto']}
|
h={['90vh', 'auto']}
|
||||||
>
|
>
|
||||||
<ModalBody flex={['1 0 0', 'auto']} overflowY={'auto'}>
|
<ModalBody flex={['1 0 0', 'auto']} overflowY={'auto'} minH={'40vh'}>
|
||||||
{isAdEdit && (
|
{isAdEdit && (
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Box {...LabelStyles} w={'80px'}>
|
<Box {...LabelStyles} w={'80px'}>
|
||||||
@ -92,17 +101,18 @@ const AIChatSettingsModal = ({
|
|||||||
</Box>
|
</Box>
|
||||||
<Box flex={1} ml={'10px'}>
|
<Box flex={1} ml={'10px'}>
|
||||||
<Switch
|
<Switch
|
||||||
isChecked={getValues(SystemInputEnum.isResponseAnswerText)}
|
isChecked={getValues(ModuleInputKeyEnum.aiChatIsResponseText)}
|
||||||
size={'lg'}
|
size={'lg'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const value = e.target.checked;
|
const value = e.target.checked;
|
||||||
setValue(SystemInputEnum.isResponseAnswerText, value);
|
setValue(ModuleInputKeyEnum.aiChatIsResponseText, value);
|
||||||
setRefresh((state) => !state);
|
setRefresh((state) => !state);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
{simpleModeTemplate?.systemForm?.aiSettings?.temperature && (
|
||||||
<Flex alignItems={'center'} mb={10} mt={isAdEdit ? 8 : 5}>
|
<Flex alignItems={'center'} mb={10} mt={isAdEdit ? 8 : 5}>
|
||||||
<Box {...LabelStyles} mr={2} w={'80px'}>
|
<Box {...LabelStyles} mr={2} w={'80px'}>
|
||||||
温度
|
温度
|
||||||
@ -116,14 +126,16 @@ const AIChatSettingsModal = ({
|
|||||||
width={'95%'}
|
width={'95%'}
|
||||||
min={0}
|
min={0}
|
||||||
max={10}
|
max={10}
|
||||||
value={getValues('temperature')}
|
value={getValues(ModuleInputKeyEnum.aiChatTemperature)}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setValue('temperature', e);
|
setValue(ModuleInputKeyEnum.aiChatTemperature, e);
|
||||||
setRefresh(!refresh);
|
setRefresh(!refresh);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
)}
|
||||||
|
{simpleModeTemplate?.systemForm?.aiSettings?.maxToken && (
|
||||||
<Flex alignItems={'center'} mt={12} mb={10}>
|
<Flex alignItems={'center'} mt={12} mb={10}>
|
||||||
<Box {...LabelStyles} mr={2} w={'80px'}>
|
<Box {...LabelStyles} mr={2} w={'80px'}>
|
||||||
回复上限
|
回复上限
|
||||||
@ -138,14 +150,17 @@ const AIChatSettingsModal = ({
|
|||||||
min={100}
|
min={100}
|
||||||
max={tokenLimit}
|
max={tokenLimit}
|
||||||
step={50}
|
step={50}
|
||||||
value={getValues('maxToken')}
|
value={getValues(ModuleInputKeyEnum.aiChatMaxToken)}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
setValue('maxToken', val);
|
setValue(ModuleInputKeyEnum.aiChatMaxToken, val);
|
||||||
setRefresh(!refresh);
|
setRefresh(!refresh);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{simpleModeTemplate?.systemForm?.aiSettings?.quoteTemplate && (
|
||||||
<Box>
|
<Box>
|
||||||
<Flex {...LabelStyles} mb={1}>
|
<Flex {...LabelStyles} mb={1}>
|
||||||
引用内容模板
|
引用内容模板
|
||||||
@ -170,15 +185,19 @@ const AIChatSettingsModal = ({
|
|||||||
选择模板
|
选择模板
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Textarea
|
<Textarea
|
||||||
rows={6}
|
rows={6}
|
||||||
placeholder={
|
placeholder={
|
||||||
t('template.Quote Content Tip', { default: Prompt_QuoteTemplateList[0].value }) || ''
|
t('template.Quote Content Tip', { default: Prompt_QuoteTemplateList[0].value }) ||
|
||||||
|
''
|
||||||
}
|
}
|
||||||
borderColor={'myGray.100'}
|
borderColor={'myGray.100'}
|
||||||
{...register('quoteTemplate')}
|
{...register(ModuleInputKeyEnum.aiChatQuoteTemplate)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
|
{simpleModeTemplate?.systemForm?.aiSettings?.quotePrompt && (
|
||||||
<Box mt={4}>
|
<Box mt={4}>
|
||||||
<Flex {...LabelStyles} mb={1}>
|
<Flex {...LabelStyles} mb={1}>
|
||||||
引用内容提示词
|
引用内容提示词
|
||||||
@ -195,9 +214,10 @@ const AIChatSettingsModal = ({
|
|||||||
t('template.Quote Prompt Tip', { default: Prompt_QuotePromptList[0].value }) || ''
|
t('template.Quote Prompt Tip', { default: Prompt_QuotePromptList[0].value }) || ''
|
||||||
}
|
}
|
||||||
borderColor={'myGray.100'}
|
borderColor={'myGray.100'}
|
||||||
{...register('quotePrompt')}
|
{...register(ModuleInputKeyEnum.aiChatQuotePrompt)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant={'base'} onClick={onClose}>
|
<Button variant={'base'} onClick={onClose}>
|
||||||
@ -215,8 +235,8 @@ const AIChatSettingsModal = ({
|
|||||||
onSuccess={(e) => {
|
onSuccess={(e) => {
|
||||||
const quoteVal = e.value;
|
const quoteVal = e.value;
|
||||||
const promptVal = Prompt_QuotePromptList.find((item) => item.title === e.title)?.value;
|
const promptVal = Prompt_QuotePromptList.find((item) => item.title === e.title)?.value;
|
||||||
setValue('quoteTemplate', quoteVal);
|
setValue(ModuleInputKeyEnum.aiChatQuoteTemplate, quoteVal);
|
||||||
setValue('quotePrompt', promptVal);
|
setValue(ModuleInputKeyEnum.aiChatQuotePrompt, promptVal);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -10,7 +10,8 @@ import {
|
|||||||
Textarea,
|
Textarea,
|
||||||
Grid,
|
Grid,
|
||||||
Divider,
|
Divider,
|
||||||
Switch
|
Switch,
|
||||||
|
Image
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
@ -28,47 +29,44 @@ import { feConfigs } from '@/web/common/system/staticData';
|
|||||||
import DatasetSelectContainer, { useDatasetSelect } from '@/components/core/dataset/SelectModal';
|
import DatasetSelectContainer, { useDatasetSelect } from '@/components/core/dataset/SelectModal';
|
||||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||||
import EmptyTip from '@/components/EmptyTip';
|
import EmptyTip from '@/components/EmptyTip';
|
||||||
|
import { AppSimpleEditFormType } from '@fastgpt/global/core/app/type';
|
||||||
|
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||||
|
|
||||||
export type KbParamsType = {
|
type DatasetParamsProps = AppSimpleEditFormType['dataset'];
|
||||||
searchSimilarity: number;
|
|
||||||
searchLimit: number;
|
|
||||||
searchEmptyText: string;
|
|
||||||
rerank: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DatasetSelectModal = ({
|
export const DatasetSelectModal = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
activeDatasets = [],
|
defaultSelectedDatasets = [],
|
||||||
onChange,
|
onChange,
|
||||||
onClose
|
onClose
|
||||||
}: {
|
}: {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
activeDatasets: SelectedDatasetType;
|
defaultSelectedDatasets: SelectedDatasetType;
|
||||||
onChange: (e: SelectedDatasetType) => void;
|
onChange: (e: SelectedDatasetType) => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { allDatasets } = useDatasetStore();
|
const { allDatasets } = useDatasetStore();
|
||||||
const [selectedKbList, setSelectedKbList] = useState<SelectedDatasetType>(
|
const [selectedDatasets, setSelectedDatasets] = useState<SelectedDatasetType>(
|
||||||
activeDatasets.filter((dataset) => {
|
defaultSelectedDatasets.filter((dataset) => {
|
||||||
return allDatasets.find((item) => item._id === dataset.datasetId);
|
return allDatasets.find((item) => item._id === dataset.datasetId);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { paths, setParentId, datasets, isLoading } = useDatasetSelect();
|
const { paths, setParentId, datasets, isFetching } = useDatasetSelect();
|
||||||
const { Loading } = useLoading();
|
const { Loading } = useLoading();
|
||||||
|
|
||||||
const filterKbList = useMemo(() => {
|
const filterDatasets = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
selected: allDatasets.filter((item) =>
|
selected: allDatasets.filter((item) =>
|
||||||
selectedKbList.find((dataset) => dataset.datasetId === item._id)
|
selectedDatasets.find((dataset) => dataset.datasetId === item._id)
|
||||||
),
|
),
|
||||||
unSelected: datasets.filter(
|
unSelected: datasets.filter(
|
||||||
(item) => !selectedKbList.find((dataset) => dataset.datasetId === item._id)
|
(item) => !selectedDatasets.find((dataset) => dataset.datasetId === item._id)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}, [datasets, allDatasets, selectedKbList]);
|
}, [datasets, allDatasets, selectedDatasets]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DatasetSelectContainer
|
<DatasetSelectContainer
|
||||||
@ -88,7 +86,7 @@ export const DatasetSelectModal = ({
|
|||||||
]}
|
]}
|
||||||
gridGap={3}
|
gridGap={3}
|
||||||
>
|
>
|
||||||
{filterKbList.selected.map((item) =>
|
{filterDatasets.selected.map((item) =>
|
||||||
(() => {
|
(() => {
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
@ -109,7 +107,7 @@ export const DatasetSelectModal = ({
|
|||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
_hover={{ color: 'red.500' }}
|
_hover={{ color: 'red.500' }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedKbList((state) =>
|
setSelectedDatasets((state) =>
|
||||||
state.filter((kb) => kb.datasetId !== item._id)
|
state.filter((kb) => kb.datasetId !== item._id)
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@ -121,7 +119,7 @@ export const DatasetSelectModal = ({
|
|||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{filterKbList.selected.length > 0 && <Divider my={3} />}
|
{filterDatasets.selected.length > 0 && <Divider my={3} />}
|
||||||
|
|
||||||
<Grid
|
<Grid
|
||||||
gridTemplateColumns={[
|
gridTemplateColumns={[
|
||||||
@ -131,7 +129,7 @@ export const DatasetSelectModal = ({
|
|||||||
]}
|
]}
|
||||||
gridGap={3}
|
gridGap={3}
|
||||||
>
|
>
|
||||||
{filterKbList.unSelected.map((item) =>
|
{filterDatasets.unSelected.map((item) =>
|
||||||
(() => {
|
(() => {
|
||||||
return (
|
return (
|
||||||
<MyTooltip
|
<MyTooltip
|
||||||
@ -155,7 +153,7 @@ export const DatasetSelectModal = ({
|
|||||||
if (item.type === DatasetTypeEnum.folder) {
|
if (item.type === DatasetTypeEnum.folder) {
|
||||||
setParentId(item._id);
|
setParentId(item._id);
|
||||||
} else if (item.type === DatasetTypeEnum.dataset) {
|
} else if (item.type === DatasetTypeEnum.dataset) {
|
||||||
const vectorModel = selectedKbList[0]?.vectorModel?.model;
|
const vectorModel = selectedDatasets[0]?.vectorModel?.model;
|
||||||
|
|
||||||
if (vectorModel && vectorModel !== item.vectorModel.model) {
|
if (vectorModel && vectorModel !== item.vectorModel.model) {
|
||||||
return toast({
|
return toast({
|
||||||
@ -163,7 +161,7 @@ export const DatasetSelectModal = ({
|
|||||||
title: t('dataset.Select Dataset Tips')
|
title: t('dataset.Select Dataset Tips')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setSelectedKbList((state) => [
|
setSelectedDatasets((state) => [
|
||||||
...state,
|
...state,
|
||||||
{ datasetId: item._id, vectorModel: item.vectorModel }
|
{ datasetId: item._id, vectorModel: item.vectorModel }
|
||||||
]);
|
]);
|
||||||
@ -199,26 +197,26 @@ export const DatasetSelectModal = ({
|
|||||||
})()
|
})()
|
||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
{filterKbList.unSelected.length === 0 && <EmptyTip text={t('common.folder.empty')} />}
|
{filterDatasets.unSelected.length === 0 && <EmptyTip text={t('common.folder.empty')} />}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
// filter out the dataset that is not in the kList
|
// filter out the dataset that is not in the kList
|
||||||
const filterKbList = selectedKbList.filter((dataset) => {
|
const filterDatasets = selectedDatasets.filter((dataset) => {
|
||||||
return allDatasets.find((item) => item._id === dataset.datasetId);
|
return allDatasets.find((item) => item._id === dataset.datasetId);
|
||||||
});
|
});
|
||||||
|
|
||||||
onClose();
|
onClose();
|
||||||
onChange(filterKbList);
|
onChange(filterDatasets);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t('common.Done')}
|
{t('common.Done')}
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|
||||||
<Loading fixed={false} loading={isLoading} />
|
<Loading fixed={false} loading={isFetching} />
|
||||||
</Flex>
|
</Flex>
|
||||||
</DatasetSelectContainer>
|
</DatasetSelectContainer>
|
||||||
);
|
);
|
||||||
@ -226,24 +224,30 @@ export const DatasetSelectModal = ({
|
|||||||
|
|
||||||
export const DatasetParamsModal = ({
|
export const DatasetParamsModal = ({
|
||||||
searchEmptyText,
|
searchEmptyText,
|
||||||
searchLimit,
|
limit,
|
||||||
searchSimilarity,
|
similarity,
|
||||||
rerank,
|
rerank,
|
||||||
onClose,
|
onClose,
|
||||||
onChange
|
onChange
|
||||||
}: KbParamsType & { onClose: () => void; onChange: (e: KbParamsType) => void }) => {
|
}: DatasetParamsProps & { onClose: () => void; onChange: (e: DatasetParamsProps) => void }) => {
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
const { register, setValue, getValues, handleSubmit } = useForm<KbParamsType>({
|
const { register, setValue, getValues, handleSubmit } = useForm<DatasetParamsProps>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
searchEmptyText,
|
searchEmptyText,
|
||||||
searchLimit,
|
limit,
|
||||||
searchSimilarity,
|
similarity,
|
||||||
rerank
|
rerank
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen={true} onClose={onClose} title={'搜索参数调整'} minW={['90vw', '600px']}>
|
<MyModal
|
||||||
|
isOpen={true}
|
||||||
|
onClose={onClose}
|
||||||
|
iconSrc="/imgs/modal/params.svg"
|
||||||
|
title={'搜索参数调整'}
|
||||||
|
minW={['90vw', '600px']}
|
||||||
|
>
|
||||||
<Flex flexDirection={'column'}>
|
<Flex flexDirection={'column'}>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
{feConfigs?.isPlus && (
|
{feConfigs?.isPlus && (
|
||||||
@ -256,9 +260,9 @@ export const DatasetParamsModal = ({
|
|||||||
</Box>
|
</Box>
|
||||||
<Switch
|
<Switch
|
||||||
size={'lg'}
|
size={'lg'}
|
||||||
isChecked={getValues('rerank')}
|
isChecked={getValues(ModuleInputKeyEnum.datasetStartReRank)}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setValue('rerank', e.target.checked);
|
setValue(ModuleInputKeyEnum.datasetStartReRank, e.target.checked);
|
||||||
setRefresh(!refresh);
|
setRefresh(!refresh);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -282,9 +286,9 @@ export const DatasetParamsModal = ({
|
|||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
step={0.01}
|
step={0.01}
|
||||||
value={getValues('searchSimilarity')}
|
value={getValues(ModuleInputKeyEnum.datasetSimilarity)}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
setValue('searchSimilarity', val);
|
setValue(ModuleInputKeyEnum.datasetSimilarity, val);
|
||||||
setRefresh(!refresh);
|
setRefresh(!refresh);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -301,9 +305,9 @@ export const DatasetParamsModal = ({
|
|||||||
]}
|
]}
|
||||||
min={1}
|
min={1}
|
||||||
max={20}
|
max={20}
|
||||||
value={getValues('searchLimit')}
|
value={getValues(ModuleInputKeyEnum.datasetLimit)}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
setValue('searchLimit', val);
|
setValue(ModuleInputKeyEnum.datasetLimit, val);
|
||||||
setRefresh(!refresh);
|
setRefresh(!refresh);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import { streamFetch } from '@/web/common/api/fetch';
|
|||||||
import MyTooltip from '@/components/MyTooltip';
|
import MyTooltip from '@/components/MyTooltip';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
import ChatBox, { type ComponentRef, type StartChatFnProps } from '@/components/ChatBox';
|
import ChatBox, { type ComponentRef, type StartChatFnProps } from '@/components/ChatBox';
|
||||||
import { getGuideModule } from '@/global/core/app/modules/utils';
|
import { getGuideModule } from '@fastgpt/global/core/module/utils';
|
||||||
import { checkChatSupportSelectFileByModules } from '@/web/core/chat/utils';
|
import { checkChatSupportSelectFileByModules } from '@/web/core/chat/utils';
|
||||||
|
|
||||||
export type ChatTestComponentRef = {
|
export type ChatTestComponentRef = {
|
||||||
|
|||||||
@ -28,11 +28,8 @@ import React, {
|
|||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
import { appModule2FlowEdge, appModule2FlowNode } from '@/utils/adapt';
|
import { appModule2FlowEdge, appModule2FlowNode } from '@/utils/adapt';
|
||||||
import { useToast } from '@/web/common/hooks/useToast';
|
import { useToast } from '@/web/common/hooks/useToast';
|
||||||
import {
|
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||||
FlowNodeInputTypeEnum,
|
import { ModuleDataTypeEnum } from '@fastgpt/global/core/module/constants';
|
||||||
FlowNodeTypeEnum,
|
|
||||||
FlowNodeValTypeEnum
|
|
||||||
} from '@fastgpt/global/core/module/node/constant';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { ModuleItemType } from '@fastgpt/global/core/module/type.d';
|
import { ModuleItemType } from '@fastgpt/global/core/module/type.d';
|
||||||
import { EventNameEnum, eventBus } from '@/web/common/utils/eventbus';
|
import { EventNameEnum, eventBus } from '@/web/common/utils/eventbus';
|
||||||
@ -42,6 +39,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
|||||||
type OnChange<ChangesType> = (changes: ChangesType[]) => void;
|
type OnChange<ChangesType> = (changes: ChangesType[]) => void;
|
||||||
export type useFlowProviderStoreType = {
|
export type useFlowProviderStoreType = {
|
||||||
reactFlowWrapper: null | React.RefObject<HTMLDivElement>;
|
reactFlowWrapper: null | React.RefObject<HTMLDivElement>;
|
||||||
|
mode: 'app' | 'plugin';
|
||||||
filterAppIds: string[];
|
filterAppIds: string[];
|
||||||
nodes: Node<FlowModuleItemType, string | undefined>[];
|
nodes: Node<FlowModuleItemType, string | undefined>[];
|
||||||
setNodes: Dispatch<SetStateAction<Node<FlowModuleItemType, string | undefined>[]>>;
|
setNodes: Dispatch<SetStateAction<Node<FlowModuleItemType, string | undefined>[]>>;
|
||||||
@ -66,6 +64,7 @@ export type useFlowProviderStoreType = {
|
|||||||
|
|
||||||
const StateContext = createContext<useFlowProviderStoreType>({
|
const StateContext = createContext<useFlowProviderStoreType>({
|
||||||
reactFlowWrapper: null,
|
reactFlowWrapper: null,
|
||||||
|
mode: 'app',
|
||||||
filterAppIds: [],
|
filterAppIds: [],
|
||||||
nodes: [],
|
nodes: [],
|
||||||
setNodes: function (
|
setNodes: function (
|
||||||
@ -118,9 +117,11 @@ const StateContext = createContext<useFlowProviderStoreType>({
|
|||||||
export const useFlowProviderStore = () => useContext(StateContext);
|
export const useFlowProviderStore = () => useContext(StateContext);
|
||||||
|
|
||||||
export const FlowProvider = ({
|
export const FlowProvider = ({
|
||||||
|
mode,
|
||||||
filterAppIds = [],
|
filterAppIds = [],
|
||||||
children
|
children
|
||||||
}: {
|
}: {
|
||||||
|
mode: useFlowProviderStoreType['mode'];
|
||||||
filterAppIds?: string[];
|
filterAppIds?: string[];
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
@ -173,7 +174,7 @@ export const FlowProvider = ({
|
|||||||
const source = nodes.find((node) => node.id === connect.source)?.data;
|
const source = nodes.find((node) => node.id === connect.source)?.data;
|
||||||
const sourceType = (() => {
|
const sourceType = (() => {
|
||||||
if (source?.flowType === FlowNodeTypeEnum.classifyQuestion) {
|
if (source?.flowType === FlowNodeTypeEnum.classifyQuestion) {
|
||||||
return FlowNodeValTypeEnum.boolean;
|
return ModuleDataTypeEnum.boolean;
|
||||||
}
|
}
|
||||||
if (source?.flowType === FlowNodeTypeEnum.pluginInput) {
|
if (source?.flowType === FlowNodeTypeEnum.pluginInput) {
|
||||||
return source?.inputs.find((input) => input.key === connect.sourceHandle)?.valueType;
|
return source?.inputs.find((input) => input.key === connect.sourceHandle)?.valueType;
|
||||||
@ -192,8 +193,8 @@ export const FlowProvider = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
sourceType !== FlowNodeValTypeEnum.any &&
|
sourceType !== ModuleDataTypeEnum.any &&
|
||||||
targetType !== FlowNodeValTypeEnum.any &&
|
targetType !== ModuleDataTypeEnum.any &&
|
||||||
sourceType !== targetType
|
sourceType !== targetType
|
||||||
) {
|
) {
|
||||||
return toast({
|
return toast({
|
||||||
@ -328,10 +329,9 @@ export const FlowProvider = ({
|
|||||||
const node = nodes.find((node) => node.id === nodeId);
|
const node = nodes.find((node) => node.id === nodeId);
|
||||||
if (!node) return nodes;
|
if (!node) return nodes;
|
||||||
const template = {
|
const template = {
|
||||||
logo: node.data.logo,
|
avatar: node.data.avatar,
|
||||||
name: node.data.name,
|
name: node.data.name,
|
||||||
intro: node.data.intro,
|
intro: node.data.intro,
|
||||||
description: node.data.description,
|
|
||||||
flowType: node.data.flowType,
|
flowType: node.data.flowType,
|
||||||
inputs: node.data.inputs,
|
inputs: node.data.inputs,
|
||||||
outputs: node.data.outputs,
|
outputs: node.data.outputs,
|
||||||
@ -407,6 +407,7 @@ export const FlowProvider = ({
|
|||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
reactFlowWrapper,
|
reactFlowWrapper,
|
||||||
|
mode,
|
||||||
filterAppIds,
|
filterAppIds,
|
||||||
nodes,
|
nodes,
|
||||||
setNodes,
|
setNodes,
|
||||||
@ -444,13 +445,13 @@ export function flowNode2Modules({
|
|||||||
const modules: ModuleItemType[] = nodes.map((item) => ({
|
const modules: ModuleItemType[] = nodes.map((item) => ({
|
||||||
moduleId: item.data.moduleId,
|
moduleId: item.data.moduleId,
|
||||||
name: item.data.name,
|
name: item.data.name,
|
||||||
logo: item.data.logo,
|
avatar: item.data.avatar,
|
||||||
flowType: item.data.flowType,
|
flowType: item.data.flowType,
|
||||||
showStatus: item.data.showStatus,
|
showStatus: item.data.showStatus,
|
||||||
position: item.position,
|
position: item.position,
|
||||||
inputs: item.data.inputs.map((item) => ({
|
inputs: item.data.inputs.map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
connected: item.connected ?? item.type !== FlowNodeInputTypeEnum.target
|
connected: Boolean(item.value ?? item.connected ?? item.type !== FlowNodeInputTypeEnum.target)
|
||||||
})),
|
})),
|
||||||
outputs: item.data.outputs.map((item) => ({
|
outputs: item.data.outputs.map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
|
|||||||
@ -12,7 +12,13 @@ const ImportSettings = ({ onClose }: { onClose: () => void }) => {
|
|||||||
const { setNodes, setEdges, initData } = useFlowProviderStore();
|
const { setNodes, setEdges, initData } = useFlowProviderStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen w={'600px'} onClose={onClose} title={t('app.Import Config')}>
|
<MyModal
|
||||||
|
isOpen
|
||||||
|
w={'600px'}
|
||||||
|
onClose={onClose}
|
||||||
|
iconSrc="/imgs/modal/params.svg"
|
||||||
|
title={t('app.Import Configs')}
|
||||||
|
>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Textarea
|
<Textarea
|
||||||
placeholder={t('app.Paste Config') || 'app.Paste Config'}
|
placeholder={t('app.Paste Config') || 'app.Paste Config'}
|
||||||
@ -38,7 +44,7 @@ const ImportSettings = ({ onClose }: { onClose: () => void }) => {
|
|||||||
onClose();
|
onClose();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast({
|
toast({
|
||||||
title: t('app.Import Config Failed')
|
title: t('app.Import Configs Failed')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -1,8 +1,17 @@
|
|||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import { Box, Flex } from '@chakra-ui/react';
|
import {
|
||||||
|
Box,
|
||||||
|
Flex,
|
||||||
|
Accordion,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionButton,
|
||||||
|
AccordionPanel,
|
||||||
|
AccordionIcon,
|
||||||
|
useTheme
|
||||||
|
} from '@chakra-ui/react';
|
||||||
import type {
|
import type {
|
||||||
FlowModuleTemplateType,
|
FlowModuleTemplateType,
|
||||||
SystemModuleTemplateType
|
moduleTemplateListType
|
||||||
} from '@fastgpt/global/core/module/type.d';
|
} from '@fastgpt/global/core/module/type.d';
|
||||||
import { useViewport, XYPosition } from 'reactflow';
|
import { useViewport, XYPosition } from 'reactflow';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
@ -16,32 +25,31 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
|||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
import EmptyTip from '@/components/EmptyTip';
|
import EmptyTip from '@/components/EmptyTip';
|
||||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
import { FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||||
import { getPluginModuleDetail } from '@/web/core/plugin/api';
|
import { getPreviewPluginModule } from '@/web/core/plugin/api';
|
||||||
import { useToast } from '@/web/common/hooks/useToast';
|
import { useToast } from '@/web/common/hooks/useToast';
|
||||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||||
|
import { moduleTemplatesList } from '@/web/core/modules/template/system';
|
||||||
|
import { ModuleTemplateTypeEnum } from '@fastgpt/global/core/module/constants';
|
||||||
|
|
||||||
enum TemplateTypeEnum {
|
enum TemplateTypeEnum {
|
||||||
system = 'system',
|
system = 'system',
|
||||||
combine = 'combine'
|
plugin = 'plugin'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ModuleTemplateProps = {
|
export type ModuleTemplateProps = {
|
||||||
systemTemplates: SystemModuleTemplateType;
|
systemTemplates: FlowModuleTemplateType[];
|
||||||
pluginTemplates: SystemModuleTemplateType;
|
pluginTemplates: FlowModuleTemplateType[];
|
||||||
show2Plugin?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const ModuleTemplateList = ({
|
const ModuleTemplateList = ({
|
||||||
systemTemplates,
|
systemTemplates,
|
||||||
pluginTemplates,
|
pluginTemplates,
|
||||||
show2Plugin = false,
|
|
||||||
isOpen,
|
isOpen,
|
||||||
onClose
|
onClose
|
||||||
}: ModuleTemplateProps & {
|
}: ModuleTemplateProps & {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [templateType, setTemplateType] = React.useState(TemplateTypeEnum.system);
|
const [templateType, setTemplateType] = React.useState(TemplateTypeEnum.system);
|
||||||
|
|
||||||
@ -53,9 +61,9 @@ const ModuleTemplateList = ({
|
|||||||
child: <RenderList templates={systemTemplates} onClose={onClose} />
|
child: <RenderList templates={systemTemplates} onClose={onClose} />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: TemplateTypeEnum.combine,
|
type: TemplateTypeEnum.plugin,
|
||||||
label: t('plugin.Plugin Module'),
|
label: t('plugin.Plugin Module'),
|
||||||
child: <RenderList templates={pluginTemplates} onClose={onClose} />
|
child: <RenderList templates={pluginTemplates} onClose={onClose} isPlugin />
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[pluginTemplates, onClose, systemTemplates, t]
|
[pluginTemplates, onClose, systemTemplates, t]
|
||||||
@ -112,20 +120,6 @@ const ModuleTemplateList = ({
|
|||||||
{item.label}
|
{item.label}
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
<Box flex={1} />
|
|
||||||
{show2Plugin && templateType === TemplateTypeEnum.combine && (
|
|
||||||
<Flex
|
|
||||||
alignItems={'center'}
|
|
||||||
_hover={{ textDecoration: 'underline' }}
|
|
||||||
cursor={'pointer'}
|
|
||||||
onClick={() => router.push('/plugin/list')}
|
|
||||||
>
|
|
||||||
<Box fontSize={'sm'} transform={'translateY(-1px)'}>
|
|
||||||
{t('plugin.To Edit Plugin')}
|
|
||||||
</Box>
|
|
||||||
<MyIcon name={'common/rightArrowLight'} w={'12px'} />
|
|
||||||
</Flex>
|
|
||||||
)}
|
|
||||||
</Flex>
|
</Flex>
|
||||||
{TemplateItem}
|
{TemplateItem}
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -135,47 +129,56 @@ const ModuleTemplateList = ({
|
|||||||
|
|
||||||
export default React.memo(ModuleTemplateList);
|
export default React.memo(ModuleTemplateList);
|
||||||
|
|
||||||
var RenderList = React.memo(function RenderList({
|
const RenderList = React.memo(function RenderList({
|
||||||
templates,
|
templates,
|
||||||
|
isPlugin = false,
|
||||||
onClose
|
onClose
|
||||||
}: {
|
}: {
|
||||||
templates: {
|
templates: FlowModuleTemplateType[];
|
||||||
label: string;
|
isPlugin?: boolean;
|
||||||
list: FlowModuleTemplateType[];
|
|
||||||
}[];
|
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const router = useRouter();
|
||||||
const { isPc } = useSystemStore();
|
const { isPc } = useSystemStore();
|
||||||
const { setNodes, reactFlowWrapper } = useFlowProviderStore();
|
const { setNodes, reactFlowWrapper } = useFlowProviderStore();
|
||||||
const { x, y, zoom } = useViewport();
|
const { x, y, zoom } = useViewport();
|
||||||
const { setLoading } = useSystemStore();
|
const { setLoading } = useSystemStore();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const formatTemplates = useMemo<moduleTemplateListType>(() => {
|
||||||
|
const copy: moduleTemplateListType = JSON.parse(JSON.stringify(moduleTemplatesList));
|
||||||
|
templates.forEach((item) => {
|
||||||
|
const index = copy.findIndex((template) => template.type === item.templateType);
|
||||||
|
if (index === -1) return;
|
||||||
|
copy[index].list.push(item);
|
||||||
|
});
|
||||||
|
return copy.filter((item) => item.list.length > 0);
|
||||||
|
}, [templates]);
|
||||||
|
|
||||||
const onAddNode = useCallback(
|
const onAddNode = useCallback(
|
||||||
async ({ template, position }: { template: FlowModuleTemplateType; position: XYPosition }) => {
|
async ({ template, position }: { template: FlowModuleTemplateType; position: XYPosition }) => {
|
||||||
if (!reactFlowWrapper?.current) return;
|
if (!reactFlowWrapper?.current) return;
|
||||||
|
|
||||||
let templateModule = { ...template };
|
const templateModule = await (async () => {
|
||||||
|
|
||||||
// get plugin module
|
|
||||||
try {
|
try {
|
||||||
if (templateModule.flowType === FlowNodeTypeEnum.pluginModule) {
|
// get plugin preview module
|
||||||
|
if (template.flowType === FlowNodeTypeEnum.pluginModule) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const pluginModule = await getPluginModuleDetail(templateModule.id);
|
const res = await getPreviewPluginModule(template.id);
|
||||||
templateModule = {
|
setLoading(false);
|
||||||
...templateModule,
|
return res;
|
||||||
...pluginModule
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
return { ...template };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return toast({
|
toast({
|
||||||
status: 'error',
|
status: 'error',
|
||||||
title: getErrText(e, t('plugin.Get Plugin Module Detail Failed'))
|
title: getErrText(e, t('plugin.Get Plugin Module Detail Failed'))
|
||||||
});
|
});
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
return Promise.reject(e);
|
||||||
}
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
|
const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
|
||||||
const mouseX = (position.x - reactFlowBounds.left - x) / zoom - 100;
|
const mouseX = (position.x - reactFlowBounds.left - x) / zoom - 100;
|
||||||
@ -196,26 +199,45 @@ var RenderList = React.memo(function RenderList({
|
|||||||
[reactFlowWrapper, setLoading, setNodes, t, toast, x, y, zoom]
|
[reactFlowWrapper, setLoading, setNodes, t, toast, x, y, zoom]
|
||||||
);
|
);
|
||||||
|
|
||||||
const list = useMemo(() => templates.map((item) => item.list).flat(), [templates]);
|
return templates.length === 0 ? (
|
||||||
|
|
||||||
return list.length === 0 ? (
|
|
||||||
<EmptyTip text={t('app.module.No Modules')} />
|
<EmptyTip text={t('app.module.No Modules')} />
|
||||||
) : (
|
) : (
|
||||||
<Box flex={'1 0 0'} overflow={'overlay'}>
|
<Box flex={'1 0 0'} overflow={'overlay'}>
|
||||||
<Box w={['100%', '330px']} mx={'auto'}>
|
<Box w={['100%', '330px']} mx={'auto'}>
|
||||||
{list.map((item) => (
|
{formatTemplates.map((item, i) => (
|
||||||
|
<Box key={item.type}>
|
||||||
|
<Flex>
|
||||||
|
<Box fontWeight={'bold'} flex={1}>
|
||||||
|
{item.label}
|
||||||
|
</Box>
|
||||||
|
{isPlugin && item.type === ModuleTemplateTypeEnum.personalPlugin && (
|
||||||
<Flex
|
<Flex
|
||||||
key={item.id}
|
alignItems={'center'}
|
||||||
|
_hover={{ textDecoration: 'underline' }}
|
||||||
|
cursor={'pointer'}
|
||||||
|
onClick={() => router.push('/plugin/list')}
|
||||||
|
>
|
||||||
|
<Box fontSize={'sm'} transform={'translateY(-1px)'}>
|
||||||
|
{t('plugin.To Edit Plugin')}
|
||||||
|
</Box>
|
||||||
|
<MyIcon name={'common/rightArrowLight'} w={'12px'} />
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
<>
|
||||||
|
{item.list.map((template) => (
|
||||||
|
<Flex
|
||||||
|
key={template.id}
|
||||||
alignItems={'center'}
|
alignItems={'center'}
|
||||||
p={5}
|
p={5}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
_hover={{ bg: 'myWhite.600' }}
|
_hover={{ bg: 'myWhite.600' }}
|
||||||
borderRadius={'md'}
|
borderRadius={'sm'}
|
||||||
draggable
|
draggable
|
||||||
onDragEnd={(e) => {
|
onDragEnd={(e) => {
|
||||||
if (e.clientX < 360) return;
|
if (e.clientX < 360) return;
|
||||||
onAddNode({
|
onAddNode({
|
||||||
template: item,
|
template: template,
|
||||||
position: { x: e.clientX, y: e.clientY }
|
position: { x: e.clientX, y: e.clientY }
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@ -223,20 +245,28 @@ var RenderList = React.memo(function RenderList({
|
|||||||
if (isPc) return;
|
if (isPc) return;
|
||||||
onClose();
|
onClose();
|
||||||
onAddNode({
|
onAddNode({
|
||||||
template: item,
|
template: template,
|
||||||
position: { x: e.clientX, y: e.clientY }
|
position: { x: e.clientX, y: e.clientY }
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Avatar src={item.logo} w={'34px'} objectFit={'contain'} borderRadius={'0'} />
|
<Avatar
|
||||||
|
src={template.avatar}
|
||||||
|
w={'34px'}
|
||||||
|
objectFit={'contain'}
|
||||||
|
borderRadius={'0'}
|
||||||
|
/>
|
||||||
<Box ml={5} flex={'1 0 0'}>
|
<Box ml={5} flex={'1 0 0'}>
|
||||||
<Box color={'black'}>{item.name}</Box>
|
<Box color={'black'}>{template.name}</Box>
|
||||||
<Box className="textEllipsis3" color={'myGray.500'} fontSize={'sm'}>
|
<Box className="textEllipsis3" color={'myGray.500'} fontSize={'sm'}>
|
||||||
{item.intro}
|
{template.intro}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
))}
|
))}
|
||||||
|
</>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
@ -39,6 +39,7 @@ const SelectAppModal = ({
|
|||||||
<MyModal
|
<MyModal
|
||||||
isOpen
|
isOpen
|
||||||
title={`选择应用${max > 1 ? `(${selectedApps.length}/${max})` : ''}`}
|
title={`选择应用${max > 1 ? `(${selectedApps.length}/${max})` : ''}`}
|
||||||
|
iconSrc="/imgs/module/ai.svg"
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
minW={'700px'}
|
minW={'700px'}
|
||||||
position={'relative'}
|
position={'relative'}
|
||||||
|
|||||||
@ -35,11 +35,12 @@ const ExtractFieldModal = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen={true} onClose={onClose}>
|
<MyModal
|
||||||
<ModalHeader display={'flex'} alignItems={'center'}>
|
isOpen={true}
|
||||||
<Avatar src={'/imgs/module/extract.png'} mr={2} w={'20px'} objectFit={'cover'} />
|
iconSrc="/imgs/module/extract.png"
|
||||||
提取字段配置
|
title={'提取字段配置'}
|
||||||
</ModalHeader>
|
onClose={onClose}
|
||||||
|
>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Box flex={'0 0 70px'}>必填</Box>
|
<Box flex={'0 0 70px'}>必填</Box>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
@ -11,65 +11,69 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import MyModal from '@/components/MyModal';
|
import MyModal from '@/components/MyModal';
|
||||||
import Avatar from '@/components/Avatar';
|
import { ModuleDataTypeEnum } from '@fastgpt/global/core/module/constants';
|
||||||
import { FlowNodeValTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import MySelect from '@/components/Select';
|
import MySelect from '@/components/Select';
|
||||||
|
import { FlowValueTypeMap } from '@/web/core/modules/constants/dataType';
|
||||||
const typeSelectList = [
|
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||||
{
|
|
||||||
label: '字符串',
|
|
||||||
value: FlowNodeValTypeEnum.string
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '数字',
|
|
||||||
value: FlowNodeValTypeEnum.number
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '布尔',
|
|
||||||
value: FlowNodeValTypeEnum.boolean
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '历史记录',
|
|
||||||
value: FlowNodeValTypeEnum.chatHistory
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '引用内容',
|
|
||||||
value: FlowNodeValTypeEnum.datasetQuote
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '任意',
|
|
||||||
value: FlowNodeValTypeEnum.any
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export type EditFieldModeType = 'input' | 'output' | 'pluginInput';
|
export type EditFieldModeType = 'input' | 'output' | 'pluginInput';
|
||||||
export type EditFieldType = {
|
export type EditFieldType = {
|
||||||
|
type?: `${FlowNodeInputTypeEnum}`; // input type
|
||||||
key: string;
|
key: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
valueType?: `${FlowNodeValTypeEnum}`;
|
valueType?: `${ModuleDataTypeEnum}`;
|
||||||
description?: string;
|
description?: string;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
|
createSign?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FieldEditModal = ({
|
const FieldEditModal = ({
|
||||||
mode,
|
mode,
|
||||||
defaultField = {
|
defaultField,
|
||||||
label: '',
|
|
||||||
key: '',
|
|
||||||
description: '',
|
|
||||||
valueType: FlowNodeValTypeEnum.string,
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
onClose,
|
onClose,
|
||||||
onSubmit
|
onSubmit
|
||||||
}: {
|
}: {
|
||||||
mode: EditFieldModeType;
|
mode: EditFieldModeType;
|
||||||
defaultField?: EditFieldType;
|
defaultField: EditFieldType;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSubmit: (data: EditFieldType) => void;
|
onSubmit: (data: EditFieldType) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const inputTypeList = [
|
||||||
|
{
|
||||||
|
label: t('core.module.inputType.target'),
|
||||||
|
value: FlowNodeInputTypeEnum.target,
|
||||||
|
valueType: ModuleDataTypeEnum.string
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('core.module.inputType.input'),
|
||||||
|
value: FlowNodeInputTypeEnum.input,
|
||||||
|
valueType: ModuleDataTypeEnum.string
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('core.module.inputType.textarea'),
|
||||||
|
value: FlowNodeInputTypeEnum.textarea,
|
||||||
|
valueType: ModuleDataTypeEnum.string
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('core.module.inputType.switch'),
|
||||||
|
value: FlowNodeInputTypeEnum.switch,
|
||||||
|
valueType: ModuleDataTypeEnum.boolean
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('core.module.inputType.selectDataset'),
|
||||||
|
value: FlowNodeInputTypeEnum.selectDataset,
|
||||||
|
valueType: ModuleDataTypeEnum.selectDataset
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const dataTypeSelectList = Object.values(FlowValueTypeMap)
|
||||||
|
.slice(0, -2)
|
||||||
|
.map((item) => ({
|
||||||
|
label: t(item.label),
|
||||||
|
value: item.value
|
||||||
|
}));
|
||||||
|
|
||||||
const { register, getValues, setValue, handleSubmit } = useForm<EditFieldType>({
|
const { register, getValues, setValue, handleSubmit } = useForm<EditFieldType>({
|
||||||
defaultValues: defaultField
|
defaultValues: defaultField
|
||||||
});
|
});
|
||||||
@ -79,39 +83,58 @@ const FieldEditModal = ({
|
|||||||
? t('app.Input Field Settings')
|
? t('app.Input Field Settings')
|
||||||
: t('app.Output Field Settings');
|
: t('app.Output Field Settings');
|
||||||
|
|
||||||
|
const showValueTypeSelect = useMemo(() => {
|
||||||
|
return getValues('type') === FlowNodeInputTypeEnum.target || mode === 'output';
|
||||||
|
}, [getValues, mode, refresh]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal
|
<MyModal isOpen={true} iconSrc="/imgs/module/extract.png" title={title} onClose={onClose}>
|
||||||
isOpen={true}
|
|
||||||
title={
|
|
||||||
<Flex alignItems={'center'}>
|
|
||||||
<Avatar src={'/imgs/module/extract.png'} mr={2} w={'20px'} objectFit={'cover'} />
|
|
||||||
{title}
|
|
||||||
</Flex>
|
|
||||||
}
|
|
||||||
onClose={onClose}
|
|
||||||
>
|
|
||||||
<ModalBody minH={'260px'} overflow={'visible'}>
|
<ModalBody minH={'260px'} overflow={'visible'}>
|
||||||
{mode === 'input' && (
|
{/* input type select: target, input, textarea.... */}
|
||||||
|
{mode === 'pluginInput' && (
|
||||||
<Flex alignItems={'center'} mb={5}>
|
<Flex alignItems={'center'} mb={5}>
|
||||||
<Box flex={'0 0 70px'}>必填</Box>
|
<Box flex={'0 0 70px'}>{t('core.module.Input Type')}</Box>
|
||||||
|
<MySelect
|
||||||
|
w={'288px'}
|
||||||
|
list={inputTypeList}
|
||||||
|
value={getValues('type')}
|
||||||
|
onchange={(e: string) => {
|
||||||
|
const type = e as `${FlowNodeInputTypeEnum}`;
|
||||||
|
const selectedItem = inputTypeList.find((item) => item.value === type);
|
||||||
|
setValue('type', type);
|
||||||
|
setValue('valueType', selectedItem?.valueType);
|
||||||
|
|
||||||
|
if (type === FlowNodeInputTypeEnum.selectDataset) {
|
||||||
|
setValue('label', selectedItem?.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
setRefresh(!refresh);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
{['input', 'pluginInput'].includes(mode) && (
|
||||||
|
<Flex alignItems={'center'} mb={5}>
|
||||||
|
<Box flex={'0 0 70px'}>{t('common.Require Input')}</Box>
|
||||||
<Switch {...register('required')} />
|
<Switch {...register('required')} />
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
{showValueTypeSelect && (
|
||||||
<Flex mb={5} alignItems={'center'}>
|
<Flex mb={5} alignItems={'center'}>
|
||||||
<Box flex={'0 0 70px'}>字段类型</Box>
|
<Box flex={'0 0 70px'}>{t('core.module.Data Type')}</Box>
|
||||||
<MySelect
|
<MySelect
|
||||||
w={'288px'}
|
w={'288px'}
|
||||||
list={typeSelectList}
|
list={dataTypeSelectList}
|
||||||
value={getValues('valueType')}
|
value={getValues('valueType')}
|
||||||
onchange={(e: string) => {
|
onchange={(e: string) => {
|
||||||
const type = e as `${FlowNodeValTypeEnum}`;
|
const type = e as `${ModuleDataTypeEnum}`;
|
||||||
setValue('valueType', type);
|
setValue('valueType', type);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
type === FlowNodeValTypeEnum.chatHistory ||
|
type === ModuleDataTypeEnum.chatHistory ||
|
||||||
type === FlowNodeValTypeEnum.datasetQuote
|
type === ModuleDataTypeEnum.datasetQuote
|
||||||
) {
|
) {
|
||||||
const label = typeSelectList.find((item) => item.value === type)?.label;
|
const label = dataTypeSelectList.find((item) => item.value === type)?.label;
|
||||||
setValue('label', label);
|
setValue('label', label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,35 +142,54 @@ const FieldEditModal = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
)}
|
||||||
|
|
||||||
<Flex mb={5} alignItems={'center'}>
|
<Flex mb={5} alignItems={'center'}>
|
||||||
<Box flex={'0 0 70px'}>字段名</Box>
|
<Box flex={'0 0 70px'}>{t('core.module.Field Name')}</Box>
|
||||||
<Input
|
<Input
|
||||||
placeholder="预约字段/sql语句……"
|
placeholder="预约字段/sql语句……"
|
||||||
{...register('label', { required: '字段名不能为空' })}
|
{...register('label', { required: '字段名不能为空' })}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex mb={5} alignItems={'center'}>
|
<Flex mb={5} alignItems={'center'}>
|
||||||
<Box flex={'0 0 70px'}>字段 key</Box>
|
<Box flex={'0 0 70px'}>{t('core.module.Field key')}</Box>
|
||||||
<Input
|
<Input
|
||||||
placeholder="appointment/sql"
|
placeholder="appointment/sql"
|
||||||
{...register('key', { required: '字段 key 不能为空' })}
|
{...register('key', { required: '字段 key 不能为空' })}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex mb={5} alignItems={'flex-start'}>
|
<Flex mb={5} alignItems={'flex-start'}>
|
||||||
<Box flex={'0 0 70px'}>字段描述</Box>
|
<Box flex={'0 0 70px'}>{t('core.module.Field Description')}</Box>
|
||||||
<Textarea placeholder="可选" rows={3} {...register('description')} />
|
<Textarea placeholder="可选" rows={3} {...register('description')} />
|
||||||
</Flex>
|
</Flex>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant={'base'} mr={3} onClick={onClose}>
|
<Button variant={'base'} mr={3} onClick={onClose}>
|
||||||
取消
|
{t('common.Close')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={handleSubmit(onSubmit)}>确认</Button>
|
<Button onClick={handleSubmit(onSubmit)}>{t('common.Confirm')}</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</MyModal>
|
</MyModal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default React.memo(FieldEditModal);
|
export default React.memo(FieldEditModal);
|
||||||
|
|
||||||
|
export const defaultInputField: EditFieldType = {
|
||||||
|
label: '',
|
||||||
|
key: '',
|
||||||
|
description: '',
|
||||||
|
type: FlowNodeInputTypeEnum.target,
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
required: true,
|
||||||
|
createSign: true
|
||||||
|
};
|
||||||
|
export const defaultOutputField: EditFieldType = {
|
||||||
|
label: '',
|
||||||
|
key: '',
|
||||||
|
description: '',
|
||||||
|
valueType: ModuleDataTypeEnum.string,
|
||||||
|
required: true,
|
||||||
|
createSign: true
|
||||||
|
};
|
||||||
|
|||||||
@ -9,14 +9,13 @@ import { useTranslation } from 'next-i18next';
|
|||||||
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
|
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
|
||||||
import { useToast } from '@/web/common/hooks/useToast';
|
import { useToast } from '@/web/common/hooks/useToast';
|
||||||
import { useFlowProviderStore, onChangeNode } from '../../FlowProvider';
|
import { useFlowProviderStore, onChangeNode } from '../../FlowProvider';
|
||||||
import {
|
import { FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||||
FlowNodeSpecialInputKeyEnum,
|
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||||
FlowNodeTypeEnum
|
|
||||||
} from '@fastgpt/global/core/module/node/constant';
|
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
import { getPluginModuleDetail } from '@/web/core/plugin/api';
|
import { getPreviewPluginModule } from '@/web/core/plugin/api';
|
||||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||||
import { useConfirm } from '@/web/common/hooks/useConfirm';
|
import { useConfirm } from '@/web/common/hooks/useConfirm';
|
||||||
|
import { LOGO_ICON } from '@fastgpt/global/core/chat/constants';
|
||||||
|
|
||||||
type Props = FlowModuleItemType & {
|
type Props = FlowModuleItemType & {
|
||||||
children?: React.ReactNode | React.ReactNode[] | string;
|
children?: React.ReactNode | React.ReactNode[] | string;
|
||||||
@ -27,9 +26,9 @@ type Props = FlowModuleItemType & {
|
|||||||
const NodeCard = (props: Props) => {
|
const NodeCard = (props: Props) => {
|
||||||
const {
|
const {
|
||||||
children,
|
children,
|
||||||
logo = '/icon/logo.svg',
|
avatar = LOGO_ICON,
|
||||||
name = '未知模块',
|
name = '未知模块',
|
||||||
description,
|
intro,
|
||||||
minW = '300px',
|
minW = '300px',
|
||||||
moduleId,
|
moduleId,
|
||||||
flowType,
|
flowType,
|
||||||
@ -59,14 +58,13 @@ const NodeCard = (props: Props) => {
|
|||||||
icon: 'common/refreshLight',
|
icon: 'common/refreshLight',
|
||||||
label: t('plugin.Synchronous version'),
|
label: t('plugin.Synchronous version'),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const pluginId = inputs.find(
|
const pluginId = inputs.find((item) => item.key === ModuleInputKeyEnum.pluginId)
|
||||||
(item) => item.key === FlowNodeSpecialInputKeyEnum.pluginId
|
?.value;
|
||||||
)?.value;
|
|
||||||
if (!pluginId) return;
|
if (!pluginId) return;
|
||||||
openConfirm(async () => {
|
openConfirm(async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const pluginModule = await getPluginModuleDetail(pluginId);
|
const pluginModule = await getPreviewPluginModule(pluginId);
|
||||||
onResetNode(moduleId, pluginModule);
|
onResetNode(moduleId, pluginModule);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return toast({
|
return toast({
|
||||||
@ -147,18 +145,13 @@ const NodeCard = (props: Props) => {
|
|||||||
className={isPreview ? 'nodrag' : ''}
|
className={isPreview ? 'nodrag' : ''}
|
||||||
>
|
>
|
||||||
<Flex className="custom-drag-handle" px={4} py={3} alignItems={'center'}>
|
<Flex className="custom-drag-handle" px={4} py={3} alignItems={'center'}>
|
||||||
<Avatar src={logo} borderRadius={'md'} objectFit={'contain'} w={'30px'} h={'30px'} />
|
<Avatar src={avatar} borderRadius={'md'} objectFit={'contain'} w={'30px'} h={'30px'} />
|
||||||
<Box ml={3} fontSize={'lg'} color={'myGray.600'}>
|
<Box ml={3} fontSize={'lg'} color={'myGray.600'}>
|
||||||
{name}
|
{name}
|
||||||
</Box>
|
</Box>
|
||||||
{description && (
|
{intro && (
|
||||||
<MyTooltip label={description} forceShow>
|
<MyTooltip label={intro} forceShow>
|
||||||
<QuestionOutlineIcon
|
<QuestionOutlineIcon display={['none', 'inline']} mb={'1px'} ml={1} />
|
||||||
display={['none', 'inline']}
|
|
||||||
transform={'translateY(1px)'}
|
|
||||||
mb={'1px'}
|
|
||||||
ml={1}
|
|
||||||
/>
|
|
||||||
</MyTooltip>
|
</MyTooltip>
|
||||||
)}
|
)}
|
||||||
<Box flex={1} />
|
<Box flex={1} />
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import React, { useCallback, useMemo } from 'react';
|
|||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import MySelect from '@/components/Select';
|
import MySelect from '@/components/Select';
|
||||||
import { TTSTypeEnum } from '@/constants/app';
|
import { TTSTypeEnum } from '@/constants/app';
|
||||||
import { AppTTSConfigType } from '@/types/app';
|
import type { AppTTSConfigType } from '@fastgpt/global/core/module/type.d';
|
||||||
import { useAudioPlay } from '@/web/common/utils/voice';
|
import { useAudioPlay } from '@/web/common/utils/voice';
|
||||||
import { audioSpeechModels } from '@/web/common/system/staticData';
|
import { audioSpeechModels } from '@/web/common/system/staticData';
|
||||||
import MyModal from '@/components/MyModal';
|
import MyModal from '@/components/MyModal';
|
||||||
@ -0,0 +1,342 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
ModalFooter,
|
||||||
|
ModalBody,
|
||||||
|
NumberInput,
|
||||||
|
NumberInputField,
|
||||||
|
NumberInputStepper,
|
||||||
|
NumberIncrementStepper,
|
||||||
|
NumberDecrementStepper,
|
||||||
|
Flex,
|
||||||
|
Switch,
|
||||||
|
Input,
|
||||||
|
Grid,
|
||||||
|
FormControl,
|
||||||
|
useTheme,
|
||||||
|
Image,
|
||||||
|
Table,
|
||||||
|
Thead,
|
||||||
|
Tbody,
|
||||||
|
Tr,
|
||||||
|
Th,
|
||||||
|
Td,
|
||||||
|
TableContainer,
|
||||||
|
BoxProps,
|
||||||
|
useDisclosure
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons';
|
||||||
|
import { VariableInputEnum } from '@fastgpt/global/core/module/constants';
|
||||||
|
import type { VariableItemType } from '@fastgpt/global/core/module/type.d';
|
||||||
|
import MyIcon from '@/components/Icon';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { useFieldArray } from 'react-hook-form';
|
||||||
|
import { customAlphabet } from 'nanoid';
|
||||||
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
import MyTooltip from '@/components/MyTooltip';
|
||||||
|
import { variableTip } from '@fastgpt/global/core/module/template/tip';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
|
import { useToast } from '@/web/common/hooks/useToast';
|
||||||
|
|
||||||
|
const VariableEdit = ({
|
||||||
|
variables,
|
||||||
|
onChange
|
||||||
|
}: {
|
||||||
|
variables: VariableItemType[];
|
||||||
|
onChange: (data: VariableItemType[]) => void;
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { toast } = useToast();
|
||||||
|
const theme = useTheme();
|
||||||
|
const [refresh, setRefresh] = useState(false);
|
||||||
|
|
||||||
|
const VariableTypeList = [
|
||||||
|
{
|
||||||
|
label: t('core.module.variable.text type'),
|
||||||
|
icon: 'settingLight',
|
||||||
|
key: VariableInputEnum.input
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('core.module.variable.select type'),
|
||||||
|
icon: 'settingLight',
|
||||||
|
key: VariableInputEnum.select
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const { isOpen: isOpenEdit, onOpen: onOpenEdit, onClose: onCloseEdit } = useDisclosure();
|
||||||
|
const {
|
||||||
|
reset: resetEdit,
|
||||||
|
register: registerEdit,
|
||||||
|
getValues: getValuesEdit,
|
||||||
|
setValue: setValuesEdit,
|
||||||
|
control: editVariableController,
|
||||||
|
handleSubmit: handleSubmitEdit
|
||||||
|
} = useForm<{ variable: VariableItemType }>();
|
||||||
|
|
||||||
|
const {
|
||||||
|
fields: selectEnums,
|
||||||
|
append: appendEnums,
|
||||||
|
remove: removeEnums
|
||||||
|
} = useFieldArray({
|
||||||
|
control: editVariableController,
|
||||||
|
name: 'variable.enums'
|
||||||
|
});
|
||||||
|
|
||||||
|
const BoxBtnStyles: BoxProps = {
|
||||||
|
cursor: 'pointer',
|
||||||
|
px: 3,
|
||||||
|
py: '2px',
|
||||||
|
borderRadius: 'md',
|
||||||
|
_hover: {
|
||||||
|
bg: 'myGray.200'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Flex alignItems={'center'}>
|
||||||
|
<Image alt={''} src={'/imgs/module/variable.png'} objectFit={'contain'} w={'18px'} />
|
||||||
|
<Box ml={2} flex={1}>
|
||||||
|
{t('core.module.Variable')}
|
||||||
|
<MyTooltip label={variableTip} forceShow>
|
||||||
|
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
|
||||||
|
</MyTooltip>
|
||||||
|
</Box>
|
||||||
|
<Flex
|
||||||
|
{...BoxBtnStyles}
|
||||||
|
onClick={() => {
|
||||||
|
resetEdit({ variable: addVariable() });
|
||||||
|
onOpenEdit();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
+ {t('common.Add New')}
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
{variables.length > 0 && (
|
||||||
|
<Box mt={2} borderRadius={'lg'} overflow={'hidden'} borderWidth={'1px'} borderBottom="none">
|
||||||
|
<TableContainer>
|
||||||
|
<Table bg={'white'}>
|
||||||
|
<Thead>
|
||||||
|
<Tr>
|
||||||
|
<Th>{t('core.module.variable.variable name')}</Th>
|
||||||
|
<Th>{t('core.module.variable.key')}</Th>
|
||||||
|
<Th>{t('common.Require Input')}</Th>
|
||||||
|
<Th></Th>
|
||||||
|
</Tr>
|
||||||
|
</Thead>
|
||||||
|
<Tbody>
|
||||||
|
{variables.map((item, index) => (
|
||||||
|
<Tr key={item.id}>
|
||||||
|
<Td>{item.label} </Td>
|
||||||
|
<Td>{item.key}</Td>
|
||||||
|
<Td>{item.required ? '✔' : ''}</Td>
|
||||||
|
<Td>
|
||||||
|
<MyIcon
|
||||||
|
mr={3}
|
||||||
|
name={'settingLight'}
|
||||||
|
w={'16px'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
onClick={() => {
|
||||||
|
resetEdit({ variable: item });
|
||||||
|
onOpenEdit();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<MyIcon
|
||||||
|
name={'delete'}
|
||||||
|
w={'16px'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
onClick={() =>
|
||||||
|
onChange(variables.filter((variable) => variable.id !== item.id))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
</Tr>
|
||||||
|
))}
|
||||||
|
</Tbody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<MyModal
|
||||||
|
iconSrc="/imgs/module/variable.png"
|
||||||
|
title={t('core.module.Variable Setting')}
|
||||||
|
isOpen={isOpenEdit}
|
||||||
|
onClose={onCloseEdit}
|
||||||
|
>
|
||||||
|
<ModalBody>
|
||||||
|
<Flex alignItems={'center'}>
|
||||||
|
<Box w={'70px'}>{t('common.Require Input')}</Box>
|
||||||
|
<Switch {...registerEdit('variable.required')} />
|
||||||
|
</Flex>
|
||||||
|
<Flex mt={5} alignItems={'center'}>
|
||||||
|
<Box w={'80px'}>{t('core.module.variable.variable name')}</Box>
|
||||||
|
<Input
|
||||||
|
{...registerEdit('variable.label', {
|
||||||
|
required: t('core.module.variable.variable name is required')
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
<Flex mt={5} alignItems={'center'}>
|
||||||
|
<Box w={'80px'}>{t('core.module.variable.key')}</Box>
|
||||||
|
<Input
|
||||||
|
{...registerEdit('variable.key', {
|
||||||
|
required: t('core.module.variable.key is required')
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Box mt={5} mb={2}>
|
||||||
|
{t('core.module.Field Type')}
|
||||||
|
</Box>
|
||||||
|
<Grid gridTemplateColumns={'repeat(2,130px)'} gridGap={4}>
|
||||||
|
{VariableTypeList.map((item) => (
|
||||||
|
<Flex
|
||||||
|
key={item.key}
|
||||||
|
px={4}
|
||||||
|
py={1}
|
||||||
|
border={theme.borders.base}
|
||||||
|
borderRadius={'md'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
{...(item.key === getValuesEdit('variable.type')
|
||||||
|
? {
|
||||||
|
bg: 'myWhite.600'
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
_hover: {
|
||||||
|
boxShadow: 'md'
|
||||||
|
},
|
||||||
|
onClick: () => {
|
||||||
|
setValuesEdit('variable.type', item.key);
|
||||||
|
setRefresh(!refresh);
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<MyIcon name={item.icon as any} w={'16px'} />
|
||||||
|
<Box ml={3}>{item.label}</Box>
|
||||||
|
</Flex>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{getValuesEdit('variable.type') === VariableInputEnum.input && (
|
||||||
|
<>
|
||||||
|
<Box mt={5} mb={2}>
|
||||||
|
{t('core.module.variable.text max length')}
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<NumberInput max={100} min={1} step={1} position={'relative'}>
|
||||||
|
<NumberInputField
|
||||||
|
{...registerEdit('variable.maxLen', {
|
||||||
|
min: 1,
|
||||||
|
max: 100,
|
||||||
|
valueAsNumber: true
|
||||||
|
})}
|
||||||
|
max={100}
|
||||||
|
/>
|
||||||
|
<NumberInputStepper>
|
||||||
|
<NumberIncrementStepper />
|
||||||
|
<NumberDecrementStepper />
|
||||||
|
</NumberInputStepper>
|
||||||
|
</NumberInput>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{getValuesEdit('variable.type') === VariableInputEnum.select && (
|
||||||
|
<>
|
||||||
|
<Box mt={5} mb={2}>
|
||||||
|
{t('core.module.variable.variable options')}
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
{selectEnums.map((item, i) => (
|
||||||
|
<Flex key={item.id} mb={2} alignItems={'center'}>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
{...registerEdit(`variable.enums.${i}.value`, {
|
||||||
|
required: t('core.module.variable.variable option is value is required')
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<MyIcon
|
||||||
|
ml={3}
|
||||||
|
name={'delete'}
|
||||||
|
w={'16px'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
p={2}
|
||||||
|
borderRadius={'lg'}
|
||||||
|
_hover={{ bg: 'red.100' }}
|
||||||
|
onClick={() => removeEnums(i)}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
<Button
|
||||||
|
variant={'solid'}
|
||||||
|
w={'100%'}
|
||||||
|
textAlign={'left'}
|
||||||
|
leftIcon={<SmallAddIcon />}
|
||||||
|
bg={'myGray.100 !important'}
|
||||||
|
onClick={() => appendEnums({ value: '' })}
|
||||||
|
>
|
||||||
|
{t('core.module.variable add option')}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
|
<ModalFooter>
|
||||||
|
<Button variant={'base'} mr={3} onClick={onCloseEdit}>
|
||||||
|
{t('common.Close')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleSubmitEdit(({ variable }) => {
|
||||||
|
// check select
|
||||||
|
if (variable.type === VariableInputEnum.select) {
|
||||||
|
const enums = variable.enums.filter((item) => item.value);
|
||||||
|
if (enums.length === 0) {
|
||||||
|
toast({
|
||||||
|
status: 'warning',
|
||||||
|
title: t('core.module.variable.variable option is required')
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const onChangeVariable = [...variables];
|
||||||
|
// update
|
||||||
|
if (variable.id) {
|
||||||
|
const index = variables.findIndex((item) => item.id === variable.id);
|
||||||
|
onChangeVariable[index] = variable;
|
||||||
|
} else {
|
||||||
|
onChangeVariable.push({
|
||||||
|
...variable,
|
||||||
|
id: nanoid()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onChange(onChangeVariable);
|
||||||
|
onCloseEdit();
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{getValuesEdit('variable.id') ? t('common.Confirm Update') : t('common.Add New')}
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</MyModal>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default React.memo(VariableEdit);
|
||||||
|
|
||||||
|
export const defaultVariable: VariableItemType = {
|
||||||
|
id: nanoid(),
|
||||||
|
key: 'key',
|
||||||
|
label: 'label',
|
||||||
|
type: VariableInputEnum.input,
|
||||||
|
required: true,
|
||||||
|
maxLen: 50,
|
||||||
|
enums: [{ value: '' }]
|
||||||
|
};
|
||||||
|
export const addVariable = () => {
|
||||||
|
const newVariable = { ...defaultVariable, key: nanoid(), id: '' };
|
||||||
|
return newVariable;
|
||||||
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NodeProps } from 'reactflow';
|
import { NodeProps } from 'reactflow';
|
||||||
import { Box, Input, Button, Flex, Textarea } from '@chakra-ui/react';
|
import { Box, Button, Flex, Textarea } from '@chakra-ui/react';
|
||||||
import NodeCard from '../modules/NodeCard';
|
import NodeCard from '../modules/NodeCard';
|
||||||
import { FlowModuleItemType } from '@fastgpt/global/core/module/type.d';
|
import { FlowModuleItemType } from '@fastgpt/global/core/module/type.d';
|
||||||
import Divider from '../modules/Divider';
|
import Divider from '../modules/Divider';
|
||||||
@ -10,11 +10,8 @@ import type { ClassifyQuestionAgentItemType } from '@fastgpt/global/core/module/
|
|||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 4);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 4);
|
||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
import {
|
import { FlowNodeOutputTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||||
FlowNodeOutputTypeEnum,
|
import { ModuleDataTypeEnum, ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||||
FlowNodeValTypeEnum,
|
|
||||||
FlowNodeSpecialInputKeyEnum
|
|
||||||
} from '@fastgpt/global/core/module/node/constant';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import SourceHandle from '../render/SourceHandle';
|
import SourceHandle from '../render/SourceHandle';
|
||||||
import MyTooltip from '@/components/MyTooltip';
|
import MyTooltip from '@/components/MyTooltip';
|
||||||
@ -32,7 +29,7 @@ const NodeCQNode = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||||||
moduleId={moduleId}
|
moduleId={moduleId}
|
||||||
flowInputList={inputs}
|
flowInputList={inputs}
|
||||||
CustomComponent={{
|
CustomComponent={{
|
||||||
[FlowNodeSpecialInputKeyEnum.agents]: ({
|
[ModuleInputKeyEnum.agents]: ({
|
||||||
key: agentKey,
|
key: agentKey,
|
||||||
value: agents = [],
|
value: agents = [],
|
||||||
...props
|
...props
|
||||||
@ -100,7 +97,7 @@ const NodeCQNode = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<SourceHandle handleKey={item.key} valueType={FlowNodeValTypeEnum.boolean} />
|
<SourceHandle handleKey={item.key} valueType={ModuleDataTypeEnum.boolean} />
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -12,11 +12,9 @@ import type { ContextExtractAgentItemType } from '@fastgpt/global/core/module/ty
|
|||||||
import RenderOutput from '../render/RenderOutput';
|
import RenderOutput from '../render/RenderOutput';
|
||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
import ExtractFieldModal from '../modules/ExtractFieldModal';
|
import ExtractFieldModal from '../modules/ExtractFieldModal';
|
||||||
import { ContextExtractEnum } from '@/constants/flow/flowField';
|
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||||
import {
|
import { FlowNodeOutputTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||||
FlowNodeOutputTypeEnum,
|
import { ModuleDataTypeEnum } from '@fastgpt/global/core/module/constants';
|
||||||
FlowNodeValTypeEnum
|
|
||||||
} from '@fastgpt/global/core/module/node/constant';
|
|
||||||
import { useFlowProviderStore, onChangeNode } from '../../FlowProvider';
|
import { useFlowProviderStore, onChangeNode } from '../../FlowProvider';
|
||||||
|
|
||||||
const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
||||||
@ -33,7 +31,7 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||||||
moduleId={moduleId}
|
moduleId={moduleId}
|
||||||
flowInputList={inputs}
|
flowInputList={inputs}
|
||||||
CustomComponent={{
|
CustomComponent={{
|
||||||
[ContextExtractEnum.extractKeys]: ({
|
[ModuleInputKeyEnum.extractKeys]: ({
|
||||||
value: extractKeys = [],
|
value: extractKeys = [],
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
@ -94,7 +92,7 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||||||
onChangeNode({
|
onChangeNode({
|
||||||
moduleId,
|
moduleId,
|
||||||
type: 'updateInput',
|
type: 'updateInput',
|
||||||
key: ContextExtractEnum.extractKeys,
|
key: ModuleInputKeyEnum.extractKeys,
|
||||||
value: {
|
value: {
|
||||||
...props,
|
...props,
|
||||||
value: extractKeys.filter((extract) => item.key !== extract.key)
|
value: extractKeys.filter((extract) => item.key !== extract.key)
|
||||||
@ -130,7 +128,7 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||||||
onClose={() => setEditExtractField(undefined)}
|
onClose={() => setEditExtractField(undefined)}
|
||||||
onSubmit={(data) => {
|
onSubmit={(data) => {
|
||||||
const extracts: ContextExtractAgentItemType[] =
|
const extracts: ContextExtractAgentItemType[] =
|
||||||
inputs.find((item) => item.key === ContextExtractEnum.extractKeys)?.value || [];
|
inputs.find((item) => item.key === ModuleInputKeyEnum.extractKeys)?.value || [];
|
||||||
|
|
||||||
const exists = extracts.find((item) => item.key === editExtractFiled.key);
|
const exists = extracts.find((item) => item.key === editExtractFiled.key);
|
||||||
|
|
||||||
@ -141,9 +139,9 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||||||
onChangeNode({
|
onChangeNode({
|
||||||
moduleId,
|
moduleId,
|
||||||
type: 'updateInput',
|
type: 'updateInput',
|
||||||
key: ContextExtractEnum.extractKeys,
|
key: ModuleInputKeyEnum.extractKeys,
|
||||||
value: {
|
value: {
|
||||||
...inputs.find((input) => input.key === ContextExtractEnum.extractKeys),
|
...inputs.find((input) => input.key === ModuleInputKeyEnum.extractKeys),
|
||||||
value: newInputs
|
value: newInputs
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -152,7 +150,7 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||||||
key: data.key,
|
key: data.key,
|
||||||
label: `提取结果-${data.desc}`,
|
label: `提取结果-${data.desc}`,
|
||||||
description: '无法提取时不会返回',
|
description: '无法提取时不会返回',
|
||||||
valueType: FlowNodeValTypeEnum.string,
|
valueType: ModuleDataTypeEnum.string,
|
||||||
type: FlowNodeOutputTypeEnum.source,
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
targets: []
|
targets: []
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,9 +11,9 @@ import RenderOutput from '../render/RenderOutput';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
FlowNodeInputTypeEnum,
|
FlowNodeInputTypeEnum,
|
||||||
FlowNodeOutputTypeEnum,
|
FlowNodeOutputTypeEnum
|
||||||
FlowNodeValTypeEnum
|
|
||||||
} from '@fastgpt/global/core/module/node/constant';
|
} from '@fastgpt/global/core/module/node/constant';
|
||||||
|
import { ModuleDataTypeEnum } from '@fastgpt/global/core/module/constants';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
||||||
import { onChangeNode } from '../../FlowProvider';
|
import { onChangeNode } from '../../FlowProvider';
|
||||||
@ -37,7 +37,7 @@ const NodeHttp = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||||||
key,
|
key,
|
||||||
value: {
|
value: {
|
||||||
key,
|
key,
|
||||||
valueType: FlowNodeValTypeEnum.string,
|
valueType: ModuleDataTypeEnum.string,
|
||||||
type: FlowNodeInputTypeEnum.target,
|
type: FlowNodeInputTypeEnum.target,
|
||||||
label: `入参${inputs.length - 1}`,
|
label: `入参${inputs.length - 1}`,
|
||||||
edit: true
|
edit: true
|
||||||
@ -62,7 +62,7 @@ const NodeHttp = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||||||
value: {
|
value: {
|
||||||
key: nanoid(),
|
key: nanoid(),
|
||||||
label: `出参${outputs.length}`,
|
label: `出参${outputs.length}`,
|
||||||
valueType: FlowNodeValTypeEnum.string,
|
valueType: ModuleDataTypeEnum.string,
|
||||||
type: FlowNodeOutputTypeEnum.source,
|
type: FlowNodeOutputTypeEnum.source,
|
||||||
edit: true,
|
edit: true,
|
||||||
targets: []
|
targets: []
|
||||||
|
|||||||