tools.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. from pydantic import BaseModel, ConfigDict
  2. from typing import Optional
  3. import time
  4. import logging
  5. from sqlalchemy import String, Column, BigInteger, Text
  6. from apps.webui.internal.db import Base, JSONField, get_db
  7. from apps.webui.models.users import Users
  8. import json
  9. import copy
  10. from env import SRC_LOG_LEVELS
  11. log = logging.getLogger(__name__)
  12. log.setLevel(SRC_LOG_LEVELS["MODELS"])
  13. ####################
  14. # Tools DB Schema
  15. ####################
  16. class Tool(Base):
  17. __tablename__ = "tool"
  18. id = Column(String, primary_key=True)
  19. user_id = Column(String)
  20. name = Column(Text)
  21. content = Column(Text)
  22. specs = Column(JSONField)
  23. meta = Column(JSONField)
  24. valves = Column(JSONField)
  25. updated_at = Column(BigInteger)
  26. created_at = Column(BigInteger)
  27. class ToolMeta(BaseModel):
  28. description: Optional[str] = None
  29. manifest: Optional[dict] = {}
  30. class ToolModel(BaseModel):
  31. id: str
  32. user_id: str
  33. name: str
  34. content: str
  35. specs: list[dict]
  36. meta: ToolMeta
  37. updated_at: int # timestamp in epoch
  38. created_at: int # timestamp in epoch
  39. model_config = ConfigDict(from_attributes=True)
  40. ####################
  41. # Forms
  42. ####################
  43. class ToolResponse(BaseModel):
  44. id: str
  45. user_id: str
  46. name: str
  47. meta: ToolMeta
  48. updated_at: int # timestamp in epoch
  49. created_at: int # timestamp in epoch
  50. class ToolForm(BaseModel):
  51. id: str
  52. name: str
  53. content: str
  54. meta: ToolMeta
  55. class ToolValves(BaseModel):
  56. valves: Optional[dict] = None
  57. class ToolsTable:
  58. def insert_new_tool(
  59. self, user_id: str, form_data: ToolForm, specs: list[dict]
  60. ) -> Optional[ToolModel]:
  61. with get_db() as db:
  62. tool = ToolModel(
  63. **{
  64. **form_data.model_dump(),
  65. "specs": specs,
  66. "user_id": user_id,
  67. "updated_at": int(time.time()),
  68. "created_at": int(time.time()),
  69. }
  70. )
  71. try:
  72. result = Tool(**tool.model_dump())
  73. db.add(result)
  74. db.commit()
  75. db.refresh(result)
  76. if result:
  77. return ToolModel.model_validate(result)
  78. else:
  79. return None
  80. except Exception as e:
  81. print(f"Error creating tool: {e}")
  82. return None
  83. def get_tool_by_id(self, id: str) -> Optional[ToolModel]:
  84. try:
  85. with get_db() as db:
  86. tool = db.get(Tool, id)
  87. return ToolModel.model_validate(tool)
  88. except Exception:
  89. return None
  90. def get_tools(self) -> list[ToolModel]:
  91. with get_db() as db:
  92. return [ToolModel.model_validate(tool) for tool in db.query(Tool).all()]
  93. def get_tool_valves_by_id(self, id: str) -> Optional[dict]:
  94. try:
  95. with get_db() as db:
  96. tool = db.get(Tool, id)
  97. return tool.valves if tool.valves else {}
  98. except Exception as e:
  99. print(f"An error occurred: {e}")
  100. return None
  101. def update_tool_valves_by_id(self, id: str, valves: dict) -> Optional[ToolValves]:
  102. try:
  103. with get_db() as db:
  104. db.query(Tool).filter_by(id=id).update(
  105. {"valves": valves, "updated_at": int(time.time())}
  106. )
  107. db.commit()
  108. return self.get_tool_by_id(id)
  109. except Exception:
  110. return None
  111. def get_user_valves_by_id_and_user_id(
  112. self, id: str, user_id: str
  113. ) -> Optional[dict]:
  114. try:
  115. user = Users.get_user_by_id(user_id)
  116. user_settings = user.settings.model_dump() if user.settings else {}
  117. # Check if user has "tools" and "valves" settings
  118. if "tools" not in user_settings:
  119. user_settings["tools"] = {}
  120. if "valves" not in user_settings["tools"]:
  121. user_settings["tools"]["valves"] = {}
  122. return user_settings["tools"]["valves"].get(id, {})
  123. except Exception as e:
  124. print(f"An error occurred: {e}")
  125. return None
  126. def update_user_valves_by_id_and_user_id(
  127. self, id: str, user_id: str, valves: dict
  128. ) -> Optional[dict]:
  129. try:
  130. user = Users.get_user_by_id(user_id)
  131. user_settings = user.settings.model_dump() if user.settings else {}
  132. # Check if user has "tools" and "valves" settings
  133. if "tools" not in user_settings:
  134. user_settings["tools"] = {}
  135. if "valves" not in user_settings["tools"]:
  136. user_settings["tools"]["valves"] = {}
  137. user_settings["tools"]["valves"][id] = valves
  138. # Update the user settings in the database
  139. Users.update_user_by_id(user_id, {"settings": user_settings})
  140. return user_settings["tools"]["valves"][id]
  141. except Exception as e:
  142. print(f"An error occurred: {e}")
  143. return None
  144. def update_tool_by_id(self, id: str, updated: dict) -> Optional[ToolModel]:
  145. try:
  146. with get_db() as db:
  147. db.query(Tool).filter_by(id=id).update(
  148. {**updated, "updated_at": int(time.time())}
  149. )
  150. db.commit()
  151. tool = db.query(Tool).get(id)
  152. db.refresh(tool)
  153. return ToolModel.model_validate(tool)
  154. except Exception:
  155. return None
  156. def delete_tool_by_id(self, id: str) -> bool:
  157. try:
  158. with get_db() as db:
  159. db.query(Tool).filter_by(id=id).delete()
  160. db.commit()
  161. return True
  162. except Exception:
  163. return False
  164. Tools = ToolsTable()