Task 4.3 closes the loop on Chunk 4: the FastAPI lifespan now selects fake vs real clients via IX_TEST_MODE (new AppConfig field), wires /healthz probes to the live selfcheck() on OllamaClient / SuryaOCRClient, and spawns the worker with a production Pipeline factory that builds SetupStep -> OCRStep -> GenAIStep -> ReliabilityStep -> ResponseHandler over the injected clients. Factories: - make_genai_client(cfg) -> FakeGenAIClient | OllamaClient - make_ocr_client(cfg) -> FakeOCRClient | SuryaOCRClient (spec §6.2) Probes run the async selfcheck on a fresh event loop in a short-lived thread so they're safe to call from either sync callers or a live FastAPI handler without stalling the request loop. Drops the worker-loop spawn_worker_task stub — the app module owns the production spawn directly. Tests: +11 unit tests (5 factories + 6 app-wiring / probe adapter / pipeline build). Full suite: 236 passed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
43 lines
1.4 KiB
Python
43 lines
1.4 KiB
Python
"""GenAI subsystem: protocol + fake client + invocation-result dataclasses.
|
|
|
|
Real backends (Ollama, …) plug in behind :class:`GenAIClient`. The factory
|
|
:func:`make_genai_client` picks between :class:`FakeGenAIClient` (for CI
|
|
/ hermetic tests via ``IX_TEST_MODE=fake``) and :class:`OllamaClient`
|
|
(production). Tests that want a real Ollama client anyway can call the
|
|
constructor directly.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from ix.config import AppConfig
|
|
from ix.genai.client import GenAIClient, GenAIInvocationResult, GenAIUsage
|
|
from ix.genai.fake import FakeGenAIClient
|
|
from ix.genai.ollama_client import OllamaClient
|
|
|
|
|
|
def make_genai_client(cfg: AppConfig) -> GenAIClient:
|
|
"""Return the :class:`GenAIClient` configured for the current run.
|
|
|
|
When ``cfg.test_mode == "fake"`` the fake is returned; the pipeline
|
|
callers are expected to override the injected client via DI if they
|
|
want a non-default canned response. Otherwise a live
|
|
:class:`OllamaClient` bound to ``cfg.ollama_url`` and the per-call
|
|
timeout is returned.
|
|
"""
|
|
|
|
if cfg.test_mode == "fake":
|
|
return FakeGenAIClient(parsed=None)
|
|
return OllamaClient(
|
|
base_url=cfg.ollama_url,
|
|
per_call_timeout_s=float(cfg.genai_call_timeout_seconds),
|
|
)
|
|
|
|
|
|
__all__ = [
|
|
"FakeGenAIClient",
|
|
"GenAIClient",
|
|
"GenAIInvocationResult",
|
|
"GenAIUsage",
|
|
"OllamaClient",
|
|
"make_genai_client",
|
|
]
|