| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- from __future__ import annotations
- from pathlib import Path
- from langchain_core.messages import AIMessage
- from production_build_agents.contracts.models import (
- ArtifactRejection,
- GlobalDataStageValidatorCandidate,
- StageRequirementResult,
- ValidationCriterionResult,
- ValidatorCandidate,
- )
- from tests.support.fake_models import ToolAwareFakeChatModel
- from production_build_agents.agents.validator.stage_context import required_stage_audit_paths
- _BRIEF_PATH = (
- Path(__file__).parents[1] / "fixtures" / "minimal_brief.json"
- )
- STAGE_AUDIT_PATHS = required_stage_audit_paths(str(_BRIEF_PATH))
- def build_stage_read_call(call_id: str) -> AIMessage:
- return AIMessage(
- content="",
- tool_calls=[
- {
- "name": "read_production_brief",
- "args": {"source_paths": STAGE_AUDIT_PATHS},
- "id": call_id,
- "type": "tool_call",
- }
- ],
- )
- def build_validator_candidate(
- *,
- run_id: str = "test-run",
- plan_id: str = "GlobalDataPlan",
- task_id: str = "Task1",
- plan_version: int = 1,
- verdict: str = "PASS",
- expectation_id: str = "Requirement1-Expectation1",
- verification_capability: str = "document_content",
- ) -> ValidatorCandidate:
- return ValidatorCandidate(
- run_id=run_id,
- plan_id=plan_id,
- plan_version=plan_version,
- task_id=task_id,
- executor_run_id=(
- f"{run_id}-executor-{task_id}-v{plan_version}"
- ),
- criterion_results=[
- ValidationCriterionResult(
- expectation_id=expectation_id,
- verification_capability=verification_capability,
- verdict=verdict,
- evidence=[f"{task_id} 的验收证据"],
- reason=f"{task_id} 的 Expectation 验收结论",
- )
- ],
- summary=f"{task_id} 验收为 {verdict}",
- )
- def build_validator_model(
- *candidates: ValidatorCandidate,
- stage_candidate: GlobalDataStageValidatorCandidate | None = None,
- include_stage: bool = True,
- ) -> ToolAwareFakeChatModel:
- responses = [
- AIMessage(content=candidate.model_dump_json())
- for candidate in candidates
- ]
- if include_stage and (candidates or stage_candidate):
- selected = stage_candidate or build_stage_validator_candidate(
- run_id=candidates[-1].run_id,
- plan_id=candidates[-1].plan_id,
- plan_version=candidates[-1].plan_version,
- )
- responses.extend(
- [
- build_stage_read_call("stage-read-production-brief"),
- AIMessage(content=selected.model_dump_json()),
- ]
- )
- return ToolAwareFakeChatModel(
- responses=responses
- )
- def build_stage_validator_candidate(
- *,
- run_id: str = "test-run",
- plan_id: str = "GlobalDataPlan",
- plan_version: int = 1,
- requirement_ids: tuple[str, ...] = ("Requirement1",),
- verdict: str = "PASS",
- missing_critical: bool = False,
- missing_minor: bool = False,
- artifact_rejections: list[ArtifactRejection] | None = None,
- ) -> GlobalDataStageValidatorCandidate:
- return GlobalDataStageValidatorCandidate(
- run_id=run_id,
- plan_id=plan_id,
- plan_version=plan_version,
- inspected_source_paths=STAGE_AUDIT_PATHS,
- requirement_results=[
- StageRequirementResult(
- requirement_id=requirement_id,
- verdict=verdict,
- evidence_artifact_ids=[],
- evidence=[f"{requirement_id} 的阶段证据"],
- reason=f"{requirement_id} 阶段验收为 {verdict}",
- )
- for requirement_id in requirement_ids
- ],
- missing_requirements=[
- *(
- [
- {
- "description": "缺少关键共享素材",
- "importance": "critical",
- "source_paths": ["$.核心制作点[0]"],
- "expected_artifact_types": ["image"],
- }
- ]
- if missing_critical
- else []
- ),
- *(
- [
- {
- "description": "缺少非关键参考说明",
- "importance": "minor",
- "source_paths": ["$.核心制作点[0]"],
- "expected_artifact_types": ["document"],
- }
- ]
- if missing_minor
- else []
- ),
- ],
- artifact_rejections=artifact_rejections or [],
- summary="Global Data 阶段验收完成",
- )
|