diff --git a/docs/api/cli-reference.md b/docs/api/cli-reference.md new file mode 100644 index 000000000..f1a49d813 --- /dev/null +++ b/docs/api/cli-reference.md @@ -0,0 +1,658 @@ +# CLI Reference + +CleverAgents ships two equivalent entry points: **`agents`** and **`cleveragents`**. +Both accept the same commands, flags, and arguments. + +See [ADR-021](../adr/ADR-021-cli-and-output-rendering.md) for the design rationale +behind the CLI structure and output rendering framework. + +--- + +## Synopsis + +``` +agents|cleveragents [--data-dir ] [--config-path ] + [--format rich|color|table|plain|json|yaml] + [--help|-h] [--version] + [--install-completion [SHELL]] [--show-completion [SHELL]] + [-v...] + [...] +``` + +--- + +## Global Flags + +These flags apply to every command and must appear **before** the subcommand name. + +| Flag | Short | Description | +|------|-------|-------------| +| `--data-dir PATH` | | Override the global data directory (database, caches, sessions, logs). Defaults to the platform data location. | +| `--config-path PATH` | | Override the global configuration file path. | +| `--format FORMAT` | | Output rendering format. One of `rich` (default), `color`, `table`, `plain`, `json`, `yaml`. Can also be set via `core.format` config key. | +| `--help` | `-h` | Print help for the current command and exit. | +| `--version` | | Print the installed version and exit. | +| `--install-completion [SHELL]` | | Install shell tab-completion for the given shell. | +| `--show-completion [SHELL]` | | Print the completion script for the given shell. | +| `-v` | | Increase log verbosity (repeatable). `-v`=ERROR, `-vv`=WARN, `-vvv`=INFO, `-vvvv`=DEBUG, `-vvvvv`=TRACE. Affects the current invocation only. | + +### Output Formats + +| Format | Description | Best For | +|--------|-------------|----------| +| `rich` | Rich CLI elements with animated spinners, progress bars, and color | Interactive terminal use **(default)** | +| `color` | Plain scrolling text with ANSI color codes | Color-capable terminals | +| `table` | ASCII box-drawing tables and panels with color | Structured visual output | +| `plain` | Plain text, no color or non-ASCII characters | Piping, logs, non-terminal consumers | +| `json` | Structured JSON | Scripts, CI/CD pipelines | +| `yaml` | Structured YAML | Configuration, programmatic consumption | + +--- + +## Environment Variables + +| Variable | Description | +|----------|-------------| +| `CLEVERAGENTS_DATA_DIR` | Default data directory (overridden by `--data-dir`) | +| `CLEVERAGENTS_CONFIG_PATH` | Default config file path (overridden by `--config-path`) | +| `CLEVERAGENTS_DEFAULT_PROVIDER` | Pin the AI provider (`openai`, `anthropic`, `google`, …) | +| `CLEVERAGENTS_DEFAULT_MODEL` | Pin the model ID | +| `OPENAI_API_KEY` | OpenAI credentials | +| `ANTHROPIC_API_KEY` | Anthropic credentials | +| `GOOGLE_API_KEY` / `GOOGLE_GENAI_API_KEY` | Google credentials | +| `AZURE_OPENAI_API_KEY` | Azure OpenAI credentials | +| `AZURE_OPENAI_ENDPOINT` | Azure OpenAI endpoint URL | +| `AZURE_OPENAI_DEPLOYMENT` | Azure deployment name | +| `OPENROUTER_API_KEY` | OpenRouter credentials | +| `GEMINI_API_KEY` / `GOOGLE_GEMINI_API_KEY` | Gemini credentials | +| `COHERE_API_KEY` | Cohere credentials | +| `GROQ_API_KEY` | Groq credentials | +| `TOGETHER_API_KEY` | Together AI credentials | +| `CLEVERAGENTS_TESTING_USE_MOCK_AI` | Force mock provider in tests (`true`/`false`) | +| `CLEVERAGENTS_LANGSMITH_ENABLED` | Enable LangSmith tracing (`true`/`false`) | +| `CLEVERAGENTS_LANGSMITH_PROJECT` | LangSmith project name | +| `CLEVERAGENTS_LANGSMITH_API_KEY` | LangSmith API key | +| `CLEVERAGENTS_LOG_LEVEL` | Log level (`DEBUG`, `INFO`, `WARN`, `ERROR`) | +| `CLEVERAGENTS_LOG_FORMAT` | Log format (`json`, `text`) | + +--- + +## Top-Level Commands + +| Command | Description | +|---------|-------------| +| `agents version` | Print version and exit | +| `agents info` | Print system snapshot (mode, paths, runtime, projects) | +| `agents diagnostics` | Check credentials, provider selection, and actor configuration | +| `agents init [--yes\|-y]` | Initialize a new CleverAgents workspace in the current directory | +| `agents tui` | Launch the interactive Textual TUI | + +### `agents diagnostics` + +Prints whether the provider registry can see your credentials, which actor/provider +is selected, and any configuration warnings. + +```bash +agents diagnostics +``` + +### `agents tui` + +Launches the full-screen interactive terminal UI. Requires the `cleveragents[tui]` +extra (`pip install "cleveragents[tui]"`). + +```bash +agents tui +``` + +--- + +## Action Commands + +Actions are reusable YAML-defined plan templates. + +| Command | Description | +|---------|-------------| +| `agents action create --config\|-c ` | Register a new action from a YAML config file | +| `agents action list [--namespace\|-n NS] [--state\|-s STATE] [REGEX]` | List registered actions, optionally filtered | +| `agents action show ` | Show full details of an action | +| `agents action archive ` | Archive (soft-delete) an action | + +### Flags + +| Flag | Short | Description | +|------|-------|-------------| +| `--config FILE` | `-c` | Path to the action YAML configuration file | +| `--namespace NS` | `-n` | Filter by namespace | +| `--state STATE` | `-s` | Filter by state (`active`, `archived`) | + +### Example + +```bash +# Register an action from a YAML file +agents action create --config examples/actions/refactor.yaml + +# List all active actions in the local namespace +agents action list --namespace local --state active + +# Inspect a specific action +agents action show local/refactor + +# Archive an action +agents action archive local/refactor +``` + +--- + +## Actor Commands + +Actors are YAML-configured execution units that encapsulate an LLM and a set of tools. + +| Command | Description | +|---------|-------------| +| `agents actor add --config\|-c [--update]` | Register or update an actor from a YAML config file | +| `agents actor remove ` | Remove a custom actor | +| `agents actor list` | List all registered actors | +| `agents actor show ` | Show full details of an actor | +| `agents actor run [flags] ` | Run an actor with a prompt | +| `agents actor set-default ` | Set the default actor for CLI commands | +| `agents actor context list [REGEX]` | List saved actor contexts | +| `agents actor context show ` | Show a saved actor context | +| `agents actor context export --output\|-o ` | Export a context to a file | +| `agents actor context import [--update] --input\|-i [NAME]` | Import a context from a file | +| `agents actor context remove [--yes\|-y] (--all\|-a\|)` | Remove one or all saved contexts | +| `agents actor context clear [--yes\|-y] (--all\|-a\|)` | Clear context history | + +### `agents actor run` Flags + +| Flag | Short | Description | +|------|-------|-------------| +| `--output FILE` | `-o` | Write output to a file | +| `--unsafe` | `-u` | Allow unsafe actor configurations | +| `--context NAME` | | Load a named context | +| `--context-dir PATH` | | Load context from a directory | +| `--load-context NAME` | | Load a previously saved context | +| `--temperature TEMP` | `-t` | Override the LLM temperature | +| `--skill SKILL` | | Attach a skill (repeatable) | + +### Example + +```bash +# Add a custom actor +agents actor add --config examples/actors/my-actor.yaml + +# List all actors (built-in and custom) +agents actor list + +# Show actor details +agents actor show openai/gpt-4o + +# Run an actor with a prompt +agents actor run openai/gpt-4o "Summarize the current project status" + +# Set a default actor so --actor is not required +agents actor set-default openai/gpt-4o +``` + +> **Note:** Built-in actors (`/`) are immutable. +> Custom actors must be named `local/`. +> Use `--unsafe` when adding/updating configurations marked unsafe. + +--- + +## Plan Commands + +Plans are instantiated from Actions and progress through four phases: +**Action → Strategize → Execute → Apply**. + +| Command | Description | +|---------|-------------| +| `agents plan use [flags] ...` | Instantiate a plan from an action and bind it to one or more projects | +| `agents plan execute ` | Advance a plan through the Strategize and Execute phases | +| `agents plan apply [--yes\|-y] ` | Apply the sandbox changeset to real project resources | +| `agents plan status ` | Show the current phase, state, and progress of a plan | +| `agents plan list [flags] [REGEX]` | List plans, optionally filtered by phase, state, project, or action | +| `agents plan tree [--show-superseded] ` | Display the decision tree for a plan | +| `agents plan explain [--show-context] [--show-reasoning] ` | Explain a specific decision in a plan | +| `agents plan correct [flags] ` | Correct a decision and recompute affected subtrees | +| `agents plan diff (--correction \|)` | Show the diff for a plan or correction attempt | +| `agents plan cancel [--reason\|-r REASON] ` | Cancel a running plan | +| `agents plan rollback [--yes\|-y] ` | Roll back a plan to a checkpoint | +| `agents plan artifacts ` | List artifacts produced by a plan | +| `agents plan prompt ` | Send guidance to a running plan | +| `agents plan errors ` | Show errors encountered during plan execution | + +### `agents plan use` Flags + +| Flag | Short | Description | +|------|-------|-------------| +| `--automation-profile PROFILE` | | Automation profile to use (e.g. `review`, `full-auto`) | +| `--invariant TEXT` | | Add a plan-scoped invariant (repeatable) | +| `--strategy-actor ACTOR` | | Override the strategy actor | +| `--execution-actor ACTOR` | | Override the execution actor | +| `--estimation-actor ACTOR` | | Override the estimation actor | +| `--invariant-actor ACTOR` | | Override the invariant reconciliation actor | +| `--execution-environment RESOURCE` | | Specify the execution environment resource | +| `--execution-env-priority PRIORITY` | | `fallback` or `override` | +| `--arg name=value` | `-a` | Pass a typed argument to the action (repeatable) | + +### `agents plan list` Flags + +| Flag | Description | +|------|-------------| +| `--phase PHASE` | Filter by phase (`action`, `strategize`, `execute`, `apply`) | +| `--state STATE` | Filter by state (`running`, `applied`, `errored`, `cancelled`, …) | +| `--project PROJECT` | Filter by project name | +| `--action ACTION` | Filter by action name | + +### `agents plan correct` Flags + +| Flag | Short | Description | +|------|-------|-------------| +| `--mode MODE` | | `revert` (undo the decision) or `append` (add guidance) | +| `--guidance TEXT` | `-g` | Natural-language correction guidance | +| `--dry-run` | | Preview the correction without applying it | +| `--yes` | `-y` | Skip confirmation prompt | + +### Example + +```bash +# Instantiate a plan from the "refactor" action for the "my-project" project +agents plan use local/refactor my-project --arg target=src/ + +# Check plan status +agents plan status 01JXYZ... + +# Execute the plan (Strategize + Execute phases) +agents plan execute 01JXYZ... + +# Review the decision tree before applying +agents plan tree 01JXYZ... + +# Apply the sandbox changes to real resources +agents plan apply 01JXYZ... + +# Correct a specific decision +agents plan correct --mode revert --guidance "Use a different approach" 01JDEC... + +# Show the diff for a plan +agents plan diff 01JXYZ... +``` + +--- + +## Project Commands + +Projects are named scopes linking resources, context policies, and invariants. + +| Command | Description | +|---------|-------------| +| `agents project create [flags] ` | Create a new project | +| `agents project list [--namespace\|-n NS] [REGEX]` | List projects | +| `agents project show ` | Show project details | +| `agents project delete [--force\|-f] [--yes\|-y] ` | Delete a project | +| `agents project link-resource [--read-only] ` | Link a resource to a project | +| `agents project unlink-resource [--yes\|-y] ` | Unlink a resource from a project | +| `agents project context set [flags] ` | Configure the ACMS context policy for a project | +| `agents project context show [--view VIEW] ` | Show the context policy for a project | +| `agents project context inspect [flags] ` | Inspect the assembled context for a project | +| `agents project context simulate [flags] ` | Simulate context assembly for a project | + +### `agents project create` Flags + +| Flag | Short | Description | +|------|-------|-------------| +| `--description DESC` | `-d` | Human-readable project description | +| `--resource RESOURCE` | | Link a resource at creation time (repeatable) | +| `--invariant TEXT` | | Add a project-scoped invariant (repeatable) | +| `--invariant-actor ACTOR` | | Override the invariant reconciliation actor | + +### `agents project context set` Flags + +| Flag | Description | +|------|-------------| +| `--view VIEW` | Context view: `strategize`, `execute`, `apply`, `default` | +| `--include-resource RESOURCE` | Include a resource in context (repeatable) | +| `--exclude-resource RESOURCE` | Exclude a resource from context (repeatable) | +| `--include-path GLOB` | Include paths matching a glob (repeatable) | +| `--exclude-path GLOB` | Exclude paths matching a glob (repeatable) | +| `--hot-max-tokens N` | Maximum tokens in the hot context tier | +| `--warm-max-decisions N` | Maximum decisions in the warm tier | +| `--cold-max-decisions N` | Maximum decisions in the cold tier | +| `--strategy STRATEGY` | Context assembly strategy (repeatable) | +| `--execution-environment RESOURCE` | Preferred execution environment | +| `--execution-env-priority PRIORITY` | `fallback` or `override` | +| `--clear` | Reset the context policy to defaults | + +### Example + +```bash +# Create a project with a linked resource +agents project create my-project --description "Main application" \ + --resource local/my-repo + +# Link an additional resource (read-only) +agents project link-resource my-project local/docs --read-only + +# List all projects +agents project list + +# Show project details +agents project show my-project + +# Configure context policy for the strategize phase +agents project context set my-project --view strategize \ + --hot-max-tokens 8000 --strategy semantic + +# Delete a project +agents project delete my-project --yes +``` + +--- + +## Resource Commands + +Resources are ULID-identified entities registered in the Resource Registry +(git repos, filesystems, databases, containers, etc.). + +| Command | Description | +|---------|-------------| +| `agents resource add [flags] [type-specific-flags...]` | Register a new resource | +| `agents resource remove [--yes\|-y] ` | Remove a resource | +| `agents resource list [--all] [--type\|-t TYPE]` | List registered resources | +| `agents resource show ` | Show resource details | +| `agents resource inspect [--tree] [--file PATH] ` | Inspect resource contents | +| `agents resource tree [--depth\|-d N] [--type\|-t TYPE] ` | Show the resource DAG subtree | +| `agents resource link-child ` | Add a child link in the resource DAG | +| `agents resource unlink-child [--yes\|-y] ` | Remove a child link | +| `agents resource stop ` | Stop a running resource (e.g. a container) | +| `agents resource rebuild ` | Rebuild a resource (e.g. rebuild a devcontainer) | +| `agents resource type add --config\|-c [--update]` | Register a custom resource type | +| `agents resource type remove [--yes\|-y] ` | Remove a custom resource type | +| `agents resource type list [REGEX]` | List resource types | +| `agents resource type show ` | Show resource type details | + +### Example + +```bash +# Register a git-checkout resource +agents resource add git-checkout local/my-repo --url https://github.com/org/repo.git + +# List all resources +agents resource list + +# Show resource details +agents resource show local/my-repo + +# Inspect the resource tree +agents resource tree local/my-repo --depth 3 + +# Stop a running devcontainer +agents resource stop local/my-devcontainer +``` + +--- + +## Skill Commands + +Skills are composable, versioned capability bundles that expose tools to actors. + +| Command | Description | +|---------|-------------| +| `agents skill add --config\|-c [--update]` | Register or update a skill from a YAML config file | +| `agents skill remove [--yes\|-y] ` | Remove a skill | +| `agents skill list [--namespace\|-n NS] [--source SOURCE]` | List registered skills | +| `agents skill show ` | Show skill details | +| `agents skill tools ` | List the tools exposed by a skill | + +### Example + +```bash +# Register a skill +agents skill add --config examples/skills/deploy.yaml + +# List all skills +agents skill list + +# Show skill details +agents skill show local/deploy-to-staging + +# List tools in a skill +agents skill tools local/deploy-to-staging +``` + +--- + +## Tool Commands + +Tools are the atomic unit of execution — namespaced, independently registered callables. + +| Command | Description | +|---------|-------------| +| `agents tool add --config\|-c [--update]` | Register or update a tool from a YAML config file | +| `agents tool remove [--yes\|-y] ` | Remove a tool | +| `agents tool list [--namespace\|-n NS] [--source SOURCE] [--type tool\|validation] [REGEX]` | List registered tools | +| `agents tool show ` | Show tool details | + +### Example + +```bash +# Register a custom tool +agents tool add --config examples/tools/my-tool.yaml + +# List all tools from MCP sources +agents tool list --source mcp + +# List only validation tools +agents tool list --type validation + +# Show tool details +agents tool show local/my-tool +``` + +--- + +## Session Commands + +Sessions are persistent conversation threads tied to an actor. + +| Command | Description | +|---------|-------------| +| `agents session create [--actor ACTOR]` | Create a new conversation session | +| `agents session list` | List all sessions | +| `agents session show ` | Show session details and message history | +| `agents session delete [--yes\|-y] ` | Delete a session | +| `agents session export [--output\|-o FILE] [--format json\|md] ` | Export a session to JSON or Markdown | +| `agents session import --input\|-i ` | Import a session from a JSON file | +| `agents session tell --session [--actor ACTOR] [--stream] ` | Send a message to a session | + +### Example + +```bash +# Create a session with a specific actor +agents session create --actor openai/gpt-4o + +# List all sessions +agents session list + +# Export as canonical JSON (importable) +agents session export --session-id abc123 --output session.json + +# Export as Markdown transcript (human-readable, not importable) +agents session export --session-id abc123 --output session.md --format md + +# Import a session +agents session import --input session.json + +# Send a message to a session +agents session tell --session abc123 "What is the current plan status?" +``` + +--- + +## Invariant Commands + +Invariants are natural-language constraints on plan execution, scoped to +global, project, action, or plan level. + +| Command | Description | +|---------|-------------| +| `agents invariant add [flags] ` | Add an invariant | +| `agents invariant list [flags] [REGEX]` | List invariants | +| `agents invariant remove [--yes\|-y] ` | Remove an invariant | + +### `agents invariant add` Flags + +| Flag | Short | Description | +|------|-------|-------------| +| `--global` | | Add a global invariant | +| `--project PROJECT` | `-p` | Scope to a project | +| `--plan PLAN_ID` | | Scope to a plan (repeatable) | +| `--action ACTION` | | Scope to an action (repeatable) | + +### `agents invariant list` Flags + +| Flag | Description | +|------|-------------| +| `--global` | Show global invariants | +| `--project PROJECT` | Filter by project | +| `--plan PLAN_ID` | Filter by plan | +| `--action ACTION` | Filter by action | +| `--effective` | Show the merged effective invariant set (plan > action > project > global) | + +### Example + +```bash +# Add a global invariant +agents invariant add --global "All output files must be UTF-8 encoded" + +# Add a project-scoped invariant +agents invariant add --project my-project "Do not modify files in the vendor/ directory" + +# List effective invariants for a plan +agents invariant list --plan 01JXYZ... --effective + +# Remove an invariant +agents invariant remove 01JINV... +``` + +--- + +## Context Commands + +The `agents context` group manages actor-level context (distinct from project +context policies managed under `agents project context`). + +| Command | Description | +|---------|-------------| +| `agents actor context list [REGEX]` | List saved actor contexts | +| `agents actor context show ` | Show a saved actor context | +| `agents actor context add` | Add context entries | +| `agents actor context export --output\|-o ` | Export a context to a file | +| `agents actor context import [--update] --input\|-i [NAME]` | Import a context from a file | +| `agents actor context remove [--yes\|-y] (--all\|-a\|)` | Remove one or all saved contexts | +| `agents actor context clear [--yes\|-y] (--all\|-a\|)` | Clear context history | + +--- + +## Server Commands + +Server mode connects the CLI to a remote CleverAgents server. + +| Command | Description | +|---------|-------------| +| `agents server connect --url --token ` | Configure a remote CleverAgents server connection | +| `agents server status` | Show the current server connection status | + +### Example + +```bash +# Connect to a remote server +agents server connect --url https://my-server.example.com --token + +# Check connection status +agents server status +``` + +--- + +## LSP Commands + +LSP servers provide language intelligence (diagnostics, completions, type info) to actors. + +| Command | Description | +|---------|-------------| +| `agents lsp add --config\|-c [--update]` | Register an LSP server | +| `agents lsp remove [--yes\|-y] ` | Remove an LSP server | +| `agents lsp list [--namespace\|-n NS] [--language LANG]` | List registered LSP servers | +| `agents lsp show ` | Show LSP server details | +| `agents lsp serve [--log-level LEVEL]` | Start the CleverAgents LSP server (for IDE integration) | + +--- + +## Automation Profile Commands + +Automation profiles define confidence thresholds that gate which plan operations +proceed automatically versus requiring human approval. + +| Command | Description | +|---------|-------------| +| `agents automation-profile add --config\|-c [--update]` | Register or update an automation profile | +| `agents automation-profile remove [--yes\|-y] ` | Remove a custom automation profile | +| `agents automation-profile list [REGEX]` | List automation profiles | +| `agents automation-profile show ` | Show automation profile details | + +Built-in profiles (immutable): `manual`, `review`, `semi-auto`, `full-auto` (and four intermediate levels). + +--- + +## Validation Commands + +Validations are tool subtypes with pass/fail semantics, always attached to a resource. + +| Command | Description | +|---------|-------------| +| `agents validation add --config\|-c [--update]` | Register a validation | +| `agents validation attach [--project PROJECT\|--plan PLAN_ID] [ARGS...]` | Attach a validation to a resource | +| `agents validation detach [--yes\|-y] ` | Detach a validation | + +--- + +## Config Commands + +| Command | Description | +|---------|-------------| +| `agents config set ` | Set a configuration key | +| `agents config get ` | Get a configuration key | +| `agents config list [--filter-values REGEX] [REGEX]` | List configuration keys | + +### Example + +```bash +# Set the default output format +agents config set core.format json + +# Pin the default provider +agents config set actor.default.provider openai + +# List all config keys +agents config list +``` + +--- + +## Naming Convention + +All entities use the namespaced name format: + +``` +[[server:]namespace/]name +``` + +- **Built-in actors** use provider prefixes: `openai/gpt-4o`, `anthropic/claude-4-sonnet` +- **Custom entities** use `local/` prefix: `local/my-actor`, `local/my-skill` +- **Server-scoped** entities: `myserver:myns/my-entity` +- **Built-in resource types** are unnamespaced: `git-checkout`, `fs-mount` + +Plans and resources are identified by **ULID** (Universally Unique Lexicographically +Sortable Identifier) when precision is needed, especially in hierarchies. diff --git a/docs/api/index.md b/docs/api/index.md index 4eee7341e..86c93a875 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -22,3 +22,45 @@ classes, functions, and exceptions with signatures and usage examples. > **Note:** Internal modules (prefixed with `_`) and implementation details > not listed in a module's `__all__` are considered private and may change > without notice. + +--- + +## CLI Reference + +The `agents` / `cleveragents` commands expose the full platform surface from the terminal. + +| Page | Description | +|------|-------------| +| [CLI Reference](cli-reference.md) | Complete command reference — all command groups, flags, arguments, and environment variables | + +--- + +## Application Services & DI + +| Page | Description | +|------|-------------| +| [Python API — Application Layer](python-api.md) | Application services, DI container usage, plan lifecycle, domain models, and key protocols | + +--- + +## Protocol Documentation + +| Page | Description | +|------|-------------| +| [Protocols](protocols.md) | A2A (JSON-RPC 2.0), MCP, LSP, and AgentSkills.io protocol details | + +--- + +## Quick Navigation + +| I want to… | Go to | +|------------|-------| +| Run a plan from the CLI | [CLI Reference → `agents plan`](cli-reference.md#plan-commands) | +| Add a resource | [CLI Reference → `agents resource`](cli-reference.md#resource-commands) | +| Configure an actor | [CLI Reference → `agents actor`](cli-reference.md#actor-commands) | +| Use the Python API to create a plan | [Python API → PlanLifecycleService](python-api.md#planlifecycleservice) | +| Understand the DI container | [Python API → DI Container](python-api.md#dependency-injection-container) | +| Integrate via A2A | [Protocols → A2A](protocols.md#a2a-agent-to-agent-protocol) | +| Expose tools via MCP | [Protocols → MCP](protocols.md#mcp-model-context-protocol) | +| Attach LSP intelligence | [Protocols → LSP](protocols.md#lsp-language-server-protocol) | +| Package skills | [Protocols → AgentSkills.io](protocols.md#agentskillsio) | diff --git a/docs/api/protocols.md b/docs/api/protocols.md new file mode 100644 index 000000000..fecdb6fdc --- /dev/null +++ b/docs/api/protocols.md @@ -0,0 +1,596 @@ +# Protocols + +CleverAgents deliberately adopts open, versioned protocols so that clients, +tools, and skills can interoperate without bespoke integrations. + +| Protocol | Role | +|----------|------| +| [A2A](#a2a-agent-to-agent-protocol) | Versioned client-server contract (JSON-RPC 2.0) | +| [MCP](#mcp-model-context-protocol) | Tool discovery and invocation over a server boundary | +| [LSP](#lsp-language-server-protocol) | Language intelligence for actors and agents | +| [AgentSkills.io](#agentskillsio) | Packaging instruction-driven, multi-step workflows | + +> **Guiding principles:** +> 1. **Prefer open protocols** — align with community standards to keep integrations portable. +> 2. **Keep adapters at the edge** — standards map into stable internal domain models so core logic remains protocol-agnostic. + +--- + +## A2A — Agent-to-Agent Protocol + +**Standard:** [a2a-protocol.org](https://a2a-protocol.org) +**ADRs:** [ADR-026](../adr/ADR-026-agent-client-protocol.md), [ADR-047](../adr/ADR-047-acp-standard-adoption.md), [ADR-048](../adr/ADR-048-server-application-architecture.md) +**Python API:** [`cleveragents.a2a`](a2a.md) + +### Overview + +A2A is the **sole** communication protocol for all client-server interaction in +CleverAgents. It is built on **JSON-RPC 2.0** and defines the fundamental +boundary between the Presentation and Application layers. Every CLI command, +TUI action, and IDE plugin operation flows through A2A regardless of deployment +mode. + +A2A is the successor to the Agent Client Protocol (ACP), which is now +deprecated. A2A retains backward compatibility with ACP's JSON-RPC 2.0 +foundation. + +### Wire Format + +All A2A messages follow the JSON-RPC 2.0 specification: + +```json +// Request +{ + "jsonrpc": "2.0", + "id": "req-001", + "method": "session.create", + "params": { + "actor": "openai/gpt-4o" + } +} + +// Success response +{ + "jsonrpc": "2.0", + "id": "req-001", + "result": { + "session_id": "sess-abc123", + "actor": "openai/gpt-4o", + "created_at": "2026-04-13T10:00:00Z" + } +} + +// Error response +{ + "jsonrpc": "2.0", + "id": "req-001", + "error": { + "code": -32000, + "message": "Actor not found: openai/gpt-4o", + "data": {"actor": "openai/gpt-4o"} + } +} +``` + +> **Breaking change (v3.7.0+):** Fields were renamed to comply with JSON-RPC 2.0. +> `a2a_version` → `jsonrpc`, `request_id` → `id`, `operation` → `method`, +> `data` → `result`. See the [CHANGELOG](../../CHANGELOG.md) for the full +> migration table. + +### Standard A2A Operations + +| Method | Description | +|--------|-------------| +| `message/send` | Send a message to an agent | +| `message/stream` | Stream a message response via SSE | +| `tasks/get` | Get task status | +| `tasks/cancel` | Cancel a running task | +| `agent/authenticatedExtendedCard` | Retrieve the Agent Card (capability discovery) | + +### CleverAgents Extension Methods + +CleverAgents extends A2A with `_cleveragents/`-prefixed methods (declared via +the A2A extension mechanism): + +| Method | Description | +|--------|-------------| +| `session.create` | Create a new conversation session | +| `session.close` | Close an existing session | +| `plan.create` | Instantiate a plan from an action | +| `plan.execute` | Execute a plan | +| `plan.status` | Query plan status | +| `plan.diff` | Retrieve the sandbox diff | +| `plan.apply` | Apply the sandbox changeset | +| `plan.correct` | Correct a decision | +| `registry.list_tools` | List available tools | +| `registry.list_resources` | List available resources | +| `registry.list_actors` | List available actors | +| `registry.list_skills` | List available skills | +| `event.subscribe` | Subscribe to the event stream | +| `diagnostics.run` | Run diagnostics | + +### Deployment Modes + +| Mode | Transport | Description | +|------|-----------|-------------| +| **Local** | stdio (JSON-RPC) | Agent runs as a subprocess; A2A flows in-process via `A2aLocalFacade` | +| **Server** | HTTP | A2A flows over HTTP to the CleverAgents server | + +```python +from cleveragents.a2a import A2aLocalFacade, A2aRequest + +# Local mode — no network, no serialization overhead +facade = A2aLocalFacade(container) +response = await facade.dispatch( + A2aRequest(method="session.create", params={"actor": "openai/gpt-4o"}) +) +session_id = response.result["session_id"] +``` + +### Agent Card Discovery + +The A2A Agent Card (`agent/authenticatedExtendedCard`) exposes the platform's +capabilities for ecosystem interoperability: + +```json +{ + "name": "CleverAgents", + "version": "1.0.0", + "description": "Unified AI agent orchestration platform", + "capabilities": { + "streaming": true, + "pushNotifications": true, + "stateTransitionHistory": true + }, + "extensions": [ + { + "uri": "https://cleverthis.com/a2a/extensions/plan-lifecycle", + "methods": ["plan.create", "plan.execute", "plan.apply", "plan.diff", "plan.correct"] + }, + { + "uri": "https://cleverthis.com/a2a/extensions/registry", + "methods": ["registry.list_tools", "registry.list_resources", "registry.list_actors"] + } + ] +} +``` + +### Event Streaming + +Subscribe to plan and session events via the A2A event stream: + +```python +from cleveragents.a2a import A2aEventQueue + +queue = A2aEventQueue() +async for event in queue.subscribe("plan-01JXYZ..."): + print(event.type, event.payload) + if event.type == "plan.applied": + break + +queue.close() # release resources on shutdown +``` + +### Error Codes + +| Code | Name | Description | +|------|------|-------------| +| `-32700` | Parse error | Invalid JSON | +| `-32600` | Invalid request | Not a valid JSON-RPC 2.0 request | +| `-32601` | Method not found | Unknown A2A method | +| `-32602` | Invalid params | Invalid method parameters | +| `-32603` | Internal error | Internal server error | +| `-32000` | Application error | CleverAgents domain error | +| `-32001` | Not available | Operation not available in current mode | +| `-32002` | Version mismatch | Incompatible A2A protocol versions | + +--- + +## MCP — Model Context Protocol + +**Standard:** [modelcontextprotocol.io](https://modelcontextprotocol.io) +**ADR:** [ADR-029](../adr/ADR-029-model-context-protocol.md) +**Python API:** [`cleveragents.mcp`](mcp.md) + +### Overview + +MCP is the standard for discovering and invoking external tools over a server +boundary via JSON-RPC. CleverAgents bridges MCP servers into the Tool Registry +via the `MCPToolAdapter`, giving actors plug-and-play access to a growing +ecosystem of tool providers. + +### Supported Transports + +| Transport | Description | +|-----------|-------------| +| `stdio` | Spawn a subprocess and communicate over stdin/stdout | +| `sse` | Server-Sent Events over HTTP | +| `streamable-http` | Streamable HTTP (MCP 1.1+) | + +### Connecting an MCP Server + +```python +from cleveragents.mcp import MCPToolAdapter, MCPServerConfig +from cleveragents.tool import ToolRegistry + +# Configure the MCP server +config = MCPServerConfig( + name="bash-tools", + transport="stdio", + command="uvx", + args=["mcp-server-bash"], +) + +# Connect and discover tools +adapter = MCPToolAdapter(config) +await adapter.connect() +tools = await adapter.discover_tools() + +# Register tools into the CleverAgents Tool Registry +registry = ToolRegistry() +adapter.register_tools(registry) + +# Invoke a tool +result = await adapter.invoke("bash", {"command": "ls -la"}) +print(result.content) + +await adapter.disconnect() +``` + +### MCP Server Configuration Reference + +| Field | Type | Description | +|-------|------|-------------| +| `name` | `str` | Server identifier (used as tool namespace prefix) | +| `transport` | `str` | `"stdio"` \| `"sse"` \| `"streamable-http"` | +| `command` | `str \| None` | Spawn command (stdio only) | +| `args` | `list[str]` | Command-line arguments | +| `env` | `dict[str, str]` | Environment variables passed to the server process | +| `url` | `str \| None` | Server URL (sse/http only) | +| `headers` | `dict[str, str]` | HTTP headers (sse/http only) | + +### Tool Discovery + +MCP tools are discovered via the `tools/list` method and registered in the +Tool Registry with `source="mcp"`. Each discovered tool becomes a +`MCPToolDescriptor`: + +```python +class MCPToolDescriptor(BaseModel): + name: str + description: str + input_schema: dict[str, Any] # JSON Schema + annotations: dict[str, Any] +``` + +### Sandbox Path Rewriting + +When running tools inside a sandbox, the `SandboxPathRewriter` rewrites +absolute host paths in tool arguments and results to sandbox-relative paths, +preventing path traversal outside the sandbox root: + +```python +from cleveragents.mcp import SandboxPathRewriter, SandboxPathRewriterConfig + +rewriter = SandboxPathRewriter( + SandboxPathRewriterConfig( + sandbox_root="/sandbox", + host_root="/home/user/project", + ) +) +rewritten_args = rewriter.rewrite_args(tool_args) +``` + +### Skill Refresh Notifications + +When an MCP server's tool list changes at runtime, `MCPRefreshHook` wires +`notifications/tools/list_changed` events to `SkillRegistry.refresh_all()`: + +```python +from cleveragents.mcp import MCPRefreshHook + +hook = MCPRefreshHook(skill_registry) +adapter.on_tools_changed(hook.on_tools_changed) +``` + +### MCP Client Lifecycle + +``` +STOPPED → STARTING → RUNNING → STOPPING → STOPPED + ↘ ERROR +``` + +The `McpClient` manages lazy start (server is only started when first needed) +and auto-stop after a configurable idle timeout: + +```python +from cleveragents.mcp import McpClient, McpClientConfig + +client_config = McpClientConfig(server=server_config, auto_stop_idle_secs=60) +client = McpClient(client_config) + +async with client: + tools = await client.list_tools() + result = await client.call_tool("bash", {"command": "echo hello"}) +``` + +--- + +## LSP — Language Server Protocol + +**Standard:** [microsoft.github.io/language-server-protocol](https://microsoft.github.io/language-server-protocol/) +**ADR:** [ADR-027](../adr/ADR-027-language-server-protocol.md) + +### Overview + +LSP is the standard for attaching language intelligence to actors and agents. +CleverAgents registers LSP servers in the global **LSP Registry** and binds +them to actor graph nodes via YAML configuration. When an actor activates, +the LSP Runtime starts the appropriate language servers for the actor's bound +languages and workspace resources. + +### Capabilities Exposed to Actors + +LSP capabilities are exposed to actors in two ways: + +1. **As callable tools** via `LSPToolAdapter` — actors can invoke LSP + operations (diagnostics, completions, references, rename, code actions) + as regular tool calls. +2. **As automatic context enrichment** — diagnostics and type annotations + are injected into the ACMS hot context automatically. + +| LSP Capability | Tool Name | Description | +|----------------|-----------|-------------| +| `textDocument/diagnostic` | `lsp.diagnostics` | Get diagnostics for a file | +| `textDocument/hover` | `lsp.hover` | Get type info and documentation at a position | +| `textDocument/definition` | `lsp.definition` | Go to definition | +| `textDocument/references` | `lsp.references` | Find all references | +| `textDocument/completion` | `lsp.completion` | Get completions at a position | +| `textDocument/rename` | `lsp.rename` | Rename a symbol | +| `textDocument/codeAction` | `lsp.code_action` | Get available code actions | +| `textDocument/signatureHelp` | `lsp.signature_help` | Get function signature help | + +### Registering an LSP Server + +```bash +# Register a Python LSP server +agents lsp add --config examples/lsp/pyright.yaml + +# List registered LSP servers +agents lsp list --language python + +# Show LSP server details +agents lsp show local/pyright +``` + +LSP server YAML configuration: + +```yaml +name: local/pyright +language: python +command: pyright-langserver +args: ["--stdio"] +env: {} +workspace_mapping: auto # auto | explicit +``` + +### Actor YAML Binding + +Bind LSP servers to actor graph nodes in the actor YAML: + +```yaml +name: local/my-python-actor +entry_node: analyze +nodes: + analyze: + type: llm + lsp_binding: + language: python # bind by language (auto-selects server) + # or: + server: local/pyright # bind by explicit server name +``` + +Different nodes in an actor's graph can have different LSP bindings, enabling +fine-grained control over which agents receive which language intelligence. + +### LSP Runtime + +The LSP Runtime in the Infrastructure layer manages: + +- **Server lifecycle** — start, stop, health monitoring +- **Workspace mapping** — maps project resources to LSP workspace folders +- **File synchronization** — keeps LSP server in sync with resource changes +- **Capability negotiation** — negotiates supported capabilities during initialization + +### Auto-Discovery + +Actors can bind LSP servers automatically based on the languages detected in +their project's resources: + +```yaml +lsp_binding: + mode: auto # detect languages from project resources +``` + +--- + +## AgentSkills.io + +**Standard:** [AgentSkills.io](https://AgentSkills.io) +**ADRs:** [ADR-028](../adr/ADR-028-agent-skills-standard.md), [ADR-030](../adr/ADR-030-skill-abstraction-definition.md) +**Python API:** [`cleveragents.skills`](skills.md) + +### Overview + +AgentSkills.io is the standard for packaging instruction-driven, multi-step +workflows as `SKILL.md` files with progressive disclosure. Agent Skills +complement MCP tools by teaching agents *how* to accomplish complex tasks +rather than simply exposing callable functions. + +### Skill Bundle Structure + +An AgentSkills-compatible skill bundle is a directory with the following layout: + +``` +my-skill/ +├── SKILL.md # Required: skill definition with progressive disclosure +├── scripts/ # Optional: executable scripts referenced by steps +│ └── deploy.sh +├── references/ # Optional: reference documents +│ └── api-spec.md +└── assets/ # Optional: static assets + └── schema.json +``` + +### `SKILL.md` Format + +```markdown +# Deploy to Staging + +## Description +Deploys the application to the staging environment. + +## Steps + +### 1. Run tests +Execute the test suite and verify all tests pass. + +```bash +scripts/run-tests.sh +``` + +### 2. Build artifacts +Build the deployment artifacts. + +### 3. Deploy +Deploy to the staging environment using the deployment script. + +```bash +scripts/deploy.sh --env staging +``` + +## Definition of Done +- All tests pass +- Application is accessible at the staging URL +- Health check returns 200 +``` + +### Loading a Skill Bundle + +```python +from pathlib import Path +from cleveragents.skills import AgentSkillLoader + +loader = AgentSkillLoader.from_folder(Path("./skills/deploy-to-staging")) +spec = loader.load() + +print(spec.name) # "deploy-to-staging" +print(spec.version) # "1.0.0" +for step in spec.steps: + print(f" Step: {step.title}") +``` + +### Discovering Skills + +```python +from cleveragents.skills import discover_agent_skills, register_discovered_skills + +result = discover_agent_skills([Path("./skills/")]) +for skill in result.skills: + print(f"Found: {skill.name} v{skill.version}") + +# Register all discovered skills +register_discovered_skills(result, skill_registry) +``` + +### Registering via CLI + +```bash +# Register a skill from a YAML config +agents skill add --config examples/skills/deploy.yaml + +# Or discover from a directory (set CLEVERAGENTS_SKILLS_PATH) +export CLEVERAGENTS_SKILLS_PATH=/path/to/skills:/another/path +agents skill list # shows all discovered skills +``` + +### Progressive Disclosure + +AgentSkills.io uses a three-tier progressive disclosure model: + +| Tier | Description | +|------|-------------| +| **Discover** | Actor learns the skill exists and its high-level description | +| **Activate** | Actor loads the full `SKILL.md` and step details | +| **Deactivate** | Actor releases the skill when no longer needed | + +This keeps the actor's context window lean — skills are only fully loaded +when the actor decides to use them. + +### `AgentSkillSpec` + +The parsed representation of a skill bundle: + +```python +class AgentSkillSpec(BaseModel): + name: str + version: str + steps: list[SkillStep] + tools: list[AgentSkillToolDescriptor] + resource_slots: list[AgentSkillResourceSlot] +``` + +### Inline Executor + +Skills can define steps as inline Python callables rather than external tool +calls. The `InlineToolExecutor` handles these: + +```python +from cleveragents.skills import InlineToolExecutor + +executor = InlineToolExecutor() +result = await executor.execute(step, context) +``` + +### Skill Context + +The `SkillContext` carries runtime state during skill execution: + +```python +class SkillContext: + session_id: str + plan_id: str + bound_resources: list[BoundResource] + cancellation_token: CancellationToken + invocation_history: list[ToolInvocationRecord] +``` + +--- + +## Protocol Interoperability + +The four protocols work together in a layered fashion: + +``` +User / IDE / CI + ↓ + A2A (JSON-RPC 2.0) ← all client-server communication + ↓ +CleverAgents Application + ↓ + ┌───────────────────────────────────────┐ + │ MCP Adapter LSP Runtime Skills │ ← tool/intelligence/skill sources + └───────────────────────────────────────┘ + ↓ + Tool Registry ← all tools unified here + ↓ + Actor (LangGraph) ← executes plans using tools +``` + +- **A2A** is the outer boundary — all clients speak A2A. +- **MCP** brings external tools into the Tool Registry. +- **LSP** brings language intelligence into actor context and as tools. +- **AgentSkills.io** brings instruction-driven workflows as activatable skills. + +All four integrate into the same internal domain model, so actors see a +unified surface regardless of where a tool or skill originated. diff --git a/docs/api/python-api.md b/docs/api/python-api.md new file mode 100644 index 000000000..1aaa27f8c --- /dev/null +++ b/docs/api/python-api.md @@ -0,0 +1,525 @@ +# Python API — Application Layer + +This page documents the **application layer** of the CleverAgents Python package: +application services, the dependency injection (DI) container, domain models, +and key protocols. For module-level API documentation (exceptions, registries, +adapters) see the [Module Index](index.md). + +See [ADR-001](../adr/ADR-001-layered-architecture.md) (layered architecture) and +[ADR-003](../adr/ADR-003-dependency-injection.md) (dependency injection) for +design rationale. + +--- + +## Architecture Overview + +CleverAgents follows a strict layered architecture: + +``` +Entry Points (CLI / TUI / A2A server) + ↓ +Application Layer ← this page + ↓ +Domain Layer (models, value objects, domain services) + ↓ +Infrastructure (database, file system, external services) + ↓ +Integration (LangChain/LangGraph, MCP, LSP adapters) + ↓ +Core (exceptions, retry, circuit breaker, async cleanup) +``` + +All cross-layer dependencies flow **downward only**. The DI container wires +everything together at startup. + +--- + +## Dependency Injection Container + +**Module:** `cleveragents.application.container` + +CleverAgents uses [dependency-injector](https://python-dependency-injector.ets-labs.org/) +for IoC. The `CleverAgentsContainer` is the root container; all application +services are registered as providers and resolved lazily. + +```python +from cleveragents.application.container import CleverAgentsContainer + +container = CleverAgentsContainer() +container.config.from_dict({"provider": "openai", ...}) +container.wire(modules=[__name__]) + +# Resolve services +plan_service = container.plan_service() +registry_service = container.registry_service() +session_service = container.session_service() +invariant_service = container.invariant_service() +``` + +### Key Providers + +| Provider | Type | Description | +|----------|------|-------------| +| `container.settings` | `Singleton` | Application `Settings` instance | +| `container.event_bus` | `Singleton` | In-process event bus | +| `container.plan_service` | `Singleton` | `PlanLifecycleService` | +| `container.registry_service` | `Singleton` | `RegistryService` | +| `container.session_service` | `Singleton` | `SessionService` | +| `container.invariant_service` | `Singleton` | `InvariantService` | +| `container.actor_registry` | `Singleton` | `ActorRegistry` | +| `container.tool_registry` | `Singleton` | `ToolRegistry` | +| `container.skill_registry` | `Singleton` | `SkillRegistry` | +| `container.provider_registry` | `Singleton` | `ProviderRegistry` | +| `container.mcp_registry` | `Singleton` | `McpRegistry` | +| `container.lsp_registry` | `Singleton` | `LSPRegistry` | +| `container.resource_registry` | `Singleton` | `ResourceRegistry` | +| `container.a2a_facade` | `Singleton` | `A2aLocalFacade` | + +> **Tip:** Always obtain services via the container rather than constructing +> them directly. This ensures correct lifecycle management and dependency +> resolution. + +--- + +## PlanLifecycleService + +**Module:** `cleveragents.application.services.plan_service` + +The central application service for the plan lifecycle. Orchestrates the +four phases (Action → Strategize → Execute → Apply) and coordinates actors, +tools, resources, and invariants. + +```python +from cleveragents.application.services.plan_service import PlanLifecycleService + +service: PlanLifecycleService = container.plan_service() + +# Create a plan from an action +plan = await service.create_plan( + action_name="local/refactor", + project_names=["my-project"], + args={"target": "src/"}, + automation_profile="review", +) + +# Execute the plan (Strategize + Execute phases) +result = await service.execute_plan(plan.plan_id) + +# Apply the sandbox changeset +await service.apply_plan(plan.plan_id) +``` + +### Key Methods + +| Method | Returns | Description | +|--------|---------|-------------| +| `create_plan(action_name, project_names, args, ...)` | `Plan` | Instantiate a plan from an action | +| `execute_plan(plan_id)` | `PlanExecutionResult` | Run Strategize and Execute phases | +| `apply_plan(plan_id)` | `PlanApplyResult` | Merge sandbox changeset into real resources | +| `get_plan(plan_id)` | `Plan` | Retrieve a plan by ID | +| `list_plans(filters)` | `list[Plan]` | List plans with optional filters | +| `cancel_plan(plan_id, reason)` | `Plan` | Cancel a running plan | +| `rollback_plan(plan_id, checkpoint_id)` | `Plan` | Roll back to a checkpoint | +| `get_plan_diff(plan_id)` | `PlanDiff` | Get the sandbox diff for a plan | +| `correct_decision(decision_id, mode, guidance)` | `CorrectionAttempt` | Correct a decision and recompute | +| `get_decision_tree(plan_id)` | `DecisionTree` | Retrieve the full decision tree | + +--- + +## RegistryService + +**Module:** `cleveragents.application.services.registry_service` + +Unified CRUD service for all registry entities: actions, actors, skills, +tools, resources, projects, LSP servers, and automation profiles. + +```python +from cleveragents.application.services.registry_service import RegistryService + +service: RegistryService = container.registry_service() + +# Register an action from a YAML file +action = await service.register_action(Path("examples/actions/refactor.yaml")) + +# List all tools +tools = await service.list_tools(namespace="local", source="mcp") + +# Register a resource +resource = await service.register_resource( + type_name="git-checkout", + name="local/my-repo", + args={"url": "https://github.com/org/repo.git"}, +) +``` + +### Key Methods + +| Method | Description | +|--------|-------------| +| `register_action(path, update=False)` | Register or update an action from YAML | +| `list_actions(namespace, state, regex)` | List actions | +| `get_action(name)` | Get an action by name | +| `archive_action(name)` | Archive an action | +| `register_actor(path, update=False)` | Register or update an actor from YAML | +| `list_actors()` | List all actors | +| `get_actor(name)` | Get an actor by name | +| `register_skill(path, update=False)` | Register or update a skill from YAML | +| `list_skills(namespace, source)` | List skills | +| `register_tool(path, update=False)` | Register or update a tool from YAML | +| `list_tools(namespace, source, type)` | List tools | +| `register_resource(type_name, name, args)` | Register a resource | +| `list_resources(type, include_stopped)` | List resources | +| `get_resource(name)` | Get a resource by name | +| `create_project(name, description, resources, invariants)` | Create a project | +| `list_projects(namespace, regex)` | List projects | +| `link_resource_to_project(project, resource, read_only)` | Link a resource to a project | + +--- + +## SessionService + +**Module:** `cleveragents.application.services.session_service` + +Manages conversation sessions — creation, retrieval, message history, +export, and import. + +```python +from cleveragents.application.services.session_service import SessionService + +service: SessionService = container.session_service() + +# Create a session +session = await service.create_session(actor="openai/gpt-4o") + +# Send a message +response = await service.send_message( + session_id=session.session_id, + content="What is the current plan status?", +) + +# Export as JSON +export_data = await service.export_session(session.session_id) + +# Export as Markdown transcript +md = await service.export_session_markdown(session.session_id) +``` + +### Key Methods + +| Method | Description | +|--------|-------------| +| `create_session(actor)` | Create a new session | +| `get_session(session_id)` | Retrieve a session | +| `list_sessions()` | List all sessions | +| `delete_session(session_id)` | Delete a session | +| `send_message(session_id, content, stream)` | Send a message and get a response | +| `export_session(session_id)` | Export session as a JSON-serializable dict | +| `export_session_markdown(session_id)` | Export session as a Markdown transcript | +| `import_session(data)` | Import a session from a previously exported dict | + +--- + +## InvariantService + +**Module:** `cleveragents.application.services.invariant_service` + +See [`cleveragents.core` — Invariant Service](core.md#invariant-service) for +the full API reference. The service is registered as a Singleton in the DI +container: + +```python +invariant_service = container.invariant_service() +``` + +--- + +## Domain Models + +**Module:** `cleveragents.domain.models` + +All domain models inherit from `DomainBaseModel` (see [Core Utilities](core.md#domain-base-model)). + +### Plan + +```python +from cleveragents.domain.models.core.plan import Plan, PlanPhase, PlanState + +class Plan(DomainBaseModel): + plan_id: str # ULID + name: str | None # namespaced name (top-level plans only) + action_name: str # action this plan was instantiated from + project_names: list[str] # bound projects + phase: PlanPhase # Action | Strategize | Execute | Apply + state: PlanState # running | applied | errored | cancelled | ... + automation_profile: str + created_at: datetime + updated_at: datetime + parent_plan_id: str | None +``` + +**`PlanPhase`** enum: `ACTION`, `STRATEGIZE`, `EXECUTE`, `APPLY` + +**`PlanState`** enum: `RUNNING`, `APPLIED`, `CONSTRAINED`, `ERRORED`, `CANCELLED` + +### Action + +```python +from cleveragents.domain.models.core.action import Action + +class Action(DomainBaseModel): + name: str # namespaced name + description: str + definition_of_done: str + strategy_actor: str | None + execution_actor: str | None + estimation_actor: str | None + invariant_actor: str | None + args: list[ActionArgument] + invariants: list[str] + state: str # "active" | "archived" +``` + +### Decision + +```python +from cleveragents.domain.models.core.decision import Decision, DecisionType + +class Decision(DomainBaseModel): + decision_id: str # ULID + plan_id: str + type: DecisionType + question: str + chosen_option: str + alternatives: list[str] + confidence: float # 0.0–1.0 + rationale: str + phase: PlanPhase + created_at: datetime + superseded_by: str | None +``` + +**`DecisionType`** enum: `PROMPT_DEFINITION`, `INVARIANT_ENFORCED`, +`STRATEGY_CHOICE`, `SUBPLAN_SPAWN`, `SUBPLAN_PARALLEL_SPAWN`, … + +### Resource + +```python +from cleveragents.domain.models.core.resource import Resource + +class Resource(DomainBaseModel): + resource_id: str # ULID + name: str # namespaced name + type_name: str # e.g. "git-checkout", "sqlite" + description: str | None + is_physical: bool + parent_ids: list[str] + child_ids: list[str] + state: str # "active" | "stopped" + created_at: datetime +``` + +### Project + +```python +from cleveragents.domain.models.core.project import Project + +class Project(DomainBaseModel): + name: str # namespaced name (sole identifier — no ULID) + description: str | None + resource_links: list[ResourceLink] + invariants: list[str] + context_policy: ContextPolicy | None + created_at: datetime +``` + +### Session + +```python +from cleveragents.domain.models.core.session import Session + +class Session(DomainBaseModel): + session_id: str + actor: str + messages: list[Message] + linked_plan_ids: list[str] + created_at: datetime + updated_at: datetime + + def as_export_markdown(self) -> str: + """Render a human-readable Markdown transcript (lossy, not importable).""" +``` + +### Invariant + +```python +from cleveragents.domain.models.core.invariant import Invariant, InvariantScope + +class Invariant(DomainBaseModel): + invariant_id: str # ULID + text: str + scope: InvariantScope # GLOBAL | PROJECT | ACTION | PLAN + source_name: str # project/action/plan name, or "global" + active: bool + non_overridable: bool # global invariants only + created_at: datetime +``` + +**`InvariantScope`** enum: `GLOBAL`, `PROJECT`, `ACTION`, `PLAN` + +--- + +## Key Protocols and Interfaces + +### `AIProviderInterface` + +**Module:** `cleveragents.providers.interface` + +Protocol that all AI provider implementations must satisfy. + +```python +class AIProviderInterface(Protocol): + @property + def name(self) -> str: ... + + @property + def model_id(self) -> str: ... + + async def generate( + self, + messages: list[Message], + tools: list[ToolSpec] | None = None, + stream: bool = False, + ) -> GenerationResult: ... +``` + +### `ResourceHandler` + +**Module:** `cleveragents.resource.handlers.base` + +Protocol for resource handler implementations. + +```python +class ResourceHandler(Protocol): + async def read(self, resource_id: str, context: ...) -> Any: ... + async def write(self, resource_id: str, data: Any, context: ...) -> None: ... + async def delete(self, resource_id: str, context: ...) -> None: ... + async def list_children(self, resource_id: str, context: ...) -> list[str]: ... + async def diff(self, resource_id: str, other_id: str, context: ...) -> str: ... + async def checkpoint(self, resource_id: str) -> str: ... + async def rollback(self, resource_id: str, checkpoint_id: str) -> None: ... + async def create_sandbox(self, resource_id: str) -> "Sandbox": ... +``` + +### `LLMCaller` + +**Module:** `cleveragents.tool` + +Protocol for calling an LLM. Implement this to plug in a custom provider +into the tool-calling runtime. + +```python +class LLMCaller(Protocol): + async def call( + self, + messages: list[Message], + tools: list[ToolSpec], + ) -> LLMResponse: ... +``` + +--- + +## End-to-End Example + +The following example shows how to use the Python API to create and execute +a plan programmatically: + +```python +import asyncio +from cleveragents.application.container import CleverAgentsContainer + +async def main(): + # Bootstrap the container + container = CleverAgentsContainer() + container.config.from_env("CLEVERAGENTS_") + + plan_service = container.plan_service() + registry_service = container.registry_service() + + # Register a resource + await registry_service.register_resource( + type_name="git-checkout", + name="local/my-repo", + args={"url": "https://github.com/org/repo.git", "path": "/workspace/repo"}, + ) + + # Create a project + await registry_service.create_project( + name="my-project", + description="Main application project", + resources=["local/my-repo"], + ) + + # Instantiate a plan + plan = await plan_service.create_plan( + action_name="local/refactor", + project_names=["my-project"], + args={"target": "src/"}, + automation_profile="review", + ) + print(f"Plan created: {plan.plan_id}") + + # Execute the plan + result = await plan_service.execute_plan(plan.plan_id) + print(f"Execution result: {result.state}") + + # Review the decision tree + tree = await plan_service.get_decision_tree(plan.plan_id) + for decision in tree.decisions: + print(f" [{decision.type}] {decision.question[:60]}…") + + # Apply if satisfied + await plan_service.apply_plan(plan.plan_id) + print("Plan applied successfully.") + +asyncio.run(main()) +``` + +--- + +## Event Bus + +**Module:** `cleveragents.application.events` + +The in-process event bus enables loose coupling between application services. +Services emit events; subscribers react without direct dependencies. + +```python +from cleveragents.application.events import EventBus, EventType + +bus: EventBus = container.event_bus() + +# Subscribe to plan phase transitions +@bus.on(EventType.PLAN_PHASE_CHANGED) +async def on_phase_change(event): + print(f"Plan {event.plan_id} moved to {event.new_phase}") + +# Emit an event (done internally by services) +await bus.emit(EventType.PLAN_PHASE_CHANGED, plan_id="01JXYZ...", new_phase="execute") +``` + +### Key Event Types + +| Event | Description | +|-------|-------------| +| `PLAN_CREATED` | A new plan was instantiated | +| `PLAN_PHASE_CHANGED` | A plan advanced to a new phase | +| `PLAN_APPLIED` | A plan was successfully applied | +| `PLAN_CANCELLED` | A plan was cancelled | +| `PLAN_ERRORED` | A plan encountered an unrecoverable error | +| `DECISION_RECORDED` | A new decision was added to the decision tree | +| `INVARIANT_VIOLATED` | An invariant was not satisfied | +| `INVARIANT_ENFORCED` | An invariant enforcement record was created | +| `INVARIANT_RECONCILED` | Invariant reconciliation completed for a phase | +| `TOOL_EXECUTED` | A tool invocation completed | +| `SESSION_CREATED` | A new session was created | +| `SESSION_MESSAGE_ADDED` | A message was added to a session | diff --git a/mkdocs.yml b/mkdocs.yml index 76940184b..f9b44c43e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -13,6 +13,9 @@ nav: - Architecture: architecture.md - API Reference: - Overview: api/index.md + - CLI Reference: api/cli-reference.md + - Python API (Application Layer): api/python-api.md + - Protocols (A2A, MCP, LSP, AgentSkills): api/protocols.md - Core Utilities: api/core.md - A2A Protocol: api/a2a.md - Actor System: api/actor.md