document.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. from datetime import datetime
  2. from typing import Literal, Optional
  3. from pydantic import BaseModel, Field, model_validator
  4. # ---------- 局部块更新 ----------
  5. class BlockUpdate(BaseModel):
  6. level: int = Field(..., ge=1, le=6, description="标题等级 1=H1 … 6=H6")
  7. index: int = Field(..., ge=0, description="该等级标题在文档中的顺序下标(从 0 开始)")
  8. content: str = Field(..., description="该块的新内容(含标题行本身)")
  9. # ---------- 请求 ----------
  10. class CreateDocumentRequest(BaseModel):
  11. title: str = Field(..., max_length=255)
  12. content: str = Field(..., description="文档内容(Markdown),最大 200KB")
  13. format: Literal["markdown"] = "markdown"
  14. session_id: Optional[str] = Field(None, alias="sessionId")
  15. template_id: Optional[str] = Field(None, alias="templateId")
  16. source: Literal["chat", "workflow"] = "chat"
  17. model_config = {"populate_by_name": True}
  18. class UpdateDocumentRequest(BaseModel):
  19. title: Optional[str] = Field(None, max_length=255)
  20. content: Optional[str] = Field(None, description="全量更新内容,与 blocks 二选一")
  21. blocks: Optional[list[BlockUpdate]] = Field(None, description="局部块更新,与 content 二选一")
  22. @model_validator(mode="after")
  23. def check_content_or_blocks(self) -> "UpdateDocumentRequest":
  24. if self.content is not None and self.blocks is not None:
  25. raise ValueError("content 与 blocks 不能同时传入")
  26. return self
  27. # ---------- 响应 ----------
  28. class DocumentResponse(BaseModel):
  29. id: str
  30. title: str
  31. content: str
  32. format: str
  33. session_id: Optional[str] = Field(None, serialization_alias="sessionId")
  34. template_id: Optional[str] = Field(None, serialization_alias="templateId")
  35. source: Literal["chat", "workflow"]
  36. created_by: Optional[str] = Field(None, serialization_alias="createdBy")
  37. created_at: datetime = Field(..., serialization_alias="createdAt")
  38. updated_at: datetime = Field(..., serialization_alias="updatedAt")
  39. model_config = {"from_attributes": True, "populate_by_name": True}
  40. class DocumentListItem(BaseModel):
  41. id: str
  42. title: str
  43. source: Literal["chat", "workflow"]
  44. template_id: Optional[str] = Field(None, serialization_alias="templateId")
  45. created_at: datetime = Field(..., serialization_alias="createdAt")
  46. updated_at: datetime = Field(..., serialization_alias="updatedAt")
  47. model_config = {"from_attributes": True, "populate_by_name": True}
  48. class Pagination(BaseModel):
  49. page: int
  50. page_size: int = Field(..., serialization_alias="pageSize")
  51. total: int
  52. total_pages: int = Field(..., serialization_alias="totalPages")
  53. model_config = {"populate_by_name": True}