"""Single-stage Authoring CDSL composition root.""" from __future__ import annotations from dataclasses import dataclass import shutil from app.cad_agent.adapters.artifact_store import FileArtifactStore from app.cad_agent.adapters.event_publisher import IdempotentInProcessPublisher from app.cad_agent.adapters.runtime import ProfileCadRuntime from app.cad_agent.adapters.sqlite_repository import SqliteTaskRepository from app.cad_agent.adapters.structured_llm import StructuredModelGateway from app.cad_agent.application.outbox import OutboxDispatcher from app.cad_agent.application.workflow import WorkflowConfig, WorkflowCoordinator from app.cad_agent.application.single_stage import SingleStageExecutor from app.settings import Settings from app.services.storage import WorkspaceStore @dataclass(frozen=True, slots=True) class CadServices: repository: SqliteTaskRepository artifacts: FileArtifactStore workflow: WorkflowCoordinator models: StructuredModelGateway outbox: OutboxDispatcher single_stage: SingleStageExecutor def compose_cad_services(settings: Settings) -> CadServices: database_root = settings.task_root.parent legacy_database = database_root / "autonomous-cad-v3.sqlite3" removed_legacy_database = False if legacy_database.exists(): # The removed coordinator persisted incompatible task/action state in # its own database. Delete it as part of the deliberate destructive # migration, including SQLite sidecars if a worker stopped mid-write. for candidate in (legacy_database, *(database_root / f"{legacy_database.name}{suffix}" for suffix in ("-wal", "-shm"))): if candidate.exists(): candidate.unlink() removed_legacy_database = True repository = SqliteTaskRepository(database_root / "autonomous-cad-single-stage.sqlite3") protocol_reset = repository.protocol_reset or removed_legacy_database if protocol_reset and settings.task_root.exists(): # Old task artifacts have no valid interpretation under the Authoring # protocol, so clear them together with the task database. shutil.rmtree(settings.task_root) if protocol_reset: WorkspaceStore(settings).clear_current_task_references() artifacts = FileArtifactStore(settings.task_root) runtime = ProfileCadRuntime(settings) models = StructuredModelGateway(settings) outbox = OutboxDispatcher(repository, IdempotentInProcessPublisher()) single_stage = SingleStageExecutor(repository, artifacts, runtime) workflow = WorkflowCoordinator( WorkflowConfig(), repository, artifacts, runtime, models, single_stage, ) return CadServices(repository, artifacts, workflow, models, outbox, single_stage)