schemas.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # -*- coding: utf-8 -*-
  2. """Schemas for the document chat module."""
  3. from typing import Any, Dict, List, Literal, Optional
  4. from pydantic import BaseModel, Field
  5. class SelectedSection(BaseModel):
  6. index: str = Field(..., description="Section index, for example 2.1")
  7. title: str = Field(..., description="Section title")
  8. content: str = Field(default="", description="Current section content from the editor")
  9. code: str = Field(default="", description="Section code")
  10. class DocumentContext(BaseModel):
  11. before: str = Field(default="", description="Previous context snippet")
  12. after: str = Field(default="", description="Following context snippet")
  13. siblings: List[Dict[str, Any]] = Field(default_factory=list)
  14. references: List[Dict[str, Any]] = Field(default_factory=list)
  15. class DocumentChatRequest(BaseModel):
  16. user_id: str
  17. message: str = Field(..., min_length=1, description="User message")
  18. selected_section: SelectedSection
  19. conversation_id: Optional[str] = None
  20. task_id: Optional[str] = None
  21. project_info: Dict[str, Any] = Field(default_factory=dict)
  22. document_context: DocumentContext = Field(default_factory=DocumentContext)
  23. conversation_history: List[Dict[str, Any]] = Field(default_factory=list)
  24. response_mode: Literal["json", "sse"] = "json"
  25. class Config:
  26. extra = "forbid"
  27. class IntentResult(BaseModel):
  28. intent: Literal["document_modify", "document_answer", "clarify", "unsupported"]
  29. confidence: float = Field(default=0.0, ge=0.0, le=1.0)
  30. skill_name: Optional[str] = None
  31. operation: str = ""
  32. target_scope: str = "selected_section"
  33. normalized_instruction: str = ""
  34. needs_clarification: bool = False
  35. clarification_question: str = ""
  36. reason: str = ""
  37. warnings: List[str] = Field(default_factory=list)
  38. class DocumentChatSkillInput(BaseModel):
  39. user_id: str
  40. user_message: str
  41. selected_section: SelectedSection
  42. intent_result: IntentResult
  43. conversation_id: Optional[str] = None
  44. task_id: Optional[str] = None
  45. project_info: Dict[str, Any] = Field(default_factory=dict)
  46. document_context: DocumentContext = Field(default_factory=DocumentContext)
  47. conversation_history: List[Dict[str, Any]] = Field(default_factory=list)
  48. class DocumentChatSkillOutput(BaseModel):
  49. skill_name: str
  50. response_type: Literal["answer", "proposal", "clarify", "unsupported"]
  51. answer: Optional[str] = None
  52. old_content: Optional[str] = None
  53. proposed_content: Optional[str] = None
  54. change_summary: List[str] = Field(default_factory=list)
  55. references: List[Dict[str, Any]] = Field(default_factory=list)
  56. warnings: List[str] = Field(default_factory=list)
  57. class DiffItem(BaseModel):
  58. type: Literal["equal", "insert", "delete", "replace", "full_content"]
  59. old_text: str = ""
  60. new_text: str = ""
  61. class DiffResult(BaseModel):
  62. old_content_hash: str
  63. new_content_hash: str
  64. diff: List[DiffItem] = Field(default_factory=list)
  65. diff_granularity: Literal["line", "full_content"] = "line"
  66. class DocumentChatData(BaseModel):
  67. callback_task_id: str
  68. response_type: Literal["answer", "proposal", "clarify", "unsupported", "error"]
  69. intent_result: Optional[Dict[str, Any]] = None
  70. answer: Optional[str] = None
  71. proposed_content: Optional[str] = None
  72. old_content_hash: Optional[str] = None
  73. new_content_hash: Optional[str] = None
  74. diff: List[Dict[str, Any]] = Field(default_factory=list)
  75. diff_granularity: Optional[str] = None
  76. change_summary: List[str] = Field(default_factory=list)
  77. references: List[Dict[str, Any]] = Field(default_factory=list)
  78. warnings: List[str] = Field(default_factory=list)
  79. selected_section: Dict[str, Any] = Field(default_factory=dict)
  80. error_message: Optional[str] = None
  81. class DocumentChatResponse(BaseModel):
  82. code: int
  83. message: str
  84. data: Optional[DocumentChatData] = None
  85. def model_to_dict(value: Any) -> Dict[str, Any]:
  86. """Return a dict for Pydantic v1/v2 models."""
  87. if value is None:
  88. return {}
  89. if isinstance(value, dict):
  90. return value
  91. if hasattr(value, "model_dump"):
  92. return value.model_dump()
  93. if hasattr(value, "dict"):
  94. return value.dict()
  95. return dict(value)