# `cleveragents.core` — Core Utilities The `core` package provides the exception hierarchy, error classification, retry patterns, circuit breaker, and async resource cleanup used throughout the entire CleverAgents platform. --- ## Domain Base Model **Module:** `cleveragents.domain.models.base` ### `DomainBaseModel` ```python from cleveragents.domain.models.base import DomainBaseModel class DomainBaseModel(BaseModel): model_config = ConfigDict( str_strip_whitespace=True, validate_assignment=True, arbitrary_types_allowed=False, populate_by_name=True, use_enum_values=True, ) ``` Shared Pydantic base class for all standard domain-layer models. Inherit from `DomainBaseModel` instead of `pydantic.BaseModel` directly to get the canonical domain-layer configuration in one place. **Configuration semantics:** | Setting | Effect | |---------|--------| | `str_strip_whitespace` | Leading/trailing whitespace stripped from all `str` fields on assignment and validation | | `validate_assignment` | Field assignments after construction are validated like constructor arguments | | `arbitrary_types_allowed=False` | All field types must be Pydantic-compatible — keeps the domain layer clean | | `populate_by_name` | Models can be constructed using either the Python field name or the JSON alias | | `use_enum_values` | Enum fields are stored and serialised as their underlying primitive values | **Usage:** ```python from cleveragents.domain.models.base import DomainBaseModel from pydantic import Field class MyDomainModel(DomainBaseModel): name: str count: int = Field(ge=0) ``` > **Note:** This class was introduced in v3.7.0 (PR #1941) to eliminate the > duplicated `model_config` that previously appeared in 14 separate domain > model files. It is a pure structural refactor with no behavioral changes. --- ## Exception Hierarchy All exceptions inherit from `CleverAgentsError`. Catch the most specific type you can handle; let everything else propagate. ``` CleverAgentsError ├── DomainError │ ├── ValidationError │ ├── BusinessRuleViolation │ │ ├── LockConflictError │ │ └── DecisionPhaseViolationError │ ├── ResourceNotFoundError (alias: NotFoundError) │ ├── ResourceConflictError │ ├── LockExpiredError │ └── PlanError ├── InfrastructureError │ ├── DatabaseError │ │ └── MigrationNotApprovedError │ ├── NetworkError │ └── ExternalServiceError ├── ProviderError │ ├── RateLimitError │ ├── ModelNotAvailableError │ └── TokenLimitExceededError ├── AuthenticationError ├── AuthorizationError ├── ConfigurationError │ └── MissingConfigurationError ├── FileSystemError ├── ExecutionError ├── StreamRoutingError └── UnsafeConfigurationError ``` ### `CleverAgentsError` ```python class CleverAgentsError(Exception): message: str details: dict[str, Any] ``` Base class for all platform exceptions. Always carries a human-readable `message` and an optional `details` dict for structured context. --- ### `ResourceNotFoundError` ```python class ResourceNotFoundError(DomainError): resource_type: str | None resource_id: str | None ``` Raised when a requested entity does not exist. If `resource_type` and `resource_id` are provided the message is auto-generated. ```python from cleveragents.core.exceptions import ResourceNotFoundError raise ResourceNotFoundError(resource_type="plan", resource_id="plan-42") # → "Plan 'plan-42' not found" ``` --- ### `LockConflictError` ```python class LockConflictError(BusinessRuleViolation): resource_type: str resource_id: str owner_id: str ``` Raised when an advisory lock cannot be acquired because another owner holds it. --- ### `RateLimitError` ```python class RateLimitError(ProviderError): retry_after: int | None # seconds to wait before retrying ``` --- ### `DecisionPhaseViolationError` ```python class DecisionPhaseViolationError(BusinessRuleViolation): decision_type: str plan_phase: str allowed_types: frozenset[str] ``` Raised when a decision type is incompatible with the plan's current phase. --- ## Error Handling Utilities **Module:** `cleveragents.core.error_handling` ### `ErrorCode` `IntEnum` mapping exception categories to HTTP-like numeric codes used for consistent CLI and API output. ### `classify_error(exc) → ErrorCode` Returns the `ErrorCode` for any exception, falling back to `ErrorCode.INTERNAL` for unknown types. ### `redact_error_details(details) → dict` Strips sensitive keys (tokens, passwords, secrets) from an error details dict before logging. ### `wrap_unexpected(exc, *, context=None) → CleverAgentsError` Wraps an unexpected exception in a `CleverAgentsError` with a safe user-facing message that hides internal stack details. ```python from cleveragents.core.error_handling import wrap_unexpected try: risky_operation() except Exception as exc: safe = wrap_unexpected(exc, context={"plan_id": plan_id}) raise safe from exc ``` --- ## Retry Patterns **Module:** `cleveragents.core.retry_patterns` Provides decorators and helpers for exponential-backoff retry with jitter, configurable per exception type. --- ## Async Cleanup **Module:** `cleveragents.core.async_cleanup` `AsyncResourceTracker` — unified async resource lifecycle with timeout-bounded cleanup, leak detection via finalizer, and async context manager support. ```python async with AsyncResourceTracker() as tracker: conn = await tracker.register(open_connection()) # conn is automatically closed on exit, even on error ``` --- ## Circuit Breaker **Module:** `cleveragents.core.circuit_breaker` Implements the circuit-breaker pattern to prevent cascading failures when calling external services. --- ## Invariant Service **Module:** `cleveragents.application.services.invariant_service` The `InvariantService` manages invariant constraints across scopes and is automatically invoked at every plan phase transition by the `InvariantReconciliationActor`. ### `InvariantService` ```python from cleveragents.application.services.invariant_service import InvariantService from cleveragents.domain.models.core.invariant import InvariantScope service = InvariantService(event_bus=event_bus) inv = service.add_invariant( text="All output files must be UTF-8 encoded", scope=InvariantScope.PROJECT, source_name="my-project", ) ``` **Constructor parameters:** | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `event_bus` | `EventBus \| None` | `None` | Optional event bus for emitting `INVARIANT_VIOLATED` / `INVARIANT_ENFORCED` / `INVARIANT_RECONCILED` events | **Methods:** | Method | Returns | Description | |--------|---------|-------------| | `add_invariant(text, scope, source_name)` | `Invariant` | Add a new invariant; validates and sanitizes text | | `list_invariants(scope, source_name, effective)` | `list[Invariant]` | Filter invariants; pass `effective=True` to get the merged precedence chain | | `remove_invariant(invariant_id)` | `Invariant` | Soft-delete an invariant (sets `active=False`) | | `get_effective_invariants(plan_id, project_name)` | `list[Invariant]` | Return merged invariants using plan > project > global precedence | | `enforce_invariants(plan_id, invariants, actor_response, violated_invariant_ids)` | `list[InvariantEnforcementRecord]` | Create enforcement records; emits `INVARIANT_VIOLATED` for each violation | **Merge precedence:** plan > project > global. Duplicate invariant texts are de-duplicated by `merge_invariants()`. **Events emitted:** | Event | When | |-------|------| | `INVARIANT_VIOLATED` | An invariant in `violated_invariant_ids` was not satisfied | | `INVARIANT_ENFORCED` | Each invariant enforcement record is created | | `INVARIANT_RECONCILED` | Once per `enforce_invariants()` call (batch summary) | > **Note:** The `InvariantService` is registered as a Singleton provider in > the DI container. Obtain it via `container.invariant_service()` rather > than constructing it directly.