1"""DI Provider for the AI Evaluation subsystem."""
2
3from __future__ import annotations
4
5from typing import TYPE_CHECKING
6
7from lexigram.ai.evaluation.config import EvaluationConfig
8from lexigram.contracts.ai.evaluation import EvaluatorProtocol
9from lexigram.contracts.ai.experiment import (
10 CheckpointStoreProtocol,
11 ExperimentTrackerProtocol,
12)
13from lexigram.contracts.core.health import HealthCheckResult, HealthStatus
14from lexigram.di.provider import Provider, ProviderPriority
15from lexigram.logging import get_logger
16
17if TYPE_CHECKING:
18 from lexigram.contracts.core.di import (
19 BootContainerProtocol,
20 ContainerRegistrarProtocol,
21 )
22
23logger = get_logger(__name__)
24
25
26class EvaluationProvider(Provider):
27 """Registers evaluation services with the DI container."""
28
29 name = "evaluation"
30 priority = ProviderPriority.DOMAIN
31 config_key: str | None = "ai_evaluation"
32 config_model: type | None = EvaluationConfig
33
34 def __init__(self, config: EvaluationConfig | None = None) -> None:
35 super().__init__()
36 self._requested_config = config
37 self._config = config or EvaluationConfig()
38
39 async def register(self, container: ContainerRegistrarProtocol) -> None:
40 self._config = self._requested_config or self._config or EvaluationConfig()
41 container.singleton(EvaluationConfig, instance=self._config)
42
43 from lexigram.ai.evaluation.evaluators.criteria import CriteriaEvaluator
44 from lexigram.ai.evaluation.evaluators.embedding_distance import (
45 EmbeddingDistanceEvaluator,
46 )
47 from lexigram.ai.evaluation.evaluators.qa import QAEvaluator
48 from lexigram.ai.evaluation.evaluators.string_distance import (
49 StringDistanceEvaluator,
50 )
51 from lexigram.ai.evaluation.harness.runner import EvaluationHarness
52
53 container.singleton(
54 EvaluatorProtocol,
55 CriteriaEvaluator(),
56 name="criteria",
57 )
58 container.singleton(
59 EvaluatorProtocol,
60 QAEvaluator(),
61 name="qa",
62 )
63 container.singleton(
64 EvaluatorProtocol,
65 StringDistanceEvaluator(),
66 name="string_distance",
67 )
68 container.singleton(
69 EvaluatorProtocol,
70 EmbeddingDistanceEvaluator(),
71 name="embedding_distance",
72 )
73 container.singleton(EvaluationHarness, EvaluationHarness())
74
75 from lexigram.ai.evaluation.checkpoints import FileCheckpointStore
76 from lexigram.ai.evaluation.tracking import LocalTracker
77
78 experiment_root = self._config.experiment_dir or "runs"
79 container.singleton(
80 ExperimentTrackerProtocol,
81 LocalTracker(root=experiment_root),
82 )
83 container.singleton(
84 CheckpointStoreProtocol,
85 FileCheckpointStore(root=experiment_root),
86 )
87
88 logger.info("evaluation_provider_registered")
89
90 async def boot(self, container: BootContainerProtocol) -> None:
91 logger.info("evaluation_provider_booted")
92
93 async def shutdown(self) -> None:
94 pass
95
96 async def health_check(self, timeout: float = 5.0) -> HealthCheckResult:
97 return HealthCheckResult(
98 component="evaluation",
99 status=HealthStatus.HEALTHY,
100 details={"status": "ok"},
101 )
102
103
104__all__ = ["EvaluationProvider"]