team.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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. TeamConfigContract,
  10. )
  11. from core_shared import JSONValue
  12. from pydantic import BaseModel, Field
  13. if TYPE_CHECKING:
  14. from app.db.models import TeamDefinition, TeamRun, TeamConfig
  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 TeamCreateRequest(BaseModel):
  54. code: str
  55. name: str
  56. description: str | None = None
  57. team_type: str = "collaborative"
  58. owner_user_id: str | None = None
  59. metadata_json: dict[str, JSONValue] = Field(default_factory=dict)
  60. class TeamStatusUpdateRequest(BaseModel):
  61. status: TeamStatus
  62. class TeamResponse(TeamDefinitionContract):
  63. @classmethod
  64. def from_entity(cls, entity: "TeamDefinition") -> "TeamResponse":
  65. return cls.model_validate(entity, from_attributes=True)
  66. class TeamConfigCreateRequest(BaseModel):
  67. team_id: str
  68. coordination_mode: str = "supervisor"
  69. objective: str | None = None
  70. member_refs: list[TeamMemberContract] = Field(default_factory=list)
  71. policy_json: dict[str, JSONValue] = Field(default_factory=dict)
  72. class TeamConfigResponse(TeamConfigContract):
  73. @classmethod
  74. def from_entity(cls, entity: "TeamConfig") -> "TeamConfigResponse":
  75. return cls.model_validate(entity, from_attributes=True)
  76. class TeamRunCreateRequest(BaseModel):
  77. team_id: str
  78. team_config_id: str | None = None
  79. session_id: str | None = None
  80. input_text: str | None = None
  81. input_json: dict[str, JSONValue] | None = None
  82. enqueue: bool = True
  83. class TeamRunStatusUpdateRequest(BaseModel):
  84. status: TeamRunStatus
  85. worker_key: str | None = None
  86. output_text: str | None = None
  87. output_json: dict[str, JSONValue] | None = None
  88. error_code: str | None = None
  89. error_message: str | None = None
  90. class TeamRunExecuteRequest(BaseModel):
  91. worker_key: str | None = None
  92. dry_run: bool = True
  93. class TeamRunResponse(TeamRunContract):
  94. @classmethod
  95. def from_entity(cls, entity: "TeamRun") -> "TeamRunResponse":
  96. return cls.model_validate(entity, from_attributes=True)
  97. class TeamRunExecuteResponse(BaseModel):
  98. run: TeamRunResponse
  99. member_run_count: int = 0
  100. dry_run: bool = True
  101. class TeamWorkerExecuteNextRequest(BaseModel):
  102. worker_key: str
  103. lease_seconds: int | None = Field(default=None, gt=0)
  104. dry_run: bool | None = None
  105. class TeamWorkerExecuteNextResponse(BaseModel):
  106. run: TeamRunResponse
  107. member_run_count: int = 0
  108. dry_run: bool = True
  109. released_lease_count: int = 0
  110. class TeamDto(BaseModel):
  111. id: str
  112. name: str
  113. description: str | None = None
  114. teamType: str
  115. status: TeamStatus
  116. ownerUserId: str | None = None
  117. metadata: dict[str, JSONValue] = Field(default_factory=dict)
  118. createdTime: datetime
  119. @classmethod
  120. def from_entity(cls, entity: "TeamDefinition") -> "TeamDto":
  121. return cls(
  122. id=entity.id,
  123. name=entity.name,
  124. description=entity.description,
  125. teamType=entity.team_type,
  126. status=entity.status,
  127. ownerUserId=entity.owner_user_id,
  128. metadata=entity.metadata_json or {},
  129. createdTime=entity.created_time)
  130. class TeamListRequestDto(PageRequest):
  131. status: TeamStatus | None = None
  132. class TeamCreateRequestDto(BaseModel):
  133. name: str
  134. description: str | None = None
  135. teamType: str = "collaborative"
  136. ownerUserId: str | None = None
  137. metadata: dict[str, JSONValue] = Field(default_factory=dict)
  138. class TeamDetailRequestDto(BaseModel):
  139. teamId: str
  140. class TeamUpdateRequestDto(BaseModel):
  141. teamId: str
  142. name: str | None = None
  143. description: str | None = None
  144. teamType: str | None = None
  145. status: TeamStatus | None = None
  146. ownerUserId: str | None = None
  147. metadata: dict[str, JSONValue] | None = None
  148. class TeamDeleteRequestDto(BaseModel):
  149. teamId: str
  150. class TeamConfigDto(BaseModel):
  151. id: str
  152. teamId: str
  153. coordinationMode: str
  154. objective: str | None = None
  155. memberRefs: list[dict[str, JSONValue]]
  156. policy: dict[str, JSONValue]
  157. createdTime: datetime
  158. @classmethod
  159. def from_entity(cls, entity: "TeamConfig") -> "TeamConfigDto":
  160. return cls(
  161. id=entity.id,
  162. teamId=entity.team_id,
  163. coordinationMode=entity.coordination_mode,
  164. objective=entity.objective,
  165. memberRefs=entity.member_refs_json,
  166. policy=entity.policy_json,
  167. createdTime=entity.created_time)
  168. class TeamConfigListRequestDto(PageRequest):
  169. teamId: str | None = None
  170. class TeamConfigCreateRequestDto(BaseModel):
  171. teamId: str
  172. coordinationMode: str = "supervisor"
  173. objective: str | None = None
  174. memberRefs: list[dict[str, JSONValue]] = Field(default_factory=list)
  175. policy: dict[str, JSONValue] = Field(default_factory=dict)
  176. class TeamConfigDetailRequestDto(BaseModel):
  177. configId: str
  178. class TeamConfigUpdateRequestDto(BaseModel):
  179. configId: str
  180. coordinationMode: str | None = None
  181. objective: str | None = None
  182. memberRefs: list[dict[str, JSONValue]] | None = None
  183. policy: dict[str, JSONValue] | None = None
  184. class TeamConfigDeleteRequestDto(BaseModel):
  185. configId: str
  186. class TeamRunDto(BaseModel):
  187. id: str
  188. teamId: str
  189. teamConfigId: str
  190. sessionId: str | None = None
  191. inputText: str | None = None
  192. inputJson: dict[str, JSONValue] | None = None
  193. outputText: str | None = None
  194. outputJson: dict[str, JSONValue] | None = None
  195. status: TeamRunStatus
  196. workerKey: str | None = None
  197. queuedTime: datetime | None = None
  198. leaseExpireTime: datetime | None = None
  199. startedTime: datetime | None = None
  200. finishedTime: datetime | None = None
  201. errorCode: str | None = None
  202. errorMessage: str | None = None
  203. createdTime: datetime
  204. @classmethod
  205. def from_entity(cls, entity: "TeamRun") -> "TeamRunDto":
  206. return cls(
  207. id=entity.id,
  208. teamId=entity.team_id,
  209. teamConfigId=entity.team_config_id,
  210. sessionId=entity.session_id,
  211. inputText=entity.input_text,
  212. inputJson=entity.input_json,
  213. outputText=entity.output_text,
  214. outputJson=entity.output_json,
  215. status=entity.status,
  216. workerKey=entity.worker_key,
  217. queuedTime=entity.queued_time,
  218. leaseExpireTime=entity.lease_expire_time,
  219. startedTime=entity.started_time,
  220. finishedTime=entity.finished_time,
  221. errorCode=entity.error_code,
  222. errorMessage=entity.error_message,
  223. createdTime=entity.created_time)
  224. class TeamRunListRequestDto(PageRequest):
  225. teamId: str | None = None
  226. sessionId: str | None = None
  227. status: TeamRunStatus | None = None
  228. class TeamRunCreateRequestDto(BaseModel):
  229. teamId: str
  230. teamConfigId: str | None = None
  231. sessionId: str | None = None
  232. inputText: str | None = None
  233. inputJson: dict[str, JSONValue] | None = None
  234. enqueue: bool = True
  235. class TeamRunDetailRequestDto(BaseModel):
  236. teamRunId: str
  237. class TeamRunStatusUpdateRequestDto(BaseModel):
  238. teamRunId: str
  239. status: TeamRunStatus
  240. workerKey: str | None = None
  241. outputText: str | None = None
  242. outputJson: dict[str, JSONValue] | None = None
  243. errorCode: str | None = None
  244. errorMessage: str | None = None
  245. class TeamRunExecuteRequestDto(BaseModel):
  246. teamRunId: str
  247. workerKey: str | None = None
  248. dryRun: bool = True
  249. class TeamRunExecuteData(BaseModel):
  250. run: TeamRunDto
  251. memberRunCount: int = 0
  252. dryRun: bool = True
  253. class TeamRunDeleteRequestDto(BaseModel):
  254. teamRunId: str
  255. class DeleteData(BaseModel):
  256. deleted: bool
  257. teamId: str | None = None
  258. configId: str | None = None
  259. teamRunId: str | None = None