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: add tool params node & tool params add array type #2824

Merged
merged 8 commits into from
Sep 28, 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
1 change: 1 addition & 0 deletions packages/global/core/workflow/node/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export enum FlowNodeTypeEnum {
queryExtension = 'cfr',
tools = 'tools',
stopTool = 'stopTool',
toolParams = 'toolParams',
lafModule = 'lafModule',
ifElseNode = 'ifElseNode',
variableUpdate = 'variableUpdate',
Expand Down
3 changes: 3 additions & 0 deletions packages/global/core/workflow/runtime/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ export type DispatchNodeResponseType = {

// form input
formInputResult?: string;

// tool params
toolParamsResult?: Record<string, any>;
};

export type DispatchNodeResultType<T = {}> = {
Expand Down
3 changes: 2 additions & 1 deletion packages/global/core/workflow/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ export const getReferenceVariableValue = ({
nodes: RuntimeNodeItemType[];
variables: Record<string, any>;
}) => {
if (!isReferenceValue(value)) {
const nodeIds = nodes.map((node) => node.nodeId);
if (!isReferenceValue(value, nodeIds)) {
return value;
}
const sourceNodeId = value[0];
Expand Down
6 changes: 4 additions & 2 deletions packages/global/core/workflow/template/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,19 @@ import { LoopNode } from './system/loop/loop';
import { LoopStartNode } from './system/loop/loopStart';
import { LoopEndNode } from './system/loop/loopEnd';
import { FormInputNode } from './system/interactive/formInput';
import { ToolParamsNode } from './system/toolParams';

const systemNodes: FlowNodeTemplateType[] = [
AiChatModule,
TextEditorNode,
AssignedAnswerModule,
DatasetSearchModule,
ClassifyQuestionModule,
ContextExtractModule,
DatasetConcatModule,
ToolModule,
ToolParamsNode,
StopToolNode,
ClassifyQuestionModule,
ContextExtractModule,
ReadFilesNode,
HttpNode468,
AiQueryExtension,
Expand Down
20 changes: 20 additions & 0 deletions packages/global/core/workflow/template/system/toolParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { FlowNodeTypeEnum } from '../../node/constant';
import { FlowNodeTemplateType } from '../../type/node';
import { FlowNodeTemplateTypeEnum } from '../../constants';
import { getHandleConfig } from '../utils';
import { i18nT } from '../../../../../web/i18n/utils';

export const ToolParamsNode: FlowNodeTemplateType = {
id: FlowNodeTypeEnum.toolParams,
templateType: FlowNodeTemplateTypeEnum.ai,
flowNodeType: FlowNodeTypeEnum.toolParams,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: 'core/workflow/template/toolParams',
name: i18nT('workflow:tool_params_config'),
intro: i18nT('workflow:intro_tool_params_config'),
version: '4811',
isTool: true,
inputs: [],
outputs: []
};
1 change: 1 addition & 0 deletions packages/global/core/workflow/type/io.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export type FlowNodeInputItemType = InputComponentPropsType & {
description?: string; // field desc
required?: boolean;
toolDescription?: string; // If this field is not empty, it is entered as a tool
enum?: string;

// render components params
canEdit?: boolean; // dynamic inputs
Expand Down
4 changes: 2 additions & 2 deletions packages/global/core/workflow/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ export const formatEditorVariablePickerIcon = (
}));
};

export const isReferenceValue = (value: any): boolean => {
return Array.isArray(value) && value.length === 2 && typeof value[0] === 'string';
export const isReferenceValue = (value: any, nodeIds: string[]): boolean => {
return Array.isArray(value) && value.length === 2 && nodeIds.includes(value[0]);
};

export const getElseIFLabel = (i: number) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,16 @@ export const runToolWithFunctionCall = async (
type: string;
description: string;
required?: boolean;
enum?: string[];
}
> = {};
item.toolParams.forEach((item) => {
const isArray = item.valueType?.startsWith('array');
properties[item.key] = {
type: item.valueType || 'string',
description: item.toolDescription || ''
type: isArray ? 'array' : item.valueType || 'string',
...(isArray && { items: { type: item.valueType?.slice(5).toLowerCase() || 'string' } }),
description: item.toolDescription || '',
enum: item.enum?.split('\n').filter(Boolean) || []
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,16 @@ export const runToolWithPromptCall = async (
type: string;
description: string;
required?: boolean;
enum?: string[];
}
> = {};
item.toolParams.forEach((item) => {
const isArray = item.valueType?.startsWith('array');
properties[item.key] = {
type: 'string',
description: item.toolDescription || ''
type: isArray ? 'array' : item.valueType || 'string',
...(isArray && { items: { type: item.valueType?.slice(5).toLowerCase() || 'string' } }),
description: item.toolDescription || '',
enum: item.enum?.split('\n').filter(Boolean) || []
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,20 @@ export const runToolWithToolChoice = async (
{
type: string;
description: string;
enum?: string[];
required?: boolean;
items?: {
type: string;
};
}
> = {};
item.toolParams.forEach((item) => {
const isArray = item.valueType?.startsWith('array');
properties[item.key] = {
type: item.valueType || 'string',
description: item.toolDescription || ''
type: isArray ? 'array' : item.valueType || 'string',
...(isArray && { items: { type: item.valueType?.slice(5).toLowerCase() || 'string' } }),
description: item.toolDescription || '',
enum: item.enum?.split('\n').filter(Boolean) || []
};
});

Expand Down Expand Up @@ -138,7 +145,6 @@ export const runToolWithToolChoice = async (
toolModel
);

// console.log(JSON.stringify(requestBody, null, 2));
/* Run llm */
const ai = getAIApi({
timeout: 480000
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';

export type Props = ModuleDispatchProps<{}>;
export type Response = DispatchNodeResultType<{}>;

export const dispatchToolParams = (props: Props): Response => {
const { params } = props;

return {
...params,
[DispatchNodeResponseKeyEnum.nodeResponse]: {
toolParamsResult: params
}
};
};
2 changes: 2 additions & 0 deletions packages/service/core/workflow/dispatch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import { dispatchLoop } from './loop/runLoop';
import { dispatchLoopEnd } from './loop/runLoopEnd';
import { dispatchLoopStart } from './loop/runLoopStart';
import { dispatchFormInput } from './interactive/formInput';
import { dispatchToolParams } from './agent/runTool/toolParams';

const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
Expand All @@ -87,6 +88,7 @@ const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.queryExtension]: dispatchQueryExtension,
[FlowNodeTypeEnum.tools]: dispatchRunTools,
[FlowNodeTypeEnum.stopTool]: dispatchStopToolCall,
[FlowNodeTypeEnum.toolParams]: dispatchToolParams,
[FlowNodeTypeEnum.lafModule]: dispatchLafRequest,
[FlowNodeTypeEnum.ifElseNode]: dispatchIfElse,
[FlowNodeTypeEnum.variableUpdate]: dispatchUpdateVariable,
Expand Down
18 changes: 10 additions & 8 deletions packages/web/components/common/Icon/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ export const iconPaths = {
'common/importLight': () => import('./icons/common/importLight.svg'),
'common/info': () => import('./icons/common/info.svg'),
'common/inviteLight': () => import('./icons/common/inviteLight.svg'),
'common/language/America': () => import('./icons/common/language/America.svg'),
'common/language/China': () => import('./icons/common/language/China.svg'),
'common/language/en': () => import('./icons/common/language/en.svg'),
'common/language/zh': () => import('./icons/common/language/zh.svg'),
'common/language/China': () => import('./icons/common/language/China.svg'),
'common/language/America': () => import('./icons/common/language/America.svg'),
'common/leftArrowLight': () => import('./icons/common/leftArrowLight.svg'),
'common/line': () => import('./icons/common/line.svg'),
'common/lineChange': () => import('./icons/common/lineChange.svg'),
Expand Down Expand Up @@ -212,8 +212,10 @@ export const iconPaths = {
'core/workflow/runSkip': () => import('./icons/core/workflow/runSkip.svg'),
'core/workflow/runSuccess': () => import('./icons/core/workflow/runSuccess.svg'),
'core/workflow/running': () => import('./icons/core/workflow/running.svg'),
'core/workflow/template/BI': () => import('./icons/core/workflow/template/BI.svg'),
'core/workflow/template/FileRead': () => import('./icons/core/workflow/template/FileRead.svg'),
'core/workflow/template/aiChat': () => import('./icons/core/workflow/template/aiChat.svg'),
'core/workflow/template/baseChart': () => import('./icons/core/workflow/template/baseChart.svg'),
'core/workflow/template/codeRun': () => import('./icons/core/workflow/template/codeRun.svg'),
'core/workflow/template/customFeedback': () =>
import('./icons/core/workflow/template/customFeedback.svg'),
Expand Down Expand Up @@ -247,15 +249,17 @@ export const iconPaths = {
'core/workflow/template/reply': () => import('./icons/core/workflow/template/reply.svg'),
'core/workflow/template/runApp': () => import('./icons/core/workflow/template/runApp.svg'),
'core/workflow/template/stopTool': () => import('./icons/core/workflow/template/stopTool.svg'),
'core/workflow/template/toolkitActive': () =>
import('./icons/core/workflow/template/toolkitActive.svg'),
'core/workflow/template/toolkitInactive': () =>
import('./icons/core/workflow/template/toolkitInactive.svg'),
'core/workflow/template/systemConfig': () =>
import('./icons/core/workflow/template/systemConfig.svg'),
'core/workflow/template/textConcat': () =>
import('./icons/core/workflow/template/textConcat.svg'),
'core/workflow/template/toolCall': () => import('./icons/core/workflow/template/toolCall.svg'),
'core/workflow/template/toolParams': () =>
import('./icons/core/workflow/template/toolParams.svg'),
'core/workflow/template/toolkitActive': () =>
import('./icons/core/workflow/template/toolkitActive.svg'),
'core/workflow/template/toolkitInactive': () =>
import('./icons/core/workflow/template/toolkitInactive.svg'),
'core/workflow/template/userSelect': () =>
import('./icons/core/workflow/template/userSelect.svg'),
'core/workflow/template/variable': () => import('./icons/core/workflow/template/variable.svg'),
Expand All @@ -267,8 +271,6 @@ export const iconPaths = {
'core/workflow/undo': () => import('./icons/core/workflow/undo.svg'),
'core/workflow/upload': () => import('./icons/core/workflow/upload.svg'),
'core/workflow/versionHistories': () => import('./icons/core/workflow/versionHistories.svg'),
'core/workflow/template/baseChart': () => import('./icons/core/workflow/template/baseChart.svg'),
'core/workflow/template/BI': () => import('./icons/core/workflow/template/BI.svg'),
date: () => import('./icons/date.svg'),
delete: () => import('./icons/delete.svg'),
edit: () => import('./icons/edit.svg'),
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/web/i18n/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"UnKnow": "Unknown",
"Warning": "Warning",
"add_new": "Add New",
"add_new_param": "Add new param",
"back": "Back",
"chose_condition": "Choose Condition",
"chosen": "Chosen",
Expand Down Expand Up @@ -1110,7 +1111,6 @@
"tag_list": "Tag List",
"team_tag": "Team Tag",
"textarea_variable_picker_tip": "Enter \"/\" to select a variable",
"tool_field": "Tool Field Parameter Configuration",
"undefined_var": "Referenced an undefined variable, add it automatically?",
"unit.character": "Character",
"unit.minute": "Minute",
Expand Down
12 changes: 12 additions & 0 deletions packages/web/i18n/en/workflow.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"create_link_error": "Error creating link",
"custom_feedback": "Custom Feedback",
"custom_input": "Custom Input",
"custom_tool_input": "Custom tool input",
"dataset_quote_role": "Role",
"dataset_quote_role_system_option_desc": "Historical records should be consistent first (recommended)",
"dataset_quote_role_tip": "When set to System, the knowledge base reference content will be placed in the system message, which can ensure the continuity of the history record, but the constraint effect may not be good.\n\nWhen set to User, the knowledge base reference content will be placed in the user message, and the {{question}} variable location needs to be specified. \nIt will have a certain impact on the consistency of historical records, but usually the constraint effect is better.",
Expand Down Expand Up @@ -77,6 +78,7 @@
"intro_text_concatenation": "Can process and output fixed or incoming text. Non-string type data will be converted to string type.",
"intro_text_content_extraction": "Can extract specified data from text, such as SQL statements, search keywords, code, etc.",
"intro_tool_call_termination": "This module needs to be configured for tool calls. When this module is executed, the current tool call will be forcibly terminated, and AI will no longer answer questions based on the tool call results.",
"intro_tool_params_config": " This module works with tool calls. It creates required tool parameters. Tool calls automatically generate parameter content and pass it to corresponding function blocks.",
"is_empty": "Is Empty",
"is_equal_to": "Is Equal To",
"is_not_empty": "Is Not Empty",
Expand Down Expand Up @@ -155,7 +157,17 @@
"text_to_extract": "Text to Extract",
"these_variables_will_be_input_parameters_for_code_execution": "These variables will be input parameters for code execution",
"tool_call_termination": "Tool Call Termination",
"tool_field": " Tool Field Parameter Configuration",
"tool_input": "Tool Input",
"tool_params.enum_placeholder": "apple \npeach \nwatermelon",
"tool_params.enum_values": "Enum values",
"tool_params.enum_values_tip": "List the possible values for this field, one per line",
"tool_params.params_description": "Description",
"tool_params.params_description_placeholder": "Name/Age/SQL statement..",
"tool_params.params_name": "Name",
"tool_params.params_name_placeholder": "name/age/sql",
"tool_params.tool_params_result": "Tool params result",
"tool_params_config": "Tool params config",
"trigger_after_application_completion": "Will be triggered after the application is fully completed",
"update_link_error": "Error updating link",
"update_specified_node_output_or_global_variable": "Can update the output value of a specified node or update global variables",
Expand Down
4 changes: 2 additions & 2 deletions packages/web/i18n/zh/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"UnKnow": "未知",
"Warning": "提示",
"add_new": "新增",
"add_new_param": "新增参数",
"back": "返回",
"chose_condition": "选择条件",
"chosen": "已选",
Expand Down Expand Up @@ -732,8 +733,8 @@
"core.module.template.empty_plugin": "空白插件",
"core.module.template.empty_workflow": "空白工作流",
"core.module.template.http body placeholder": "与 Apifox 相同的语法",
"core.module.template.self_output": "插件输出",
"core.module.template.self_input": "插件输入",
"core.module.template.self_output": "插件输出",
"core.module.template.system_config": "系统配置",
"core.module.template.system_config_info": "可以配置应用的系统参数",
"core.module.template.work_start": "流程开始",
Expand Down Expand Up @@ -1109,7 +1110,6 @@
"tag_list": "标签列表",
"team_tag": "团队标签",
"textarea_variable_picker_tip": "输入\"/\"可选择变量",
"tool_field": "工具字段参数配置",
"undefined_var": "引用了未定义的变量,是否自动添加?",
"unit.character": "字符",
"unit.minute": "分钟",
Expand Down
12 changes: 12 additions & 0 deletions packages/web/i18n/zh/workflow.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"create_link_error": "创建链接异常",
"custom_feedback": "自定义反馈",
"custom_input": "自定义输入",
"custom_tool_input": "自定义工具参数",
"dataset_quote_role": "角色",
"dataset_quote_role_system_option_desc": "历史记录连贯优先(推荐)",
"dataset_quote_role_tip": "设置为 System 时,将会把知识库引用内容放置到 system 消息中,可以确保历史记录的连贯性,但约束效果可能不佳,需要多调试。\n设置为 User 时,将会把知识库引用内容放置到 user 消息中,并且需要指定 {{question}} 变量位置。会对历史记录连贯性有一定影响,但通常约束效果更优。",
Expand Down Expand Up @@ -77,6 +78,7 @@
"intro_text_concatenation": "可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。",
"intro_text_content_extraction": "可从文本中提取指定的数据,例如:sql语句、搜索关键词、代码等",
"intro_tool_call_termination": "该模块需配置工具调用使用。当该模块被执行时,本次工具调用将会强制结束,并且不再调用AI针对工具调用结果回答问题。",
"intro_tool_params_config": "该模块需要配合工具调用使用。可以创建所需的工具参数,工具调用将自动生成参数内容并传给对应的功能块。",
"is_empty": "为空",
"is_equal_to": "等于",
"is_not_empty": "不为空",
Expand Down Expand Up @@ -155,7 +157,17 @@
"text_to_extract": "需要提取的文本",
"these_variables_will_be_input_parameters_for_code_execution": "这些变量会作为代码的运行的输入参数",
"tool_call_termination": "工具调用终止",
"tool_field": "工具参数配置",
"tool_input": "工具参数",
"tool_params.enum_placeholder": "apple \npeach \nwatermelon",
"tool_params.enum_values": "枚举值(可选)",
"tool_params.enum_values_tip": "列举出该字段可能的值,每行一个",
"tool_params.params_description": "参数描述",
"tool_params.params_description_placeholder": "姓名/年龄/SQL 语句...",
"tool_params.params_name": "参数名",
"tool_params.params_name_placeholder": "name/age/sql",
"tool_params.tool_params_result": "参数配置结果",
"tool_params_config": "工具参数配置",
"trigger_after_application_completion": "将在应用完全结束后触发",
"update_link_error": "更新链接异常",
"update_specified_node_output_or_global_variable": "可以更新指定节点的输出值或更新全局变量",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,12 @@ export const WholeResponseContent = ({

{/* form input */}
<Row label={t('workflow:form_input_result')} value={activeModule?.formInputResult} />

{/* tool params */}
<Row
label={t('workflow:tool_params.tool_params_result')}
value={activeModule?.toolParamsResult}
/>
</Box>
) : null;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,12 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
if (item.flowNodeType === FlowNodeTypeEnum.lafModule && !feConfigs.lafEnv) {
return false;
}
// tool stop
if (!hasToolNode && item.flowNodeType === FlowNodeTypeEnum.stopTool) {
// tool stop or tool params
if (
!hasToolNode &&
(item.flowNodeType === FlowNodeTypeEnum.stopTool ||
item.flowNodeType === FlowNodeTypeEnum.toolParams)
) {
return false;
}
return true;
Expand Down
Loading
Loading