mirror of
https://gitee.com/dify_ai/dify.git
synced 2024-12-04 04:07:47 +08:00
Fix/workflow tool incorrect parameter configurations (#3402)
Co-authored-by: Joel <iamjoel007@gmail.com>
This commit is contained in:
parent
f7f8ef257c
commit
64e395d6cf
@ -243,6 +243,19 @@ class Tool(BaseModel, ABC):
|
|||||||
tool_parameters[parameter.name] = float(tool_parameters[parameter.name])
|
tool_parameters[parameter.name] = float(tool_parameters[parameter.name])
|
||||||
elif parameter.type == ToolParameter.ToolParameterType.BOOLEAN:
|
elif parameter.type == ToolParameter.ToolParameterType.BOOLEAN:
|
||||||
if not isinstance(tool_parameters[parameter.name], bool):
|
if not isinstance(tool_parameters[parameter.name], bool):
|
||||||
|
# check if it is a string
|
||||||
|
if isinstance(tool_parameters[parameter.name], str):
|
||||||
|
# check true false
|
||||||
|
if tool_parameters[parameter.name].lower() in ['true', 'false']:
|
||||||
|
tool_parameters[parameter.name] = tool_parameters[parameter.name].lower() == 'true'
|
||||||
|
# check 1 0
|
||||||
|
elif tool_parameters[parameter.name] in ['1', '0']:
|
||||||
|
tool_parameters[parameter.name] = tool_parameters[parameter.name] == '1'
|
||||||
|
else:
|
||||||
|
tool_parameters[parameter.name] = bool(tool_parameters[parameter.name])
|
||||||
|
elif isinstance(tool_parameters[parameter.name], int | float):
|
||||||
|
tool_parameters[parameter.name] = tool_parameters[parameter.name] != 0
|
||||||
|
else:
|
||||||
tool_parameters[parameter.name] = bool(tool_parameters[parameter.name])
|
tool_parameters[parameter.name] = bool(tool_parameters[parameter.name])
|
||||||
|
|
||||||
return tool_parameters
|
return tool_parameters
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
from typing import Literal, Union
|
from typing import Any, Literal, Union
|
||||||
|
|
||||||
from pydantic import BaseModel, validator
|
from pydantic import BaseModel, validator
|
||||||
|
|
||||||
from core.workflow.entities.base_node_data_entities import BaseNodeData
|
from core.workflow.entities.base_node_data_entities import BaseNodeData
|
||||||
|
|
||||||
ToolParameterValue = Union[str, int, float, bool]
|
|
||||||
|
|
||||||
class ToolEntity(BaseModel):
|
class ToolEntity(BaseModel):
|
||||||
provider_id: str
|
provider_id: str
|
||||||
@ -12,11 +11,23 @@ class ToolEntity(BaseModel):
|
|||||||
provider_name: str # redundancy
|
provider_name: str # redundancy
|
||||||
tool_name: str
|
tool_name: str
|
||||||
tool_label: str # redundancy
|
tool_label: str # redundancy
|
||||||
tool_configurations: dict[str, ToolParameterValue]
|
tool_configurations: dict[str, Any]
|
||||||
|
|
||||||
|
@validator('tool_configurations', pre=True, always=True)
|
||||||
|
def validate_tool_configurations(cls, value, values):
|
||||||
|
if not isinstance(value, dict):
|
||||||
|
raise ValueError('tool_configurations must be a dictionary')
|
||||||
|
|
||||||
|
for key in values.get('tool_configurations', {}).keys():
|
||||||
|
value = values.get('tool_configurations', {}).get(key)
|
||||||
|
if not isinstance(value, str | int | float | bool):
|
||||||
|
raise ValueError(f'{key} must be a string')
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
class ToolNodeData(BaseNodeData, ToolEntity):
|
class ToolNodeData(BaseNodeData, ToolEntity):
|
||||||
class ToolInput(BaseModel):
|
class ToolInput(BaseModel):
|
||||||
value: Union[ToolParameterValue, list[str]]
|
value: Union[Any, list[str]]
|
||||||
type: Literal['mixed', 'variable', 'constant']
|
type: Literal['mixed', 'variable', 'constant']
|
||||||
|
|
||||||
@validator('type', pre=True, always=True)
|
@validator('type', pre=True, always=True)
|
||||||
@ -25,9 +36,13 @@ class ToolNodeData(BaseNodeData, ToolEntity):
|
|||||||
value = values.get('value')
|
value = values.get('value')
|
||||||
if typ == 'mixed' and not isinstance(value, str):
|
if typ == 'mixed' and not isinstance(value, str):
|
||||||
raise ValueError('value must be a string')
|
raise ValueError('value must be a string')
|
||||||
elif typ == 'variable' and not isinstance(value, list):
|
elif typ == 'variable':
|
||||||
|
if not isinstance(value, list):
|
||||||
raise ValueError('value must be a list')
|
raise ValueError('value must be a list')
|
||||||
elif typ == 'constant' and not isinstance(value, ToolParameterValue):
|
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):
|
||||||
raise ValueError('value must be a string, int, float, or bool')
|
raise ValueError('value must be a string, int, float, or bool')
|
||||||
return typ
|
return typ
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import produce from 'immer'
|
import produce from 'immer'
|
||||||
import { useBoolean } from 'ahooks'
|
import { useBoolean } from 'ahooks'
|
||||||
@ -25,7 +25,7 @@ const useConfig = (id: string, payload: ToolNodeType) => {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
const { inputs, setInputs } = useNodeCrud<ToolNodeType>(id, payload)
|
const { inputs, setInputs: doSetInputs } = useNodeCrud<ToolNodeType>(id, payload)
|
||||||
/*
|
/*
|
||||||
* tool_configurations: tool setting, not dynamic setting
|
* tool_configurations: tool setting, not dynamic setting
|
||||||
* tool_parameters: tool dynamic setting(by user)
|
* tool_parameters: tool dynamic setting(by user)
|
||||||
@ -58,10 +58,41 @@ const useConfig = (id: string, payload: ToolNodeType) => {
|
|||||||
}, [currCollection?.name, hideSetAuthModal, t, handleFetchAllTools, provider_type])
|
}, [currCollection?.name, hideSetAuthModal, t, handleFetchAllTools, provider_type])
|
||||||
|
|
||||||
const currTool = currCollection?.tools.find(tool => tool.name === tool_name)
|
const currTool = currCollection?.tools.find(tool => tool.name === tool_name)
|
||||||
const formSchemas = currTool ? toolParametersToFormSchemas(currTool.parameters) : []
|
const formSchemas = useMemo(() => {
|
||||||
|
return currTool ? toolParametersToFormSchemas(currTool.parameters) : []
|
||||||
|
}, [currTool])
|
||||||
const toolInputVarSchema = formSchemas.filter((item: any) => item.form === 'llm')
|
const toolInputVarSchema = formSchemas.filter((item: any) => item.form === 'llm')
|
||||||
// use setting
|
// use setting
|
||||||
const toolSettingSchema = formSchemas.filter((item: any) => item.form !== 'llm')
|
const toolSettingSchema = formSchemas.filter((item: any) => item.form !== 'llm')
|
||||||
|
const hasShouldTransferTypeSettingInput = toolSettingSchema.some(item => item.type === 'boolean' || item.type === 'number-input')
|
||||||
|
|
||||||
|
const setInputs = useCallback((value: ToolNodeType) => {
|
||||||
|
if (!hasShouldTransferTypeSettingInput) {
|
||||||
|
doSetInputs(value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const newInputs = produce(value, (draft) => {
|
||||||
|
const newConfig = { ...draft.tool_configurations }
|
||||||
|
Object.keys(draft.tool_configurations).forEach((key) => {
|
||||||
|
const schema = formSchemas.find(item => item.variable === key)
|
||||||
|
const value = newConfig[key]
|
||||||
|
if (schema?.type === 'boolean') {
|
||||||
|
if (typeof value === 'string')
|
||||||
|
newConfig[key] = parseInt(value, 10)
|
||||||
|
|
||||||
|
if (typeof value === 'boolean')
|
||||||
|
newConfig[key] = value ? 1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema?.type === 'number-input') {
|
||||||
|
if (typeof value === 'string' && value !== '')
|
||||||
|
newConfig[key] = parseFloat(value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
draft.tool_configurations = newConfig
|
||||||
|
})
|
||||||
|
doSetInputs(newInputs)
|
||||||
|
}, [doSetInputs, formSchemas, hasShouldTransferTypeSettingInput])
|
||||||
const [notSetDefaultValue, setNotSetDefaultValue] = useState(false)
|
const [notSetDefaultValue, setNotSetDefaultValue] = useState(false)
|
||||||
const toolSettingValue = (() => {
|
const toolSettingValue = (() => {
|
||||||
if (notSetDefaultValue)
|
if (notSetDefaultValue)
|
||||||
|
Loading…
Reference in New Issue
Block a user