Task 002: add shared domain contracts

This commit is contained in:
2026-05-21 17:45:00 +03:00
parent d42f0c4392
commit a0ae06adfa
31 changed files with 4043 additions and 27 deletions
@@ -0,0 +1,63 @@
from __future__ import annotations
import importlib.util
import os
import sys
from functools import lru_cache
from pathlib import Path
from typing import Any, Mapping
@lru_cache(maxsize=1)
def _backend_contracts_module() -> Any:
contracts_dir = _backend_contracts_dir()
init_file = contracts_dir / "__init__.py"
module_name = "_pipeline_backend_domain_contracts"
existing = sys.modules.get(module_name)
if existing is not None and Path(str(existing.__file__)).resolve() == init_file.resolve():
return existing
sys.modules.pop(module_name, None)
spec = importlib.util.spec_from_file_location(
module_name,
init_file,
submodule_search_locations=[str(contracts_dir)],
)
if spec is None or spec.loader is None:
raise RuntimeError(f"Cannot load backend contract module from {init_file}")
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
return module
def _backend_contracts_dir() -> Path:
for candidate in _backend_contract_candidates():
init_file = candidate / "__init__.py"
if init_file.is_file():
return candidate
candidates = ", ".join(str(path) for path in _backend_contract_candidates())
raise RuntimeError(f"Cannot find backend contract package. Checked: {candidates}")
def _backend_contract_candidates() -> tuple[Path, ...]:
configured = os.environ.get("PIPELINE_BACKEND_CONTRACTS_DIR")
candidates: list[Path] = []
if configured:
candidates.append(Path(configured))
current_file = Path(__file__).resolve()
candidates.append(Path("/app/backend_contracts/contracts"))
for parent in current_file.parents:
candidates.append(parent / "apps" / "backend" / "src" / "domain" / "contracts")
return tuple(dict.fromkeys(candidates))
def validate_agent_job_output(payload: Mapping[str, Any]) -> Any:
contracts = _backend_contracts_module()
return contracts.AgentJobOutput.model_validate(payload)