plugin_entities.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import enum
  2. from typing import Any, Optional, Union
  3. from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validator
  4. from core.entities.parameter_entities import CommonParameterType
  5. from core.tools.entities.common_entities import I18nObject
  6. from core.tools.entities.tool_entities import (
  7. ToolIdentity,
  8. ToolParameterOption,
  9. ToolProviderIdentity,
  10. )
  11. class AgentStrategyProviderIdentity(ToolProviderIdentity):
  12. pass
  13. class AgentStrategyParameter(BaseModel):
  14. class AgentStrategyParameterType(enum.StrEnum):
  15. STRING = CommonParameterType.STRING.value
  16. NUMBER = CommonParameterType.NUMBER.value
  17. BOOLEAN = CommonParameterType.BOOLEAN.value
  18. SELECT = CommonParameterType.SELECT.value
  19. SECRET_INPUT = CommonParameterType.SECRET_INPUT.value
  20. FILE = CommonParameterType.FILE.value
  21. FILES = CommonParameterType.FILES.value
  22. APP_SELECTOR = CommonParameterType.APP_SELECTOR.value
  23. TOOL_SELECTOR = CommonParameterType.TOOL_SELECTOR.value
  24. MODEL_SELECTOR = CommonParameterType.MODEL_SELECTOR.value
  25. TOOLS_SELECTOR = CommonParameterType.TOOLS_SELECTOR.value
  26. # deprecated, should not use.
  27. SYSTEM_FILES = CommonParameterType.SYSTEM_FILES.value
  28. def as_normal_type(self):
  29. if self in {
  30. AgentStrategyParameter.AgentStrategyParameterType.SECRET_INPUT,
  31. AgentStrategyParameter.AgentStrategyParameterType.SELECT,
  32. }:
  33. return "string"
  34. return self.value
  35. def cast_value(self, value: Any, /):
  36. try:
  37. match self:
  38. case (
  39. AgentStrategyParameter.AgentStrategyParameterType.STRING
  40. | AgentStrategyParameter.AgentStrategyParameterType.SECRET_INPUT
  41. | AgentStrategyParameter.AgentStrategyParameterType.SELECT
  42. ):
  43. if value is None:
  44. return ""
  45. else:
  46. return value if isinstance(value, str) else str(value)
  47. case AgentStrategyParameter.AgentStrategyParameterType.BOOLEAN:
  48. if value is None:
  49. return False
  50. elif isinstance(value, str):
  51. # Allowed YAML boolean value strings: https://yaml.org/type/bool.html
  52. # and also '0' for False and '1' for True
  53. match value.lower():
  54. case "true" | "yes" | "y" | "1":
  55. return True
  56. case "false" | "no" | "n" | "0":
  57. return False
  58. case _:
  59. return bool(value)
  60. else:
  61. return value if isinstance(value, bool) else bool(value)
  62. case AgentStrategyParameter.AgentStrategyParameterType.NUMBER:
  63. if isinstance(value, int | float):
  64. return value
  65. elif isinstance(value, str) and value:
  66. if "." in value:
  67. return float(value)
  68. else:
  69. return int(value)
  70. case (
  71. AgentStrategyParameter.AgentStrategyParameterType.SYSTEM_FILES
  72. | AgentStrategyParameter.AgentStrategyParameterType.FILES
  73. ):
  74. if not isinstance(value, list):
  75. return [value]
  76. return value
  77. case AgentStrategyParameter.AgentStrategyParameterType.FILE:
  78. if isinstance(value, list):
  79. if len(value) != 1:
  80. raise ValueError(
  81. "This parameter only accepts one file but got multiple files while invoking."
  82. )
  83. else:
  84. return value[0]
  85. return value
  86. case (
  87. AgentStrategyParameter.AgentStrategyParameterType.TOOL_SELECTOR
  88. | AgentStrategyParameter.AgentStrategyParameterType.MODEL_SELECTOR
  89. | AgentStrategyParameter.AgentStrategyParameterType.APP_SELECTOR
  90. | AgentStrategyParameter.AgentStrategyParameterType.TOOLS_SELECTOR
  91. ):
  92. if not isinstance(value, dict):
  93. raise ValueError("The selector must be a dictionary.")
  94. return value
  95. case _:
  96. return str(value)
  97. except Exception:
  98. raise ValueError(f"The tool parameter value {value} is not in correct type of {self.as_normal_type()}.")
  99. name: str = Field(..., description="The name of the parameter")
  100. label: I18nObject = Field(..., description="The label presented to the user")
  101. placeholder: Optional[I18nObject] = Field(default=None, description="The placeholder presented to the user")
  102. type: AgentStrategyParameterType = Field(..., description="The type of the parameter")
  103. scope: str | None = None
  104. required: Optional[bool] = False
  105. default: Optional[Union[float, int, str]] = None
  106. min: Optional[Union[float, int]] = None
  107. max: Optional[Union[float, int]] = None
  108. options: list[ToolParameterOption] = Field(default_factory=list)
  109. @field_validator("options", mode="before")
  110. @classmethod
  111. def transform_options(cls, v):
  112. if not isinstance(v, list):
  113. return []
  114. return v
  115. @classmethod
  116. def get_simple_instance(
  117. cls,
  118. name: str,
  119. type: AgentStrategyParameterType,
  120. required: bool,
  121. options: Optional[list[str]] = None,
  122. ):
  123. """
  124. get a simple tool parameter
  125. :param name: the name of the parameter
  126. :param llm_description: the description presented to the LLM
  127. :param type: the type of the parameter
  128. :param required: if the parameter is required
  129. :param options: the options of the parameter
  130. """
  131. # convert options to ToolParameterOption
  132. if options:
  133. option_objs = [
  134. ToolParameterOption(value=option, label=I18nObject(en_US=option, zh_Hans=option)) for option in options
  135. ]
  136. else:
  137. option_objs = []
  138. return cls(
  139. name=name,
  140. label=I18nObject(en_US="", zh_Hans=""),
  141. placeholder=None,
  142. type=type,
  143. required=required,
  144. options=option_objs,
  145. )
  146. class AgentStrategyProviderEntity(BaseModel):
  147. identity: AgentStrategyProviderIdentity
  148. plugin_id: Optional[str] = Field(None, description="The id of the plugin")
  149. class AgentStrategyIdentity(ToolIdentity):
  150. pass
  151. class AgentStrategyEntity(BaseModel):
  152. identity: AgentStrategyIdentity
  153. parameters: list[AgentStrategyParameter] = Field(default_factory=list)
  154. description: I18nObject = Field(..., description="The description of the agent strategy")
  155. output_schema: Optional[dict] = None
  156. # pydantic configs
  157. model_config = ConfigDict(protected_namespaces=())
  158. @field_validator("parameters", mode="before")
  159. @classmethod
  160. def set_parameters(cls, v, validation_info: ValidationInfo) -> list[AgentStrategyParameter]:
  161. return v or []
  162. class AgentProviderEntityWithPlugin(AgentStrategyProviderEntity):
  163. strategies: list[AgentStrategyEntity] = Field(default_factory=list)