mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-18 17:51:24 +00:00
4.8 preview (#1288)
* Revert "lafAccount add pat & re request when token invalid (#76)" (#77) This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be. * perf: workflow ux * system config * Newflow (#89) * docs: Add doc for Xinference (#1266) Signed-off-by: Carson Yang <yangchuansheng33@gmail.com> * Revert "lafAccount add pat & re request when token invalid (#76)" (#77) This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be. * perf: workflow ux * system config * Revert "lafAccount add pat & re request when token invalid (#76)" (#77) This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be. * Revert "lafAccount add pat & re request when token invalid (#76)" (#77) This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be. * Revert "lafAccount add pat & re request when token invalid (#76)" (#77) This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be. * rename code * move code * update flow * input type selector * perf: workflow runtime * feat: node adapt newflow * feat: adapt plugin * feat: 360 connection * check workflow * perf: flow 性能 * change plugin input type (#81) * change plugin input type * plugin label mode * perf: nodecard * debug * perf: debug ui * connection ui * change workflow ui (#82) * feat: workflow debug * adapt openAPI for new workflow (#83) * adapt openAPI for new workflow * i18n * perf: plugin debug * plugin input ui * delete * perf: global variable select * fix rebase * perf: workflow performance * feat: input render type icon * input icon * adapt flow (#84) * adapt newflow * temp * temp * fix * feat: app schedule trigger * feat: app schedule trigger * perf: schedule ui * feat: ioslatevm run js code * perf: workflow varialbe table ui * feat: adapt simple mode * feat: adapt input params * output * feat: adapt tamplate * fix: ts * add if-else module (#86) * perf: worker * if else node * perf: tiktoken worker * fix: ts * perf: tiktoken * fix if-else node (#87) * fix if-else node * type * fix * perf: audio render * perf: Parallel worker * log * perf: if else node * adapt plugin * prompt * perf: reference ui * reference ui * handle ux * template ui and plugin tool * adapt v1 workflow * adapt v1 workflow completions * perf: time variables * feat: workflow keyboard shortcuts * adapt v1 workflow * update workflow example doc (#88) * fix: simple mode select tool --------- Signed-off-by: Carson Yang <yangchuansheng33@gmail.com> Co-authored-by: Carson Yang <yangchuansheng33@gmail.com> Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com> * doc * perf: extract node * extra node field * update plugin version * doc * variable * change doc & fix prompt editor (#90) * fold workflow code * value type label --------- Signed-off-by: Carson Yang <yangchuansheng33@gmail.com> Co-authored-by: Carson Yang <yangchuansheng33@gmail.com> Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
22
packages/global/core/workflow/api.d.ts
vendored
Normal file
22
packages/global/core/workflow/api.d.ts
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import { VectorModelItemType } from '../ai/model.d';
|
||||
import { NodeInputKeyEnum } from './constants';
|
||||
|
||||
export type SelectedDatasetType = { datasetId: string; vectorModel: VectorModelItemType }[];
|
||||
|
||||
export type HttpBodyType<T = Record<string, any>> = {
|
||||
[NodeInputKeyEnum.addInputParam]: Record<string, any>;
|
||||
} & T;
|
||||
export type HttpQueryType = {
|
||||
appId: string;
|
||||
chatId?: string;
|
||||
responseChatItemId?: string;
|
||||
variables: Record<string, any>;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
/* http node */
|
||||
export type HttpParamAndHeaderItemType = {
|
||||
key: string;
|
||||
type: string;
|
||||
value: string;
|
||||
};
|
175
packages/global/core/workflow/constants.ts
Normal file
175
packages/global/core/workflow/constants.ts
Normal file
@@ -0,0 +1,175 @@
|
||||
export enum FlowNodeTemplateTypeEnum {
|
||||
systemInput = 'systemInput',
|
||||
tools = 'tools',
|
||||
textAnswer = 'textAnswer',
|
||||
functionCall = 'functionCall',
|
||||
externalCall = 'externalCall',
|
||||
|
||||
personalPlugin = 'personalPlugin',
|
||||
|
||||
other = 'other'
|
||||
}
|
||||
|
||||
export enum WorkflowIOValueTypeEnum {
|
||||
string = 'string',
|
||||
number = 'number',
|
||||
boolean = 'boolean',
|
||||
any = 'any',
|
||||
|
||||
chatHistory = 'chatHistory',
|
||||
datasetQuote = 'datasetQuote',
|
||||
dynamic = 'dynamic',
|
||||
|
||||
// plugin special type
|
||||
selectApp = 'selectApp',
|
||||
selectDataset = 'selectDataset',
|
||||
|
||||
// tool
|
||||
tools = 'tools'
|
||||
}
|
||||
|
||||
/* reg: modulename key */
|
||||
export enum NodeInputKeyEnum {
|
||||
// old
|
||||
welcomeText = 'welcomeText',
|
||||
switch = 'switch', // a trigger switch
|
||||
history = 'history',
|
||||
userChatInput = 'userChatInput',
|
||||
answerText = 'text',
|
||||
|
||||
// system config
|
||||
questionGuide = 'questionGuide',
|
||||
tts = 'tts',
|
||||
whisper = 'whisper',
|
||||
variables = 'variables',
|
||||
scheduleTrigger = 'scheduleTrigger',
|
||||
|
||||
agents = 'agents', // cq agent key
|
||||
|
||||
// latest
|
||||
// common
|
||||
aiModel = 'model',
|
||||
aiSystemPrompt = 'systemPrompt',
|
||||
description = 'description',
|
||||
anyInput = 'system_anyInput',
|
||||
textareaInput = 'system_textareaInput',
|
||||
addInputParam = 'system_addInputParam',
|
||||
|
||||
// history
|
||||
historyMaxAmount = 'maxContext',
|
||||
|
||||
// ai chat
|
||||
aiChatTemperature = 'temperature',
|
||||
aiChatMaxToken = 'maxToken',
|
||||
aiChatSettingModal = 'aiSettings',
|
||||
aiChatIsResponseText = 'isResponseAnswerText',
|
||||
aiChatQuoteTemplate = 'quoteTemplate',
|
||||
aiChatQuotePrompt = 'quotePrompt',
|
||||
aiChatDatasetQuote = 'quoteQA',
|
||||
|
||||
// dataset
|
||||
datasetSelectList = 'datasets',
|
||||
datasetSimilarity = 'similarity',
|
||||
datasetMaxTokens = 'limit',
|
||||
datasetSearchMode = 'searchMode',
|
||||
datasetSearchUsingReRank = 'usingReRank',
|
||||
datasetSearchUsingExtensionQuery = 'datasetSearchUsingExtensionQuery',
|
||||
datasetSearchExtensionModel = 'datasetSearchExtensionModel',
|
||||
datasetSearchExtensionBg = 'datasetSearchExtensionBg',
|
||||
|
||||
// context extract
|
||||
contextExtractInput = 'content',
|
||||
extractKeys = 'extractKeys',
|
||||
|
||||
// http
|
||||
httpReqUrl = 'system_httpReqUrl',
|
||||
httpHeaders = 'system_httpHeader',
|
||||
httpMethod = 'system_httpMethod',
|
||||
httpParams = 'system_httpParams',
|
||||
httpJsonBody = 'system_httpJsonBody',
|
||||
abandon_httpUrl = 'url',
|
||||
|
||||
// app
|
||||
runAppSelectApp = 'app',
|
||||
|
||||
// plugin
|
||||
pluginId = 'pluginId',
|
||||
pluginStart = 'pluginStart',
|
||||
|
||||
// if else
|
||||
condition = 'condition',
|
||||
ifElseList = 'ifElseList'
|
||||
}
|
||||
|
||||
export enum NodeOutputKeyEnum {
|
||||
// common
|
||||
userChatInput = 'userChatInput',
|
||||
history = 'history',
|
||||
answerText = 'answerText', // module answer. the value will be show and save to history
|
||||
success = 'success',
|
||||
failed = 'failed',
|
||||
text = 'system_text',
|
||||
addOutputParam = 'system_addOutputParam',
|
||||
|
||||
// dataset
|
||||
datasetQuoteQA = 'quoteQA',
|
||||
|
||||
// classify
|
||||
cqResult = 'cqResult',
|
||||
// context extract
|
||||
contextExtractFields = 'fields',
|
||||
|
||||
// tf switch
|
||||
resultTrue = 'system_resultTrue',
|
||||
resultFalse = 'system_resultFalse',
|
||||
|
||||
// tools
|
||||
selectedTools = 'selectedTools',
|
||||
|
||||
// http
|
||||
httpRawResponse = 'httpRawResponse',
|
||||
|
||||
// plugin
|
||||
pluginStart = 'pluginStart',
|
||||
|
||||
if = 'IF',
|
||||
else = 'ELSE'
|
||||
}
|
||||
|
||||
export enum VariableInputEnum {
|
||||
input = 'input',
|
||||
textarea = 'textarea',
|
||||
select = 'select',
|
||||
external = 'external'
|
||||
}
|
||||
export const variableMap = {
|
||||
[VariableInputEnum.input]: {
|
||||
icon: 'core/app/variable/input',
|
||||
title: 'core.module.variable.input type',
|
||||
desc: ''
|
||||
},
|
||||
[VariableInputEnum.textarea]: {
|
||||
icon: 'core/app/variable/textarea',
|
||||
title: 'core.module.variable.textarea type',
|
||||
desc: '允许用户最多输入4000字的对话框。'
|
||||
},
|
||||
[VariableInputEnum.select]: {
|
||||
icon: 'core/app/variable/select',
|
||||
title: 'core.module.variable.select type',
|
||||
desc: ''
|
||||
},
|
||||
[VariableInputEnum.external]: {
|
||||
icon: 'core/app/variable/external',
|
||||
title: 'core.module.variable.External type',
|
||||
desc: '可以通过API接口或分享链接的Query传递变量。增加该类型变量的主要目的是用于变量提示。使用例子: 你可以通过分享链接Query中拼接Token,来实现内部系统身份鉴权。'
|
||||
}
|
||||
};
|
||||
|
||||
export const DYNAMIC_INPUT_REFERENCE_KEY = 'DYNAMIC_INPUT_REFERENCE_KEY';
|
||||
|
||||
/* run time */
|
||||
export enum RuntimeEdgeStatusEnum {
|
||||
'waiting' = 'waiting',
|
||||
'active' = 'active',
|
||||
'skipped' = 'skipped'
|
||||
}
|
118
packages/global/core/workflow/node/constant.ts
Normal file
118
packages/global/core/workflow/node/constant.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
export enum FlowNodeInputTypeEnum { // render ui
|
||||
reference = 'reference', // reference to other node output
|
||||
input = 'input', // one line input
|
||||
numberInput = 'numberInput',
|
||||
switch = 'switch', // true/false
|
||||
|
||||
// editor
|
||||
textarea = 'textarea',
|
||||
JSONEditor = 'JSONEditor',
|
||||
|
||||
addInputParam = 'addInputParam', // params input
|
||||
|
||||
// special input
|
||||
selectApp = 'selectApp',
|
||||
|
||||
// ai model select
|
||||
selectLLMModel = 'selectLLMModel',
|
||||
settingLLMModel = 'settingLLMModel',
|
||||
|
||||
// dataset special input
|
||||
selectDataset = 'selectDataset',
|
||||
selectDatasetParamsModal = 'selectDatasetParamsModal',
|
||||
settingDatasetQuotePrompt = 'settingDatasetQuotePrompt',
|
||||
|
||||
select = 'select',
|
||||
|
||||
hidden = 'hidden',
|
||||
custom = 'custom'
|
||||
}
|
||||
export const FlowNodeInputMap: Record<
|
||||
FlowNodeInputTypeEnum,
|
||||
{
|
||||
icon: string;
|
||||
}
|
||||
> = {
|
||||
[FlowNodeInputTypeEnum.reference]: {
|
||||
icon: 'core/workflow/inputType/reference'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.input]: {
|
||||
icon: 'core/workflow/inputType/input'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.numberInput]: {
|
||||
icon: 'core/workflow/inputType/numberInput'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.select]: {
|
||||
icon: 'core/workflow/inputType/input'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.switch]: {
|
||||
icon: 'core/workflow/inputType/switch'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.textarea]: {
|
||||
icon: 'core/workflow/inputType/textarea'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.JSONEditor]: {
|
||||
icon: 'core/workflow/inputType/jsonEditor'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.addInputParam]: {
|
||||
icon: 'core/workflow/inputType/dynamic'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.selectApp]: {
|
||||
icon: 'core/workflow/inputType/selectApp'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.selectLLMModel]: {
|
||||
icon: 'core/workflow/inputType/selectLLM'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.settingLLMModel]: {
|
||||
icon: 'core/workflow/inputType/selectLLM'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.selectDataset]: {
|
||||
icon: 'core/workflow/inputType/selectDataset'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.selectDatasetParamsModal]: {
|
||||
icon: 'core/workflow/inputType/selectDataset'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.settingDatasetQuotePrompt]: {
|
||||
icon: 'core/workflow/inputType/selectDataset'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.hidden]: {
|
||||
icon: 'core/workflow/inputType/select'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.custom]: {
|
||||
icon: 'core/workflow/inputType/select'
|
||||
}
|
||||
};
|
||||
|
||||
export enum FlowNodeOutputTypeEnum {
|
||||
hidden = 'hidden',
|
||||
source = 'source',
|
||||
static = 'static',
|
||||
dynamic = 'dynamic'
|
||||
}
|
||||
|
||||
export enum FlowNodeTypeEnum {
|
||||
emptyNode = 'emptyNode',
|
||||
systemConfig = 'userGuide',
|
||||
globalVariable = 'globalVariable',
|
||||
workflowStart = 'workflowStart',
|
||||
chatNode = 'chatNode',
|
||||
|
||||
datasetSearchNode = 'datasetSearchNode',
|
||||
datasetConcatNode = 'datasetConcatNode',
|
||||
|
||||
answerNode = 'answerNode',
|
||||
classifyQuestion = 'classifyQuestion',
|
||||
contentExtract = 'contentExtract',
|
||||
httpRequest468 = 'httpRequest468',
|
||||
runApp = 'app',
|
||||
pluginModule = 'pluginModule',
|
||||
pluginInput = 'pluginInput',
|
||||
pluginOutput = 'pluginOutput',
|
||||
queryExtension = 'cfr',
|
||||
tools = 'tools',
|
||||
stopTool = 'stopTool',
|
||||
lafModule = 'lafModule',
|
||||
ifElseNode = 'ifElseNode'
|
||||
}
|
||||
|
||||
export const EDGE_TYPE = 'default';
|
39
packages/global/core/workflow/node/type.d.ts
vendored
Normal file
39
packages/global/core/workflow/node/type.d.ts
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
react flow type
|
||||
*/
|
||||
import { FlowNodeInputTypeEnum, FlowNodeOutputTypeEnum, FlowNodeTypeEnum } from './constant';
|
||||
import { WorkflowIOValueTypeEnum, NodeInputKeyEnum, NodeOutputKeyEnum } from '../constants';
|
||||
import { SelectedDatasetType } from '../api';
|
||||
import { LLMModelTypeEnum } from '../../ai/constants';
|
||||
|
||||
/* --------------- edit field ------------------- */
|
||||
export type EditInputFieldMapType = EditOutputFieldMapType & {
|
||||
inputType?: boolean;
|
||||
};
|
||||
export type EditOutputFieldMapType = {
|
||||
key?: boolean;
|
||||
description?: boolean;
|
||||
valueType?: boolean; // output
|
||||
required?: boolean;
|
||||
defaultValue?: boolean;
|
||||
};
|
||||
export type EditNodeFieldType = {
|
||||
inputType?: FlowNodeInputTypeEnum; // input type
|
||||
valueType?: WorkflowIOValueTypeEnum;
|
||||
required?: boolean;
|
||||
key?: string;
|
||||
label?: string;
|
||||
description?: string;
|
||||
isToolInput?: boolean;
|
||||
|
||||
defaultValue?: string;
|
||||
maxLength?: number;
|
||||
max?: number;
|
||||
min?: number;
|
||||
editField?: EditInputFieldMapType;
|
||||
dynamicParamDefaultValue?: {
|
||||
inputType?: FlowNodeInputTypeEnum; // input type
|
||||
valueType?: WorkflowIOValueTypeEnum;
|
||||
required?: boolean;
|
||||
};
|
||||
};
|
29
packages/global/core/workflow/runtime/constants.ts
Normal file
29
packages/global/core/workflow/runtime/constants.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { FlowNodeInputTypeEnum } from '../node/constant';
|
||||
|
||||
export enum SseResponseEventEnum {
|
||||
error = 'error',
|
||||
answer = 'answer', // animation stream
|
||||
fastAnswer = 'fastAnswer', // direct answer text, not animation
|
||||
flowNodeStatus = 'flowNodeStatus', // update node status
|
||||
|
||||
toolCall = 'toolCall', // tool start
|
||||
toolParams = 'toolParams', // tool params return
|
||||
toolResponse = 'toolResponse', // tool response return
|
||||
flowResponses = 'flowResponses' // sse response request
|
||||
}
|
||||
|
||||
export enum DispatchNodeResponseKeyEnum {
|
||||
skipHandleId = 'skipHandleId', // skip handle id
|
||||
nodeResponse = 'responseData', // run node response
|
||||
nodeDispatchUsages = 'nodeDispatchUsages', // the node bill.
|
||||
childrenResponses = 'childrenResponses', // Some nodes make recursive calls that need to be returned
|
||||
toolResponses = 'toolResponses', // The result is passed back to the tool node for use
|
||||
assistantResponses = 'assistantResponses' // assistant response
|
||||
}
|
||||
|
||||
export const needReplaceReferenceInputTypeList = [
|
||||
FlowNodeInputTypeEnum.reference,
|
||||
FlowNodeInputTypeEnum.settingDatasetQuotePrompt,
|
||||
FlowNodeInputTypeEnum.addInputParam,
|
||||
FlowNodeInputTypeEnum.custom
|
||||
] as string[];
|
104
packages/global/core/workflow/runtime/type.d.ts
vendored
Normal file
104
packages/global/core/workflow/runtime/type.d.ts
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
import { ChatNodeUsageType } from '../../../support/wallet/bill/type';
|
||||
import { ChatItemValueItemType, ToolRunResponseItemType } from '../../chat/type';
|
||||
import { FlowNodeInputItemType, FlowNodeOutputItemType } from '../type/io.d';
|
||||
import { StoreNodeItemType } from '../type';
|
||||
import { DispatchNodeResponseKeyEnum } from './constants';
|
||||
import { StoreEdgeItemType } from '../type/edge';
|
||||
import { NodeInputKeyEnum } from '../constants';
|
||||
|
||||
export type RuntimeNodeItemType = {
|
||||
nodeId: StoreNodeItemType['nodeId'];
|
||||
name: StoreNodeItemType['name'];
|
||||
avatar: StoreNodeItemType['avatar'];
|
||||
intro?: StoreNodeItemType['intro'];
|
||||
flowNodeType: StoreNodeItemType['flowNodeType'];
|
||||
showStatus?: StoreNodeItemType['showStatus'];
|
||||
isEntry?: StoreNodeItemType['isEntry'];
|
||||
|
||||
inputs: FlowNodeInputItemType[];
|
||||
outputs: FlowNodeOutputItemType[];
|
||||
|
||||
pluginId?: string;
|
||||
};
|
||||
|
||||
export type RuntimeEdgeItemType = StoreEdgeItemType & {
|
||||
status: 'waiting' | 'active' | 'skipped';
|
||||
};
|
||||
|
||||
export type DispatchNodeResponseType = {
|
||||
// common
|
||||
moduleLogo?: string;
|
||||
runningTime?: number;
|
||||
query?: string;
|
||||
textOutput?: string;
|
||||
|
||||
// bill
|
||||
tokens?: number;
|
||||
model?: string;
|
||||
contextTotalLen?: number;
|
||||
totalPoints?: number;
|
||||
|
||||
// chat
|
||||
temperature?: number;
|
||||
maxToken?: number;
|
||||
quoteList?: SearchDataResponseItemType[];
|
||||
historyPreview?: {
|
||||
obj: `${ChatRoleEnum}`;
|
||||
value: string;
|
||||
}[]; // completion context array. history will slice
|
||||
|
||||
// dataset search
|
||||
similarity?: number;
|
||||
limit?: number;
|
||||
searchMode?: `${DatasetSearchModeEnum}`;
|
||||
searchUsingReRank?: boolean;
|
||||
extensionModel?: string;
|
||||
extensionResult?: string;
|
||||
extensionTokens?: number;
|
||||
|
||||
// cq
|
||||
cqList?: ClassifyQuestionAgentItemType[];
|
||||
cqResult?: string;
|
||||
|
||||
// content extract
|
||||
extractDescription?: string;
|
||||
extractResult?: Record<string, any>;
|
||||
|
||||
// http
|
||||
params?: Record<string, any>;
|
||||
body?: Record<string, any>;
|
||||
headers?: Record<string, any>;
|
||||
httpResult?: Record<string, any>;
|
||||
|
||||
// plugin output
|
||||
pluginOutput?: Record<string, any>;
|
||||
pluginDetail?: ChatHistoryItemResType[];
|
||||
|
||||
// if-else
|
||||
ifElseResult?: 'IF' | 'ELSE';
|
||||
|
||||
// tool
|
||||
toolCallTokens?: number;
|
||||
toolDetail?: ChatHistoryItemResType[];
|
||||
toolStop?: boolean;
|
||||
};
|
||||
|
||||
export type DispatchNodeResultType<T> = {
|
||||
[DispatchNodeResponseKeyEnum.skipHandleId]?: string[]; // skip some edge handle id
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]?: DispatchNodeResponseType; // The node response detail
|
||||
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]?: ChatNodeUsageType[]; //
|
||||
[DispatchNodeResponseKeyEnum.childrenResponses]?: DispatchNodeResultType[];
|
||||
[DispatchNodeResponseKeyEnum.toolResponses]?: ToolRunResponseItemType;
|
||||
[DispatchNodeResponseKeyEnum.assistantResponses]?: ChatItemValueItemType[];
|
||||
} & T;
|
||||
|
||||
/* Single node props */
|
||||
export type AIChatNodeProps = {
|
||||
[NodeInputKeyEnum.aiModel]: string;
|
||||
[NodeInputKeyEnum.aiSystemPrompt]?: string;
|
||||
[NodeInputKeyEnum.aiChatTemperature]: number;
|
||||
[NodeInputKeyEnum.aiChatMaxToken]: number;
|
||||
[NodeInputKeyEnum.aiChatIsResponseText]: boolean;
|
||||
[NodeInputKeyEnum.aiChatQuoteTemplate]?: string;
|
||||
[NodeInputKeyEnum.aiChatQuotePrompt]?: string;
|
||||
};
|
199
packages/global/core/workflow/runtime/utils.ts
Normal file
199
packages/global/core/workflow/runtime/utils.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
import { ChatCompletionRequestMessageRoleEnum } from '../../ai/constants';
|
||||
import { NodeOutputKeyEnum } from '../constants';
|
||||
import { FlowNodeTypeEnum } from '../node/constant';
|
||||
import { StoreNodeItemType } from '../type';
|
||||
import { StoreEdgeItemType } from '../type/edge';
|
||||
import { RuntimeEdgeItemType, RuntimeNodeItemType } from './type';
|
||||
import { VARIABLE_NODE_ID } from '../../../../../projects/app/src/web/core/workflow/constants/index';
|
||||
|
||||
export const initWorkflowEdgeStatus = (edges: StoreEdgeItemType[]): RuntimeEdgeItemType[] => {
|
||||
return (
|
||||
edges?.map((edge) => ({
|
||||
...edge,
|
||||
status: 'waiting'
|
||||
})) || []
|
||||
);
|
||||
};
|
||||
|
||||
export const getDefaultEntryNodeIds = (nodes: (StoreNodeItemType | RuntimeNodeItemType)[]) => {
|
||||
const entryList = [
|
||||
FlowNodeTypeEnum.systemConfig,
|
||||
FlowNodeTypeEnum.workflowStart,
|
||||
FlowNodeTypeEnum.pluginInput
|
||||
];
|
||||
return nodes
|
||||
.filter((node) => entryList.includes(node.flowNodeType as any))
|
||||
.map((item) => item.nodeId);
|
||||
};
|
||||
|
||||
export const storeNodes2RuntimeNodes = (
|
||||
nodes: StoreNodeItemType[],
|
||||
entryNodeIds: string[]
|
||||
): RuntimeNodeItemType[] => {
|
||||
return (
|
||||
nodes.map<RuntimeNodeItemType>((node) => {
|
||||
return {
|
||||
nodeId: node.nodeId,
|
||||
name: node.name,
|
||||
avatar: node.avatar,
|
||||
intro: node.intro,
|
||||
flowNodeType: node.flowNodeType,
|
||||
showStatus: node.showStatus,
|
||||
isEntry: entryNodeIds.includes(node.nodeId),
|
||||
inputs: node.inputs,
|
||||
outputs: node.outputs,
|
||||
pluginId: node.pluginId
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
};
|
||||
|
||||
export const filterWorkflowEdges = (edges: RuntimeEdgeItemType[]) => {
|
||||
return edges.filter(
|
||||
(edge) =>
|
||||
edge.sourceHandle !== NodeOutputKeyEnum.selectedTools &&
|
||||
edge.targetHandle !== NodeOutputKeyEnum.selectedTools
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
区分普通连线和递归连线
|
||||
递归连线:可以通过往上查询 nodes,最终追溯到自身
|
||||
*/
|
||||
export const splitEdges2WorkflowEdges = ({
|
||||
edges,
|
||||
allEdges,
|
||||
currentNode
|
||||
}: {
|
||||
edges: RuntimeEdgeItemType[];
|
||||
allEdges: RuntimeEdgeItemType[];
|
||||
currentNode: RuntimeNodeItemType;
|
||||
}) => {
|
||||
const commonEdges: RuntimeEdgeItemType[] = [];
|
||||
const recursiveEdges: RuntimeEdgeItemType[] = [];
|
||||
|
||||
edges.forEach((edge) => {
|
||||
const checkIsCurrentNode = (edge: RuntimeEdgeItemType): boolean => {
|
||||
const sourceEdge = allEdges.find((item) => item.target === edge.source);
|
||||
if (!sourceEdge) return false;
|
||||
if (sourceEdge.source === currentNode.nodeId) return true;
|
||||
return checkIsCurrentNode(sourceEdge);
|
||||
};
|
||||
if (checkIsCurrentNode(edge)) {
|
||||
recursiveEdges.push(edge);
|
||||
} else {
|
||||
commonEdges.push(edge);
|
||||
}
|
||||
});
|
||||
|
||||
return { commonEdges, recursiveEdges };
|
||||
};
|
||||
|
||||
/*
|
||||
1. 输入线分类:普通线和递归线(可以追溯到自身)
|
||||
2. 起始线全部非 waiting 执行,或递归线全部非 waiting 执行
|
||||
*/
|
||||
export const checkNodeRunStatus = ({
|
||||
node,
|
||||
runtimeEdges
|
||||
}: {
|
||||
node: RuntimeNodeItemType;
|
||||
runtimeEdges: RuntimeEdgeItemType[];
|
||||
}) => {
|
||||
const workflowEdges = filterWorkflowEdges(runtimeEdges).filter(
|
||||
(item) => item.target === node.nodeId
|
||||
);
|
||||
|
||||
if (workflowEdges.length === 0) {
|
||||
return 'run';
|
||||
}
|
||||
|
||||
const { commonEdges, recursiveEdges } = splitEdges2WorkflowEdges({
|
||||
edges: workflowEdges,
|
||||
allEdges: runtimeEdges,
|
||||
currentNode: node
|
||||
});
|
||||
|
||||
// check skip
|
||||
if (commonEdges.every((item) => item.status === 'skipped')) {
|
||||
return 'skip';
|
||||
}
|
||||
if (recursiveEdges.length > 0 && recursiveEdges.every((item) => item.status === 'skipped')) {
|
||||
return 'skip';
|
||||
}
|
||||
|
||||
// check active
|
||||
if (commonEdges.every((item) => item.status !== 'waiting')) {
|
||||
return 'run';
|
||||
}
|
||||
if (recursiveEdges.length > 0 && recursiveEdges.every((item) => item.status !== 'waiting')) {
|
||||
return 'run';
|
||||
}
|
||||
|
||||
return 'wait';
|
||||
};
|
||||
|
||||
export const getReferenceVariableValue = ({
|
||||
value,
|
||||
nodes,
|
||||
variables
|
||||
}: {
|
||||
value: [string, string];
|
||||
nodes: RuntimeNodeItemType[];
|
||||
variables: Record<string, any>;
|
||||
}) => {
|
||||
if (
|
||||
!Array.isArray(value) ||
|
||||
value.length !== 2 ||
|
||||
typeof value[0] !== 'string' ||
|
||||
typeof value[1] !== 'string'
|
||||
) {
|
||||
return value;
|
||||
}
|
||||
const sourceNodeId = value[0];
|
||||
const outputId = value[1];
|
||||
|
||||
if (sourceNodeId === VARIABLE_NODE_ID && outputId) {
|
||||
return variables[outputId];
|
||||
}
|
||||
|
||||
const node = nodes.find((node) => node.nodeId === sourceNodeId);
|
||||
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const outputValue = node.outputs.find((output) => output.id === outputId)?.value;
|
||||
|
||||
return outputValue;
|
||||
};
|
||||
|
||||
export const textAdaptGptResponse = ({
|
||||
text,
|
||||
model = '',
|
||||
finish_reason = null,
|
||||
extraData = {}
|
||||
}: {
|
||||
model?: string;
|
||||
text: string | null;
|
||||
finish_reason?: null | 'stop';
|
||||
extraData?: Object;
|
||||
}) => {
|
||||
return JSON.stringify({
|
||||
...extraData,
|
||||
id: '',
|
||||
object: '',
|
||||
created: 0,
|
||||
model,
|
||||
choices: [
|
||||
{
|
||||
delta:
|
||||
text === null
|
||||
? {}
|
||||
: { role: ChatCompletionRequestMessageRoleEnum.Assistant, content: text },
|
||||
index: 0,
|
||||
finish_reason
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
123
packages/global/core/workflow/template/constants.ts
Normal file
123
packages/global/core/workflow/template/constants.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { SystemConfigNode } from './system/systemConfig';
|
||||
import { EmptyNode } from './system/emptyNode';
|
||||
import { WorkflowStart } from './system/workflowStart';
|
||||
import { AiChatModule } from './system/aiChat';
|
||||
import { DatasetSearchModule } from './system/datasetSearch';
|
||||
import { DatasetConcatModule } from './system/datasetConcat';
|
||||
import { AssignedAnswerModule } from './system/assignedAnswer';
|
||||
import { ClassifyQuestionModule } from './system/classifyQuestion';
|
||||
import { ContextExtractModule } from './system/contextExtract';
|
||||
import { HttpModule468 } from './system/http468';
|
||||
|
||||
import { ToolModule } from './system/tools';
|
||||
import { StopToolNode } from './system/stopTool';
|
||||
|
||||
import { RunAppModule } from './system/runApp';
|
||||
import { PluginInputModule } from './system/pluginInput';
|
||||
import { PluginOutputModule } from './system/pluginOutput';
|
||||
import { RunPluginModule } from './system/runPlugin';
|
||||
import { AiQueryExtension } from './system/queryExtension';
|
||||
|
||||
import type { FlowNodeTemplateType, nodeTemplateListType } from '../type';
|
||||
import { FlowNodeTemplateTypeEnum } from '../../workflow/constants';
|
||||
import { lafModule } from './system/laf';
|
||||
import { ifElseNode } from './system/ifElse/index';
|
||||
|
||||
/* app flow module templates */
|
||||
export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
SystemConfigNode,
|
||||
WorkflowStart,
|
||||
AiChatModule,
|
||||
AssignedAnswerModule,
|
||||
DatasetSearchModule,
|
||||
DatasetConcatModule,
|
||||
RunAppModule,
|
||||
ToolModule,
|
||||
StopToolNode,
|
||||
ClassifyQuestionModule,
|
||||
ContextExtractModule,
|
||||
HttpModule468,
|
||||
AiQueryExtension,
|
||||
lafModule,
|
||||
ifElseNode
|
||||
];
|
||||
/* plugin flow module templates */
|
||||
export const pluginSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
PluginInputModule,
|
||||
PluginOutputModule,
|
||||
AiChatModule,
|
||||
AssignedAnswerModule,
|
||||
DatasetSearchModule,
|
||||
DatasetConcatModule,
|
||||
RunAppModule,
|
||||
ToolModule,
|
||||
StopToolNode,
|
||||
ClassifyQuestionModule,
|
||||
ContextExtractModule,
|
||||
HttpModule468,
|
||||
AiQueryExtension,
|
||||
lafModule,
|
||||
ifElseNode
|
||||
];
|
||||
|
||||
/* all module */
|
||||
export const moduleTemplatesFlat: FlowNodeTemplateType[] = [
|
||||
EmptyNode,
|
||||
SystemConfigNode,
|
||||
WorkflowStart,
|
||||
AiChatModule,
|
||||
DatasetSearchModule,
|
||||
DatasetConcatModule,
|
||||
AssignedAnswerModule,
|
||||
ClassifyQuestionModule,
|
||||
ContextExtractModule,
|
||||
HttpModule468,
|
||||
ToolModule,
|
||||
StopToolNode,
|
||||
AiChatModule,
|
||||
RunAppModule,
|
||||
PluginInputModule,
|
||||
PluginOutputModule,
|
||||
RunPluginModule,
|
||||
AiQueryExtension,
|
||||
lafModule,
|
||||
ifElseNode
|
||||
];
|
||||
|
||||
export const moduleTemplatesList: nodeTemplateListType = [
|
||||
{
|
||||
type: FlowNodeTemplateTypeEnum.systemInput,
|
||||
label: 'core.module.template.System input module',
|
||||
list: []
|
||||
},
|
||||
{
|
||||
type: FlowNodeTemplateTypeEnum.textAnswer,
|
||||
label: 'core.module.template.Response module',
|
||||
list: []
|
||||
},
|
||||
{
|
||||
type: FlowNodeTemplateTypeEnum.functionCall,
|
||||
label: 'core.module.template.Function module',
|
||||
list: []
|
||||
},
|
||||
{
|
||||
type: FlowNodeTemplateTypeEnum.tools,
|
||||
label: 'core.module.template.Tool module',
|
||||
list: []
|
||||
},
|
||||
{
|
||||
type: FlowNodeTemplateTypeEnum.externalCall,
|
||||
label: 'core.module.template.External module',
|
||||
list: []
|
||||
},
|
||||
{
|
||||
type: FlowNodeTemplateTypeEnum.personalPlugin,
|
||||
label: '',
|
||||
list: []
|
||||
},
|
||||
{
|
||||
type: FlowNodeTemplateTypeEnum.other,
|
||||
label: '其他',
|
||||
list: []
|
||||
}
|
||||
];
|
65
packages/global/core/workflow/template/input.ts
Normal file
65
packages/global/core/workflow/template/input.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { NodeInputKeyEnum } from '../constants';
|
||||
import { FlowNodeInputTypeEnum } from '../node/constant';
|
||||
import { WorkflowIOValueTypeEnum } from '../constants';
|
||||
import { chatNodeSystemPromptTip } from './tip';
|
||||
import { FlowNodeInputItemType } from '../type/io';
|
||||
|
||||
export const Input_Template_History: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.history,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.chatHistory,
|
||||
label: 'core.module.input.label.chat history',
|
||||
required: true,
|
||||
min: 0,
|
||||
max: 30,
|
||||
value: 6
|
||||
};
|
||||
|
||||
export const Input_Template_UserChatInput: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.userChatInput,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: '用户问题',
|
||||
required: true
|
||||
};
|
||||
|
||||
export const Input_Template_DynamicInput: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.addInputParam,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.addInputParam],
|
||||
valueType: WorkflowIOValueTypeEnum.dynamic,
|
||||
label: '',
|
||||
required: false
|
||||
};
|
||||
|
||||
export const Input_Template_SelectAIModel: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.aiModel,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.selectLLMModel, FlowNodeInputTypeEnum.reference],
|
||||
label: 'core.module.input.label.aiModel',
|
||||
required: true,
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
};
|
||||
export const Input_Template_SettingAiModel: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.aiModel,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.settingLLMModel, FlowNodeInputTypeEnum.reference],
|
||||
label: 'core.module.input.label.aiModel',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
};
|
||||
|
||||
export const Input_Template_System_Prompt: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.aiSystemPrompt,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
max: 3000,
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: 'core.ai.Prompt',
|
||||
description: chatNodeSystemPromptTip,
|
||||
placeholder: chatNodeSystemPromptTip
|
||||
};
|
||||
|
||||
export const Input_Template_Dataset_Quote: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.aiChatDatasetQuote,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.settingDatasetQuotePrompt],
|
||||
label: '',
|
||||
debugLabel: '知识库引用',
|
||||
description: '',
|
||||
valueType: WorkflowIOValueTypeEnum.datasetQuote
|
||||
};
|
17
packages/global/core/workflow/template/output.ts
Normal file
17
packages/global/core/workflow/template/output.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { FlowNodeOutputItemType } from '../type/io.d';
|
||||
import { NodeOutputKeyEnum } from '../constants';
|
||||
import { FlowNodeOutputTypeEnum } from '../node/constant';
|
||||
import { WorkflowIOValueTypeEnum } from '../constants';
|
||||
|
||||
export const Output_Template_AddOutput: FlowNodeOutputItemType = {
|
||||
id: NodeOutputKeyEnum.addOutputParam,
|
||||
key: NodeOutputKeyEnum.addOutputParam,
|
||||
type: FlowNodeOutputTypeEnum.dynamic,
|
||||
valueType: WorkflowIOValueTypeEnum.dynamic,
|
||||
label: '',
|
||||
|
||||
editField: {
|
||||
key: true,
|
||||
valueType: true
|
||||
}
|
||||
};
|
105
packages/global/core/workflow/template/system/aiChat.ts
Normal file
105
packages/global/core/workflow/template/system/aiChat.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import {
|
||||
Input_Template_SettingAiModel,
|
||||
Input_Template_Dataset_Quote,
|
||||
Input_Template_History,
|
||||
Input_Template_System_Prompt,
|
||||
Input_Template_UserChatInput
|
||||
} from '../input';
|
||||
import { chatNodeSystemPromptTip } from '../tip';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const AiChatModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.chatNode,
|
||||
templateType: FlowNodeTemplateTypeEnum.textAnswer,
|
||||
flowNodeType: FlowNodeTypeEnum.chatNode,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/AI.png',
|
||||
name: 'AI 对话',
|
||||
intro: 'AI 大模型对话',
|
||||
showStatus: true,
|
||||
isTool: true,
|
||||
inputs: [
|
||||
Input_Template_SettingAiModel,
|
||||
// --- settings modal
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatTemperature,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden], // Set in the pop-up window
|
||||
label: '',
|
||||
value: 0,
|
||||
valueType: WorkflowIOValueTypeEnum.number,
|
||||
min: 0,
|
||||
max: 10,
|
||||
step: 1
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatMaxToken,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden], // Set in the pop-up window
|
||||
label: '',
|
||||
value: 2000,
|
||||
valueType: WorkflowIOValueTypeEnum.number,
|
||||
min: 100,
|
||||
max: 4000,
|
||||
step: 50
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatIsResponseText,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
value: true,
|
||||
valueType: WorkflowIOValueTypeEnum.boolean
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatQuoteTemplate,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatQuotePrompt,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
// settings modal ---
|
||||
{
|
||||
...Input_Template_System_Prompt,
|
||||
label: 'core.ai.Prompt',
|
||||
description: chatNodeSystemPromptTip,
|
||||
placeholder: chatNodeSystemPromptTip
|
||||
},
|
||||
Input_Template_History,
|
||||
{ ...Input_Template_UserChatInput, toolDescription: '用户问题' },
|
||||
Input_Template_Dataset_Quote
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.history,
|
||||
key: NodeOutputKeyEnum.history,
|
||||
label: 'core.module.output.label.New context',
|
||||
description: 'core.module.output.description.New context',
|
||||
valueType: WorkflowIOValueTypeEnum.chatHistory,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.answerText,
|
||||
key: NodeOutputKeyEnum.answerText,
|
||||
label: 'core.module.output.label.Ai response content',
|
||||
description: 'core.module.output.description.Ai response content',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
]
|
||||
};
|
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/index.d';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum,
|
||||
NodeOutputKeyEnum
|
||||
} from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const AssignedAnswerModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.answerNode,
|
||||
templateType: FlowNodeTemplateTypeEnum.textAnswer,
|
||||
flowNodeType: FlowNodeTypeEnum.answerNode,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/reply.png',
|
||||
name: '指定回复',
|
||||
intro:
|
||||
'该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。',
|
||||
inputs: [
|
||||
{
|
||||
key: NodeInputKeyEnum.answerText,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: 'core.module.input.label.Response content',
|
||||
description: 'core.module.input.description.Response content',
|
||||
placeholder: 'core.module.input.description.Response content'
|
||||
}
|
||||
],
|
||||
outputs: []
|
||||
};
|
@@ -0,0 +1,75 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum,
|
||||
NodeOutputKeyEnum
|
||||
} from '../../constants';
|
||||
import {
|
||||
Input_Template_SelectAIModel,
|
||||
Input_Template_History,
|
||||
Input_Template_UserChatInput
|
||||
} from '../input';
|
||||
import { Input_Template_System_Prompt } from '../input';
|
||||
import { LLMModelTypeEnum } from '../../../ai/constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const ClassifyQuestionModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.classifyQuestion,
|
||||
templateType: FlowNodeTemplateTypeEnum.functionCall,
|
||||
flowNodeType: FlowNodeTypeEnum.classifyQuestion,
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(true, false, true, true),
|
||||
avatar: '/imgs/workflow/cq.png',
|
||||
name: '问题分类',
|
||||
intro: `根据用户的历史记录和当前问题判断该次提问的类型。可以添加多组问题类型,下面是一个模板例子:\n类型1: 打招呼\n类型2: 关于商品“使用”问题\n类型3: 关于商品“购买”问题\n类型4: 其他问题`,
|
||||
showStatus: true,
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_SelectAIModel,
|
||||
llmModelType: LLMModelTypeEnum.classify
|
||||
},
|
||||
{
|
||||
...Input_Template_System_Prompt,
|
||||
label: 'core.module.input.label.Background',
|
||||
description: 'core.module.input.description.Background',
|
||||
placeholder: 'core.module.input.placeholder.Classify background'
|
||||
},
|
||||
Input_Template_History,
|
||||
Input_Template_UserChatInput,
|
||||
{
|
||||
key: NodeInputKeyEnum.agents,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
label: '',
|
||||
value: [
|
||||
{
|
||||
value: '打招呼',
|
||||
key: 'wqre'
|
||||
},
|
||||
{
|
||||
value: '关于 xxx 的问题',
|
||||
key: 'sdfa'
|
||||
},
|
||||
{
|
||||
value: '其他问题',
|
||||
key: 'agex'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.cqResult,
|
||||
key: NodeOutputKeyEnum.cqResult,
|
||||
label: '分类结果',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
]
|
||||
};
|
@@ -0,0 +1,86 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import { Input_Template_SelectAIModel, Input_Template_History } from '../input';
|
||||
import { LLMModelTypeEnum } from '../../../ai/constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const ContextExtractModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.contentExtract,
|
||||
templateType: FlowNodeTemplateTypeEnum.functionCall,
|
||||
flowNodeType: FlowNodeTypeEnum.contentExtract,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/extract.png',
|
||||
name: '文本内容提取',
|
||||
intro: '可从文本中提取指定的数据,例如:sql语句、搜索关键词、代码等',
|
||||
showStatus: true,
|
||||
isTool: true,
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_SelectAIModel,
|
||||
llmModelType: LLMModelTypeEnum.extractFields
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.description,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: '提取要求描述',
|
||||
description:
|
||||
'给AI一些对应的背景知识或要求描述,引导AI更好的完成任务。\n该输入框可使用全局变量。',
|
||||
placeholder:
|
||||
'例如: \n1. 当前时间为: {{cTime}}。你是一个实验室预约助手,你的任务是帮助用户预约实验室,从文本中获取对应的预约信息。\n2. 你是谷歌搜索助手,需要从文本中提取出合适的搜索词。'
|
||||
},
|
||||
Input_Template_History,
|
||||
{
|
||||
key: NodeInputKeyEnum.contextExtractInput,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea],
|
||||
label: '需要提取的文本',
|
||||
required: true,
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
toolDescription: '需要检索的内容'
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.extractKeys,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
description: "由 '描述' 和 'key' 组成一个目标字段,可提取多个目标字段",
|
||||
value: [] // {desc: string; key: string; required: boolean; enum: string[]}[]
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
// {
|
||||
// id: NodeOutputKeyEnum.success,
|
||||
// key: NodeOutputKeyEnum.success,
|
||||
// label: '字段完全提取',
|
||||
// valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
// type: FlowNodeOutputTypeEnum.source
|
||||
// },
|
||||
// {
|
||||
// id: NodeOutputKeyEnum.failed,
|
||||
// key: NodeOutputKeyEnum.failed,
|
||||
// label: '提取字段缺失',
|
||||
// description: '存在一个或多个字段未提取成功。尽管使用了默认值也算缺失。',
|
||||
// valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
// type: FlowNodeOutputTypeEnum.source
|
||||
// },
|
||||
{
|
||||
id: NodeOutputKeyEnum.contextExtractFields,
|
||||
key: NodeOutputKeyEnum.contextExtractFields,
|
||||
label: '完整提取结果',
|
||||
description: '一个 JSON 字符串,例如:{"name:":"YY","Time":"2023/7/2 18:00"}',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
]
|
||||
};
|
@@ -0,0 +1,59 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import { Input_Template_Dataset_Quote } from '../input';
|
||||
import { getNanoid } from '../../../../common/string/tools';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { FlowNodeInputItemType } from '../../type/io.d';
|
||||
|
||||
export const getOneQuoteInputTemplate = (key = getNanoid()): FlowNodeInputItemType => ({
|
||||
...Input_Template_Dataset_Quote,
|
||||
key,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
description: ''
|
||||
});
|
||||
|
||||
export const DatasetConcatModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.datasetConcatNode,
|
||||
flowNodeType: FlowNodeTypeEnum.datasetConcatNode,
|
||||
templateType: FlowNodeTemplateTypeEnum.other,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/concat.svg',
|
||||
name: '知识库搜索引用合并',
|
||||
intro: '可以将多个知识库搜索结果进行合并输出。使用 RRF 的合并方式进行最终排序输出。',
|
||||
showStatus: false,
|
||||
inputs: [
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetMaxTokens,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
label: '最大 Tokens',
|
||||
value: 1500,
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
{
|
||||
key: 'customComponent',
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
label: ''
|
||||
},
|
||||
getOneQuoteInputTemplate()
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.datasetQuoteQA,
|
||||
key: NodeOutputKeyEnum.datasetQuoteQA,
|
||||
label: 'core.module.Dataset quote.label',
|
||||
type: FlowNodeOutputTypeEnum.static,
|
||||
valueType: WorkflowIOValueTypeEnum.datasetQuote
|
||||
}
|
||||
]
|
||||
};
|
105
packages/global/core/workflow/template/system/datasetSearch.ts
Normal file
105
packages/global/core/workflow/template/system/datasetSearch.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import { Input_Template_UserChatInput } from '../input';
|
||||
import { DatasetSearchModeEnum } from '../../../dataset/constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const Dataset_SEARCH_DESC =
|
||||
'调用“语义检索”和“全文检索”能力,从“知识库”中查找可能与问题相关的参考内容';
|
||||
|
||||
export const DatasetSearchModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.datasetSearchNode,
|
||||
templateType: FlowNodeTemplateTypeEnum.functionCall,
|
||||
flowNodeType: FlowNodeTypeEnum.datasetSearchNode,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/db.png',
|
||||
name: '知识库搜索',
|
||||
intro: Dataset_SEARCH_DESC,
|
||||
showStatus: true,
|
||||
isTool: true,
|
||||
inputs: [
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSelectList,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.selectDataset, FlowNodeInputTypeEnum.reference],
|
||||
label: 'core.module.input.label.Select dataset',
|
||||
value: [],
|
||||
valueType: WorkflowIOValueTypeEnum.selectDataset,
|
||||
list: [],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSimilarity,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.selectDatasetParamsModal],
|
||||
label: '',
|
||||
value: 0.4,
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
// setting from modal
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetMaxTokens,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
value: 1500,
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchMode,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
value: DatasetSearchModeEnum.embedding
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchUsingReRank,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
value: false
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchUsingExtensionQuery,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
value: true
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchExtensionModel,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchExtensionBg,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
...Input_Template_UserChatInput,
|
||||
toolDescription: '需要检索的内容'
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.datasetQuoteQA,
|
||||
key: NodeOutputKeyEnum.datasetQuoteQA,
|
||||
label: 'core.module.Dataset quote.label',
|
||||
description: '特殊数组格式,搜索结果为空时,返回空数组。',
|
||||
type: FlowNodeOutputTypeEnum.static,
|
||||
valueType: WorkflowIOValueTypeEnum.datasetQuote
|
||||
}
|
||||
]
|
||||
};
|
17
packages/global/core/workflow/template/system/emptyNode.ts
Normal file
17
packages/global/core/workflow/template/system/emptyNode.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const EmptyNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.emptyNode,
|
||||
templateType: FlowNodeTemplateTypeEnum.systemInput,
|
||||
flowNodeType: FlowNodeTypeEnum.emptyNode,
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(false, false, false, false),
|
||||
avatar: '',
|
||||
name: '',
|
||||
intro: '',
|
||||
inputs: [],
|
||||
outputs: []
|
||||
};
|
@@ -0,0 +1,31 @@
|
||||
import { FlowNodeTemplateTypeEnum, WorkflowIOValueTypeEnum } from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { VariableItemType } from '../../../app/type';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
|
||||
export const getGlobalVariableNode = ({
|
||||
id,
|
||||
variables
|
||||
}: {
|
||||
id: string;
|
||||
variables: VariableItemType[];
|
||||
}): FlowNodeTemplateType => {
|
||||
return {
|
||||
id,
|
||||
templateType: FlowNodeTemplateTypeEnum.other,
|
||||
flowNodeType: FlowNodeTypeEnum.systemConfig,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/variable.png',
|
||||
name: '全局变量',
|
||||
intro: '',
|
||||
inputs: [],
|
||||
outputs: variables.map((item) => ({
|
||||
id: item.key,
|
||||
key: item.key,
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: item.label
|
||||
}))
|
||||
};
|
||||
};
|
92
packages/global/core/workflow/template/system/http468.ts
Normal file
92
packages/global/core/workflow/template/system/http468.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/index.d';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import { Input_Template_DynamicInput } from '../input';
|
||||
import { Output_Template_AddOutput } from '../output';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const HttpModule468: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.httpRequest468,
|
||||
templateType: FlowNodeTemplateTypeEnum.externalCall,
|
||||
flowNodeType: FlowNodeTypeEnum.httpRequest468,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/http.png',
|
||||
name: 'HTTP 请求',
|
||||
intro: '可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)',
|
||||
showStatus: true,
|
||||
isTool: true,
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_DynamicInput,
|
||||
description: 'core.module.input.description.HTTP Dynamic Input',
|
||||
editField: {
|
||||
key: true,
|
||||
valueType: true
|
||||
}
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.httpMethod,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: '',
|
||||
value: 'POST',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.httpReqUrl,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: '',
|
||||
description: 'core.module.input.description.Http Request Url',
|
||||
placeholder: 'https://api.ai.com/getInventory',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.httpHeaders,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
value: [],
|
||||
label: '',
|
||||
description: 'core.module.input.description.Http Request Header',
|
||||
placeholder: 'core.module.input.description.Http Request Header',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.httpParams,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
value: [],
|
||||
label: '',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.httpJsonBody,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
value: '',
|
||||
label: '',
|
||||
required: false
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
Output_Template_AddOutput,
|
||||
{
|
||||
id: NodeOutputKeyEnum.httpRawResponse,
|
||||
key: NodeOutputKeyEnum.httpRawResponse,
|
||||
label: '原始响应',
|
||||
description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。',
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
]
|
||||
};
|
@@ -0,0 +1,84 @@
|
||||
export enum VariableConditionEnum {
|
||||
equalTo = 'equalTo',
|
||||
notEqual = 'notEqual',
|
||||
isEmpty = 'isEmpty',
|
||||
isNotEmpty = 'isNotEmpty',
|
||||
include = 'include',
|
||||
notInclude = 'notInclude',
|
||||
startWith = 'startWith',
|
||||
endWith = 'endWith',
|
||||
|
||||
greaterThan = 'greaterThan',
|
||||
greaterThanOrEqualTo = 'greaterThanOrEqualTo',
|
||||
lessThan = 'lessThan',
|
||||
lessThanOrEqualTo = 'lessThanOrEqualTo',
|
||||
|
||||
lengthEqualTo = 'lengthEqualTo',
|
||||
lengthNotEqualTo = 'lengthNotEqualTo',
|
||||
lengthGreaterThan = 'lengthGreaterThan',
|
||||
lengthGreaterThanOrEqualTo = 'lengthGreaterThanOrEqualTo',
|
||||
lengthLessThan = 'lengthLessThan',
|
||||
lengthLessThanOrEqualTo = 'lengthLessThanOrEqualTo'
|
||||
}
|
||||
|
||||
export const stringConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '等于', value: VariableConditionEnum.equalTo },
|
||||
{ label: '不等于', value: VariableConditionEnum.notEqual },
|
||||
{ label: '包含', value: VariableConditionEnum.include },
|
||||
{ label: '不包含', value: VariableConditionEnum.notInclude },
|
||||
{ label: '开始为', value: VariableConditionEnum.startWith },
|
||||
{ label: '结束为', value: VariableConditionEnum.endWith }
|
||||
];
|
||||
export const numberConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '等于', value: VariableConditionEnum.equalTo },
|
||||
{ label: '不等于', value: VariableConditionEnum.notEqual },
|
||||
{ label: '大于', value: VariableConditionEnum.greaterThan },
|
||||
{ label: '大于等于', value: VariableConditionEnum.greaterThanOrEqualTo },
|
||||
{ label: '小于', value: VariableConditionEnum.lessThan },
|
||||
{ label: '小于等于', value: VariableConditionEnum.lessThanOrEqualTo }
|
||||
];
|
||||
export const booleanConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '等于', value: VariableConditionEnum.equalTo }
|
||||
];
|
||||
export const arrayConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '包含', value: VariableConditionEnum.include },
|
||||
{ label: '不包含', value: VariableConditionEnum.notInclude },
|
||||
{ label: '长度等于', value: VariableConditionEnum.lengthEqualTo },
|
||||
{ label: '长度不等于', value: VariableConditionEnum.lengthNotEqualTo },
|
||||
{ label: '长度大于', value: VariableConditionEnum.lengthGreaterThan },
|
||||
{ label: '长度大于等于', value: VariableConditionEnum.lengthGreaterThanOrEqualTo },
|
||||
{ label: '长度小于', value: VariableConditionEnum.lengthLessThan },
|
||||
{ label: '长度小于等于', value: VariableConditionEnum.lengthLessThanOrEqualTo }
|
||||
];
|
||||
export const objectConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty }
|
||||
];
|
||||
export const allConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '等于', value: VariableConditionEnum.equalTo },
|
||||
{ label: '不等于', value: VariableConditionEnum.notEqual },
|
||||
{ label: '包含', value: VariableConditionEnum.include },
|
||||
{ label: '不包含', value: VariableConditionEnum.notInclude },
|
||||
{ label: '开始为', value: VariableConditionEnum.startWith },
|
||||
{ label: '结束为', value: VariableConditionEnum.endWith },
|
||||
{ label: '大于', value: VariableConditionEnum.greaterThan },
|
||||
{ label: '大于等于', value: VariableConditionEnum.greaterThanOrEqualTo },
|
||||
{ label: '小于', value: VariableConditionEnum.lessThan },
|
||||
{ label: '小于等于', value: VariableConditionEnum.lessThanOrEqualTo },
|
||||
{ label: '长度等于', value: VariableConditionEnum.lengthEqualTo },
|
||||
{ label: '长度不等于', value: VariableConditionEnum.lengthNotEqualTo },
|
||||
{ label: '长度大于', value: VariableConditionEnum.lengthGreaterThan },
|
||||
{ label: '长度大于等于', value: VariableConditionEnum.lengthGreaterThanOrEqualTo },
|
||||
{ label: '长度小于', value: VariableConditionEnum.lengthLessThan },
|
||||
{ label: '长度小于等于', value: VariableConditionEnum.lengthLessThanOrEqualTo }
|
||||
];
|
@@ -0,0 +1,64 @@
|
||||
import {
|
||||
FlowNodeTemplateTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
WorkflowIOValueTypeEnum
|
||||
} from '../../../constants';
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../../type';
|
||||
import { getHandleConfig } from '../../utils';
|
||||
|
||||
export const ifElseNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.ifElseNode,
|
||||
templateType: FlowNodeTemplateTypeEnum.tools,
|
||||
flowNodeType: FlowNodeTypeEnum.ifElseNode,
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(true, false, true, true),
|
||||
avatar: '/imgs/workflow/ifElse.svg',
|
||||
name: '判断器',
|
||||
intro: '根据一定的条件,执行不同的分支。',
|
||||
showStatus: true,
|
||||
inputs: [
|
||||
{
|
||||
key: NodeInputKeyEnum.condition,
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: '',
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
required: false,
|
||||
value: 'AND' // AND, OR
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.ifElseList,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
label: '',
|
||||
value: [
|
||||
{
|
||||
variable: undefined,
|
||||
condition: undefined,
|
||||
value: undefined
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.if,
|
||||
key: NodeOutputKeyEnum.if,
|
||||
label: 'IF',
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
type: FlowNodeOutputTypeEnum.source
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.else,
|
||||
key: NodeOutputKeyEnum.else,
|
||||
label: 'ELSE',
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
type: FlowNodeOutputTypeEnum.source
|
||||
}
|
||||
]
|
||||
};
|
9
packages/global/core/workflow/template/system/ifElse/type.d.ts
vendored
Normal file
9
packages/global/core/workflow/template/system/ifElse/type.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import { ReferenceValueProps } from 'core/workflow/type/io';
|
||||
import { VariableConditionEnum } from './constant';
|
||||
|
||||
export type IfElseConditionType = 'AND' | 'OR';
|
||||
export type IfElseListItemType = {
|
||||
variable?: ReferenceValueProps;
|
||||
condition?: VariableConditionEnum;
|
||||
value?: string;
|
||||
};
|
60
packages/global/core/workflow/template/system/laf.ts
Normal file
60
packages/global/core/workflow/template/system/laf.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/index.d';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import { Input_Template_DynamicInput } from '../input';
|
||||
import { Output_Template_AddOutput } from '../output';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const lafModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.lafModule,
|
||||
templateType: FlowNodeTemplateTypeEnum.externalCall,
|
||||
flowNodeType: FlowNodeTypeEnum.lafModule,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/laf.png',
|
||||
name: 'Laf 函数调用(测试)',
|
||||
intro: '可以调用Laf账号下的云函数。',
|
||||
showStatus: true,
|
||||
isTool: true,
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_DynamicInput,
|
||||
description: '接收前方节点的输出值作为变量,这些变量可以被 Laf 请求参数使用。',
|
||||
editField: {
|
||||
key: true,
|
||||
valueType: true
|
||||
}
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.httpReqUrl,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: '',
|
||||
description: 'core.module.input.description.Http Request Url',
|
||||
placeholder: 'https://api.ai.com/getInventory',
|
||||
required: false
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.httpRawResponse,
|
||||
key: NodeOutputKeyEnum.httpRawResponse,
|
||||
label: '原始响应',
|
||||
description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。',
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
...Output_Template_AddOutput
|
||||
}
|
||||
]
|
||||
};
|
20
packages/global/core/workflow/template/system/pluginInput.ts
Normal file
20
packages/global/core/workflow/template/system/pluginInput.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const PluginInputModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.pluginInput,
|
||||
templateType: FlowNodeTemplateTypeEnum.systemInput,
|
||||
flowNodeType: FlowNodeTypeEnum.pluginInput,
|
||||
sourceHandle: getHandleConfig(false, true, false, false),
|
||||
targetHandle: getHandleConfig(false, false, false, false),
|
||||
unique: true,
|
||||
forbidDelete: true,
|
||||
avatar: '/imgs/workflow/input.png',
|
||||
name: '定义插件输入',
|
||||
intro: '自定义配置外部输入,使用插件时,仅暴露自定义配置的输入',
|
||||
showStatus: false,
|
||||
inputs: [],
|
||||
outputs: []
|
||||
};
|
@@ -0,0 +1,20 @@
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const PluginOutputModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.pluginOutput,
|
||||
templateType: FlowNodeTemplateTypeEnum.systemInput,
|
||||
flowNodeType: FlowNodeTypeEnum.pluginOutput,
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(false, false, false, true),
|
||||
unique: true,
|
||||
forbidDelete: true,
|
||||
avatar: '/imgs/workflow/output.png',
|
||||
name: '定义插件输出',
|
||||
intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出',
|
||||
showStatus: false,
|
||||
inputs: [],
|
||||
outputs: []
|
||||
};
|
@@ -0,0 +1,59 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/index.d';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import {
|
||||
Input_Template_History,
|
||||
Input_Template_UserChatInput,
|
||||
Input_Template_SelectAIModel
|
||||
} from '../input';
|
||||
import { LLMModelTypeEnum } from '../../../ai/constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const AiQueryExtension: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.chatNode,
|
||||
templateType: FlowNodeTemplateTypeEnum.other,
|
||||
flowNodeType: FlowNodeTypeEnum.queryExtension,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/cfr.svg',
|
||||
name: '问题优化',
|
||||
intro:
|
||||
'使用问题优化功能,可以提高知识库连续对话时搜索的精度。使用该功能后,会先利用 AI 根据上下文构建一个或多个新的检索词,这些检索词更利于进行知识库搜索。该模块已内置在知识库搜索模块中,如果您仅进行一次知识库搜索,可直接使用知识库内置的补全功能。',
|
||||
showStatus: true,
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_SelectAIModel,
|
||||
llmModelType: LLMModelTypeEnum.queryExtension
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiSystemPrompt,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
label: 'core.app.edit.Query extension background prompt',
|
||||
max: 300,
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
description: 'core.app.edit.Query extension background tip',
|
||||
placeholder: 'core.module.QueryExtension.placeholder'
|
||||
},
|
||||
Input_Template_History,
|
||||
Input_Template_UserChatInput
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.text,
|
||||
key: NodeOutputKeyEnum.text,
|
||||
label: 'core.module.output.label.query extension result',
|
||||
description: 'core.module.output.description.query extension result',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
]
|
||||
};
|
56
packages/global/core/workflow/template/system/runApp.ts
Normal file
56
packages/global/core/workflow/template/system/runApp.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/index.d';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import { Input_Template_History, Input_Template_UserChatInput } from '../input';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const RunAppModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.runApp,
|
||||
templateType: FlowNodeTemplateTypeEnum.externalCall,
|
||||
flowNodeType: FlowNodeTypeEnum.runApp,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/app.png',
|
||||
name: '应用调用',
|
||||
intro: '可以选择一个其他应用进行调用',
|
||||
showStatus: true,
|
||||
inputs: [
|
||||
{
|
||||
key: NodeInputKeyEnum.runAppSelectApp,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.selectApp, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.selectApp,
|
||||
label: '选择一个应用',
|
||||
description: '选择一个其他应用进行调用',
|
||||
required: true
|
||||
},
|
||||
Input_Template_History,
|
||||
Input_Template_UserChatInput
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.history,
|
||||
key: NodeOutputKeyEnum.history,
|
||||
label: '新的上下文',
|
||||
description: '将该应用回复内容拼接到历史记录中,作为新的上下文返回',
|
||||
valueType: WorkflowIOValueTypeEnum.chatHistory,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.answerText,
|
||||
key: NodeOutputKeyEnum.answerText,
|
||||
label: '回复的文本',
|
||||
description: '将在应用完全结束后触发',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
]
|
||||
};
|
18
packages/global/core/workflow/template/system/runPlugin.ts
Normal file
18
packages/global/core/workflow/template/system/runPlugin.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const RunPluginModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.pluginModule,
|
||||
templateType: FlowNodeTemplateTypeEnum.externalCall,
|
||||
flowNodeType: FlowNodeTypeEnum.pluginModule,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
intro: '',
|
||||
name: '',
|
||||
showStatus: false,
|
||||
isTool: true,
|
||||
inputs: [], // [{key:'pluginId'},...]
|
||||
outputs: []
|
||||
};
|
18
packages/global/core/workflow/template/system/stopTool.ts
Normal file
18
packages/global/core/workflow/template/system/stopTool.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type';
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const StopToolNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.stopTool,
|
||||
templateType: FlowNodeTemplateTypeEnum.functionCall,
|
||||
flowNodeType: FlowNodeTypeEnum.stopTool,
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: '/imgs/workflow/toolStop.svg',
|
||||
name: '工具调用终止',
|
||||
intro:
|
||||
'该模块需配置工具调用使用。当该模块被执行时,本次工具调用将会强制结束,并且不再调用AI针对工具调用结果回答问题。',
|
||||
inputs: [],
|
||||
outputs: []
|
||||
};
|
@@ -0,0 +1,61 @@
|
||||
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/index.d';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const SystemConfigNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.systemConfig,
|
||||
templateType: FlowNodeTemplateTypeEnum.systemInput,
|
||||
flowNodeType: FlowNodeTypeEnum.systemConfig,
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(false, false, false, false),
|
||||
avatar: '/imgs/workflow/userGuide.png',
|
||||
name: '系统配置',
|
||||
intro: '可以配置应用的系统参数。',
|
||||
unique: true,
|
||||
forbidDelete: true,
|
||||
inputs: [
|
||||
{
|
||||
key: NodeInputKeyEnum.welcomeText,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: 'core.app.Welcome Text'
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.variables,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
label: 'core.module.Variable',
|
||||
value: []
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.questionGuide,
|
||||
valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: ''
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.tts,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
label: ''
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.whisper,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
label: ''
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.scheduleTrigger,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
label: ''
|
||||
}
|
||||
],
|
||||
outputs: []
|
||||
};
|
68
packages/global/core/workflow/template/system/tools.ts
Normal file
68
packages/global/core/workflow/template/system/tools.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/index.d';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum,
|
||||
NodeInputKeyEnum
|
||||
} from '../../constants';
|
||||
import {
|
||||
Input_Template_SettingAiModel,
|
||||
Input_Template_History,
|
||||
Input_Template_System_Prompt,
|
||||
Input_Template_UserChatInput
|
||||
} from '../input';
|
||||
import { chatNodeSystemPromptTip } from '../tip';
|
||||
import { LLMModelTypeEnum } from '../../../ai/constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const ToolModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.tools,
|
||||
flowNodeType: FlowNodeTypeEnum.tools,
|
||||
templateType: FlowNodeTemplateTypeEnum.functionCall,
|
||||
sourceHandle: getHandleConfig(true, true, false, true),
|
||||
targetHandle: getHandleConfig(true, true, false, true),
|
||||
avatar: '/imgs/workflow/tool.svg',
|
||||
name: '工具调用(实验)',
|
||||
intro: '通过AI模型自动选择一个或多个功能块进行调用,也可以对插件进行调用。',
|
||||
showStatus: true,
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_SettingAiModel,
|
||||
llmModelType: LLMModelTypeEnum.all
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatTemperature,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden], // Set in the pop-up window
|
||||
label: '',
|
||||
value: 0,
|
||||
valueType: WorkflowIOValueTypeEnum.number,
|
||||
min: 0,
|
||||
max: 10,
|
||||
step: 1
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatMaxToken,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden], // Set in the pop-up window
|
||||
label: '',
|
||||
value: 2000,
|
||||
valueType: WorkflowIOValueTypeEnum.number,
|
||||
min: 100,
|
||||
max: 4000,
|
||||
step: 50
|
||||
},
|
||||
{
|
||||
...Input_Template_System_Prompt,
|
||||
label: 'core.ai.Prompt',
|
||||
description: chatNodeSystemPromptTip,
|
||||
placeholder: chatNodeSystemPromptTip
|
||||
},
|
||||
Input_Template_History,
|
||||
Input_Template_UserChatInput
|
||||
],
|
||||
outputs: []
|
||||
};
|
@@ -0,0 +1,32 @@
|
||||
import { FlowNodeOutputTypeEnum, FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/index.d';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { Input_Template_UserChatInput } from '../input';
|
||||
|
||||
export const WorkflowStart: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.workflowStart,
|
||||
templateType: FlowNodeTemplateTypeEnum.systemInput,
|
||||
flowNodeType: FlowNodeTypeEnum.workflowStart,
|
||||
sourceHandle: getHandleConfig(false, true, false, false),
|
||||
targetHandle: getHandleConfig(false, false, false, false),
|
||||
avatar: '/imgs/workflow/userChatInput.svg',
|
||||
name: '流程开始',
|
||||
intro: '',
|
||||
forbidDelete: true,
|
||||
unique: true,
|
||||
inputs: [{ ...Input_Template_UserChatInput, toolDescription: '用户问题' }],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.userChatInput,
|
||||
key: NodeOutputKeyEnum.userChatInput,
|
||||
label: 'core.module.input.label.user question',
|
||||
type: FlowNodeOutputTypeEnum.static,
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
}
|
||||
]
|
||||
};
|
3
packages/global/core/workflow/template/tip.ts
Normal file
3
packages/global/core/workflow/template/tip.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const chatNodeSystemPromptTip = 'core.app.tip.chatNodeSystemPromptTip';
|
||||
export const welcomeTextTip = 'core.app.tip.welcomeTextTip';
|
||||
export const variableTip = 'core.app.tip.variableTip';
|
6
packages/global/core/workflow/template/utils.ts
Normal file
6
packages/global/core/workflow/template/utils.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export const getHandleConfig = (top: boolean, right: boolean, bottom: boolean, left: boolean) => ({
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
left
|
||||
});
|
12
packages/global/core/workflow/type/edge.d.ts
vendored
Normal file
12
packages/global/core/workflow/type/edge.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { RuntimeEdgeStatusEnum } from '../constants';
|
||||
|
||||
export type StoreEdgeItemType = {
|
||||
source: string;
|
||||
sourceHandle: string;
|
||||
target: string;
|
||||
targetHandle: string;
|
||||
};
|
||||
|
||||
export type RuntimeEdgeItemType = StoreEdgeItemType & {
|
||||
status: `${RuntimeEdgeStatusEnum}`;
|
||||
};
|
45
packages/global/core/workflow/type/fe.d.ts
vendored
Normal file
45
packages/global/core/workflow/type/fe.d.ts
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
export type FlowNodeChangeProps = { nodeId: string } & (
|
||||
| {
|
||||
type: 'attr'; // key: attr, value: new value
|
||||
key: string;
|
||||
value: any;
|
||||
}
|
||||
| {
|
||||
type: 'updateInput'; // key: update input key, value: new input value
|
||||
key: string;
|
||||
value: any;
|
||||
}
|
||||
| {
|
||||
type: 'replaceInput'; // key: old input key, value: new input value
|
||||
key: string;
|
||||
value: any;
|
||||
}
|
||||
| {
|
||||
type: 'addInput'; // key: null, value: new input value
|
||||
value: any;
|
||||
index?: number;
|
||||
}
|
||||
| {
|
||||
type: 'delInput'; // key: delete input key, value: null
|
||||
key: string;
|
||||
}
|
||||
| {
|
||||
type: 'updateOutput'; // key: update output key, value: new output value
|
||||
key: string;
|
||||
value: any;
|
||||
}
|
||||
| {
|
||||
type: 'replaceOutput'; // key: old output key, value: new output value
|
||||
key: string;
|
||||
value: any;
|
||||
}
|
||||
| {
|
||||
type: 'addOutput'; // key: null, value: new output value
|
||||
value: any;
|
||||
index?: number;
|
||||
}
|
||||
| {
|
||||
type: 'delOutput'; // key: delete output key, value: null
|
||||
key: string;
|
||||
}
|
||||
);
|
147
packages/global/core/workflow/type/index.d.ts
vendored
Normal file
147
packages/global/core/workflow/type/index.d.ts
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
import { FlowNodeTypeEnum } from '../node/constant';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum,
|
||||
VariableInputEnum
|
||||
} from '../constants';
|
||||
import { DispatchNodeResponseKeyEnum } from '../runtime/constants';
|
||||
import { FlowNodeInputItemType, FlowNodeOutputItemType } from './io.d';
|
||||
import { UserModelSchema } from '../../../support/user/type';
|
||||
import {
|
||||
ChatHistoryItemResType,
|
||||
ChatItemType,
|
||||
ChatItemValueItemType,
|
||||
ToolRunResponseItemType,
|
||||
UserChatItemValueItemType
|
||||
} from '../../chat/type';
|
||||
import { ChatNodeUsageType } from '../../../support/wallet/bill/type';
|
||||
import { RuntimeNodeItemType } from '../runtime/type';
|
||||
import { PluginTypeEnum } from '../../plugin/constants';
|
||||
import { RuntimeEdgeItemType, StoreEdgeItemType } from './edge';
|
||||
import { NextApiResponse } from 'next';
|
||||
|
||||
export type FlowNodeCommonType = {
|
||||
flowNodeType: `${FlowNodeTypeEnum}`; // render node card
|
||||
|
||||
avatar?: string;
|
||||
name: string;
|
||||
intro?: string; // template list intro
|
||||
showStatus?: boolean; // chatting response step status
|
||||
|
||||
// data
|
||||
inputs: FlowNodeInputItemType[];
|
||||
outputs: FlowNodeOutputItemType[];
|
||||
|
||||
// plugin data
|
||||
pluginId?: string;
|
||||
pluginType?: `${PluginTypeEnum}`;
|
||||
parentId?: string;
|
||||
};
|
||||
|
||||
export type FlowNodeTemplateType = FlowNodeCommonType & {
|
||||
id: string; // module id, unique
|
||||
templateType: `${FlowNodeTemplateTypeEnum}`;
|
||||
|
||||
// show handle
|
||||
sourceHandle?: {
|
||||
left: boolean;
|
||||
right: boolean;
|
||||
top: boolean;
|
||||
bottom: boolean;
|
||||
};
|
||||
targetHandle?: {
|
||||
left: boolean;
|
||||
right: boolean;
|
||||
top: boolean;
|
||||
bottom: boolean;
|
||||
};
|
||||
|
||||
// info
|
||||
isTool?: boolean; // can be connected by tool
|
||||
|
||||
// action
|
||||
forbidDelete?: boolean; // forbid delete
|
||||
unique?: boolean;
|
||||
};
|
||||
export type FlowNodeItemType = FlowNodeTemplateType & {
|
||||
nodeId: string;
|
||||
isError?: boolean;
|
||||
debugResult?: {
|
||||
status: 'running' | 'success' | 'skipped' | 'failed';
|
||||
message?: string;
|
||||
showResult?: boolean; // show and hide result modal
|
||||
response?: ChatHistoryItemResType;
|
||||
isExpired?: boolean;
|
||||
};
|
||||
};
|
||||
export type nodeTemplateListType = {
|
||||
type: `${FlowNodeTemplateTypeEnum}`;
|
||||
label: string;
|
||||
list: FlowNodeTemplateType[];
|
||||
}[];
|
||||
|
||||
// store node type
|
||||
export type StoreNodeItemType = FlowNodeCommonType & {
|
||||
nodeId: string;
|
||||
position?: {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
};
|
||||
|
||||
/* connection type */
|
||||
export type NodeTargetNodeItemType = {
|
||||
nodeId: string;
|
||||
sourceHandle: string;
|
||||
targetHandle: string;
|
||||
};
|
||||
export type NodeSourceNodeItemType = {
|
||||
nodeId: string;
|
||||
};
|
||||
|
||||
/* --------------- function type -------------------- */
|
||||
export type SelectAppItemType = {
|
||||
id: string;
|
||||
name: string;
|
||||
logo: string;
|
||||
};
|
||||
|
||||
/* agent */
|
||||
export type ClassifyQuestionAgentItemType = {
|
||||
value: string;
|
||||
key: string;
|
||||
};
|
||||
export type ContextExtractAgentItemType = {
|
||||
desc: string;
|
||||
key: string;
|
||||
required: boolean;
|
||||
defaultValue?: string;
|
||||
enum?: string;
|
||||
};
|
||||
|
||||
/* -------------- running module -------------- */
|
||||
|
||||
export type ChatDispatchProps = {
|
||||
res?: NextApiResponse;
|
||||
mode: 'test' | 'chat' | 'debug';
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
user: UserModelSchema;
|
||||
appId?: string;
|
||||
chatId?: string;
|
||||
responseChatItemId?: string;
|
||||
histories: ChatItemType[];
|
||||
variables: Record<string, any>;
|
||||
inputFiles?: UserChatItemValueItemType['file'][];
|
||||
stream: boolean;
|
||||
detail: boolean; // response detail
|
||||
maxRunTimes: number;
|
||||
};
|
||||
|
||||
export type ModuleDispatchProps<T> = ChatDispatchProps & {
|
||||
node: RuntimeNodeItemType;
|
||||
runtimeNodes: RuntimeNodeItemType[];
|
||||
runtimeEdges: RuntimeEdgeItemType[];
|
||||
params: T;
|
||||
};
|
61
packages/global/core/workflow/type/io.d.ts
vendored
Normal file
61
packages/global/core/workflow/type/io.d.ts
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
import { LLMModelTypeEnum } from '../../ai/constants';
|
||||
import { WorkflowIOValueTypeEnum, NodeInputKeyEnum, NodeOutputKeyEnum } from '../constants';
|
||||
import { FlowNodeInputTypeEnum, FlowNodeOutputTypeEnum } from '../node/constant';
|
||||
import { EditInputFieldMapType, EditNodeFieldType, EditOutputFieldMapType } from '../node/type';
|
||||
|
||||
export type FlowNodeInputItemType = {
|
||||
selectedTypeIndex?: number;
|
||||
renderTypeList: FlowNodeInputTypeEnum[]; // Node Type. Decide on a render style
|
||||
|
||||
key: `${NodeInputKeyEnum}` | string;
|
||||
valueType?: WorkflowIOValueTypeEnum; // data type
|
||||
value?: any;
|
||||
label: string;
|
||||
debugLabel?: string;
|
||||
description?: string; // field desc
|
||||
required?: boolean;
|
||||
toolDescription?: string; // If this field is not empty, it is entered as a tool
|
||||
|
||||
maxLength?: number; // input,textarea
|
||||
|
||||
// edit
|
||||
canEdit?: boolean;
|
||||
|
||||
// render components params
|
||||
referencePlaceholder?: string;
|
||||
placeholder?: string; // input,textarea
|
||||
|
||||
list?: { label: string; value: any }[]; // select
|
||||
|
||||
markList?: { label: string; value: any }[]; // slider
|
||||
step?: number; // slider
|
||||
max?: number; // slider, number input
|
||||
min?: number; // slider, number input
|
||||
|
||||
defaultValue?: string;
|
||||
|
||||
// dynamic input
|
||||
editField?: EditNodeFieldType['editField'];
|
||||
dynamicParamDefaultValue?: EditNodeFieldType['dynamicParamDefaultValue'];
|
||||
|
||||
llmModelType?: `${LLMModelTypeEnum}`;
|
||||
};
|
||||
|
||||
export type FlowNodeOutputItemType = {
|
||||
id: string; // output unique id(Does not follow the key change)
|
||||
type: `${FlowNodeOutputTypeEnum}`;
|
||||
key: `${NodeOutputKeyEnum}` | string;
|
||||
valueType?: WorkflowIOValueTypeEnum;
|
||||
value?: any;
|
||||
|
||||
label?: string;
|
||||
description?: string;
|
||||
defaultValue?: any;
|
||||
required?: boolean;
|
||||
|
||||
// component params
|
||||
canEdit?: boolean;
|
||||
editField?: EditOutputFieldMapType; // 添加
|
||||
};
|
||||
|
||||
export type ReferenceValueProps = [string, string | undefined];
|
134
packages/global/core/workflow/utils.ts
Normal file
134
packages/global/core/workflow/utils.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { FlowNodeOutputTypeEnum, FlowNodeTypeEnum } from './node/constant';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
VariableInputEnum,
|
||||
variableMap
|
||||
} from './constants';
|
||||
import { FlowNodeInputItemType, FlowNodeOutputItemType } from './type/io.d';
|
||||
import { StoreNodeItemType } from './type';
|
||||
import type {
|
||||
VariableItemType,
|
||||
AppTTSConfigType,
|
||||
AppWhisperConfigType,
|
||||
AppScheduledTriggerConfigType
|
||||
} from '../app/type';
|
||||
import { EditorVariablePickerType } from '../../../web/components/common/Textarea/PromptEditor/type';
|
||||
import { defaultWhisperConfig } from '../app/constants';
|
||||
|
||||
export const getHandleId = (nodeId: string, type: 'source' | 'target', key: string) => {
|
||||
return `${nodeId}-${type}-${key}`;
|
||||
};
|
||||
|
||||
export const checkInputIsReference = (input: FlowNodeInputItemType) => {
|
||||
const value = input.value;
|
||||
if (
|
||||
Array.isArray(value) &&
|
||||
value.length === 2 &&
|
||||
typeof value[0] === 'string' &&
|
||||
typeof value[1] === 'string'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/* node */
|
||||
export const getGuideModule = (modules: StoreNodeItemType[]) =>
|
||||
modules.find((item) => item.flowNodeType === FlowNodeTypeEnum.systemConfig);
|
||||
|
||||
export const splitGuideModule = (guideModules?: StoreNodeItemType) => {
|
||||
const welcomeText: string =
|
||||
guideModules?.inputs?.find((item) => item.key === NodeInputKeyEnum.welcomeText)?.value || '';
|
||||
|
||||
const variableModules: VariableItemType[] =
|
||||
guideModules?.inputs.find((item) => item.key === NodeInputKeyEnum.variables)?.value || [];
|
||||
|
||||
const questionGuide: boolean =
|
||||
!!guideModules?.inputs?.find((item) => item.key === NodeInputKeyEnum.questionGuide)?.value ||
|
||||
false;
|
||||
|
||||
const ttsConfig: AppTTSConfigType = guideModules?.inputs?.find(
|
||||
(item) => item.key === NodeInputKeyEnum.tts
|
||||
)?.value || { type: 'web' };
|
||||
|
||||
const whisperConfig: AppWhisperConfigType =
|
||||
guideModules?.inputs?.find((item) => item.key === NodeInputKeyEnum.whisper)?.value ||
|
||||
defaultWhisperConfig;
|
||||
|
||||
const scheduledTriggerConfig: AppScheduledTriggerConfigType | null =
|
||||
guideModules?.inputs?.find((item) => item.key === NodeInputKeyEnum.scheduleTrigger)?.value ??
|
||||
null;
|
||||
|
||||
return {
|
||||
welcomeText,
|
||||
variableModules,
|
||||
questionGuide,
|
||||
ttsConfig,
|
||||
whisperConfig,
|
||||
scheduledTriggerConfig
|
||||
};
|
||||
};
|
||||
|
||||
export const getOrInitModuleInputValue = (input: FlowNodeInputItemType) => {
|
||||
if (input.value !== undefined || !input.valueType) return input.value;
|
||||
|
||||
const map: Record<string, any> = {
|
||||
[WorkflowIOValueTypeEnum.boolean]: false,
|
||||
[WorkflowIOValueTypeEnum.number]: 0,
|
||||
[WorkflowIOValueTypeEnum.string]: ''
|
||||
};
|
||||
|
||||
return map[input.valueType];
|
||||
};
|
||||
|
||||
export const getModuleInputUiField = (input: FlowNodeInputItemType) => {
|
||||
// if (input.renderTypeList === FlowNodeInputTypeEnum.input || input.type === FlowNodeInputTypeEnum.textarea) {
|
||||
// return {
|
||||
// placeholder: input.placeholder || input.description
|
||||
// };
|
||||
// }
|
||||
return {};
|
||||
};
|
||||
|
||||
export const pluginData2FlowNodeIO = (
|
||||
nodes: StoreNodeItemType[]
|
||||
): {
|
||||
inputs: FlowNodeInputItemType[];
|
||||
outputs: FlowNodeOutputItemType[];
|
||||
} => {
|
||||
const pluginInput = nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput);
|
||||
const pluginOutput = nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginOutput);
|
||||
|
||||
return {
|
||||
inputs: pluginInput
|
||||
? pluginInput.inputs.map((item) => ({
|
||||
...item,
|
||||
...getModuleInputUiField(item),
|
||||
value: getOrInitModuleInputValue(item),
|
||||
canEdit: false
|
||||
}))
|
||||
: [],
|
||||
outputs: pluginOutput
|
||||
? [
|
||||
...pluginOutput.inputs.map((item) => ({
|
||||
id: item.key,
|
||||
type: FlowNodeOutputTypeEnum.static,
|
||||
key: item.key,
|
||||
valueType: item.valueType,
|
||||
label: item.label || item.key,
|
||||
description: item.description
|
||||
}))
|
||||
]
|
||||
: []
|
||||
};
|
||||
};
|
||||
|
||||
export const formatEditorVariablePickerIcon = (
|
||||
variables: { key: string; label: string; type?: `${VariableInputEnum}` }[]
|
||||
): EditorVariablePickerType[] => {
|
||||
return variables.map((item) => ({
|
||||
...item,
|
||||
icon: item.type ? variableMap[item.type]?.icon : variableMap['input'].icon
|
||||
}));
|
||||
};
|
Reference in New Issue
Block a user