Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 700543f87e |
+1
-1
@@ -327,7 +327,7 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
- `agents action create` now accepts `--format`/`-f` flag, matching all
|
||||
other action subcommands. (#959)
|
||||
|
||||
## Unreleased (pre-3.7.0)
|
||||
### Pre-release changes (merged into v3.7.0)
|
||||
|
||||
- Eliminated redundant fields (`excluded_decisions`, `rollback_tier_depth`,
|
||||
`child_plans_to_rollback`) from `CorrectionDryRunReport` that duplicated data
|
||||
|
||||
@@ -9,6 +9,8 @@ embracing modern Python tooling.
|
||||
- Unified CLI entry points: `cleveragents` and `agents`
|
||||
- **Interactive TUI** (`agents tui`) — full-screen Textual app with multi-session tabs,
|
||||
persona switching, slash commands, reference picker, and context-sensitive F1 help
|
||||
- **First-run experience** — actor selection overlay on first launch; creates a default
|
||||
persona automatically so you can start chatting immediately
|
||||
- **Persona system** — YAML-backed personas bind actors, argument presets, and scope
|
||||
references to named identities; persisted in `~/.config/cleveragents/personas/`
|
||||
- **Session management** — create, list, export, and import conversation sessions;
|
||||
@@ -19,7 +21,8 @@ embracing modern Python tooling.
|
||||
- **Server mode** — `agents server connect` configures a remote CleverAgents server;
|
||||
Kubernetes Helm chart in `k8s/` for production deployment
|
||||
- **A2A integration** — Agent-to-Agent protocol facade wires CLI and TUI to live
|
||||
application services (session, plan, registry, event)
|
||||
application services (session, plan, registry, event); `ValueError` now maps to
|
||||
`VALIDATION_ERROR` for correct protocol semantics
|
||||
- **Permissions screen** — TUI overlay for reviewing tool permission requests with
|
||||
unified, side-by-side, and context diff views; session-scoped allow/reject decisions
|
||||
- **Actor thought blocks** — expandable reasoning trace widgets rendered inline in the
|
||||
@@ -28,8 +31,16 @@ embracing modern Python tooling.
|
||||
graph persistence for ACMS context strategies
|
||||
- **Database resource handler** — full CRUD and checkpoint/rollback support for SQLite,
|
||||
PostgreSQL, MySQL, and DuckDB resources
|
||||
- **Devcontainer resource handler** — `delete()`, `list_children()`, `diff()`, and
|
||||
`create_sandbox()` now fully implemented
|
||||
- **Estimation lifecycle** — `actor.default.estimation` config key wires an estimation
|
||||
actor into the Strategize-to-Estimate lifecycle hook
|
||||
actor into the Strategize-to-Estimate lifecycle hook; emits `PLAN_ESTIMATION_COMPLETE`
|
||||
domain event; failures are informational and never block Execute
|
||||
- **Enriched domain events** — `PLAN_APPLIED` carries changeset statistics
|
||||
(files changed, lines added/removed, resources modified, apply duration);
|
||||
`PLAN_CANCELLED` includes progress context; all events carry `user_identity`
|
||||
- **Correction attempts** — `correction_attempts` table tracks every decision correction
|
||||
with full lifecycle state machine (`pending → executing → complete/failed`)
|
||||
- Fast Typer/Click-based interface with parity for help/version behavior
|
||||
- Behavior-driven coverage via Behave and Robot Framework
|
||||
- Nox automation for linting, typing, testing, docs, builds, and benchmarks
|
||||
@@ -65,7 +76,8 @@ pip install -e ".[tui]"
|
||||
agents tui
|
||||
```
|
||||
|
||||
Inside the TUI:
|
||||
On first launch, the **Actor Selection Overlay** guides you through picking an actor.
|
||||
A default persona is created automatically. Inside the TUI:
|
||||
|
||||
- Type a message and press `Enter` to chat with the active actor
|
||||
- Press `/` to open the slash command overlay (67 commands across 14 groups)
|
||||
@@ -94,6 +106,17 @@ agents server connect --url https://my-server.example.com --token <TOKEN>
|
||||
agents server status
|
||||
```
|
||||
|
||||
### Estimation lifecycle
|
||||
|
||||
Configure an estimation actor to get cost/time/risk forecasts before plan execution:
|
||||
|
||||
```bash
|
||||
agents config set actor.default.estimation anthropic/claude-4-sonnet
|
||||
agents plan use <PLAN_ID>
|
||||
agents plan execute # estimation runs automatically before Execute phase
|
||||
agents plan show <PLAN_ID> # shows cost_estimate_usd and risk level
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Pre-commit hooks run automatically on every `git commit` (formatting, linting, type
|
||||
@@ -124,13 +147,24 @@ nox -s docs
|
||||
nox -s serve_docs
|
||||
```
|
||||
|
||||
Key reference documents:
|
||||
|
||||
- [Architecture Overview](docs/reference/architecture_overview.md)
|
||||
- [TUI Reference](docs/reference/tui.md)
|
||||
- [Plan Lifecycle](docs/reference/plan_execute.md)
|
||||
- [Estimation Lifecycle](docs/reference/estimation_lifecycle.md)
|
||||
- [Decision Correction](docs/reference/decision_correction.md)
|
||||
- [Correction Attempts](docs/reference/correction_attempts.md)
|
||||
- [Resource Handlers](docs/reference/resource_handlers.md)
|
||||
- [UKO Runtime](docs/reference/uko_runtime.md)
|
||||
|
||||
## Tests
|
||||
|
||||
Behave feature scenarios live under `features/` and Robot suites under `robot/`. Use the Nox sessions above to execute them in parity with the implementation plan.
|
||||
|
||||
## Observability
|
||||
|
||||
LangSmith tracing is optional and off by default. Enable it by exporting `CLEVERAGENTS_LANGSMITH_ENABLED=true` along with a project name and API key (`CLEVERAGENTS_LANGSMITH_PROJECT`, `CLEVERAGENTS_LANGSMITH_API_KEY`). The settings module automatically mirrors these values to `LANGCHAIN_TRACING_V2`, `LANGCHAIN_PROJECT`, and `LANGCHAIN_API_KEY`, so LangChain/LangGraph agents emit traces without extra wiring. Additional knobs such as `CLEVERAGENTS_LANGSMITH_ENDPOINT`, `CLEVERAGENTS_LANGSMITH_USER_ID`, and `CLEVERAGENTS_LANGSMITH_TAGS` are documented in `docs/observability.md`.
|
||||
LangSmith tracing is optional and off by default. Enable it by exporting `CLEVERAGENTS_LANGSMITH_ENABLED=true` along with a project name and API key (`CLEVERAGENTS_LANGSMITH_PROJECT`, `CLEVERAGENTS_LANGSMITH_API_KEY`). The settings module automatically mirrors these values to `LANGCHAIN_TRACING_V2`, `LANGCHAIN_PROJECT`, and `LANGCHAIN_API_KEY`, so LangChain/LangGraph agents emit traces without extra wiring. Additional knobs such as `CLEVERAGENTS_LANGSMITH_ENDPOINT`, `CLEVERAGENTS_LANGSMITH_USER_ID`, and `CLEVERAGENTS_LANGSMITH_TAGS` are documented in `docs/reference/observability.md`.
|
||||
|
||||
## LLM provider configuration
|
||||
|
||||
@@ -159,3 +193,20 @@ Set `CLEVERAGENTS_DEFAULT_PROVIDER` to pin the global provider (for example `exp
|
||||
- Built-in actors (`<provider>/<model>`) are immutable, custom actors must be named `local/<id>`, and the default actor cannot be removed. Use `--unsafe` when adding/updating configs marked unsafe; runtime only warns when invoking unsafe actors.
|
||||
- `CLEVERAGENTS_TESTING_USE_MOCK_AI=true` forces the in-repo mock provider so Behave/Robot suites never hit external APIs.
|
||||
- The full capability matrix (streaming, tool calls, JSON mode, etc.) is documented in `docs/reference/providers.md`.
|
||||
|
||||
## What's New in v3.7.0
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md) for the full list. Highlights:
|
||||
|
||||
- **TUI** — full Textual-based interactive terminal UI with persona system, 67 slash
|
||||
commands, reference picker, permissions screen, thought blocks, and first-run experience
|
||||
- **Session management** — `agents session` command group with export/import
|
||||
- **Server mode** — `agents server connect` + Kubernetes Helm chart
|
||||
- **A2A integration** — local facade wired to live application services
|
||||
- **Estimation lifecycle** — optional pre-Execute cost/time/risk forecasting
|
||||
- **Enriched domain events** — `PLAN_APPLIED` with changeset stats, `user_identity` on all events
|
||||
- **Correction attempts** — full lifecycle tracking for decision corrections
|
||||
- **Resource handlers** — DatabaseResourceHandler and DevcontainerHandler protocol completion
|
||||
- **UKO runtime** — query interface, inference engine, and graph persistence
|
||||
- **ACMS** — Phase 2 pipeline protocol aliases
|
||||
- **Bug fixes** — session DI wiring, plan stale-cache, project context commit, action `--format` flag
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
# Architecture Overview
|
||||
|
||||
CleverAgents is a Python-first automation platform for orchestrating
|
||||
complex, long-running tasks with AI actors. This document provides a
|
||||
high-level map of the system's layers, core abstractions, and the
|
||||
protocols that connect them. For the authoritative design rationale
|
||||
behind each decision, refer to the relevant
|
||||
[Architecture Decision Records](../adr/index.md).
|
||||
|
||||
> **Specification is the source of truth.** If this document conflicts
|
||||
> with `docs/specification.md`, the specification takes precedence.
|
||||
|
||||
---
|
||||
|
||||
## System Layers
|
||||
|
||||
CleverAgents follows a strict layered architecture (ADR-001):
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ Presentation Layer │
|
||||
│ CLI (Typer/Click) · TUI (Textual) · Server (ASGI/A2A) │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ Application Layer │
|
||||
│ Services · Use-case orchestration · Event bus │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ Domain Layer │
|
||||
│ Models · Value objects · Domain events · Invariants │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ Infrastructure Layer │
|
||||
│ SQLAlchemy ORM · Alembic migrations · Resource handlers │
|
||||
│ LangChain/LangGraph · MCP adapter · LSP runtime │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Dependencies flow **downward only**. The domain layer has no imports
|
||||
from infrastructure or application layers.
|
||||
|
||||
---
|
||||
|
||||
## Core Abstractions
|
||||
|
||||
### Plan Lifecycle
|
||||
|
||||
The central workflow abstraction. A plan moves through four phases:
|
||||
|
||||
```
|
||||
Action ──► Strategize ──► [Estimate] ──► Execute ──► Apply
|
||||
```
|
||||
|
||||
| Phase | Description |
|
||||
|-------|-------------|
|
||||
| **Action** | Defines the goal: what the actor should accomplish |
|
||||
| **Strategize** | Actor produces a decision tree of steps |
|
||||
| **Estimate** | Optional: estimation actor forecasts cost/time/risk |
|
||||
| **Execute** | Steps are executed; decisions recorded |
|
||||
| **Apply** | Validated changes committed to resources |
|
||||
|
||||
Phase transitions are governed by **Automation Profiles** (ADR-017),
|
||||
which set confidence thresholds for autonomous vs. human-approved
|
||||
transitions.
|
||||
|
||||
See [ADR-006](../adr/ADR-006-plan-lifecycle.md) and
|
||||
[`plan_execute.md`](plan_execute.md).
|
||||
|
||||
### Decision Tree
|
||||
|
||||
Every plan produces a **decision tree** — a versioned, append-only
|
||||
record of every choice made during execution. Decisions can be
|
||||
corrected, rolled back, and replayed (ADR-007, ADR-033–035).
|
||||
|
||||
Key decision types: `tool_call`, `resource_selection`, `sub_plan`,
|
||||
`human_approval`, `correction`.
|
||||
|
||||
### Actors
|
||||
|
||||
Actors are the AI agents that execute plans. Each actor is a named,
|
||||
namespaced configuration binding a provider/model to a set of
|
||||
capabilities. Built-in actors follow `<provider>/<model>` naming;
|
||||
custom actors use `local/<id>`.
|
||||
|
||||
See [ADR-010](../adr/ADR-010-actor-and-agent-architecture.md) and
|
||||
[`actor_runtime.md`](actor_runtime.md).
|
||||
|
||||
### Resources
|
||||
|
||||
Resources are the managed objects that plans operate on — files,
|
||||
databases, containers, devcontainers, LSP servers, and more. The
|
||||
resource system uses a DAG for dependency tracking and a handler
|
||||
protocol for CRUD, checkpointing, and sandboxing (ADR-008, ADR-036).
|
||||
|
||||
See [`resources.md`](resources.md) and [`resource_handlers.md`](resource_handlers.md).
|
||||
|
||||
### Skills
|
||||
|
||||
Skills are reusable, versioned capability bundles that extend what
|
||||
actors can do. They are resolved from local files, Git repositories,
|
||||
or the AgentSkills.io registry (ADR-012, ADR-028, ADR-030).
|
||||
|
||||
### Tools
|
||||
|
||||
Tools are the atomic operations actors invoke during execution. The
|
||||
tool system provides reachability analysis, access projection, and
|
||||
MCP adapter integration (ADR-011, ADR-029, ADR-037).
|
||||
|
||||
---
|
||||
|
||||
## Key Services (Application Layer)
|
||||
|
||||
| Service | Responsibility |
|
||||
|---------|---------------|
|
||||
| `PlanLifecycleService` | Phase transitions, estimation hook, event emission |
|
||||
| `PlanApplyService` | Validation gate, changeset statistics, `PLAN_APPLIED` event |
|
||||
| `CorrectionService` | Decision correction, dry-run reports, rollback |
|
||||
| `SessionService` | Session CRUD, message persistence |
|
||||
| `PermissionService` | Tool permission requests, session-scoped decisions |
|
||||
| `AuditEventSubscriber` | SEC7 audit log from domain events |
|
||||
| `UKOQueryInterface` | ACMS context strategy queries against UKO graph |
|
||||
| `UKOInferenceEngine` | Implicit triple inference (confidence 0.7) |
|
||||
| `UKOGraphPersistence` | UKO graph serialisation/restore across restarts |
|
||||
|
||||
---
|
||||
|
||||
## Estimation Lifecycle (v3.7.0)
|
||||
|
||||
When `actor.default.estimation` is configured, the Strategize→Execute
|
||||
transition invokes an estimation actor before execution begins:
|
||||
|
||||
```
|
||||
Strategize complete
|
||||
│
|
||||
▼
|
||||
EstimationActor.run(plan)
|
||||
│
|
||||
├── stores EstimationResult on plan
|
||||
├── populates plan.cost_estimate_usd
|
||||
└── emits PLAN_ESTIMATION_COMPLETE event
|
||||
│
|
||||
▼ (estimation failure is informational — never blocks Execute)
|
||||
Execute phase begins
|
||||
```
|
||||
|
||||
See [`estimation_lifecycle.md`](estimation_lifecycle.md).
|
||||
|
||||
---
|
||||
|
||||
## Protocols and Standards
|
||||
|
||||
CleverAgents integrates three industry protocols for interoperability:
|
||||
|
||||
| Protocol | Purpose | ADR |
|
||||
|----------|---------|-----|
|
||||
| **A2A** (Agent-to-Agent) | CLI/TUI ↔ application service communication | ADR-026, ADR-047 |
|
||||
| **MCP** (Model Context Protocol) | Tool and resource exposure to LLM actors | ADR-029 |
|
||||
| **LSP** (Language Server Protocol) | Code intelligence for resource types | ADR-027, ADR-040 |
|
||||
|
||||
### A2A Facade
|
||||
|
||||
The A2A local facade is the single communication channel between the
|
||||
presentation layer (CLI, TUI) and the application layer. It maps A2A
|
||||
protocol messages to service calls and translates domain errors to
|
||||
A2A error codes:
|
||||
|
||||
| Domain Error | A2A Code |
|
||||
|-------------|----------|
|
||||
| `NotFoundError` | `NOT_FOUND` |
|
||||
| `ValidationError` | `VALIDATION_ERROR` |
|
||||
| `InvalidStateError` | `INVALID_STATE` |
|
||||
| `PlanError` | `PLAN_ERROR` |
|
||||
| `ValueError` | `VALIDATION_ERROR` |
|
||||
|
||||
---
|
||||
|
||||
## Dependency Injection
|
||||
|
||||
All services are wired through a DI container (ADR-003). The container
|
||||
is initialised once at startup (`agents init`) and injected into CLI
|
||||
commands and TUI handlers. This ensures testability and prevents
|
||||
hidden global state.
|
||||
|
||||
See [`di.md`](di.md).
|
||||
|
||||
---
|
||||
|
||||
## Persistence
|
||||
|
||||
| Store | Technology | Purpose |
|
||||
|-------|-----------|---------|
|
||||
| Primary DB | SQLite (default) / PostgreSQL | Plans, decisions, sessions, resources, audit log |
|
||||
| Migrations | Alembic | Schema versioning |
|
||||
| Persona config | YAML files (`~/.config/cleveragents/personas/`) | TUI persona definitions |
|
||||
| TUI state | YAML (`~/.config/cleveragents/tui-state.yaml`) | Last-used persona |
|
||||
| Checkpoints | Per-handler strategy | Rollback points for resource mutations |
|
||||
|
||||
See [ADR-019](../adr/ADR-019-storage-and-persistence.md) and
|
||||
[`database_schema.md`](database_schema.md).
|
||||
|
||||
---
|
||||
|
||||
## Sandboxing and Safety
|
||||
|
||||
Every resource mutation during Execute is wrapped in a sandbox. The
|
||||
`SandboxManager` coordinates cross-mechanism sandbox commits atomically
|
||||
(all-or-nothing, LIFO rollback on partial failure). Automation profiles
|
||||
control which transitions require human approval.
|
||||
|
||||
See [ADR-015](../adr/ADR-015-sandbox-and-checkpoint.md),
|
||||
[ADR-038](../adr/ADR-038-cross-mechanism-sandbox-coordination.md), and
|
||||
[`sandbox.md`](sandbox.md).
|
||||
|
||||
---
|
||||
|
||||
## Interactive Terminal UI (v3.7.0)
|
||||
|
||||
The TUI (`agents tui`) is a full-screen Textual application that
|
||||
communicates with the application layer exclusively through the A2A
|
||||
local facade — the same protocol used by the CLI.
|
||||
|
||||
```
|
||||
TUI (Textual App)
|
||||
│
|
||||
├── InputModeRouter ─── Normal / Command (/) / Shell (!)
|
||||
├── SlashCommandOverlay ─── 67 commands, 14 groups
|
||||
├── ReferencePickerOverlay ─── @reference expansion
|
||||
├── HelpPanelOverlay (F1) ─── context-sensitive help
|
||||
├── PermissionsScreen ─── tool permission diff review
|
||||
├── ActorSelectionOverlay ─── first-run actor picker
|
||||
└── PersonaBar ─── active persona / preset / scope count
|
||||
│
|
||||
▼
|
||||
A2A Local Facade
|
||||
│
|
||||
▼
|
||||
Application Services
|
||||
```
|
||||
|
||||
See [`tui.md`](tui.md) and
|
||||
[ADR-044](../adr/ADR-044-tui-architecture-and-framework.md).
|
||||
|
||||
---
|
||||
|
||||
## Server Mode (v3.7.0)
|
||||
|
||||
`agents server connect` configures a remote CleverAgents server.
|
||||
The server exposes the same A2A protocol over HTTP/WebSocket. A
|
||||
Kubernetes Helm chart (`k8s/`) and `Dockerfile.server` are provided
|
||||
for production deployment.
|
||||
|
||||
See [ADR-023](../adr/ADR-023-server-mode.md),
|
||||
[ADR-048](../adr/ADR-048-server-application-architecture.md), and
|
||||
[`server_client_stubs.md`](server_client_stubs.md).
|
||||
|
||||
---
|
||||
|
||||
## Observability
|
||||
|
||||
LangSmith tracing is optional and off by default. Domain events flow
|
||||
through the event bus to the `AuditEventSubscriber`, which writes
|
||||
structured audit log entries (SEC7 compliance). All `PLAN_APPLIED`
|
||||
events carry changeset statistics (files changed, lines added/removed,
|
||||
resources modified, apply duration).
|
||||
|
||||
See [ADR-025](../adr/ADR-025-observability-and-logging.md) and
|
||||
[`observability.md`](observability.md).
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Specification](../specification.md) — authoritative source of truth
|
||||
- [ADR Index](../adr/index.md) — all architectural decisions
|
||||
- [Plan Lifecycle](plan_execute.md)
|
||||
- [Decision Correction](decision_correction.md)
|
||||
- [Resource System](resources.md)
|
||||
- [Actor Runtime](actor_runtime.md)
|
||||
- [TUI Reference](tui.md)
|
||||
- [ACMS / UKO](acms.md)
|
||||
- [Dependency Injection](di.md)
|
||||
- [Database Schema](database_schema.md)
|
||||
@@ -0,0 +1,178 @@
|
||||
# Correction Attempts
|
||||
|
||||
The `correction_attempts` table records every attempt to correct a
|
||||
decision in a plan's decision tree. Each attempt tracks the original
|
||||
decision being corrected, the guidance provided, the new decision
|
||||
produced, and the lifecycle state of the correction process.
|
||||
|
||||
Introduced in v3.7.0 (issue #1087). See also
|
||||
[`decision_correction.md`](decision_correction.md) for the correction
|
||||
workflow and [`decision_model.md`](decision_model.md) for the decision
|
||||
domain model.
|
||||
|
||||
**Module**: `cleveragents.infrastructure.database.repositories`
|
||||
**Domain model**: `cleveragents.domain.models.core.correction`
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
When `plan correct` is invoked, the `CorrectionService` creates a
|
||||
`CorrectionAttemptRecord` to track the correction lifecycle:
|
||||
|
||||
```
|
||||
pending ──► executing ──► complete
|
||||
└──► failed
|
||||
```
|
||||
|
||||
Terminal states (`complete`, `failed`) are irreversible. Once a
|
||||
correction attempt reaches a terminal state, `update_state()` rejects
|
||||
further transitions.
|
||||
|
||||
---
|
||||
|
||||
## CorrectionAttemptRecord
|
||||
|
||||
| Field | Type | Constraints | Description |
|
||||
|-------|------|-------------|-------------|
|
||||
| `id` | `str` | UUID, required | Unique attempt identifier |
|
||||
| `plan_id` | `str` | FK → plans, RESTRICT | Plan containing the decision |
|
||||
| `original_decision_id` | `str` | FK → decisions, RESTRICT | Decision being corrected |
|
||||
| `new_decision_id` | `str \| None` | FK → decisions, nullable | Replacement decision (set on complete) |
|
||||
| `guidance` | `str` | max 10 000 chars, non-empty | Human or actor guidance for the correction |
|
||||
| `mode` | `CorrectionMode` | enum | Correction mode (`append`, `replace`, `rollback`) |
|
||||
| `state` | `CorrectionAttemptState` | enum | Current lifecycle state |
|
||||
| `created_at` | `datetime` | UTC, millisecond precision | When the attempt was created |
|
||||
| `completed_at` | `datetime \| None` | UTC, millisecond precision | When the attempt reached a terminal state |
|
||||
|
||||
### CorrectionAttemptState
|
||||
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `pending` | Attempt created, not yet executing |
|
||||
| `executing` | Correction actor is running |
|
||||
| `complete` | Correction succeeded; `new_decision_id` is set |
|
||||
| `failed` | Correction failed; `new_decision_id` is `None` |
|
||||
|
||||
### Valid Transitions
|
||||
|
||||
| From | To |
|
||||
|------|----|
|
||||
| `pending` | `executing` |
|
||||
| `executing` | `complete` |
|
||||
| `executing` | `failed` |
|
||||
|
||||
All other transitions raise `InvalidCorrectionStateTransitionError`.
|
||||
|
||||
---
|
||||
|
||||
## CorrectionAttemptRepository
|
||||
|
||||
**Module**: `cleveragents.infrastructure.database.repositories`
|
||||
|
||||
### Methods
|
||||
|
||||
#### `create(attempt: CorrectionAttemptRecord) -> CorrectionAttemptRecord`
|
||||
|
||||
Persist a new correction attempt. Raises `ValueError` with a
|
||||
descriptive message if `plan_id` or `original_decision_id` violates a
|
||||
foreign-key constraint.
|
||||
|
||||
```python
|
||||
attempt = CorrectionAttemptRecord(
|
||||
id=str(uuid4()),
|
||||
plan_id="plan-abc",
|
||||
original_decision_id="decision-xyz",
|
||||
guidance="The file path should use forward slashes.",
|
||||
mode=CorrectionMode.REPLACE,
|
||||
state=CorrectionAttemptState.PENDING,
|
||||
created_at=datetime.now(UTC),
|
||||
)
|
||||
saved = repo.create(attempt)
|
||||
```
|
||||
|
||||
#### `get(attempt_id: str) -> CorrectionAttemptRecord | None`
|
||||
|
||||
Retrieve a correction attempt by ID. Returns `None` if not found.
|
||||
|
||||
#### `list_by_plan(plan_id: str) -> list[CorrectionAttemptRecord]`
|
||||
|
||||
Return all correction attempts for a plan, ordered by `created_at`
|
||||
ascending.
|
||||
|
||||
#### `update_state(attempt_id, new_state, *, new_decision_id=None, completed_at=None) -> CorrectionAttemptRecord`
|
||||
|
||||
Transition the attempt to a new state. Rules:
|
||||
|
||||
- Validates the transition against `CORRECTION_ATTEMPT_VALID_TRANSITIONS`.
|
||||
- Raises `InvalidCorrectionStateTransitionError` for invalid transitions.
|
||||
- Auto-sets `completed_at` to `datetime.now(UTC)` when transitioning to
|
||||
a terminal state if `completed_at` is not explicitly provided.
|
||||
- Raises `ValueError` if `completed_at` is provided for a non-terminal
|
||||
transition.
|
||||
- `new_decision_id` is stripped of whitespace before storage.
|
||||
|
||||
---
|
||||
|
||||
## State Transition Constants
|
||||
|
||||
```python
|
||||
from cleveragents.domain.models.core.correction import (
|
||||
CORRECTION_ATTEMPT_VALID_TRANSITIONS,
|
||||
CORRECTION_ATTEMPT_TERMINAL_STATES,
|
||||
)
|
||||
|
||||
# CORRECTION_ATTEMPT_VALID_TRANSITIONS: dict[CorrectionAttemptState, set[CorrectionAttemptState]]
|
||||
# CORRECTION_ATTEMPT_TERMINAL_STATES: frozenset[CorrectionAttemptState]
|
||||
```
|
||||
|
||||
`validate_correction_state_transition(current, new)` raises
|
||||
`InvalidCorrectionStateTransitionError` if the transition is not in
|
||||
`CORRECTION_ATTEMPT_VALID_TRANSITIONS`.
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE correction_attempts (
|
||||
id TEXT PRIMARY KEY,
|
||||
plan_id TEXT NOT NULL REFERENCES plans(id) ON DELETE RESTRICT,
|
||||
original_decision_id TEXT NOT NULL REFERENCES decisions(id) ON DELETE RESTRICT,
|
||||
new_decision_id TEXT REFERENCES decisions(id) ON DELETE RESTRICT,
|
||||
guidance TEXT NOT NULL,
|
||||
mode TEXT NOT NULL,
|
||||
state TEXT NOT NULL DEFAULT 'pending',
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
|
||||
completed_at TEXT
|
||||
);
|
||||
```
|
||||
|
||||
**FK semantics**: Both `original_decision_id` and `new_decision_id` use
|
||||
`RESTRICT` (not `CASCADE`) to preserve the correction audit trail when
|
||||
decisions are cleaned up.
|
||||
|
||||
---
|
||||
|
||||
## CorrectionDryRunReport
|
||||
|
||||
`CorrectionService.generate_dry_run_report()` returns a
|
||||
`CorrectionDryRunReport`. Redundant top-level fields were removed in
|
||||
v3.7.0 (issue #1087); consumers must now access correction impact data
|
||||
through the embedded `impact` sub-object:
|
||||
|
||||
| Old field (removed) | New canonical path |
|
||||
|--------------------|--------------------|
|
||||
| `excluded_decisions` | `report.impact.excluded_decisions` |
|
||||
| `rollback_tier_depth` | `report.impact.rollback_tier_depth` |
|
||||
| `child_plans_to_rollback` | `report.impact.affected_child_plans` |
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Decision Correction](decision_correction.md)
|
||||
- [Decision Model](decision_model.md)
|
||||
- [Decision Service](decision_service.md)
|
||||
- [Plan Lifecycle](plan_execute.md)
|
||||
- [Database Schema](database_schema.md)
|
||||
@@ -0,0 +1,192 @@
|
||||
# Estimation Lifecycle
|
||||
|
||||
The estimation lifecycle is an optional hook that runs between the
|
||||
**Strategize** and **Execute** phases of a plan. When configured, an
|
||||
estimation actor analyses the plan's decision tree and produces an
|
||||
`EstimationResult` containing cost, time, and risk forecasts.
|
||||
|
||||
Introduced in v3.7.0 (issue #1310). See also
|
||||
[`plan_execute.md`](plan_execute.md) for the full plan lifecycle.
|
||||
|
||||
**Module**: `cleveragents.application.services.plan_lifecycle_service`
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
```
|
||||
Strategize phase completes
|
||||
│
|
||||
▼
|
||||
actor.default.estimation configured?
|
||||
│
|
||||
Yes │ No
|
||||
│──────────────────► Execute phase begins immediately
|
||||
▼
|
||||
EstimationActor.run(plan)
|
||||
│
|
||||
├── EstimationResult stored on plan
|
||||
├── plan.cost_estimate_usd populated
|
||||
└── PLAN_ESTIMATION_COMPLETE event emitted
|
||||
│
|
||||
▼ (failure is informational — never blocks Execute)
|
||||
Execute phase begins
|
||||
```
|
||||
|
||||
Estimation failures are **informational only**. A failed or missing
|
||||
estimation actor never prevents the plan from advancing to Execute.
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
Set the estimation actor via the `actor.default.estimation` config key:
|
||||
|
||||
```bash
|
||||
agents config set actor.default.estimation anthropic/claude-4-sonnet
|
||||
```
|
||||
|
||||
Or in `~/.config/cleveragents/config.yaml`:
|
||||
|
||||
```yaml
|
||||
actor:
|
||||
default:
|
||||
estimation: anthropic/claude-4-sonnet
|
||||
```
|
||||
|
||||
When this key is absent or empty, the estimation hook is skipped.
|
||||
|
||||
---
|
||||
|
||||
## EstimationResult
|
||||
|
||||
**Module**: `cleveragents.domain.models.core.estimation`
|
||||
|
||||
All fields are optional. The estimation actor populates whichever
|
||||
metrics it can compute.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `estimated_cost_usd` | `float \| None` | Estimated LLM cost in USD (≥ 0) |
|
||||
| `estimated_tokens` | `int \| None` | Estimated total token usage (≥ 0) |
|
||||
| `estimated_steps` | `int \| None` | Expected number of execution steps (≥ 0) |
|
||||
| `estimated_child_plans` | `int \| None` | Expected number of child plans |
|
||||
| `estimated_time_seconds` | `float \| None` | Estimated execution time in seconds (≥ 0) |
|
||||
| `risk_level` | `"low" \| "medium" \| "high" \| "critical" \| None` | Risk assessment |
|
||||
| `risk_factors` | `tuple[str, ...]` | Identified risk factors (max 100 items) |
|
||||
| `summary` | `str` | Human-readable estimation summary (max 10 000 chars) |
|
||||
| `raw_output` | `str` | Raw actor output before parsing (max 100 000 chars) |
|
||||
|
||||
`EstimationResult` is a **frozen** Pydantic model. Instances are
|
||||
immutable after construction.
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
from cleveragents.domain.models.core.estimation import EstimationResult
|
||||
|
||||
result = EstimationResult(
|
||||
estimated_cost_usd=0.42,
|
||||
estimated_tokens=15_000,
|
||||
estimated_steps=8,
|
||||
risk_level="low",
|
||||
risk_factors=("no external API calls", "read-only resources"),
|
||||
summary="Low-risk plan with ~8 steps and minimal token usage.",
|
||||
)
|
||||
|
||||
# Only non-empty fields for display
|
||||
print(result.as_display_dict())
|
||||
# {
|
||||
# "estimated_cost_usd": 0.42,
|
||||
# "estimated_tokens": 15000,
|
||||
# "estimated_steps": 8,
|
||||
# "risk_level": "low",
|
||||
# "risk_factors": ["no external API calls", "read-only resources"],
|
||||
# "summary": "Low-risk plan with ~8 steps and minimal token usage.",
|
||||
# }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PLAN_ESTIMATION_COMPLETE Event
|
||||
|
||||
When estimation succeeds, `PlanLifecycleService` emits a
|
||||
`PLAN_ESTIMATION_COMPLETE` domain event with the following details:
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| `event_type` | `EventType.PLAN_ESTIMATION_COMPLETE` |
|
||||
| `plan_id` | ID of the plan being estimated |
|
||||
| `actor` | Name of the estimation actor |
|
||||
| `estimated_cost_usd` | From `EstimationResult.estimated_cost_usd` |
|
||||
| `risk_level` | From `EstimationResult.risk_level` |
|
||||
| `summary` | From `EstimationResult.summary` |
|
||||
|
||||
The event is published to the event bus and picked up by the
|
||||
`AuditEventSubscriber` for SEC7 audit logging.
|
||||
|
||||
---
|
||||
|
||||
## plan.cost_estimate_usd
|
||||
|
||||
After a successful estimation, `plan.cost_estimate_usd` is set to
|
||||
`EstimationResult.estimated_cost_usd`. This value is included in:
|
||||
|
||||
- `agents plan show` output (when non-null)
|
||||
- `agents plan list` table (when non-null)
|
||||
- The `PLAN_APPLIED` event's audit details
|
||||
|
||||
---
|
||||
|
||||
## CLI Visibility
|
||||
|
||||
```bash
|
||||
# Show plan details including cost estimate
|
||||
agents plan show <PLAN_ID>
|
||||
|
||||
# Example output (with estimation configured)
|
||||
# Plan: my-feature-plan
|
||||
# Phase: Execute
|
||||
# Cost estimate: $0.42
|
||||
# Risk: low
|
||||
# ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Writing an Estimation Actor
|
||||
|
||||
An estimation actor is a standard CleverAgents actor. It receives the
|
||||
plan's decision tree as context and should return a structured
|
||||
`EstimationResult`-compatible response.
|
||||
|
||||
The actor is invoked with the plan's action description and decision
|
||||
tree summary. It should return JSON that the lifecycle service parses
|
||||
into an `EstimationResult`.
|
||||
|
||||
```yaml
|
||||
# Example custom estimation actor
|
||||
name: my-estimator
|
||||
namespace: local
|
||||
provider: anthropic
|
||||
model: claude-4-sonnet
|
||||
system_prompt: |
|
||||
You are a cost and risk estimation expert for AI automation plans.
|
||||
Given a plan's action and decision tree, estimate:
|
||||
- Total LLM cost in USD
|
||||
- Total token usage
|
||||
- Number of execution steps
|
||||
- Risk level (low/medium/high/critical)
|
||||
- Key risk factors
|
||||
Return a JSON object matching the EstimationResult schema.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Plan Lifecycle](plan_execute.md)
|
||||
- [Plan Apply](plan_apply.md)
|
||||
- [Actor Runtime](actor_runtime.md)
|
||||
- [Domain Events](event_bus.md)
|
||||
- [Audit Logging](audit_logging.md)
|
||||
@@ -488,6 +488,100 @@ and can be expanded or collapsed with `Space`.
|
||||
|
||||
See [`tui_thought_block.md`](tui_thought_block.md) for the full API reference.
|
||||
|
||||
|
||||
## First-Run Experience
|
||||
|
||||
On the first launch (when no personas are configured), the TUI displays
|
||||
the **Actor Selection Overlay** — a guided setup screen that lets the
|
||||
user pick an actor to get started.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Welcome to CleverAgents │
|
||||
│ │
|
||||
│ Select an actor to get started: │
|
||||
│ │
|
||||
│ > anthropic/claude-4-sonnet │
|
||||
│ anthropic/claude-4-opus │
|
||||
│ openai/gpt-4o │
|
||||
│ openai/o3 │
|
||||
│ google/gemini-2 │
|
||||
│ │
|
||||
│ Search: ___________ │
|
||||
│ [Enter] Select [Esc] Cancel │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
After the user selects an actor, a `"default"` persona is automatically
|
||||
created and persisted to the persona registry. Subsequent launches
|
||||
restore the last-used persona and skip the first-run overlay.
|
||||
|
||||
**First-run detection**: `is_first_run(registry)` returns `True` when
|
||||
`PersonaRegistry.list_personas()` returns an empty list.
|
||||
|
||||
**Module**: `cleveragents.tui.first_run`
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `is_first_run(registry)` | Returns `True` when no personas are configured |
|
||||
| `create_default_persona_for_actor(registry, actor)` | Creates and persists a `"default"` persona for the given actor |
|
||||
|
||||
**Widget**: `cleveragents.tui.widgets.actor_selection_overlay`
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `render_actor_selection(actors, selected_index, search_query)` | Renders the actor selection overlay content |
|
||||
|
||||
Default actors offered in the overlay:
|
||||
|
||||
- `anthropic/claude-4-sonnet`
|
||||
- `anthropic/claude-4-opus`
|
||||
- `openai/gpt-4o`
|
||||
- `openai/o3`
|
||||
- `google/gemini-2`
|
||||
|
||||
---
|
||||
|
||||
## Session Export / Import (TUI)
|
||||
|
||||
Sessions can be exported and imported directly from the TUI using slash
|
||||
commands or the Sessions Screen.
|
||||
|
||||
```bash
|
||||
# Export the current session to JSON
|
||||
/session:export
|
||||
|
||||
# Import a session from a JSON file
|
||||
/session:import
|
||||
```
|
||||
|
||||
Export produces a JSON file containing the full session transcript and
|
||||
metadata. Import restores a session from a previously exported file.
|
||||
Both operations are also available via the CLI:
|
||||
|
||||
```bash
|
||||
agents session export --session-id <ID> --output session.json
|
||||
agents session import --input session.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Persona Export / Import (TUI)
|
||||
|
||||
Personas can be exported to YAML and imported from YAML files:
|
||||
|
||||
```bash
|
||||
# Export a persona
|
||||
/persona:export
|
||||
|
||||
# Import a persona
|
||||
/persona:import
|
||||
```
|
||||
|
||||
Export paths must be relative to the current working directory.
|
||||
Imported personas are validated against the persona schema before
|
||||
being saved to the registry.
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [ADR-044: TUI Architecture and Framework](../adr/ADR-044-tui-architecture-and-framework.md)
|
||||
|
||||
@@ -11,6 +11,7 @@ site_dir: build/site
|
||||
nav:
|
||||
- Specification: specification.md
|
||||
- Architecture: architecture.md
|
||||
- Architecture Overview: reference/architecture_overview.md
|
||||
- API Reference:
|
||||
- Overview: api/index.md
|
||||
- Core Utilities: api/core.md
|
||||
|
||||
Reference in New Issue
Block a user