tool.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. from datetime import datetime
  2. from typing import TYPE_CHECKING, Generic, TypeVar
  3. from core_domain import (
  4. ToolBindingContract,
  5. ToolBindingDetailContract,
  6. ToolCredentialContract,
  7. ToolCredentialRevealContract,
  8. ToolDefinitionContract,
  9. ToolVersionContract,
  10. )
  11. from core_shared import JSONValue
  12. from pydantic import BaseModel, Field
  13. if TYPE_CHECKING:
  14. from app.db.models import ToolBinding, ToolCredential, ToolDefinition, ToolVersion
  15. T = TypeVar("T")
  16. class ApiErrorResponse(BaseModel):
  17. errorType: str
  18. message: str
  19. details: dict[str, JSONValue] = Field(default_factory=dict)
  20. class ApiResponse(BaseModel, Generic[T]):
  21. success: bool = True
  22. data: T | None = None
  23. error: ApiErrorResponse | None = None
  24. requestId: str
  25. serverTime: datetime
  26. class PageRequest(BaseModel):
  27. page: int = Field(default=1, ge=1)
  28. pageSize: int = Field(default=20, ge=1, le=200)
  29. keyword: str | None = None
  30. @property
  31. def offset(self) -> int:
  32. return (self.page - 1) * self.pageSize
  33. class PageResult(BaseModel, Generic[T]):
  34. items: list[T]
  35. total: int
  36. page: int
  37. pageSize: int
  38. hasMore: bool
  39. @classmethod
  40. def from_items(
  41. cls,
  42. *,
  43. items: list[T],
  44. total: int,
  45. page: int,
  46. page_size: int) -> "PageResult[T]":
  47. return cls(
  48. items=items,
  49. total=total,
  50. page=page,
  51. pageSize=page_size,
  52. hasMore=page * page_size < total)
  53. class ToolCreateRequest(BaseModel):
  54. plugin_id: str | None = None
  55. code: str | None = None
  56. name: str
  57. tool_type: str
  58. description: str | None = None
  59. class ToolResponse(ToolDefinitionContract):
  60. @classmethod
  61. def from_entity(cls, entity: "ToolDefinition") -> "ToolResponse":
  62. return cls.model_validate(entity, from_attributes=True)
  63. class ToolVersionCreateRequest(BaseModel):
  64. tool_id: str
  65. input_schema_json: dict[str, JSONValue] = Field(default_factory=dict)
  66. output_schema_json: dict[str, JSONValue] = Field(default_factory=dict)
  67. invoke_config_json: dict[str, JSONValue] = Field(default_factory=dict)
  68. timeout_ms: int | None = None
  69. retry_policy_json: dict[str, JSONValue] = Field(default_factory=dict)
  70. class ToolVersionResponse(ToolVersionContract):
  71. @classmethod
  72. def from_entity(cls, entity: "ToolVersion") -> "ToolVersionResponse":
  73. return cls.model_validate(entity, from_attributes=True)
  74. class ToolBindingCreateRequest(BaseModel):
  75. app_id: str
  76. tool_version_id: str
  77. credential_id: str | None = None
  78. binding_scope: str = "app"
  79. enabled: bool = True
  80. config_json: dict[str, JSONValue] = Field(default_factory=dict)
  81. class ToolBindingResponse(ToolBindingContract):
  82. @classmethod
  83. def from_entity(cls, entity: "ToolBinding") -> "ToolBindingResponse":
  84. return cls.model_validate(entity, from_attributes=True)
  85. class ToolBindingDetailResponse(ToolBindingDetailContract):
  86. binding: ToolBindingResponse
  87. tool_version: ToolVersionResponse
  88. tool_definition: ToolResponse
  89. class ToolCredentialCreateRequest(BaseModel):
  90. name: str
  91. credential_type: str = "generic"
  92. secret_json: dict[str, JSONValue] = Field(default_factory=dict)
  93. metadata_json: dict[str, JSONValue] = Field(default_factory=dict)
  94. class ToolCredentialResponse(ToolCredentialContract):
  95. @classmethod
  96. def from_entity(cls, entity: "ToolCredential") -> "ToolCredentialResponse":
  97. return cls.model_validate(entity, from_attributes=True)
  98. class ToolCredentialRevealResponse(ToolCredentialRevealContract):
  99. credential: ToolCredentialResponse
  100. class ToolDto(BaseModel):
  101. id: str
  102. pluginId: str | None = None
  103. name: str
  104. toolType: str
  105. description: str | None = None
  106. createdTime: datetime
  107. @classmethod
  108. def from_entity(cls, entity: "ToolDefinition") -> "ToolDto":
  109. return cls(
  110. id=entity.id,
  111. pluginId=entity.plugin_id,
  112. name=entity.name,
  113. toolType=entity.tool_type,
  114. description=entity.description,
  115. createdTime=entity.created_time)
  116. class ToolCreateRequestDto(BaseModel):
  117. pluginId: str | None = None
  118. name: str
  119. toolType: str = "mcp"
  120. description: str | None = None
  121. class ToolDeleteRequestDto(BaseModel):
  122. toolId: str
  123. class ToolDetailRequestDto(BaseModel):
  124. toolId: str
  125. class ToolUpdateRequestDto(BaseModel):
  126. toolId: str
  127. name: str | None = None
  128. toolType: str | None = None
  129. description: str | None = None
  130. pluginId: str | None = None
  131. class ToolVersionDto(BaseModel):
  132. id: str
  133. toolId: str
  134. versionNo: int
  135. inputSchema: dict[str, JSONValue] | None = None
  136. outputSchema: dict[str, JSONValue] | None = None
  137. invokeConfig: dict[str, JSONValue] | None = None
  138. timeoutMs: int | None = None
  139. retryPolicy: dict[str, JSONValue] | None = None
  140. createdTime: datetime
  141. @classmethod
  142. def from_entity(cls, entity: "ToolVersion") -> "ToolVersionDto":
  143. return cls(
  144. id=entity.id,
  145. toolId=entity.tool_id,
  146. versionNo=entity.version_no,
  147. inputSchema=entity.input_schema_json,
  148. outputSchema=entity.output_schema_json,
  149. invokeConfig=entity.invoke_config_json,
  150. timeoutMs=entity.timeout_ms,
  151. retryPolicy=entity.retry_policy_json,
  152. createdTime=entity.created_time)
  153. class ToolVersionListRequestDto(PageRequest):
  154. toolId: str | None = None
  155. class ToolVersionCreateRequestDto(BaseModel):
  156. toolId: str
  157. inputSchema: dict[str, JSONValue] = Field(default_factory=dict)
  158. outputSchema: dict[str, JSONValue] = Field(default_factory=dict)
  159. invokeConfig: dict[str, JSONValue] = Field(default_factory=dict)
  160. timeoutMs: int | None = None
  161. retryPolicy: dict[str, JSONValue] = Field(default_factory=dict)
  162. class ToolVersionDeleteRequestDto(BaseModel):
  163. connectionId: str
  164. class ToolVersionDetailRequestDto(BaseModel):
  165. connectionId: str
  166. class ToolVersionUpdateRequestDto(BaseModel):
  167. connectionId: str
  168. inputSchema: dict[str, JSONValue] | None = None
  169. outputSchema: dict[str, JSONValue] | None = None
  170. invokeConfig: dict[str, JSONValue] | None = None
  171. timeoutMs: int | None = None
  172. retryPolicy: dict[str, JSONValue] | None = None
  173. class ToolBindingDto(BaseModel):
  174. id: str
  175. appId: str
  176. toolVersionId: str
  177. credentialId: str | None = None
  178. bindingScope: str
  179. configJson: dict[str, JSONValue] | None = None
  180. createdTime: datetime
  181. @classmethod
  182. def from_entity(cls, entity: "ToolBinding") -> "ToolBindingDto":
  183. return cls(
  184. id=entity.id,
  185. appId=entity.app_id,
  186. toolVersionId=entity.tool_version_id,
  187. credentialId=entity.credential_id,
  188. bindingScope=entity.binding_scope,
  189. configJson=entity.config_json,
  190. createdTime=entity.created_time)
  191. class ToolBindingListRequestDto(PageRequest):
  192. appId: str | None = None
  193. class ToolBindingCreateRequestDto(BaseModel):
  194. appId: str
  195. toolVersionId: str
  196. credentialId: str | None = None
  197. bindingScope: str = "app"
  198. configJson: dict[str, JSONValue] = Field(default_factory=dict)
  199. class ToolBindingDeleteRequestDto(BaseModel):
  200. bindingId: str
  201. class ToolBindingDetailRequestDto(BaseModel):
  202. bindingId: str
  203. class ToolBindingUpdateRequestDto(BaseModel):
  204. bindingId: str
  205. credentialId: str | None = None
  206. bindingScope: str | None = None
  207. configJson: dict[str, JSONValue] | None = None
  208. class ToolCredentialDto(BaseModel):
  209. id: str
  210. name: str
  211. credentialType: str
  212. secretFingerprint: str
  213. encryptionAlgorithm: str
  214. metadataJson: dict[str, JSONValue] = Field(default_factory=dict)
  215. createdTime: datetime
  216. @classmethod
  217. def from_entity(cls, entity: "ToolCredential") -> "ToolCredentialDto":
  218. return cls(
  219. id=entity.id,
  220. name=entity.name,
  221. credentialType=entity.credential_type,
  222. secretFingerprint=entity.secret_fingerprint,
  223. encryptionAlgorithm=entity.encryption_algorithm,
  224. metadataJson=entity.metadata_json,
  225. createdTime=entity.created_time)
  226. class ToolCredentialCreateRequestDto(BaseModel):
  227. name: str
  228. credentialType: str = "generic"
  229. secretJson: dict[str, JSONValue] = Field(default_factory=dict)
  230. metadataJson: dict[str, JSONValue] = Field(default_factory=dict)
  231. class ToolCredentialDeleteRequestDto(BaseModel):
  232. credentialId: str
  233. class ToolCredentialDetailRequestDto(BaseModel):
  234. credentialId: str
  235. class ToolCredentialUpdateRequestDto(BaseModel):
  236. credentialId: str
  237. name: str | None = None
  238. metadataJson: dict[str, JSONValue] | None = None
  239. class ToolCredentialRevealRequestDto(BaseModel):
  240. credentialId: str
  241. class ToolCredentialRevealDto(BaseModel):
  242. credential: ToolCredentialDto
  243. secretJson: dict[str, JSONValue] = Field(default_factory=dict)
  244. class McpToolDto(BaseModel):
  245. name: str
  246. description: str | None = None
  247. inputSchema: dict[str, JSONValue] | None = None
  248. class McpConnectRequestDto(BaseModel):
  249. name: str | None = None
  250. config: dict[str, JSONValue]
  251. class McpConnectData(BaseModel):
  252. tool: ToolDto
  253. connection: ToolVersionDto
  254. discoveredTools: list[McpToolDto] = Field(default_factory=list)
  255. class DeleteData(BaseModel):
  256. deleted: bool
  257. toolId: str | None = None
  258. connectionId: str | None = None
  259. bindingId: str | None = None
  260. credentialId: str | None = None