# Architecture Overview CleverAgents is a Python-first AI agent orchestration platform. It provides a unified CLI (`agents`), an interactive TUI, an embedded runtime, and service orchestration tools for building and running complex, long-running AI-driven workflows. This document gives a developer-oriented overview of the system. For the authoritative specification see [`docs/specification.md`](specification.md). For individual design decisions see the [ADR index](adr/index.md). --- ## High-Level Component Map ```mermaid graph TD subgraph "Entry Points" CLI["CLI
(agents / cleveragents)"] TUI["TUI
(agents tui)"] SERVER["Server
(agents server)"] end subgraph "Application Layer" A2A["A2A Facade
(local / HTTP)"] DI["DI Container
(application.container)"] SERVICES["Application Services
(plan, session, actor, skill, tool, …)"] end subgraph "Domain Layer" PLAN["Plan Lifecycle
(Strategize → Execute → Apply)"] ACTOR["Actor System
(config, loader, compiler)"] RESOURCE["Resource DAG
(handlers, inheritance)"] DECISION["Decision Tree
(record, version, rollback)"] end subgraph "Infrastructure Layer" DB["Database
(SQLAlchemy + Alembic)"] SANDBOX["Sandbox
(checkpoint, rollback)"] OBS["Observability
(logging, metrics, audit)"] EVENTS["Event Bus
(reactive streams)"] PLUGINS["Plugin Manager"] end subgraph "Integration Layer" LANGGRAPH["LangGraph Bridge"] MCP["MCP Adapter"] LSP["LSP Client"] ACMS["ACMS
(context management)"] UKO["UKO Runtime
(knowledge ontology)"] end CLI --> A2A TUI --> A2A SERVER --> A2A A2A --> DI DI --> SERVICES SERVICES --> PLAN SERVICES --> ACTOR SERVICES --> RESOURCE SERVICES --> DECISION PLAN --> LANGGRAPH ACTOR --> LANGGRAPH LANGGRAPH --> MCP LANGGRAPH --> LSP SERVICES --> ACMS ACMS --> UKO SERVICES --> DB SERVICES --> SANDBOX SERVICES --> OBS SERVICES --> EVENTS SERVICES --> PLUGINS ``` --- ## Layered Architecture CleverAgents follows a strict layered architecture ([ADR-001](adr/ADR-001-layered-architecture.md)): | Layer | Package | Responsibility | |-------|---------|----------------| | **Entry Points** | `cli`, `tui` | User-facing interfaces | | **Application** | `application` | DI wiring, service orchestration | | **Domain** | `domain`, `actor`, `skills`, `tool`, `resource` | Business logic | | **Infrastructure** | `infrastructure` | Database, sandbox, events, observability | | **Integration** | `a2a`, `mcp`, `lsp`, `langgraph`, `acms` | External protocol adapters | | **Core** | `core`, `shared`, `config` | Cross-cutting utilities | Dependencies flow **downward only** — upper layers may import from lower layers but never the reverse. --- ## Plan Lifecycle The plan lifecycle is the central abstraction ([ADR-006](adr/ADR-006-plan-lifecycle.md)): ``` Action ──► Strategize ──► Execute ──► Apply │ │ │ │ │ (estimate) (validate) (diff review) │ │ └───────────────────────────┘ (correction / rollback) ``` | Phase | Description | |-------|-------------| | **Action** | User intent captured as a plan request | | **Strategize** | LLM generates a structured plan with operations | | **Execute** | Operations executed against resources via tools | | **Apply** | Validated changes committed; diff reviewed and approved | Phase transitions are gated by: - **Validation pipeline** — rule-based checks with severity levels - **Definition-of-Done** — explicit criteria evaluated before Apply - **Advisory locking** — prevents concurrent modification of the same plan - **Invariant reconciliation** — `InvariantReconciliationActor` runs automatically at each phase transition (`start_strategize`, `execute_plan`, `apply_plan`); failures raise `ReconciliationBlockedError` and emit `INVARIANT_VIOLATED` events, blocking the transition until invariants are satisfied --- ## Actor System Actors are the execution units ([ADR-010](adr/ADR-010-actor-and-agent-architecture.md), [ADR-031](adr/ADR-031-actor-abstraction-definition.md)): - Defined in YAML with a LangGraph node graph - Each node binds an LLM, a set of tools, and optional LSP/MCP sources - Compiled by `ActorCompiler` into a runnable `CompiledActor` - Registered in `ActorRegistry` and resolved by name at runtime ```yaml # examples/actors/graph_workflow.yaml name: openai/gpt-4o entry_node: planner nodes: planner: model: gpt-4o tool_sources: [builtin, mcp://bash-tools] executor: model: gpt-4o-mini tool_sources: [builtin] edges: - from: planner to: executor condition: needs_execution ``` --- ## Tool System Tools are the atomic capabilities available to actors ([ADR-011](adr/ADR-011-tool-system.md)): - Registered in `ToolRegistry` with a `ToolSpec` (JSON Schema) and executor - Four-stage lifecycle: **activate → validate → execute → deactivate** - Sources: `builtin`, `mcp`, `lsp`, `skill` - Safety profiles control sandbox requirements, human approval gates, and cost limits - Read-only enforcement blocks write-capable tools on read-only plans --- ## Skill System Skills are composable capability bundles ([ADR-012](adr/ADR-012-skill-system.md), [ADR-028](adr/ADR-028-agent-skills-standard.md)): - Loaded from YAML or AgentSkills.io-compatible directories - Three-tier progressive disclosure: **discover → activate → deactivate** - Each skill exposes one or more tools to the actor - `SkillRegistry` tracks all registered skills; `SkillRefreshResult` reports changes --- ## Resource System Resources are managed external entities ([ADR-008](adr/ADR-008-resource-system.md)): - Organized as a DAG (Directed Acyclic Graph) with dependency tracking - Type hierarchy with multiple inheritance and field merging ([ADR-042](adr/ADR-042-resource-type-inheritance.md)) - Built-in types: `file`, `directory`, `sqlite`, `postgresql`, `mysql`, `duckdb`, `container.docker`, `container.podman`, `lsp.*`, `cloud.*` - Each type has a handler implementing CRUD, checkpoint, and rollback --- ## Context Management (ACMS) The Advanced Context Management System manages what context is sent to the LLM at each phase ([ADR-014](adr/ADR-014-context-management-acms.md)): - **Tier 1** — Always-present system context - **Tier 2** — Phase-specific context (plan, project, actor) - **Tier 3** — Dynamic retrieval (semantic search, UKO inference) The **UKO Runtime** (Universal Knowledge Ontology) provides graph-based knowledge inference and persistence for Tier 3 context strategies. Key UKO capabilities: - **Typed triples with provenance** — every triple carries `sourceResource`, `validFrom`, and `isCurrent` metadata - **Temporal versioning** — a revision chain tracks ontology state across indexing runs, enabling point-in-time queries - **Implicit inference** — `UKOInferenceEngine` produces `uko:implicitSiblingOf`, `uko:implicitContains`, and `uko:implicitDependsOn` triples with confidence 0.7 - **Graph persistence** — `UKOGraphPersistence` serialises/restores state via JSON-file or in-memory backends across application restarts **Context hydration** bridges the resource registry and the ACMS tier service. `context_tier_hydrator.hydrate_tiers_for_plan()` reads files from all resources linked to the active project and stores them as `TieredFragment` objects in `ContextTierService` before context assembly begins. Without hydration, the LLM receives zero file context. See [ACMS Context Hydration](modules/context-hydration.md) for details. --- ## Invariant Reconciliation The **Invariant Reconciliation Actor** (`builtin/invariant-reconciliation`) is automatically invoked at the start of the Strategize, Execute, and Apply phase transitions by `PlanLifecycleService`. **Reconciliation algorithm** (spec §19440–19600): 1. Collect invariants from four scopes: global, project, action, plan. 2. Group by normalised text (case-insensitive, stripped). 3. Detect conflicts between invariants at different scopes. 4. Resolve using specificity: `plan > action > project > global`. Exception: `non_overridable` global invariants always win. 5. Record an `invariant_enforced` decision for each active invariant. 6. Return a reconciled `InvariantSet`. **Failure behaviour:** - Reconciliation failures block the phase transition with `ReconciliationBlockedError` and emit an `INVARIANT_VIOLATED` event. - Post-correction reconciliation runs via `CORRECTION_APPLIED` event subscription (best-effort; does not block correction completion). **DI registration:** `InvariantService` is registered as a Singleton provider in the DI container. ```python from cleveragents.actor.reconciliation import InvariantReconciliationActor actor = InvariantReconciliationActor( invariant_service=container.invariant_service(), decision_service=container.decision_service(), ) result = actor.run(plan_id="...", project_name="...", action_name="...") # result.reconciled_set — effective InvariantSet # result.conflicts — list[ConflictRecord] with resolution details ``` --- ## Git Worktree Sandbox Apply When `plan apply` commits changes to a git-checkout resource, the changes are isolated in a dedicated git branch and worktree rather than written directly to the working tree. **Flow:** 1. `PlanLifecycleService` detects a git-checkout resource and creates a `GitWorktreeSandbox`. 2. A new branch `cleveragents/plan-` is created from the current HEAD. 3. A temporary worktree is created at a system temp directory. 4. The actor writes changes inside the worktree. 5. On approval: changes are staged, committed in the worktree, then merged back to the original branch via `git merge`. 6. On rejection: the worktree is discarded and the original branch is untouched. Non-git projects fall back to the original flat file copy strategy. See [Git Worktree Sandbox](modules/git-worktree-sandbox.md) for the full API reference. --- ## A2A Protocol Boundary All CLI, TUI, and server interactions cross the A2A boundary ([ADR-026](adr/ADR-026-agent-client-protocol.md), [ADR-047](adr/ADR-047-acp-standard-adoption.md)): - **Local mode** — `A2aLocalFacade` maps operations to direct Python calls - **Server mode** — `A2aHttpTransport` (stub; full implementation pending) - Version negotiation via `A2aVersionNegotiator` --- ## MCP Integration External tool servers are integrated via the Model Context Protocol ([ADR-029](adr/ADR-029-model-context-protocol.md)): - `MCPToolAdapter` manages server lifecycle and tool discovery - `McpClient` provides lazy start and auto-stop - `SandboxPathRewriter` prevents path traversal - `MCPRefreshHook` keeps skill registrations in sync with server changes --- ## LSP Integration Language Server Protocol servers provide code intelligence tools ([ADR-027](adr/ADR-027-language-server-protocol.md)): - `LSPClient` manages server lifecycle and capability negotiation - LSP tools are registered in `ToolRegistry` with `source="lsp"` - Per-node LSP bindings in actor YAML control which server each node uses --- ## Dependency Injection All application services are wired via the DI container ([ADR-003](adr/ADR-003-dependency-injection.md)): ```python from cleveragents.application.container import Container container = Container() plan_service = container.plan_service() session_service = container.session_service() ``` The container is the single source of truth for service instantiation. Never construct services directly in application code. --- ## Observability ([ADR-025](adr/ADR-025-observability-and-logging.md)) - Structured logging via `cleveragents.config.logging` - Metrics processing via `cleveragents.config.metrics_processor` - Audit logging via `infrastructure.observability` - Token/cost tracking per plan and per day with budget enforcement --- ## Key Design Decisions | Decision | ADR | Summary | |----------|-----|---------| | Layered architecture | [ADR-001](adr/ADR-001-layered-architecture.md) | Strict layer boundaries, no upward imports | | Namespace system | [ADR-002](adr/ADR-002-namespace-system.md) | `provider/name` qualified identifiers | | Dependency injection | [ADR-003](adr/ADR-003-dependency-injection.md) | Single DI container, no service locator | | Plan lifecycle | [ADR-006](adr/ADR-006-plan-lifecycle.md) | Four-phase lifecycle with gating | | LangGraph integration | [ADR-022](adr/ADR-022-langchain-langgraph-integration.md) | LangGraph as graph execution engine | | Sandboxing | [ADR-015](adr/ADR-015-sandbox-and-checkpoint.md) | Checkpoint/rollback for all resource writes | | Template security | [ADR-032](adr/ADR-032-jinja2-yaml-template-preprocessing.md) | Sandboxed Jinja2 with allowlist | | TUI framework | [ADR-044](adr/ADR-044-tui-architecture-and-framework.md) | Textual-based full-screen TUI with first-run experience, persona system, session export/import | | Server architecture | [ADR-048](adr/ADR-048-server-application-architecture.md) | ASGI server with Kubernetes deployment |