team.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. from datetime import datetime
  2. from typing import TYPE_CHECKING, Generic, TypeVar
  3. from core_domain import (
  4. TeamDefinitionContract,
  5. TeamMemberContract,
  6. TeamRunContract,
  7. TeamRunStatus,
  8. TeamStatus,
  9. TeamVersionContract,
  10. TeamVersionStatus,
  11. )
  12. from core_shared import JSONValue
  13. from pydantic import BaseModel, Field
  14. if TYPE_CHECKING:
  15. from app.db.models import TeamDefinition, TeamRun, TeamVersion
  16. T = TypeVar("T")
  17. class ApiErrorResponse(BaseModel):
  18. errorType: str
  19. message: str
  20. details: dict[str, JSONValue] = Field(default_factory=dict)
  21. class ApiResponse(BaseModel, Generic[T]):
  22. success: bool = True
  23. data: T | None = None
  24. error: ApiErrorResponse | None = None
  25. requestId: str
  26. serverTime: datetime
  27. class PageRequest(BaseModel):
  28. page: int = Field(default=1, ge=1)
  29. pageSize: int = Field(default=20, ge=1, le=200)
  30. keyword: str | None = None
  31. @property
  32. def offset(self) -> int:
  33. return (self.page - 1) * self.pageSize
  34. class PageResult(BaseModel, Generic[T]):
  35. items: list[T]
  36. total: int
  37. page: int
  38. pageSize: int
  39. hasMore: bool
  40. @classmethod
  41. def from_items(
  42. cls,
  43. *,
  44. items: list[T],
  45. total: int,
  46. page: int,
  47. page_size: int) -> "PageResult[T]":
  48. return cls(
  49. items=items,
  50. total=total,
  51. page=page,
  52. pageSize=page_size,
  53. hasMore=page * page_size < total)
  54. class TeamCreateRequest(BaseModel):
  55. code: str
  56. name: str
  57. description: str | None = None
  58. team_type: str = "collaborative"
  59. owner_user_id: str | None = None
  60. metadata_json: dict[str, JSONValue] = Field(default_factory=dict)
  61. class TeamStatusUpdateRequest(BaseModel):
  62. status: TeamStatus
  63. class TeamResponse(TeamDefinitionContract):
  64. @classmethod
  65. def from_entity(cls, entity: "TeamDefinition") -> "TeamResponse":
  66. return cls.model_validate(entity, from_attributes=True)
  67. class TeamVersionCreateRequest(BaseModel):
  68. team_id: str
  69. status: TeamVersionStatus = "draft"
  70. coordination_mode: str = "supervisor"
  71. objective: str | None = None
  72. member_refs: list[TeamMemberContract] = Field(default_factory=list)
  73. policy_json: dict[str, JSONValue] = Field(default_factory=dict)
  74. class TeamVersionResponse(TeamVersionContract):
  75. @classmethod
  76. def from_entity(cls, entity: "TeamVersion") -> "TeamVersionResponse":
  77. return cls.model_validate(entity, from_attributes=True)
  78. class TeamRunCreateRequest(BaseModel):
  79. team_id: str
  80. team_version_id: str | None = None
  81. session_id: str | None = None
  82. input_text: str | None = None
  83. input_json: dict[str, JSONValue] | None = None
  84. class TeamRunStatusUpdateRequest(BaseModel):
  85. status: TeamRunStatus
  86. worker_key: str | None = None
  87. output_text: str | None = None
  88. output_json: dict[str, JSONValue] | None = None
  89. error_code: str | None = None
  90. error_message: str | None = None
  91. class TeamRunExecuteRequest(BaseModel):
  92. worker_key: str | None = None
  93. dry_run: bool = True
  94. class TeamRunResponse(TeamRunContract):
  95. @classmethod
  96. def from_entity(cls, entity: "TeamRun") -> "TeamRunResponse":
  97. return cls.model_validate(entity, from_attributes=True)
  98. class TeamRunExecuteResponse(BaseModel):
  99. run: TeamRunResponse
  100. member_run_count: int = 0
  101. dry_run: bool = True
  102. class TeamWorkerExecuteNextRequest(BaseModel):
  103. worker_key: str
  104. lease_seconds: int | None = Field(default=None, gt=0)
  105. dry_run: bool | None = None
  106. class TeamWorkerExecuteNextResponse(BaseModel):
  107. run: TeamRunResponse
  108. member_run_count: int = 0
  109. dry_run: bool = True
  110. released_lease_count: int = 0
  111. class TeamDto(BaseModel):
  112. id: str
  113. name: str
  114. description: str | None = None
  115. teamType: str
  116. status: TeamStatus
  117. ownerUserId: str | None = None
  118. metadata: dict[str, JSONValue] = Field(default_factory=dict)
  119. createdTime: datetime
  120. @classmethod
  121. def from_entity(cls, entity: "TeamDefinition") -> "TeamDto":
  122. return cls(
  123. id=entity.id,
  124. name=entity.name,
  125. description=entity.description,
  126. teamType=entity.team_type,
  127. status=entity.status,
  128. ownerUserId=entity.owner_user_id,
  129. metadata=entity.metadata_json or {},
  130. createdTime=entity.created_time)
  131. class TeamListRequestDto(PageRequest):
  132. status: TeamStatus | None = None
  133. class TeamCreateRequestDto(BaseModel):
  134. name: str
  135. description: str | None = None
  136. teamType: str = "collaborative"
  137. ownerUserId: str | None = None
  138. metadata: dict[str, JSONValue] = Field(default_factory=dict)
  139. class TeamDetailRequestDto(BaseModel):
  140. teamId: str
  141. class TeamUpdateRequestDto(BaseModel):
  142. teamId: str
  143. name: str | None = None
  144. description: str | None = None
  145. teamType: str | None = None
  146. status: TeamStatus | None = None
  147. ownerUserId: str | None = None
  148. metadata: dict[str, JSONValue] | None = None
  149. class TeamDeleteRequestDto(BaseModel):
  150. teamId: str
  151. class TeamConfigDto(BaseModel):
  152. id: str
  153. teamId: str
  154. versionNo: int
  155. status: TeamVersionStatus
  156. coordinationMode: str
  157. objective: str | None = None
  158. memberRefs: list[dict[str, JSONValue]]
  159. policy: dict[str, JSONValue]
  160. publishedTime: datetime | None = None
  161. createdTime: datetime
  162. @classmethod
  163. def from_entity(cls, entity: "TeamVersion") -> "TeamConfigDto":
  164. return cls(
  165. id=entity.id,
  166. teamId=entity.team_id,
  167. versionNo=entity.version_no,
  168. status=entity.status,
  169. coordinationMode=entity.coordination_mode,
  170. objective=entity.objective,
  171. memberRefs=entity.member_refs_json,
  172. policy=entity.policy_json,
  173. publishedTime=entity.published_time,
  174. createdTime=entity.created_time)
  175. class TeamConfigListRequestDto(PageRequest):
  176. teamId: str | None = None
  177. class TeamConfigCreateRequestDto(BaseModel):
  178. teamId: str
  179. status: TeamVersionStatus = "draft"
  180. coordinationMode: str = "supervisor"
  181. objective: str | None = None
  182. memberRefs: list[dict[str, JSONValue]] = Field(default_factory=list)
  183. policy: dict[str, JSONValue] = Field(default_factory=dict)
  184. class TeamConfigDetailRequestDto(BaseModel):
  185. configId: str
  186. class TeamConfigUpdateRequestDto(BaseModel):
  187. configId: str
  188. status: TeamVersionStatus | None = None
  189. coordinationMode: str | None = None
  190. objective: str | None = None
  191. memberRefs: list[dict[str, JSONValue]] | None = None
  192. policy: dict[str, JSONValue] | None = None
  193. class TeamConfigDeleteRequestDto(BaseModel):
  194. configId: str
  195. class TeamRunDto(BaseModel):
  196. id: str
  197. teamId: str
  198. teamConfigId: str
  199. sessionId: str | None = None
  200. inputText: str | None = None
  201. inputJson: dict[str, JSONValue] | None = None
  202. outputText: str | None = None
  203. outputJson: dict[str, JSONValue] | None = None
  204. status: TeamRunStatus
  205. workerKey: str | None = None
  206. queuedTime: datetime | None = None
  207. leaseExpireTime: datetime | None = None
  208. startedTime: datetime | None = None
  209. finishedTime: datetime | None = None
  210. errorCode: str | None = None
  211. errorMessage: str | None = None
  212. createdTime: datetime
  213. @classmethod
  214. def from_entity(cls, entity: "TeamRun") -> "TeamRunDto":
  215. return cls(
  216. id=entity.id,
  217. teamId=entity.team_id,
  218. teamConfigId=entity.team_version_id,
  219. sessionId=entity.session_id,
  220. inputText=entity.input_text,
  221. inputJson=entity.input_json,
  222. outputText=entity.output_text,
  223. outputJson=entity.output_json,
  224. status=entity.status,
  225. workerKey=entity.worker_key,
  226. queuedTime=entity.queued_time,
  227. leaseExpireTime=entity.lease_expire_time,
  228. startedTime=entity.started_time,
  229. finishedTime=entity.finished_time,
  230. errorCode=entity.error_code,
  231. errorMessage=entity.error_message,
  232. createdTime=entity.created_time)
  233. class TeamRunListRequestDto(PageRequest):
  234. teamId: str | None = None
  235. sessionId: str | None = None
  236. status: TeamRunStatus | None = None
  237. class TeamRunCreateRequestDto(BaseModel):
  238. teamId: str
  239. teamConfigId: str | None = None
  240. sessionId: str | None = None
  241. inputText: str | None = None
  242. inputJson: dict[str, JSONValue] | None = None
  243. class TeamRunDetailRequestDto(BaseModel):
  244. teamRunId: str
  245. class TeamRunStatusUpdateRequestDto(BaseModel):
  246. teamRunId: str
  247. status: TeamRunStatus
  248. workerKey: str | None = None
  249. outputText: str | None = None
  250. outputJson: dict[str, JSONValue] | None = None
  251. errorCode: str | None = None
  252. errorMessage: str | None = None
  253. class TeamRunExecuteRequestDto(BaseModel):
  254. teamRunId: str
  255. workerKey: str | None = None
  256. dryRun: bool = True
  257. class TeamRunExecuteData(BaseModel):
  258. run: TeamRunDto
  259. memberRunCount: int = 0
  260. dryRun: bool = True
  261. class TeamRunDeleteRequestDto(BaseModel):
  262. teamRunId: str
  263. class DeleteData(BaseModel):
  264. deleted: bool
  265. teamId: str | None = None
  266. configId: str | None = None
  267. teamRunId: str | None = None