Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: admin add custom plugin; fix: Plugin run variable error; #2582

Merged
merged 6 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 28 additions & 27 deletions docSite/content/zh-cn/docs/development/upgrading/4810.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,30 +54,31 @@ curl --location --request POST 'https://{{host}}/api/admin/initv4810' \
5. 新增 - 工作流本次编辑记录,取代自动保存
6. 新增 - 工作流版本支持重命名
7. 新增 - 应用调用迁移成单独节点,同时可以传递全局变量和用户的文件。
8. 商业版新增 - 飞书机器人接入
9. 商业版新增 - 公众号接入接入
10. 商业版新增 - 自助开票申请
11. 商业版新增 - SSO 定制
12. 优化 - SSE 响应优化。
13. 优化 - 无 SSL 证书情况下,优化复制。
14. 优化 - 单选框打开后自动滚动到选中的位置。
15. 优化 - 知识库集合禁用,目录禁用会递归修改其下所有 children 的禁用状态。
16. 优化 - 节点选择,避免切换 tab 时候,path 加载报错。
17. 优化 - 最新 React Markdown 组件,支持 Base64 图片。
18. 优化 - 知识库列表 UI。
19. 优化 - 知识库详情页 UI。
20. 优化 - 支持无网络配置情况下运行。
21. 优化 - 部分全局变量,增加数据类型约束。
22. 修复 - 全局变量 key 可能重复。
23. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
24. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
25. 修复 - 选择 Milvus 部署时,无法导出知识库。
26. 修复 - 创建 APP 副本,无法复制系统配置。
27. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
28. 修复 - 内容提取的数据类型与输出数据类型未一致。
29. 修复 - 工作流运行时间统计错误。
30. 修复 - stream 模式下,工具调用有可能出现 undefined
31. 修复 - 全局变量在 API 中无法持久化。
32. 修复 - OpenAPI,detail=false模式下,不应该返回 tool 调用结果,仅返回文字。(可解决 cow 不适配问题)
33. 修复 - 知识库标签重复加载。
34. 修复 - Debug 模式下,循环调用边问题。
8. 新增 - 插件增加使用说明配置。
9. 商业版新增 - 飞书机器人接入
10. 商业版新增 - 公众号接入接入
11. 商业版新增 - 自助开票申请
12. 商业版新增 - SSO 定制
13. 优化 - SSE 响应优化。
14. 优化 - 无 SSL 证书情况下,优化复制。
15. 优化 - 单选框打开后自动滚动到选中的位置。
16. 优化 - 知识库集合禁用,目录禁用会递归修改其下所有 children 的禁用状态。
17. 优化 - 节点选择,避免切换 tab 时候,path 加载报错。
18. 优化 - 最新 React Markdown 组件,支持 Base64 图片。
19. 优化 - 知识库列表 UI。
20. 优化 - 知识库详情页 UI。
21. 优化 - 支持无网络配置情况下运行。
22. 优化 - 部分全局变量,增加数据类型约束。
23. 修复 - 全局变量 key 可能重复。
24. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
25. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
26. 修复 - 选择 Milvus 部署时,无法导出知识库。
27. 修复 - 创建 APP 副本,无法复制系统配置。
28. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
29. 修复 - 内容提取的数据类型与输出数据类型未一致。
30. 修复 - 工作流运行时间统计错误。
31. 修复 - stream 模式下,工具调用有可能出现 undefined
32. 修复 - 全局变量在 API 中无法持久化。
33. 修复 - OpenAPI,detail=false模式下,不应该返回 tool 调用结果,仅返回文字。(可解决 cow 不适配问题)
34. 修复 - 知识库标签重复加载。
35. 修复 - Debug 模式下,循环调用边问题。
8 changes: 4 additions & 4 deletions packages/global/core/workflow/runtime/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,10 @@ export type DispatchNodeResponseType = {
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[];
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]?: ChatNodeUsageType[]; // Node total usage
[DispatchNodeResponseKeyEnum.childrenResponses]?: DispatchNodeResultType[]; // Children node response
[DispatchNodeResponseKeyEnum.toolResponses]?: ToolRunResponseItemType; // Tool response
[DispatchNodeResponseKeyEnum.assistantResponses]?: ChatItemValueItemType[]; // Assistant response(Store to db)
} & T;

/* Single node props */
Expand Down
2 changes: 1 addition & 1 deletion packages/global/core/workflow/template/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { HttpNode468 } from './system/http468';
import { ToolModule } from './system/tools';
import { StopToolNode } from './system/stopTool';

import { RunAppModule } from './system/runApp/index';
import { RunAppModule } from './system/abandoned/runApp/index';
import { PluginInputModule } from './system/pluginInput';
import { PluginOutputModule } from './system/pluginOutput';
import { RunPluginModule } from './system/runPlugin';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import {
FlowNodeInputTypeEnum,
FlowNodeOutputTypeEnum,
FlowNodeTypeEnum
} from '../../../node/constant';
import { FlowNodeTemplateType } from '../../../type/node.d';
} from '../../../../node/constant';
import { FlowNodeTemplateType } from '../../../../type/node';
import {
WorkflowIOValueTypeEnum,
NodeInputKeyEnum,
NodeOutputKeyEnum,
FlowNodeTemplateTypeEnum
} from '../../../constants';
import { Input_Template_History, Input_Template_UserChatInput } from '../../input';
import { getHandleConfig } from '../../utils';
import { i18nT } from '../../../../../../web/i18n/utils';
} from '../../../../constants';
import { Input_Template_History, Input_Template_UserChatInput } from '../../../input';
import { getHandleConfig } from '../../../utils';
import { i18nT } from '../../../../../../../web/i18n/utils';

export const RunAppModule: FlowNodeTemplateType = {
id: FlowNodeTypeEnum.runApp,
Expand Down
4 changes: 3 additions & 1 deletion packages/global/core/workflow/type/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export type WorkflowTemplateBasicType = {
};
export type WorkflowTemplateType = {
id: string;
parentId?: string;
parentId?: ParentIdType;
isFolder?: boolean;

name: string;
Expand Down Expand Up @@ -62,6 +62,8 @@ export type TemplateMarketListItemType = {

// system plugin
export type SystemPluginTemplateItemType = WorkflowTemplateType & {
customWorkflow?: string;

templateType: FlowNodeTemplateTypeEnum;
isTool?: boolean;

Expand Down
12 changes: 8 additions & 4 deletions packages/global/core/workflow/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { IfElseResultEnum } from './template/system/ifElse/constant';
import { RuntimeNodeItemType } from './runtime/type';
import { getReferenceVariableValue } from './runtime/utils';
import { Input_Template_History, Input_Template_UserChatInput } from './template/input';
import { i18nT } from '../../../web/i18n/utils';

export const getHandleId = (nodeId: string, type: 'source' | 'target', key: string) => {
return `${nodeId}-${type}-${key}`;
Expand Down Expand Up @@ -254,8 +255,8 @@ export const appData2FlowNodeIO = ({
id: NodeOutputKeyEnum.history,
key: NodeOutputKeyEnum.history,
required: true,
label: 'core.module.output.label.New context',
description: 'core.module.output.description.New context',
label: i18nT('common:core.module.output.label.New context'),
description: i18nT('common:core.module.output.description.New context'),
valueType: WorkflowIOValueTypeEnum.chatHistory,
valueDesc: chatHistoryValueDesc,
type: FlowNodeOutputTypeEnum.static
Expand All @@ -264,8 +265,8 @@ export const appData2FlowNodeIO = ({
id: NodeOutputKeyEnum.answerText,
key: NodeOutputKeyEnum.answerText,
required: false,
label: 'core.module.output.label.Ai response content',
description: 'core.module.output.description.Ai response content',
label: i18nT('common:core.module.output.label.Ai response content'),
description: i18nT('common:core.module.output.description.Ai response content'),
valueType: WorkflowIOValueTypeEnum.string,
type: FlowNodeOutputTypeEnum.static
}
Expand Down Expand Up @@ -325,6 +326,9 @@ export const updatePluginInputByVariables = (
);
};

/* Remove pluginInput variables from global variables
(completions api: Plugin input get value from global variables)
*/
export const removePluginInputVariables = (
variables: Record<string, any>,
nodes: RuntimeNodeItemType[]
Expand Down
3 changes: 2 additions & 1 deletion packages/service/core/app/plugin/systemPluginSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const SystemPluginSchema = new Schema({
currentCost: {
type: Number,
default: 0
}
},
customConfig: Object
});

SystemPluginSchema.index({ pluginId: 1 });
Expand Down
16 changes: 15 additions & 1 deletion packages/service/core/app/plugin/type.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
import {
SystemPluginTemplateItemType,
WorkflowTemplateBasicType
} from '@fastgpt/global/core/workflow/type';

export type SystemPluginConfigSchemaType = {
pluginId: string;
Expand All @@ -7,4 +11,14 @@ export type SystemPluginConfigSchemaType = {
currentCost: number;
isActive: boolean;
inputConfig: SystemPluginTemplateItemType['inputConfig'];

customConfig?: {
name: string;
avatar: string;
intro?: string;
version: string;
weight?: number;
workflow: WorkflowTemplateBasicType;
templateType: FlowNodeTemplateTypeEnum;
};
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* Abandoned */
import type { ChatItemType } from '@fastgpt/global/core/chat/type.d';
import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
import { SelectAppItemType } from '@fastgpt/global/core/workflow/template/system/runApp/type';
import { SelectAppItemType } from '@fastgpt/global/core/workflow/template/system/abandoned/runApp/type';
import { dispatchWorkFlow } from '../index';
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '@fastgpt/global/core/workflow/runtime/utils';
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import { getHistories } from '../utils';
import { filterSystemVariables, getHistories } from '../utils';
import { chatValue2RuntimePrompt, runtimePrompt2ChatsValue } from '@fastgpt/global/core/chat/adapt';
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
import { authAppByTmbId } from '../../../../support/permission/app/auth';
Expand All @@ -34,10 +34,11 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
query,
node: { pluginId },
workflowStreamResponse,
params
params,
variables
} = props;

const { userChatInput, history, ...variables } = params;
const { userChatInput, history, ...childrenAppVariables } = params;
if (!userChatInput) {
return Promise.reject('Input is empty');
}
Expand All @@ -63,6 +64,13 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
const chatHistories = getHistories(history, histories);
const { files } = chatValue2RuntimePrompt(query);

// Concat variables
const systemVariables = filterSystemVariables(variables);
const childrenRunVariables = {
...systemVariables,
...childrenAppVariables
};

const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({
...props,
app: appData,
Expand All @@ -76,7 +84,7 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
files,
text: userChatInput
}),
variables: variables
variables: childrenRunVariables
});

const completeMessages = chatHistories.concat([
Expand Down
9 changes: 5 additions & 4 deletions packages/service/core/workflow/dispatch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { dispatchAnswer } from './tools/answer';
import { dispatchClassifyQuestion } from './agent/classifyQuestion';
import { dispatchContentExtract } from './agent/extract';
import { dispatchHttp468Request } from './tools/http468';
import { dispatchAppRequest } from './tools/runApp';
import { dispatchAppRequest } from './abandoned/runApp';
import { dispatchQueryExtension } from './tools/queryExternsion';
import { dispatchRunPlugin } from './plugin/run';
import { dispatchPluginInput } from './plugin/runInput';
Expand Down Expand Up @@ -63,7 +63,7 @@ import {
InteractiveNodeResponseItemType,
UserSelectInteractive
} from '@fastgpt/global/core/workflow/template/system/userSelect/type';
import { dispatchRunAppNode } from './agent/runAppModule';
import { dispatchRunAppNode } from './agent/runApp';

const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
Expand All @@ -74,7 +74,6 @@ const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.classifyQuestion]: dispatchClassifyQuestion,
[FlowNodeTypeEnum.contentExtract]: dispatchContentExtract,
[FlowNodeTypeEnum.httpRequest468]: dispatchHttp468Request,
[FlowNodeTypeEnum.runApp]: dispatchAppRequest,
[FlowNodeTypeEnum.appModule]: dispatchRunAppNode,
[FlowNodeTypeEnum.pluginModule]: dispatchRunPlugin,
[FlowNodeTypeEnum.pluginInput]: dispatchPluginInput,
Expand All @@ -95,7 +94,9 @@ const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.systemConfig]: dispatchSystemConfig,
[FlowNodeTypeEnum.pluginConfig]: () => Promise.resolve(),
[FlowNodeTypeEnum.emptyNode]: () => Promise.resolve(),
[FlowNodeTypeEnum.globalVariable]: () => Promise.resolve()
[FlowNodeTypeEnum.globalVariable]: () => Promise.resolve(),

[FlowNodeTypeEnum.runApp]: dispatchAppRequest // abandoned
};

type Props = ChatDispatchProps & {
Expand Down
49 changes: 24 additions & 25 deletions packages/service/core/workflow/dispatch/plugin/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import {
storeNodes2RuntimeNodes
} from '@fastgpt/global/core/workflow/runtime/utils';
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
import { updateToolInputValue } from '../agent/runTool/utils';
import { authPluginByTmbId } from '../../../../support/permission/app/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { computedPluginUsage } from '../../../app/plugin/utils';
import { filterSystemVariables } from '../utils';

type RunPluginProps = ModuleDispatchProps<{
[key: string]: any;
Expand All @@ -25,7 +25,7 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
app: workflowApp,
mode,
teamId,
params: data
params: data // Plugin input
} = props;

if (!pluginId) {
Expand All @@ -41,32 +41,31 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi

const plugin = await getPluginRuntimeById(pluginId);

// concat dynamic inputs
const inputModule = plugin.nodes.find(
(item) => item.flowNodeType === FlowNodeTypeEnum.pluginInput
);
if (!inputModule) return Promise.reject('Plugin error, It has no set input.');
const runtimeNodes = storeNodes2RuntimeNodes(
plugin.nodes,
getWorkflowEntryNodeIds(plugin.nodes)
).map((node) => {
// Update plugin input value
if (node.flowNodeType === FlowNodeTypeEnum.pluginInput) {
return {
...node,
showStatus: false,
inputs: node.inputs.map((input) => ({
...input,
value: data[input.key] ?? input.value
}))
};
}
return {
...node,
showStatus: false
};
});

const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({
...props,
runtimeNodes: storeNodes2RuntimeNodes(plugin.nodes, getWorkflowEntryNodeIds(plugin.nodes)).map(
(node) => {
if (node.flowNodeType === FlowNodeTypeEnum.pluginInput) {
return {
...node,
showStatus: false,
inputs: updateToolInputValue({
inputs: node.inputs,
params: data
})
};
}
return {
...node,
showStatus: false
};
}
),
variables: filterSystemVariables(props.variables),
runtimeNodes,
runtimeEdges: initWorkflowEdgeStatus(plugin.edges)
});

Expand Down
9 changes: 9 additions & 0 deletions packages/service/core/workflow/dispatch/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,15 @@ export const removeSystemVariable = (variables: Record<string, any>) => {

return copyVariables;
};
export const filterSystemVariables = (variables: Record<string, any>) => {
return {
appId: variables.appId,
chatId: variables.chatId,
responseChatItemId: variables.responseChatItemId,
histories: variables.histories,
cTime: variables.cTime
};
};

export const formatHttpError = (error: any) => {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const RenderInput = () => {
rounded={'md'}
fontSize={'sm'}
color={'myGray.600'}
mb={4}
>
<Markdown source={chatConfig.instruction} />
</Box>
Expand Down
Loading
Loading