tools.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. import json
  2. from datetime import datetime
  3. from typing import Any, Optional, cast
  4. import sqlalchemy as sa
  5. from deprecated import deprecated
  6. from sqlalchemy import ForeignKey, func
  7. from sqlalchemy.orm import Mapped, mapped_column
  8. from core.tools.entities.common_entities import I18nObject
  9. from core.tools.entities.tool_bundle import ApiToolBundle
  10. from core.tools.entities.tool_entities import ApiProviderSchemaType, WorkflowToolParameterConfiguration
  11. from models.base import Base
  12. from .engine import db
  13. from .model import Account, App, Tenant
  14. from .types import StringUUID
  15. class BuiltinToolProvider(Base):
  16. """
  17. This table stores the tool provider information for built-in tools for each tenant.
  18. """
  19. __tablename__ = "tool_builtin_providers"
  20. __table_args__ = (
  21. db.PrimaryKeyConstraint("id", name="tool_builtin_provider_pkey"),
  22. # one tenant can only have one tool provider with the same name
  23. db.UniqueConstraint("tenant_id", "provider", name="unique_builtin_tool_provider"),
  24. )
  25. # id of the tool provider
  26. id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()"))
  27. # id of the tenant
  28. tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=True)
  29. # who created this tool provider
  30. user_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
  31. # name of the tool provider
  32. provider: Mapped[str] = mapped_column(db.String(256), nullable=False)
  33. # credential of the tool provider
  34. encrypted_credentials: Mapped[str] = mapped_column(db.Text, nullable=True)
  35. created_at: Mapped[datetime] = mapped_column(
  36. db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)")
  37. )
  38. updated_at: Mapped[datetime] = mapped_column(
  39. db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)")
  40. )
  41. @property
  42. def credentials(self) -> dict:
  43. return cast(dict, json.loads(self.encrypted_credentials))
  44. class ApiToolProvider(Base):
  45. """
  46. The table stores the api providers.
  47. """
  48. __tablename__ = "tool_api_providers"
  49. __table_args__ = (
  50. db.PrimaryKeyConstraint("id", name="tool_api_provider_pkey"),
  51. db.UniqueConstraint("name", "tenant_id", name="unique_api_tool_provider"),
  52. )
  53. id = db.Column(StringUUID, server_default=db.text("uuid_generate_v4()"))
  54. # name of the api provider
  55. name = db.Column(db.String(40), nullable=False)
  56. # icon
  57. icon = db.Column(db.String(255), nullable=False)
  58. # original schema
  59. schema = db.Column(db.Text, nullable=False)
  60. schema_type_str: Mapped[str] = db.Column(db.String(40), nullable=False)
  61. # who created this tool
  62. user_id = db.Column(StringUUID, nullable=False)
  63. # tenant id
  64. tenant_id = db.Column(StringUUID, nullable=False)
  65. # description of the provider
  66. description = db.Column(db.Text, nullable=False)
  67. # json format tools
  68. tools_str = db.Column(db.Text, nullable=False)
  69. # json format credentials
  70. credentials_str = db.Column(db.Text, nullable=False)
  71. # privacy policy
  72. privacy_policy = db.Column(db.String(255), nullable=True)
  73. # custom_disclaimer
  74. custom_disclaimer: Mapped[str] = mapped_column(sa.TEXT, default="")
  75. created_at: Mapped[datetime] = mapped_column(db.DateTime, nullable=False, server_default=func.current_timestamp())
  76. updated_at: Mapped[datetime] = mapped_column(db.DateTime, nullable=False, server_default=func.current_timestamp())
  77. @property
  78. def schema_type(self) -> ApiProviderSchemaType:
  79. return ApiProviderSchemaType.value_of(self.schema_type_str)
  80. @property
  81. def tools(self) -> list[ApiToolBundle]:
  82. return [ApiToolBundle(**tool) for tool in json.loads(self.tools_str)]
  83. @property
  84. def credentials(self) -> dict:
  85. return dict(json.loads(self.credentials_str))
  86. @property
  87. def user(self) -> Account | None:
  88. return db.session.query(Account).filter(Account.id == self.user_id).first()
  89. @property
  90. def tenant(self) -> Tenant | None:
  91. return db.session.query(Tenant).filter(Tenant.id == self.tenant_id).first()
  92. class ToolLabelBinding(Base):
  93. """
  94. The table stores the labels for tools.
  95. """
  96. __tablename__ = "tool_label_bindings"
  97. __table_args__ = (
  98. db.PrimaryKeyConstraint("id", name="tool_label_bind_pkey"),
  99. db.UniqueConstraint("tool_id", "label_name", name="unique_tool_label_bind"),
  100. )
  101. id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()"))
  102. # tool id
  103. tool_id: Mapped[str] = mapped_column(db.String(64), nullable=False)
  104. # tool type
  105. tool_type: Mapped[str] = mapped_column(db.String(40), nullable=False)
  106. # label name
  107. label_name: Mapped[str] = mapped_column(db.String(40), nullable=False)
  108. class WorkflowToolProvider(Base):
  109. """
  110. The table stores the workflow providers.
  111. """
  112. __tablename__ = "tool_workflow_providers"
  113. __table_args__ = (
  114. db.PrimaryKeyConstraint("id", name="tool_workflow_provider_pkey"),
  115. db.UniqueConstraint("name", "tenant_id", name="unique_workflow_tool_provider"),
  116. db.UniqueConstraint("tenant_id", "app_id", name="unique_workflow_tool_provider_app_id"),
  117. )
  118. id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()"))
  119. # name of the workflow provider
  120. name: Mapped[str] = mapped_column(db.String(40), nullable=False)
  121. # label of the workflow provider
  122. label: Mapped[str] = mapped_column(db.String(255), nullable=False, server_default="")
  123. # icon
  124. icon: Mapped[str] = mapped_column(db.String(255), nullable=False)
  125. # app id of the workflow provider
  126. app_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
  127. # version of the workflow provider
  128. version: Mapped[str] = mapped_column(db.String(255), nullable=False, server_default="")
  129. # who created this tool
  130. user_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
  131. # tenant id
  132. tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
  133. # description of the provider
  134. description: Mapped[str] = mapped_column(db.Text, nullable=False)
  135. # parameter configuration
  136. parameter_configuration: Mapped[str] = mapped_column(db.Text, nullable=False, server_default="[]")
  137. # privacy policy
  138. privacy_policy: Mapped[str] = mapped_column(db.String(255), nullable=True, server_default="")
  139. created_at: Mapped[datetime] = mapped_column(
  140. db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)")
  141. )
  142. updated_at: Mapped[datetime] = mapped_column(
  143. db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)")
  144. )
  145. @property
  146. def schema_type(self) -> ApiProviderSchemaType:
  147. return ApiProviderSchemaType.value_of(self.schema_type_str)
  148. @property
  149. def user(self) -> Account | None:
  150. return db.session.query(Account).filter(Account.id == self.user_id).first()
  151. @property
  152. def tenant(self) -> Tenant | None:
  153. return db.session.query(Tenant).filter(Tenant.id == self.tenant_id).first()
  154. @property
  155. def parameter_configurations(self) -> list[WorkflowToolParameterConfiguration]:
  156. return [WorkflowToolParameterConfiguration(**config) for config in json.loads(self.parameter_configuration)]
  157. @property
  158. def app(self) -> App | None:
  159. return db.session.query(App).filter(App.id == self.app_id).first()
  160. class ToolModelInvoke(Base):
  161. """
  162. store the invoke logs from tool invoke
  163. """
  164. __tablename__ = "tool_model_invokes"
  165. __table_args__ = (db.PrimaryKeyConstraint("id", name="tool_model_invoke_pkey"),)
  166. id = db.Column(StringUUID, server_default=db.text("uuid_generate_v4()"))
  167. # who invoke this tool
  168. user_id = db.Column(StringUUID, nullable=False)
  169. # tenant id
  170. tenant_id = db.Column(StringUUID, nullable=False)
  171. # provider
  172. provider = db.Column(db.String(40), nullable=False)
  173. # type
  174. tool_type = db.Column(db.String(40), nullable=False)
  175. # tool name
  176. tool_name = db.Column(db.String(40), nullable=False)
  177. # invoke parameters
  178. model_parameters = db.Column(db.Text, nullable=False)
  179. # prompt messages
  180. prompt_messages = db.Column(db.Text, nullable=False)
  181. # invoke response
  182. model_response = db.Column(db.Text, nullable=False)
  183. prompt_tokens = db.Column(db.Integer, nullable=False, server_default=db.text("0"))
  184. answer_tokens = db.Column(db.Integer, nullable=False, server_default=db.text("0"))
  185. answer_unit_price = db.Column(db.Numeric(10, 4), nullable=False)
  186. answer_price_unit = db.Column(db.Numeric(10, 7), nullable=False, server_default=db.text("0.001"))
  187. provider_response_latency = db.Column(db.Float, nullable=False, server_default=db.text("0"))
  188. total_price = db.Column(db.Numeric(10, 7))
  189. currency = db.Column(db.String(255), nullable=False)
  190. created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp())
  191. updated_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp())
  192. @deprecated
  193. class ToolConversationVariables(Base):
  194. """
  195. store the conversation variables from tool invoke
  196. """
  197. __tablename__ = "tool_conversation_variables"
  198. __table_args__ = (
  199. db.PrimaryKeyConstraint("id", name="tool_conversation_variables_pkey"),
  200. # add index for user_id and conversation_id
  201. db.Index("user_id_idx", "user_id"),
  202. db.Index("conversation_id_idx", "conversation_id"),
  203. )
  204. id = db.Column(StringUUID, server_default=db.text("uuid_generate_v4()"))
  205. # conversation user id
  206. user_id = db.Column(StringUUID, nullable=False)
  207. # tenant id
  208. tenant_id = db.Column(StringUUID, nullable=False)
  209. # conversation id
  210. conversation_id = db.Column(StringUUID, nullable=False)
  211. # variables pool
  212. variables_str = db.Column(db.Text, nullable=False)
  213. created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp())
  214. updated_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp())
  215. @property
  216. def variables(self) -> Any:
  217. return json.loads(self.variables_str)
  218. class ToolFile(Base):
  219. """
  220. store the file created by agent
  221. """
  222. __tablename__ = "tool_files"
  223. __table_args__ = (
  224. db.PrimaryKeyConstraint("id", name="tool_file_pkey"),
  225. db.Index("tool_file_conversation_id_idx", "conversation_id"),
  226. )
  227. id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()"))
  228. # conversation user id
  229. user_id: Mapped[str] = mapped_column(StringUUID)
  230. # tenant id
  231. tenant_id: Mapped[str] = mapped_column(StringUUID)
  232. # conversation id
  233. conversation_id: Mapped[str] = mapped_column(StringUUID, nullable=True)
  234. # file key
  235. file_key: Mapped[str] = mapped_column(db.String(255), nullable=False)
  236. # mime type
  237. mimetype: Mapped[str] = mapped_column(db.String(255), nullable=False)
  238. # original url
  239. original_url: Mapped[str] = mapped_column(db.String(2048), nullable=True)
  240. # name
  241. name: Mapped[str] = mapped_column(default="")
  242. # size
  243. size: Mapped[int] = mapped_column(default=-1)
  244. @deprecated
  245. class DeprecatedPublishedAppTool(Base):
  246. """
  247. The table stores the apps published as a tool for each person.
  248. """
  249. __tablename__ = "tool_published_apps"
  250. __table_args__ = (
  251. db.PrimaryKeyConstraint("id", name="published_app_tool_pkey"),
  252. db.UniqueConstraint("app_id", "user_id", name="unique_published_app_tool"),
  253. )
  254. # id of the app
  255. app_id = db.Column(StringUUID, ForeignKey("apps.id"), nullable=False)
  256. # who published this tool
  257. description = db.Column(db.Text, nullable=False)
  258. # llm_description of the tool, for LLM
  259. llm_description = db.Column(db.Text, nullable=False)
  260. # query description, query will be seem as a parameter of the tool,
  261. # to describe this parameter to llm, we need this field
  262. query_description = db.Column(db.Text, nullable=False)
  263. # query name, the name of the query parameter
  264. query_name = db.Column(db.String(40), nullable=False)
  265. # name of the tool provider
  266. tool_name = db.Column(db.String(40), nullable=False)
  267. # author
  268. author = db.Column(db.String(40), nullable=False)
  269. created_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)"))
  270. updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)"))
  271. @property
  272. def description_i18n(self) -> I18nObject:
  273. return I18nObject(**json.loads(self.description))
  274. id = db.Column(StringUUID, server_default=db.text("uuid_generate_v4()"))
  275. user_id: Mapped[str] = db.Column(StringUUID, nullable=False)
  276. tenant_id: Mapped[str] = db.Column(StringUUID, nullable=False)
  277. conversation_id: Mapped[Optional[str]] = db.Column(StringUUID, nullable=True)
  278. file_key: Mapped[str] = db.Column(db.String(255), nullable=False)
  279. mimetype: Mapped[str] = db.Column(db.String(255), nullable=False)
  280. original_url: Mapped[Optional[str]] = db.Column(db.String(2048), nullable=True)
  281. name: Mapped[str] = mapped_column(default="")
  282. size: Mapped[int] = mapped_column(default=-1)
  283. def __init__(
  284. self,
  285. *,
  286. user_id: str,
  287. tenant_id: str,
  288. conversation_id: Optional[str] = None,
  289. file_key: str,
  290. mimetype: str,
  291. original_url: Optional[str] = None,
  292. name: str,
  293. size: int,
  294. ):
  295. self.user_id = user_id
  296. self.tenant_id = tenant_id
  297. self.conversation_id = conversation_id
  298. self.file_key = file_key
  299. self.mimetype = mimetype
  300. self.original_url = original_url
  301. self.name = name
  302. self.size = size