models.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. """Completely isolated persistence models for ``find_agent_v2``."""
  2. from __future__ import annotations
  3. from datetime import datetime
  4. from decimal import Decimal
  5. from sqlalchemy import BigInteger, Index, Integer, Numeric, String, Text, UniqueConstraint, func
  6. from sqlalchemy.dialects.mysql import LONGTEXT
  7. from sqlalchemy.orm import Mapped, mapped_column
  8. from supply_infra.db.base import Base
  9. _LONG_TEXT = Text().with_variant(LONGTEXT(), "mysql")
  10. class FindAgentV2Run(Base):
  11. __tablename__ = "find_agent_v2_run"
  12. __table_args__ = (
  13. UniqueConstraint("run_id", name="uk_find_agent_v2_run_id"),
  14. Index("idx_find_agent_v2_run_status", "status"),
  15. Index("idx_find_agent_v2_run_demand", "demand_grade_id"),
  16. )
  17. id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
  18. run_id: Mapped[str] = mapped_column(String(64), nullable=False)
  19. demand_grade_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  20. demand_word: Mapped[str] = mapped_column(String(256), nullable=False)
  21. triggered_by_user_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  22. triggered_by_username: Mapped[str | None] = mapped_column(String(64), nullable=True)
  23. trigger_source: Mapped[str] = mapped_column(String(32), nullable=False, default="cli")
  24. input_json: Mapped[str] = mapped_column(_LONG_TEXT, nullable=False)
  25. rule_config_json: Mapped[str] = mapped_column(Text, nullable=False)
  26. status: Mapped[str] = mapped_column(String(24), nullable=False, default="running")
  27. outcome_status: Mapped[str | None] = mapped_column(String(24), nullable=True)
  28. current_round: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
  29. search_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
  30. candidate_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
  31. valid_primary_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
  32. input_tokens: Mapped[int] = mapped_column(BigInteger, nullable=False, default=0)
  33. output_tokens: Mapped[int] = mapped_column(BigInteger, nullable=False, default=0)
  34. total_tokens: Mapped[int] = mapped_column(BigInteger, nullable=False, default=0)
  35. cost_usd: Mapped[Decimal] = mapped_column(Numeric(18, 8), nullable=False, default=0)
  36. intent_summary: Mapped[str | None] = mapped_column(Text, nullable=True)
  37. stop_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
  38. obagent_run_uid: Mapped[str | None] = mapped_column(String(64), nullable=True)
  39. create_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now())
  40. update_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now(), onupdate=func.now())
  41. class FindAgentV2Round(Base):
  42. __tablename__ = "find_agent_v2_round"
  43. __table_args__ = (
  44. UniqueConstraint("run_id", "round_index", name="uk_find_agent_v2_round"),
  45. Index("idx_find_agent_v2_round_run", "run_id", "round_index"),
  46. )
  47. id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
  48. run_id: Mapped[str] = mapped_column(String(64), nullable=False)
  49. round_index: Mapped[int] = mapped_column(Integer, nullable=False)
  50. phase: Mapped[str] = mapped_column(String(24), nullable=False, default="planning")
  51. status: Mapped[str] = mapped_column(String(16), nullable=False, default="open")
  52. plan_json: Mapped[str | None] = mapped_column(_LONG_TEXT, nullable=True)
  53. start_snapshot_json: Mapped[str | None] = mapped_column(Text, nullable=True)
  54. end_snapshot_json: Mapped[str | None] = mapped_column(Text, nullable=True)
  55. error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
  56. create_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now())
  57. update_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now(), onupdate=func.now())
  58. class FindAgentV2Search(Base):
  59. __tablename__ = "find_agent_v2_search"
  60. __table_args__ = (Index("idx_find_agent_v2_search_run", "run_id", "id"),)
  61. id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
  62. run_id: Mapped[str] = mapped_column(String(64), nullable=False)
  63. round_index: Mapped[int] = mapped_column(Integer, nullable=False)
  64. keyword: Mapped[str] = mapped_column(String(256), nullable=False)
  65. query_reason: Mapped[str] = mapped_column(Text, nullable=False)
  66. source_type: Mapped[str] = mapped_column(String(32), nullable=False)
  67. provider: Mapped[str] = mapped_column(String(32), nullable=False)
  68. cursor: Mapped[str] = mapped_column(String(128), nullable=False, default="0")
  69. page_no: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
  70. has_more: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
  71. next_cursor: Mapped[str | None] = mapped_column(String(128), nullable=True)
  72. provider_state_json: Mapped[str | None] = mapped_column(Text, nullable=True)
  73. result_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
  74. status: Mapped[str] = mapped_column(String(16), nullable=False)
  75. error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
  76. raw_response_json: Mapped[str | None] = mapped_column(_LONG_TEXT, nullable=True)
  77. create_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now())
  78. class FindAgentV2Candidate(Base):
  79. __tablename__ = "find_agent_v2_candidate"
  80. __table_args__ = (
  81. UniqueConstraint("run_id", "aweme_id", name="uk_find_agent_v2_candidate_aweme"),
  82. Index("idx_find_agent_v2_candidate_bucket", "run_id", "decision_bucket"),
  83. )
  84. id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
  85. run_id: Mapped[str] = mapped_column(String(64), nullable=False)
  86. # Logical reference only. find_agent_v2 deliberately uses no database FKs.
  87. first_search_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  88. aweme_id: Mapped[str] = mapped_column(String(64), nullable=False)
  89. title: Mapped[str | None] = mapped_column(String(512), nullable=True)
  90. content_link: Mapped[str | None] = mapped_column(String(1024), nullable=True)
  91. author_name: Mapped[str | None] = mapped_column(String(256), nullable=True)
  92. author_sec_uid: Mapped[str | None] = mapped_column(String(256), nullable=True)
  93. source_keywords_json: Mapped[str | None] = mapped_column(Text, nullable=True)
  94. tags_json: Mapped[str | None] = mapped_column(Text, nullable=True)
  95. publish_at: Mapped[datetime | None] = mapped_column(nullable=True)
  96. duration_seconds: Mapped[Decimal | None] = mapped_column(Numeric(10, 3), nullable=True)
  97. play_count: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  98. like_count: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  99. comment_count: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  100. collect_count: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  101. share_count: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  102. detail_json: Mapped[str | None] = mapped_column(_LONG_TEXT, nullable=True)
  103. portrait_json: Mapped[str | None] = mapped_column(_LONG_TEXT, nullable=True)
  104. detail_status: Mapped[str] = mapped_column(String(16), nullable=False, default="pending")
  105. portrait_status: Mapped[str] = mapped_column(String(16), nullable=False, default="pending")
  106. content_50_plus_ratio: Mapped[Decimal | None] = mapped_column(Numeric(8, 6), nullable=True)
  107. account_50_plus_ratio: Mapped[Decimal | None] = mapped_column(Numeric(8, 6), nullable=True)
  108. relevance_score: Mapped[Decimal | None] = mapped_column(Numeric(8, 6), nullable=True)
  109. elder_score: Mapped[Decimal | None] = mapped_column(Numeric(8, 6), nullable=True)
  110. share_score: Mapped[Decimal | None] = mapped_column(Numeric(8, 6), nullable=True)
  111. value_score: Mapped[Decimal | None] = mapped_column(Numeric(8, 6), nullable=True)
  112. gate_status: Mapped[str | None] = mapped_column(String(16), nullable=True)
  113. gate_result_json: Mapped[str | None] = mapped_column(Text, nullable=True)
  114. decision_bucket: Mapped[str] = mapped_column(String(24), nullable=False, default="pending_evaluation")
  115. decision_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
  116. reject_reason_code: Mapped[str | None] = mapped_column(String(64), nullable=True)
  117. create_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now())
  118. update_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now(), onupdate=func.now())
  119. class FindAgentV2Evidence(Base):
  120. __tablename__ = "find_agent_v2_evidence"
  121. __table_args__ = (Index("idx_find_agent_v2_evidence_subject", "run_id", "candidate_id", "id"),)
  122. id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
  123. run_id: Mapped[str] = mapped_column(String(64), nullable=False)
  124. candidate_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  125. evidence_type: Mapped[str] = mapped_column(String(32), nullable=False)
  126. provider: Mapped[str] = mapped_column(String(32), nullable=False)
  127. status: Mapped[str] = mapped_column(String(16), nullable=False)
  128. raw_json: Mapped[str | None] = mapped_column(_LONG_TEXT, nullable=True)
  129. normalized_json: Mapped[str | None] = mapped_column(_LONG_TEXT, nullable=True)
  130. error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
  131. create_time: Mapped[datetime] = mapped_column(nullable=False, server_default=func.now())