schemas.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. from __future__ import annotations
  2. from typing import Any, Literal
  3. from pydantic import BaseModel, Field, field_validator
  4. ConfirmStatus = Literal["PENDING", "TRUSTED", "SUSPICIOUS", "IGNORED", "NEED_MORE_INFO"]
  5. ItemType = Literal["service", "process"]
  6. AiProviderType = Literal["OPENAI", "OPENAI_COMPATIBLE", "GOOGLE_GEMINI"]
  7. MouseAutomationAction = Literal["move_to", "move_rel", "click", "double_click", "right_click", "drag_to", "scroll"]
  8. KeyboardAutomationAction = Literal["press", "hotkey", "write", "key_down", "key_up"]
  9. AutomationNodeType = Literal["mouse", "keyboard", "text_input", "start_program", "close_programs"]
  10. class StatusUpdate(BaseModel):
  11. confirm_status: ConfirmStatus
  12. user_note: str | None = None
  13. class BatchStatusUpdate(BaseModel):
  14. ids: list[int] = Field(default_factory=list)
  15. confirm_status: ConfirmStatus
  16. user_note: str | None = None
  17. class AiImportItem(BaseModel):
  18. type: ItemType
  19. name: str
  20. description: str | None = None
  21. judgement: Literal["TRUSTED", "SUSPICIOUS", "NEED_MORE_INFO"]
  22. risk_level: Literal["LOW", "MEDIUM", "HIGH"]
  23. reason: str | None = None
  24. suggestion: str | None = None
  25. tags: list[str] | None = None
  26. @field_validator("tags", mode="before")
  27. @classmethod
  28. def normalize_tags(cls, value: Any) -> list[str] | None:
  29. if value is None:
  30. return None
  31. if isinstance(value, str):
  32. return [value]
  33. if isinstance(value, list):
  34. names: list[str] = []
  35. for item in value:
  36. if isinstance(item, str):
  37. names.append(item)
  38. elif isinstance(item, dict) and item.get("name"):
  39. names.append(str(item["name"]))
  40. return names
  41. raise ValueError("tags must be a string, list of strings, or list of objects with name")
  42. class AiImportRequest(BaseModel):
  43. items: list[AiImportItem]
  44. class PromptRequest(BaseModel):
  45. ids: list[int] | None = None
  46. scope: Literal["selected", "pending"] = "pending"
  47. class TagCreate(BaseModel):
  48. name: str = Field(min_length=1, max_length=80)
  49. description: str | None = None
  50. is_controllable: bool = True
  51. class TagUpdate(BaseModel):
  52. name: str = Field(min_length=1, max_length=80)
  53. description: str | None = None
  54. is_controllable: bool = True
  55. class TagAssignRequest(BaseModel):
  56. tag_ids: list[int] = Field(default_factory=list)
  57. class ProcessStartRequest(BaseModel):
  58. command: str = Field(min_length=1)
  59. cwd: str | None = None
  60. class AutomationPowerRequest(BaseModel):
  61. delay_seconds: int = Field(default=0, ge=0, le=86400)
  62. force: bool = False
  63. reason: str | None = Field(default=None, max_length=512)
  64. class AutomationProgramStartRequest(BaseModel):
  65. command: str = Field(min_length=1)
  66. cwd: str | None = None
  67. shell: bool = True
  68. class AutomationProgramStopRequest(BaseModel):
  69. pid: int | None = Field(default=None, ge=0)
  70. name: str | None = Field(default=None, min_length=1)
  71. timeout_seconds: float = Field(default=8, ge=0, le=60)
  72. kill_after_timeout: bool = True
  73. class AutomationScreenshotRequest(BaseModel):
  74. save_path: str | None = None
  75. include_base64: bool = True
  76. class AutomationMouseRequest(BaseModel):
  77. action: MouseAutomationAction
  78. x: int | None = None
  79. y: int | None = None
  80. duration: float = Field(default=0, ge=0, le=60)
  81. button: Literal["left", "middle", "right"] = "left"
  82. clicks: int = Field(default=1, ge=1, le=20)
  83. amount: int = 0
  84. class AutomationKeyboardRequest(BaseModel):
  85. action: KeyboardAutomationAction
  86. key: str | None = None
  87. keys: list[str] | None = None
  88. text: str | None = None
  89. interval: float = Field(default=0, ge=0, le=10)
  90. class AutomationVisionAnalyzeRequest(BaseModel):
  91. provider_id: int | None = None
  92. model_id: int | None = None
  93. temperature: float = Field(default=0.1, ge=0, le=2)
  94. class AutomationScreenshotCaptureRequest(BaseModel):
  95. save: bool = True
  96. class AutomationElementLocateRequest(BaseModel):
  97. provider_id: int | None = None
  98. model_id: int | None = None
  99. temperature: float = Field(default=0.1, ge=0, le=2)
  100. class AutomationActionBase(BaseModel):
  101. screen_id: int | None = None
  102. provider_id: int | None = None
  103. model_id: int | None = None
  104. temperature: float = Field(default=0.1, ge=0, le=2)
  105. workflow_id: int | None = None
  106. node_id: int | None = None
  107. class AutomationMouseActionRequest(AutomationActionBase):
  108. x: int
  109. y: int
  110. mouse_action: Literal["click", "double_click", "right_click"]
  111. class AutomationKeyboardActionRequest(AutomationActionBase):
  112. keys: list[str] = Field(min_length=1)
  113. class AutomationTextInputRequest(AutomationActionBase):
  114. text: str
  115. class AutomationStartProgramRequest(AutomationActionBase):
  116. command: str = Field(min_length=1)
  117. cwd: str | None = None
  118. shell: bool = True
  119. class AutomationCloseProgramsRequest(BaseModel):
  120. pids: list[int] | None = None
  121. class AutomationWorkflowNode(BaseModel):
  122. node_key: str | None = None
  123. node_type: AutomationNodeType
  124. screen_id: int | None = None
  125. title: str | None = None
  126. position_x: float = 80
  127. position_y: float = 80
  128. next_node_keys: list[str] = Field(default_factory=list)
  129. config: dict[str, Any] = Field(default_factory=dict)
  130. class AutomationWorkflowSaveRequest(BaseModel):
  131. name: str = Field(min_length=1, max_length=160)
  132. description: str | None = None
  133. nodes: list[AutomationWorkflowNode] = Field(default_factory=list)
  134. class AutomationWorkflowRunRequest(BaseModel):
  135. provider_id: int | None = None
  136. model_id: int | None = None
  137. temperature: float | None = Field(default=None, ge=0, le=2)
  138. class SystemSettingsUpdate(BaseModel):
  139. default_ai_provider_id: int | None = None
  140. default_ai_model_id: int | None = None
  141. default_ai_temperature: float | None = Field(default=None, ge=0, le=2)
  142. automation_file_root: str | None = None
  143. automation_screen_path: str | None = None
  144. automation_error_path: str | None = None
  145. automation_runtime_path: str | None = None
  146. automation_auto_screenshot_enabled: bool | None = None
  147. automation_auto_screenshot_interval: int | None = Field(default=None, ge=1, le=3600)
  148. class AiProviderCreate(BaseModel):
  149. name: str = Field(min_length=1, max_length=120)
  150. provider_type: AiProviderType
  151. base_url: str | None = None
  152. api_key: str | None = None
  153. enabled: bool = True
  154. class AiProviderUpdate(BaseModel):
  155. name: str = Field(min_length=1, max_length=120)
  156. provider_type: AiProviderType
  157. base_url: str | None = None
  158. api_key: str | None = None
  159. clear_api_key: bool = False
  160. enabled: bool = True
  161. class AiModelCreate(BaseModel):
  162. provider_id: int
  163. name: str = Field(min_length=1, max_length=160)
  164. display_name: str | None = None
  165. is_default: bool = False
  166. class AiModelUpdate(BaseModel):
  167. provider_id: int
  168. name: str = Field(min_length=1, max_length=160)
  169. display_name: str | None = None
  170. is_default: bool = False
  171. class AiChatRequest(BaseModel):
  172. provider_id: int
  173. model_id: int
  174. prompt: str = Field(min_length=1)
  175. temperature: float = Field(default=0.2, ge=0, le=2)
  176. class AiAnalyzeRequest(BaseModel):
  177. provider_id: int
  178. model_id: int
  179. temperature: float = Field(default=0.2, ge=0, le=2)
  180. ids: list[int] | None = None
  181. scope: Literal["selected", "pending"] = "pending"