diff --git a/api/core/plugin/entities/parameters.py b/api/core/plugin/entities/parameters.py index bfa662b9f6..7d085e0106 100644 --- a/api/core/plugin/entities/parameters.py +++ b/api/core/plugin/entities/parameters.py @@ -79,6 +79,10 @@ class PluginParameter(BaseModel): default: Union[float, int, str, bool, list, dict] | None = None min: Union[float, int] | None = None max: Union[float, int] | None = None + multiple: bool | None = Field( + default=False, + description="Whether the parameter is multiple select, only valid for select or dynamic-select type", + ) precision: int | None = None options: list[PluginParameterOption] = Field(default_factory=list) @@ -112,8 +116,11 @@ def cast_parameter_value(typ: StrEnum, value: Any, /): ): if value is None: return "" - else: - return value if isinstance(value, str) else str(value) + if isinstance(value, list): + return value + if isinstance(value, str): + return value + return str(value) case PluginParameterType.BOOLEAN: if value is None: diff --git a/api/core/workflow/nodes/tool/entities.py b/api/core/workflow/nodes/tool/entities.py index c1cfbb1edc..0bf274115c 100644 --- a/api/core/workflow/nodes/tool/entities.py +++ b/api/core/workflow/nodes/tool/entities.py @@ -54,8 +54,8 @@ class ToolNodeData(BaseNodeData, ToolEntity): for val in value: if not isinstance(val, str): raise ValueError("value must be a list of strings") - elif typ == "constant" and not isinstance(value, str | int | float | bool | dict): - raise ValueError("value must be a string, int, float, bool or dict") + elif typ == "constant" and not isinstance(value, str | int | float | bool | list | dict): + raise ValueError("value must be a string, int, float, bool, list or dict") return typ tool_parameters: dict[str, ToolInput] diff --git a/web/app/components/header/account-setting/model-provider-page/declarations.ts b/web/app/components/header/account-setting/model-provider-page/declarations.ts index a5dd46b59f..243570da26 100644 --- a/web/app/components/header/account-setting/model-provider-page/declarations.ts +++ b/web/app/components/header/account-setting/model-provider-page/declarations.ts @@ -121,6 +121,7 @@ export type CredentialFormSchemaBase = { label: TypeWithI18N type: FormTypeEnum required: boolean + multiple?: boolean default?: string tooltip?: TypeWithI18N show_on: FormShowOnObject[] diff --git a/web/app/components/workflow/nodes/_base/components/form-input-item.tsx b/web/app/components/workflow/nodes/_base/components/form-input-item.tsx index 419f905fa5..65299911d9 100644 --- a/web/app/components/workflow/nodes/_base/components/form-input-item.tsx +++ b/web/app/components/workflow/nodes/_base/components/form-input-item.tsx @@ -110,6 +110,8 @@ const FormInputItem: FC = ({ return VarType.arrayFile else if (type === FormTypeEnum.file) return VarType.file + else if (isMultipleSelect) + return VarType.array else if (isSelect) return VarType.string // else if (isAppSelector) @@ -129,6 +131,8 @@ const FormInputItem: FC = ({ const getFilterVar = () => { if (isNumber) return (varPayload: any) => varPayload.type === VarType.number + else if (isMultipleSelect) + return (varPayload: any) => [VarType.array, VarType.arrayString, VarType.arrayNumber, VarType.arrayObject].includes(varPayload.type) else if (isString) return (varPayload: any) => [VarType.string, VarType.number, VarType.secret].includes(varPayload.type) else if (isFile)