from __future__ import annotations from pathlib import Path from src.core.models import JobConfig, JobResult from src.core.pipelines import build_pipeline_catalog, create_pipeline_context from src.core.toolbox import PDFToolbox, build_default_pdf_toolbox from src.utils.file_utils import ensure_dir class OfflinePDFOrchestrator: def __init__(self, work_dir: Path, toolbox: PDFToolbox | None = None): self.work_dir = ensure_dir(Path(work_dir)) self.toolbox = toolbox or build_default_pdf_toolbox() self.pipeline_catalog = build_pipeline_catalog(self.toolbox) def list_available_pipelines(self) -> list[str]: return list(self.pipeline_catalog.keys()) def run(self, config: JobConfig) -> JobResult: pipeline_name = config.pipeline or "full_document" if pipeline_name not in self.pipeline_catalog: raise ValueError( f"Unknown pipeline '{pipeline_name}'. " f"Available pipelines: {', '.join(self.list_available_pipelines())}" ) context = create_pipeline_context(config, self.toolbox, self.work_dir) pipeline = self.pipeline_catalog[pipeline_name] try: pipeline.run(context) return context.finish_success( context.state["final_pdf"], context.state["manifest"], ) except Exception as exc: context.errors.append(str(exc)) context.logger.log("orchestrator", "error", "Job failed", error=str(exc)) return context.finish_failure()