review.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. from __future__ import annotations
  2. """行程评审结果模型:TripReviewResult包含评审结论、问题列表与修改意见。"""
  3. from typing import Literal
  4. from pydantic import Field, model_validator
  5. from app.schemas.common import AppModel
  6. ReviewCategory = Literal[
  7. "requirement_fit",
  8. "pace",
  9. "geography",
  10. "flight",
  11. "hotel",
  12. "budget",
  13. "completeness",
  14. "grounding",
  15. "user_experience",
  16. "other",
  17. ]
  18. ReviewSeverity = Literal[
  19. "blocking",
  20. "warning",
  21. ]
  22. class ReviewIssue(AppModel):
  23. """Reviewer发现的单个语义问题。"""
  24. category: ReviewCategory
  25. severity: ReviewSeverity
  26. message: str
  27. day_index: int | None = Field(
  28. default=None,
  29. ge=1,
  30. le=30,
  31. )
  32. activity_name: str | None = None
  33. evidence: str | None = None
  34. suggestion: str | None = None
  35. class TripReviewResult(AppModel):
  36. """Trip Reviewer的结构化审查结果。"""
  37. approved: bool
  38. summary: str
  39. strengths: list[str] = Field(
  40. default_factory=list
  41. )
  42. issues: list[ReviewIssue] = Field(
  43. default_factory=list
  44. )
  45. # 非阻塞优化建议。
  46. recommendations: list[str] = Field(
  47. default_factory=list
  48. )
  49. # 仅在方案不通过时填写,
  50. # 下一轮Planner必须执行这些修改。
  51. revision_feedback: list[str] = Field(
  52. default_factory=list
  53. )
  54. @model_validator(mode="after")
  55. def validate_review_result(
  56. self,
  57. ) -> "TripReviewResult":
  58. blocking_issues = [
  59. issue
  60. for issue in self.issues
  61. if issue.severity == "blocking"
  62. ]
  63. if self.approved:
  64. if blocking_issues:
  65. raise ValueError(
  66. "审查通过时不能包含blocking问题。"
  67. )
  68. if self.revision_feedback:
  69. raise ValueError(
  70. "审查通过时revision_feedback"
  71. "必须为空。"
  72. )
  73. else:
  74. if not self.revision_feedback:
  75. raise ValueError(
  76. "审查不通过时必须给出"
  77. "revision_feedback。"
  78. )
  79. return self