Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

parameters.py 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import enum
  2. import json
  3. from typing import Any, Optional, Union
  4. from pydantic import BaseModel, Field, field_validator
  5. from core.entities.parameter_entities import CommonParameterType
  6. from core.tools.entities.common_entities import I18nObject
  7. from core.workflow.nodes.base.entities import NumberType
  8. class PluginParameterOption(BaseModel):
  9. value: str = Field(..., description="The value of the option")
  10. label: I18nObject = Field(..., description="The label of the option")
  11. icon: Optional[str] = Field(
  12. default=None, description="The icon of the option, can be a url or a base64 encoded image"
  13. )
  14. @field_validator("value", mode="before")
  15. @classmethod
  16. def transform_id_to_str(cls, value) -> str:
  17. if not isinstance(value, str):
  18. return str(value)
  19. else:
  20. return value
  21. class PluginParameterType(enum.StrEnum):
  22. """
  23. all available parameter types
  24. """
  25. STRING = CommonParameterType.STRING.value
  26. NUMBER = CommonParameterType.NUMBER.value
  27. BOOLEAN = CommonParameterType.BOOLEAN.value
  28. SELECT = CommonParameterType.SELECT.value
  29. SECRET_INPUT = CommonParameterType.SECRET_INPUT.value
  30. FILE = CommonParameterType.FILE.value
  31. FILES = CommonParameterType.FILES.value
  32. APP_SELECTOR = CommonParameterType.APP_SELECTOR.value
  33. MODEL_SELECTOR = CommonParameterType.MODEL_SELECTOR.value
  34. TOOLS_SELECTOR = CommonParameterType.TOOLS_SELECTOR.value
  35. ANY = CommonParameterType.ANY.value
  36. DYNAMIC_SELECT = CommonParameterType.DYNAMIC_SELECT.value
  37. # deprecated, should not use.
  38. SYSTEM_FILES = CommonParameterType.SYSTEM_FILES.value
  39. # MCP object and array type parameters
  40. ARRAY = CommonParameterType.ARRAY.value
  41. OBJECT = CommonParameterType.OBJECT.value
  42. class MCPServerParameterType(enum.StrEnum):
  43. """
  44. MCP server got complex parameter types
  45. """
  46. ARRAY = "array"
  47. OBJECT = "object"
  48. class PluginParameterAutoGenerate(BaseModel):
  49. class Type(enum.StrEnum):
  50. PROMPT_INSTRUCTION = "prompt_instruction"
  51. type: Type
  52. class PluginParameterTemplate(BaseModel):
  53. enabled: bool = Field(default=False, description="Whether the parameter is jinja enabled")
  54. class PluginParameter(BaseModel):
  55. name: str = Field(..., description="The name of the parameter")
  56. label: I18nObject = Field(..., description="The label presented to the user")
  57. placeholder: Optional[I18nObject] = Field(default=None, description="The placeholder presented to the user")
  58. scope: str | None = None
  59. auto_generate: Optional[PluginParameterAutoGenerate] = None
  60. template: Optional[PluginParameterTemplate] = None
  61. required: bool = False
  62. default: Optional[Union[float, int, str]] = None
  63. min: Optional[Union[float, int]] = None
  64. max: Optional[Union[float, int]] = None
  65. precision: Optional[int] = None
  66. options: list[PluginParameterOption] = Field(default_factory=list)
  67. @field_validator("options", mode="before")
  68. @classmethod
  69. def transform_options(cls, v):
  70. if not isinstance(v, list):
  71. return []
  72. return v
  73. def as_normal_type(typ: enum.StrEnum):
  74. if typ.value in {
  75. PluginParameterType.SECRET_INPUT,
  76. PluginParameterType.SELECT,
  77. }:
  78. return "string"
  79. return typ.value
  80. def cast_parameter_value(typ: enum.StrEnum, value: Any, /):
  81. try:
  82. match typ.value:
  83. case PluginParameterType.STRING | PluginParameterType.SECRET_INPUT | PluginParameterType.SELECT:
  84. if value is None:
  85. return ""
  86. else:
  87. return value if isinstance(value, str) else str(value)
  88. case PluginParameterType.BOOLEAN:
  89. if value is None:
  90. return False
  91. elif isinstance(value, str):
  92. # Allowed YAML boolean value strings: https://yaml.org/type/bool.html
  93. # and also '0' for False and '1' for True
  94. match value.lower():
  95. case "true" | "yes" | "y" | "1":
  96. return True
  97. case "false" | "no" | "n" | "0":
  98. return False
  99. case _:
  100. return bool(value)
  101. else:
  102. return value if isinstance(value, bool) else bool(value)
  103. case PluginParameterType.NUMBER:
  104. if isinstance(value, int | float):
  105. return value
  106. elif isinstance(value, str) and value:
  107. if "." in value:
  108. return float(value)
  109. else:
  110. return int(value)
  111. case PluginParameterType.SYSTEM_FILES | PluginParameterType.FILES:
  112. if not isinstance(value, list):
  113. return [value]
  114. return value
  115. case PluginParameterType.FILE:
  116. if isinstance(value, list):
  117. if len(value) != 1:
  118. raise ValueError("This parameter only accepts one file but got multiple files while invoking.")
  119. else:
  120. return value[0]
  121. return value
  122. case PluginParameterType.MODEL_SELECTOR | PluginParameterType.APP_SELECTOR:
  123. if not isinstance(value, dict):
  124. raise ValueError("The selector must be a dictionary.")
  125. return value
  126. case PluginParameterType.TOOLS_SELECTOR:
  127. if value and not isinstance(value, list):
  128. raise ValueError("The tools selector must be a list.")
  129. return value
  130. case PluginParameterType.ANY:
  131. if value and not isinstance(value, str | dict | list | NumberType):
  132. raise ValueError("The var selector must be a string, dictionary, list or number.")
  133. return value
  134. case PluginParameterType.ARRAY:
  135. if not isinstance(value, list):
  136. # Try to parse JSON string for arrays
  137. if isinstance(value, str):
  138. try:
  139. parsed_value = json.loads(value)
  140. if isinstance(parsed_value, list):
  141. return parsed_value
  142. except (json.JSONDecodeError, ValueError):
  143. pass
  144. return [value]
  145. return value
  146. case PluginParameterType.OBJECT:
  147. if not isinstance(value, dict):
  148. # Try to parse JSON string for objects
  149. if isinstance(value, str):
  150. try:
  151. parsed_value = json.loads(value)
  152. if isinstance(parsed_value, dict):
  153. return parsed_value
  154. except (json.JSONDecodeError, ValueError):
  155. pass
  156. return {}
  157. return value
  158. case _:
  159. return str(value)
  160. except ValueError:
  161. raise
  162. except Exception:
  163. raise ValueError(f"The tool parameter value {value} is not in correct type of {as_normal_type(typ)}.")
  164. def init_frontend_parameter(rule: PluginParameter, type: enum.StrEnum, value: Any):
  165. """
  166. init frontend parameter by rule
  167. """
  168. parameter_value = value
  169. if not parameter_value and parameter_value != 0:
  170. # get default value
  171. parameter_value = rule.default
  172. if not parameter_value and rule.required:
  173. raise ValueError(f"tool parameter {rule.name} not found in tool config")
  174. if type == PluginParameterType.SELECT:
  175. # check if tool_parameter_config in options
  176. options = [x.value for x in rule.options]
  177. if parameter_value is not None and parameter_value not in options:
  178. raise ValueError(f"tool parameter {rule.name} value {parameter_value} not in options {options}")
  179. return cast_parameter_value(type, parameter_value)