mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-20 10:59:12 +08:00
refactor: agent strategy parameter
This commit is contained in:
parent
46bb246ecc
commit
dedc1b0c3a
@ -340,7 +340,7 @@ class BaseAgentRunner(AppRunner):
|
|||||||
if isinstance(tool_input, dict):
|
if isinstance(tool_input, dict):
|
||||||
try:
|
try:
|
||||||
tool_input = json.dumps(tool_input, ensure_ascii=False)
|
tool_input = json.dumps(tool_input, ensure_ascii=False)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
tool_input = json.dumps(tool_input)
|
tool_input = json.dumps(tool_input)
|
||||||
|
|
||||||
updated_agent_thought.tool_input = tool_input
|
updated_agent_thought.tool_input = tool_input
|
||||||
@ -349,7 +349,7 @@ class BaseAgentRunner(AppRunner):
|
|||||||
if isinstance(observation, dict):
|
if isinstance(observation, dict):
|
||||||
try:
|
try:
|
||||||
observation = json.dumps(observation, ensure_ascii=False)
|
observation = json.dumps(observation, ensure_ascii=False)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
observation = json.dumps(observation)
|
observation = json.dumps(observation)
|
||||||
|
|
||||||
updated_agent_thought.observation = observation
|
updated_agent_thought.observation = observation
|
||||||
@ -389,7 +389,7 @@ class BaseAgentRunner(AppRunner):
|
|||||||
if isinstance(tool_invoke_meta, dict):
|
if isinstance(tool_invoke_meta, dict):
|
||||||
try:
|
try:
|
||||||
tool_invoke_meta = json.dumps(tool_invoke_meta, ensure_ascii=False)
|
tool_invoke_meta = json.dumps(tool_invoke_meta, ensure_ascii=False)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
tool_invoke_meta = json.dumps(tool_invoke_meta)
|
tool_invoke_meta = json.dumps(tool_invoke_meta)
|
||||||
|
|
||||||
updated_agent_thought.tool_meta_str = tool_invoke_meta
|
updated_agent_thought.tool_meta_str = tool_invoke_meta
|
||||||
@ -433,11 +433,11 @@ class BaseAgentRunner(AppRunner):
|
|||||||
tool_call_response: list[ToolPromptMessage] = []
|
tool_call_response: list[ToolPromptMessage] = []
|
||||||
try:
|
try:
|
||||||
tool_inputs = json.loads(agent_thought.tool_input)
|
tool_inputs = json.loads(agent_thought.tool_input)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
tool_inputs = {tool: {} for tool in tools}
|
tool_inputs = {tool: {} for tool in tools}
|
||||||
try:
|
try:
|
||||||
tool_responses = json.loads(agent_thought.observation)
|
tool_responses = json.loads(agent_thought.observation)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
tool_responses = dict.fromkeys(tools, agent_thought.observation)
|
tool_responses = dict.fromkeys(tools, agent_thought.observation)
|
||||||
|
|
||||||
for tool in tools:
|
for tool in tools:
|
||||||
|
@ -1,17 +1,164 @@
|
|||||||
from typing import Optional
|
import enum
|
||||||
|
from typing import Any, Optional, Union
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validator
|
from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validator
|
||||||
|
|
||||||
|
from core.entities.parameter_entities import CommonParameterType
|
||||||
from core.tools.entities.common_entities import I18nObject
|
from core.tools.entities.common_entities import I18nObject
|
||||||
from core.tools.entities.tool_entities import ToolIdentity, ToolParameter, ToolProviderIdentity
|
from core.tools.entities.tool_entities import (
|
||||||
|
ToolIdentity,
|
||||||
|
ToolParameterOption,
|
||||||
|
ToolProviderIdentity,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AgentStrategyProviderIdentity(ToolProviderIdentity):
|
class AgentStrategyProviderIdentity(ToolProviderIdentity):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AgentStrategyParameter(ToolParameter):
|
class AgentStrategyParameter(BaseModel):
|
||||||
pass
|
class AgentStrategyParameterType(enum.StrEnum):
|
||||||
|
STRING = CommonParameterType.STRING.value
|
||||||
|
NUMBER = CommonParameterType.NUMBER.value
|
||||||
|
BOOLEAN = CommonParameterType.BOOLEAN.value
|
||||||
|
SELECT = CommonParameterType.SELECT.value
|
||||||
|
SECRET_INPUT = CommonParameterType.SECRET_INPUT.value
|
||||||
|
FILE = CommonParameterType.FILE.value
|
||||||
|
FILES = CommonParameterType.FILES.value
|
||||||
|
APP_SELECTOR = CommonParameterType.APP_SELECTOR.value
|
||||||
|
TOOL_SELECTOR = CommonParameterType.TOOL_SELECTOR.value
|
||||||
|
MODEL_SELECTOR = CommonParameterType.MODEL_SELECTOR.value
|
||||||
|
TOOLS_SELECTOR = CommonParameterType.TOOLS_SELECTOR.value
|
||||||
|
|
||||||
|
# deprecated, should not use.
|
||||||
|
SYSTEM_FILES = CommonParameterType.SYSTEM_FILES.value
|
||||||
|
|
||||||
|
def as_normal_type(self):
|
||||||
|
if self in {
|
||||||
|
AgentStrategyParameter.AgentStrategyParameterType.SECRET_INPUT,
|
||||||
|
AgentStrategyParameter.AgentStrategyParameterType.SELECT,
|
||||||
|
}:
|
||||||
|
return "string"
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
def cast_value(self, value: Any, /):
|
||||||
|
try:
|
||||||
|
match self:
|
||||||
|
case (
|
||||||
|
AgentStrategyParameter.AgentStrategyParameterType.STRING
|
||||||
|
| AgentStrategyParameter.AgentStrategyParameterType.SECRET_INPUT
|
||||||
|
| AgentStrategyParameter.AgentStrategyParameterType.SELECT
|
||||||
|
):
|
||||||
|
if value is None:
|
||||||
|
return ""
|
||||||
|
else:
|
||||||
|
return value if isinstance(value, str) else str(value)
|
||||||
|
|
||||||
|
case AgentStrategyParameter.AgentStrategyParameterType.BOOLEAN:
|
||||||
|
if value is None:
|
||||||
|
return False
|
||||||
|
elif isinstance(value, str):
|
||||||
|
# Allowed YAML boolean value strings: https://yaml.org/type/bool.html
|
||||||
|
# and also '0' for False and '1' for True
|
||||||
|
match value.lower():
|
||||||
|
case "true" | "yes" | "y" | "1":
|
||||||
|
return True
|
||||||
|
case "false" | "no" | "n" | "0":
|
||||||
|
return False
|
||||||
|
case _:
|
||||||
|
return bool(value)
|
||||||
|
else:
|
||||||
|
return value if isinstance(value, bool) else bool(value)
|
||||||
|
|
||||||
|
case AgentStrategyParameter.AgentStrategyParameterType.NUMBER:
|
||||||
|
if isinstance(value, int | float):
|
||||||
|
return value
|
||||||
|
elif isinstance(value, str) and value:
|
||||||
|
if "." in value:
|
||||||
|
return float(value)
|
||||||
|
else:
|
||||||
|
return int(value)
|
||||||
|
case (
|
||||||
|
AgentStrategyParameter.AgentStrategyParameterType.SYSTEM_FILES
|
||||||
|
| AgentStrategyParameter.AgentStrategyParameterType.FILES
|
||||||
|
):
|
||||||
|
if not isinstance(value, list):
|
||||||
|
return [value]
|
||||||
|
return value
|
||||||
|
case AgentStrategyParameter.AgentStrategyParameterType.FILE:
|
||||||
|
if isinstance(value, list):
|
||||||
|
if len(value) != 1:
|
||||||
|
raise ValueError(
|
||||||
|
"This parameter only accepts one file but got multiple files while invoking."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return value[0]
|
||||||
|
return value
|
||||||
|
case (
|
||||||
|
AgentStrategyParameter.AgentStrategyParameterType.TOOL_SELECTOR
|
||||||
|
| AgentStrategyParameter.AgentStrategyParameterType.MODEL_SELECTOR
|
||||||
|
| AgentStrategyParameter.AgentStrategyParameterType.APP_SELECTOR
|
||||||
|
| AgentStrategyParameter.AgentStrategyParameterType.TOOLS_SELECTOR
|
||||||
|
):
|
||||||
|
if not isinstance(value, dict):
|
||||||
|
raise ValueError("The selector must be a dictionary.")
|
||||||
|
return value
|
||||||
|
case _:
|
||||||
|
return str(value)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
raise ValueError(f"The tool parameter value {value} is not in correct type of {self.as_normal_type()}.")
|
||||||
|
|
||||||
|
name: str = Field(..., description="The name of the parameter")
|
||||||
|
label: I18nObject = Field(..., description="The label presented to the user")
|
||||||
|
placeholder: Optional[I18nObject] = Field(default=None, description="The placeholder presented to the user")
|
||||||
|
type: AgentStrategyParameterType = Field(..., description="The type of the parameter")
|
||||||
|
scope: str | None = None
|
||||||
|
required: Optional[bool] = False
|
||||||
|
default: Optional[Union[float, int, str]] = None
|
||||||
|
min: Optional[Union[float, int]] = None
|
||||||
|
max: Optional[Union[float, int]] = None
|
||||||
|
options: list[ToolParameterOption] = Field(default_factory=list)
|
||||||
|
|
||||||
|
@field_validator("options", mode="before")
|
||||||
|
@classmethod
|
||||||
|
def transform_options(cls, v):
|
||||||
|
if not isinstance(v, list):
|
||||||
|
return []
|
||||||
|
return v
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_simple_instance(
|
||||||
|
cls,
|
||||||
|
name: str,
|
||||||
|
type: AgentStrategyParameterType,
|
||||||
|
required: bool,
|
||||||
|
options: Optional[list[str]] = None,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
get a simple tool parameter
|
||||||
|
|
||||||
|
:param name: the name of the parameter
|
||||||
|
:param llm_description: the description presented to the LLM
|
||||||
|
:param type: the type of the parameter
|
||||||
|
:param required: if the parameter is required
|
||||||
|
:param options: the options of the parameter
|
||||||
|
"""
|
||||||
|
# convert options to ToolParameterOption
|
||||||
|
if options:
|
||||||
|
option_objs = [
|
||||||
|
ToolParameterOption(value=option, label=I18nObject(en_US=option, zh_Hans=option)) for option in options
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
option_objs = []
|
||||||
|
return cls(
|
||||||
|
name=name,
|
||||||
|
label=I18nObject(en_US="", zh_Hans=""),
|
||||||
|
placeholder=None,
|
||||||
|
type=type,
|
||||||
|
required=required,
|
||||||
|
options=option_objs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AgentStrategyProviderEntity(BaseModel):
|
class AgentStrategyProviderEntity(BaseModel):
|
||||||
|
@ -14,6 +14,7 @@ class CommonParameterType(Enum):
|
|||||||
APP_SELECTOR = "app-selector"
|
APP_SELECTOR = "app-selector"
|
||||||
TOOL_SELECTOR = "tool-selector"
|
TOOL_SELECTOR = "tool-selector"
|
||||||
MODEL_SELECTOR = "model-selector"
|
MODEL_SELECTOR = "model-selector"
|
||||||
|
TOOLS_SELECTOR = "array[tools]"
|
||||||
|
|
||||||
|
|
||||||
class AppSelectorScope(Enum):
|
class AppSelectorScope(Enum):
|
||||||
|
@ -14,7 +14,12 @@ from core.file import FileType
|
|||||||
from core.file.models import FileTransferMethod
|
from core.file.models import FileTransferMethod
|
||||||
from core.ops.ops_trace_manager import TraceQueueManager
|
from core.ops.ops_trace_manager import TraceQueueManager
|
||||||
from core.tools.__base.tool import Tool
|
from core.tools.__base.tool import Tool
|
||||||
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolInvokeMessageBinary, ToolInvokeMeta, ToolParameter
|
from core.tools.entities.tool_entities import (
|
||||||
|
ToolInvokeMessage,
|
||||||
|
ToolInvokeMessageBinary,
|
||||||
|
ToolInvokeMeta,
|
||||||
|
ToolParameter,
|
||||||
|
)
|
||||||
from core.tools.errors import (
|
from core.tools.errors import (
|
||||||
ToolEngineInvokeError,
|
ToolEngineInvokeError,
|
||||||
ToolInvokeError,
|
ToolInvokeError,
|
||||||
@ -66,7 +71,7 @@ class ToolEngine:
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
tool_parameters = json.loads(tool_parameters)
|
tool_parameters = json.loads(tool_parameters)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
if not isinstance(tool_parameters, dict):
|
if not isinstance(tool_parameters, dict):
|
||||||
raise ValueError(f"tool_parameters should be a dict, but got a string: {tool_parameters}")
|
raise ValueError(f"tool_parameters should be a dict, but got a string: {tool_parameters}")
|
||||||
|
@ -548,7 +548,7 @@ class ToolManager:
|
|||||||
cls._builtin_tools_labels[tool.entity.identity.name] = tool.entity.identity.label
|
cls._builtin_tools_labels[tool.entity.identity.name] = tool.entity.identity.label
|
||||||
yield provider
|
yield provider
|
||||||
|
|
||||||
except Exception as e:
|
except Exception:
|
||||||
logger.exception(f"load builtin provider {provider}")
|
logger.exception(f"load builtin provider {provider}")
|
||||||
continue
|
continue
|
||||||
# set builtin providers loaded
|
# set builtin providers loaded
|
||||||
@ -670,7 +670,7 @@ class ToolManager:
|
|||||||
workflow_provider_controllers.append(
|
workflow_provider_controllers.append(
|
||||||
ToolTransformService.workflow_provider_to_controller(db_provider=provider)
|
ToolTransformService.workflow_provider_to_controller(db_provider=provider)
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
# app has been deleted
|
# app has been deleted
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ class WorkflowTool(Tool):
|
|||||||
file_dict["url"] = file.generate_url()
|
file_dict["url"] = file.generate_url()
|
||||||
|
|
||||||
files.append(file_dict)
|
files.append(file_dict)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
logger.exception(f"Failed to transform file {file}")
|
logger.exception(f"Failed to transform file {file}")
|
||||||
else:
|
else:
|
||||||
parameters_result[parameter.name] = tool_parameters.get(parameter.name)
|
parameters_result[parameter.name] = tool_parameters.get(parameter.name)
|
||||||
|
@ -197,7 +197,7 @@ class ToolTransformService:
|
|||||||
raise ValueError("user not found")
|
raise ValueError("user not found")
|
||||||
|
|
||||||
username = user.name
|
username = user.name
|
||||||
except Exception as e:
|
except Exception:
|
||||||
logger.exception(f"failed to get user name for api provider {db_provider.id}")
|
logger.exception(f"failed to get user name for api provider {db_provider.id}")
|
||||||
# add provider into providers
|
# add provider into providers
|
||||||
credentials = db_provider.credentials
|
credentials = db_provider.credentials
|
||||||
|
Loading…
x
Reference in New Issue
Block a user