test_mission_factory.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import json
  2. from datetime import UTC, datetime
  3. from script_build_host.agents.prompts import PARAGRAPH_WORKER_PROMPT, PLANNER_PROMPT
  4. from script_build_host.application.mission_factory import ScriptMissionFactory
  5. from script_build_host.domain.input_snapshot import ScriptBuildInputSnapshotV1
  6. from script_build_host.domain.records import MissionBinding
  7. def _snapshot() -> ScriptBuildInputSnapshotV1:
  8. return ScriptBuildInputSnapshotV1(
  9. snapshot_id="11",
  10. script_build_id=4,
  11. execution_id=1,
  12. topic_build_id=2,
  13. topic_id=3,
  14. topic={
  15. "topic": {
  16. "id": 3,
  17. "result": "真实嵌套选题结果",
  18. "topic_direction": "fallback",
  19. }
  20. },
  21. account={"account_name": "每天心理学"},
  22. persona_points=(),
  23. section_patterns=(),
  24. strategies=(),
  25. prompt_manifest=(),
  26. datasource_manifest={},
  27. model_manifest={
  28. "presets": {
  29. "script_planner": {
  30. "model": "planner-model",
  31. "temperature": 0.1,
  32. "max_iterations": 42,
  33. }
  34. }
  35. },
  36. canonical_sha256="sha256:" + "b" * 64,
  37. created_at=datetime.now(UTC),
  38. )
  39. def _binding() -> MissionBinding:
  40. now = datetime.now(UTC)
  41. return MissionBinding(
  42. binding_id=1,
  43. script_build_id=4,
  44. root_trace_id="root",
  45. input_snapshot_id=11,
  46. active_direction_artifact_version_id=None,
  47. accepted_root_artifact_version_id=None,
  48. engine_version="test",
  49. schema_version="v1",
  50. created_at=now,
  51. updated_at=now,
  52. )
  53. def test_factory_reads_nested_real_topic_and_does_not_double_prefix_digest() -> None:
  54. factory = ScriptMissionFactory()
  55. spec = factory.build_root_task_spec(_snapshot())
  56. assert "真实嵌套选题结果" in str(spec["objective"])
  57. assert "title" not in str(spec)
  58. assert "workflow" not in str(spec).lower()
  59. message = json.loads(factory.build_planner_message(_binding(), _snapshot()))
  60. assert message["input_sha256"] == "sha256:" + "b" * 64
  61. assert "Retrieval children under that Direction" in message["instruction"]
  62. assert "exact reason PHASE_ONE_CAPABILITY_BOUNDARY" in message["instruction"]
  63. config = factory.build_run_config(_binding(), _snapshot())
  64. assert config.agent_type == "script_planner"
  65. assert config.model == "planner-model"
  66. assert config.temperature == 0.1
  67. assert config.max_iterations == 42
  68. assert config.new_trace_id == "root"
  69. assert config.context["phase"] == 1
  70. assert config.enable_memory is False
  71. assert config.enable_research_flow is False
  72. def test_phase_prompts_isolate_boundaries_and_expose_dynamic_phase_two_invariants() -> None:
  73. factory = ScriptMissionFactory()
  74. assert "PHASE_TWO_CANDIDATE_PORTFOLIO_READY" not in PLANNER_PROMPT
  75. assert "using the returned Direction Task ID as `parent_task_id`" in PLANNER_PROMPT
  76. assert "`PHASE_ONE_CAPABILITY_BOUNDARY` with no additional text" in PLANNER_PROMPT
  77. phase_two = factory.build_phase_two_policy(_snapshot())
  78. assert "PHASE_TWO_CANDIDATE_PORTFOLIO_READY" in phase_two
  79. assert "Create exactly one CandidatePortfolio as Root's Phase2 child" in phase_two
  80. assert "Plan any number and order" in phase_two
  81. assert "Every Phase2 contract has nonempty goal_ids" in phase_two
  82. assert "pins the exact accepted Direction DecisionRef" in phase_two
  83. assert "carry all Direction Goal IDs" in phase_two
  84. assert "Paragraph-first exploration may use a null base" in phase_two
  85. assert "only with a Structure covering its scope" in phase_two
  86. assert "partitions their complete accepted candidate closure" in phase_two
  87. assert "CandidatePortfolio and Compose write only script-build://writes" in phase_two
  88. assert "paragraph writers stay below script-build://writes/paragraphs" in phase_two
  89. assert "element writers below script-build://writes/elements" in phase_two
  90. assert "derive a strategy reference" in PARAGRAPH_WORKER_PROMPT