docs(cli): align actor-first help and registry rules

This commit is contained in:
2026-01-14 19:24:50 -05:00
parent 77cd7e61f0
commit 34d13d3e0d
8 changed files with 81 additions and 26 deletions
+1
View File
@@ -77,5 +77,6 @@ Set `CLEVERAGENTS_DEFAULT_PROVIDER` to pin the global provider (for example `exp
- `agents diagnostics` prints whether the registry can see your credentials and which actor/provider is selected.
- `agents tell` and `agents build` require `--actor <name>` unless a default actor is set; use `agents actor set-default <name>` to configure one.
- 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.) plus every supported environment variable is documented in `docs/reference/providers.md` and `docs/reference/env_variables.yaml`.
@@ -85,6 +85,8 @@ The concrete registry (`src/cleveragents/providers/registry.py:1-357`) and setti
- **Mock isolation:** `CLEVERAGENTS_TESTING_USE_MOCK_AI` remains the only bypass inside `application/container.py`, keeping mocks out of production code per the implementation plan.
- **Actor registry boundaries:** The registry persists canonical config blobs/hashes/graph descriptors, seeds immutable built-in actors named `<provider>/<model>` from settings defaults, enforces `local/<id>` for custom actors, blocks removal of built-ins or the default actor, and requires `--unsafe` confirmation when an actor config is marked unsafe; CLI help/docs mirror these guards.
These details are mirrored in `docs/reference/providers.md` and `docs/reference/env_variables.yaml` so the ADR now points at the actual runtime behavior.
### Provider Implementations
@@ -19,7 +19,7 @@ Python CLI framework options:
- **Fire**: Auto-generates CLI from functions, less control
## Decision
We will use **Typer** as our CLI framework, leveraging its type hint integration and modern Python features.
We will use **Typer** as our CLI framework, leveraging its type hint integration and modern Python features. The CLI surface is actor-first: provider/model flags were removed in favor of `--actor` plus a default actor stored in the actor registry (see ADR-008 for registry boundaries).
### Architecture
@@ -31,7 +31,7 @@ from pathlib import Path
app = typer.Typer(
name="agents",
help="CleverAgents - AI-powered development assistant",
help="CleverAgents - AI-powered development assistant (actor-first CLI)",
no_args_is_help=True,
rich_markup_mode="rich",
pretty_exceptions_enable=True,
@@ -39,13 +39,13 @@ app = typer.Typer(
)
# Sub-command groups
plan_app = typer.Typer(help="Plan management commands")
plan_app = typer.Typer(help="Plan operations (actor required)")
context_app = typer.Typer(help="Context management commands")
model_app = typer.Typer(help="Model management commands")
actor_app = typer.Typer(help="Actor management and defaults")
app.add_typer(plan_app, name="plan")
app.add_typer(context_app, name="context")
app.add_typer(model_app, name="model")
app.add_typer(actor_app, name="actor")
```
### Command Implementation
@@ -62,7 +62,7 @@ console = Console()
def create_plan(
name: str = Argument(..., help="Name of the plan"),
description: str = Option(None, "--desc", "-d", help="Plan description"),
model: str = Option("gpt-4", "--model", "-m", help="AI model to use"),
actor: str = Option(None, "--actor", "-a", help="Actor to use (defaults to the configured default actor)"),
context: Optional[List[Path]] = Option(None, "--context", "-c", help="Context files"),
interactive: bool = Option(True, "--interactive/--no-interactive", help="Interactive mode")
):
@@ -71,7 +71,7 @@ def create_plan(
args = PlanCreateArgs(
name=name,
description=description,
model=model,
actor=actor,
context=context or []
)
+13 -4
View File
@@ -21,11 +21,20 @@ See `docs/reference/env_variables.yaml` for the full catalog (including AWS/Vert
## Default selection logic
1. **Actor selection (required)** `agents tell/build --actor <name>` chooses the provider/model embedded in the actor config. If omitted, the default actor set via `agents actor set-default` is used; in test mode (`CLEVERAGENTS_TESTING_USE_MOCK_AI=true`), the mock actor is auto-provisioned.
2. **Actor configuration** provider/model come from the actors stored config blob; these replace earlier `--provider/--model` overrides.
3. **Settings defaults** `Settings.default_provider` / `Settings.default_model` still feed the registry for built-in actors, but the actor registry remains the source of truth.
4. **Auto fallback** when a built-in actor is requested and no model is specified, the registry uses its published default; built-ins are created from the fallback order `openai → anthropic → google → azure → openrouter → groq → together → cohere → gemini`.
2. **Actor lifecycle and naming** built-in actors are generated from the registry as `<provider>/<model>` and are immutable; custom actors must be named `local/<id>`, persist a canonical config blob + hash + graph_descriptor in the config DB, and the default actor (or any built-in) cannot be removed.
3. **Settings defaults** `Settings.default_provider` / `Settings.default_model` only seed the built-in actors. The actor registry is the source of truth once actors are created.
4. **Unsafe confirmation** actors marked unsafe must be added/updated with `--unsafe`; runtime surfaces warnings at verbosity ≥ warning but does not require `--unsafe` to invoke them.
5. **Auto fallback** when a built-in actor is requested and no model is specified, the registry uses its published default; built-ins are created from the fallback order `openai → anthropic → google → azure → openrouter → groq → together → cohere → gemini`.
The `agents diagnostics` command prints whether credentials were discovered along with the selected provider/model. Behave scenarios in `features/provider_registry_coverage.feature` cover every branch of this flow.
The `agents diagnostics` command prints whether credentials were discovered along with the selected actor. Behave scenarios in `features/provider_registry_coverage.feature` cover every branch of this flow.
## Actor CLI quick start
- `agents actor add --name local/<id> --config <path> [--unsafe] [--set-default]` stores the canonical actor blob (provider/model/options/graph_descriptor) and requires `--unsafe` when the config is marked unsafe.
- `agents actor update --name <actor> [--config <path>] [--unsafe|--safe] [--set-default] [--option key=value]` merges overrides into the stored blob; unsafe/safe are mutually exclusive.
- `agents actor set-default <name>` sets the default actor used when `--actor` is omitted; defaults cannot be removed.
- `agents actor list` / `agents actor show <name>` display built-in `<provider>/<model>` actors plus custom `local/<id>` entries with unsafe/default/built-in markers and config hashes.
- `agents actor remove local/<id>` removes only custom actors that are not the default; built-ins are immutable.
## OpenRouter header semantics
+12 -7
View File
@@ -664,6 +664,11 @@ All 10 ADRs have been created in `docs/architecture/decisions/`:
- Next action: refactor `plan`/`chat` command help and associated steps to require `--actor`, then update provider-model scenarios to actor equivalents prior to removing legacy flags.
- 2026-01-10: Plan CLI now enforces actor-only selection; provider/model overrides are removed from PlanService entry points, and default actor resolution fails unless a default is set or testing mode (`CLEVERAGENTS_TESTING_USE_MOCK_AI`) provisions the mock actor.
**2026-01-14: Actor help/docs aligned to actor-only surface and safety guards**
- Updated CLI help text to call out actor requirements, default resolution, built-in immutability, and unsafe confirmation (`src/cleveragents/cli/main.py:58-126`, `src/cleveragents/cli/commands/plan.py:28`, `src/cleveragents/cli/commands/actor.py:20`).
- Ported actor-focused doc guidance and CLI examples into provider/ADR references and README (`docs/reference/providers.md:21-37`, `docs/architecture/decisions/ADR-009-cli-framework.md:21-69`, `docs/architecture/decisions/ADR-008-provider-plugin-architecture.md:79-90`, `README.md:56-79`).
- Ran `nox -s unit_tests -- features/cli.feature features/core_cli_commands.feature features/actor_cli_coverage.feature` to verify help output and actor CLI flows after the documentation/help updates (all scenarios pass).
**2025-12-09: Provider streaming normalization + Behave coverage refresh**
- `PlanService.generate_plan_streaming` now consumes the new provider iterator contract, normalizes nested `__end__/response` payloads, validates streamed `Change` objects, persists token counts, and still emits the legacy CLI end event for compatibility (`src/cleveragents/application/services/plan_service.py:858`).
- `LangChainChatProvider.stream_changes` (plus both mock providers) now yield LangGraph workflow events followed by `{"__end__": {"response": ProviderResponse}}`, guaranteeing a consistent exit shape and structured usage logging (`src/cleveragents/providers/llm/langchain_chat_provider.py:154`, `features/mocks/langchain_mock_provider.py:269`, `features/mocks/mock_ai_provider.py:218`).
@@ -4467,14 +4472,14 @@ If you can do all of the above by end of Day 1, you're on track!
- [X] Update `chat`/`plan` and any other provider/model entry points to require `--actor` (remove `--model/--provider` flags and help text), honor `default_actor` when flag is omitted, retain git v2 tag's `run` flags (`--context`, `--load-context`, etc.) via `ContextService`, emit warnings at verbosity ≥ warning for unsafe actors (runtime does not require `--unsafe`), and allow built-in or custom actors as default. Ensure selection resolves to provider registry entries with per-model options forwarded and package-produced graph descriptors injected into execution, and reject raw provider/model usage in favor of actor names.
- [X] Merge CLI-supplied actor option overrides into canonical blobs without injecting provider/model metadata into options and only persist options when provided (`src/cleveragents/cli/commands/actor.py:65-189`, `src/cleveragents/actor/config.py:82-138`, `src/cleveragents/actor/registry.py:52-73`).
- [X] Wire actor options into graph/context invocation (package defaults + initial context variables), ensure graph execution receives merged options (package options → CLI overrides → defaults), and keep config hash/unsafe persistence semantics with audit timestamps intact.
- [ ] Port git `v2` tag API/CLI documentation relevant to actors/configuration into docs; scrub `--model/--provider` references and any `v2` naming; update CLI help/man pages and `agents --help` output to describe `--actor`, unsafe semantics, default resolution, and removal guards.
- [X] Port git `v2` tag API/CLI documentation relevant to actors/configuration into docs; scrub `--model/--provider` references and any `v2` naming; update CLI help/man pages and `agents --help` output to describe `--actor`, unsafe semantics, default resolution, and removal guards.
- [ ] Delete the temporary `./v2` reference directory once Stage 7.5 actor porting and documentation are complete (final cleanup step).
- [ ] Document:
- [ ] Update **Phase 2 Notes**, README, and docs (actor/CLI pages) with actor naming rules (`<provider>/<model>` built-ins, `local/<id>` customs), registry storage in config DB (blob + hash + unsafe + graph_descriptor + timestamps + default pointer), default selection behavior, unsafe semantics (`--unsafe`/`--safe` exclusivity), removal guard for defaults, built-in immutability, context flag parity with v2, and the requirement that actor config files remain in the exact v2 format (no new formats/routing).
- [ ] Document actor command examples for add/update/set-default/remove/list/show and chat/plan usage, including sample warnings for unsafe actors at verbosity ≥ warning, default resolution examples, failure cases (missing config, missing prefix, attempting to remove default, unsafe flag required), runtime not requiring `--unsafe`, and explicit statements that actor config files must conform to the v2 format without extensions or alternative schemas.
- [ ] Replace CLI help/man output and README/guide snippets to show actor-only flags, removing provider/model examples and legacy option mentions before finalizing the actor-first surface.
- [ ] Update architecture references/ADRs (ADR-008/ADR-011 or addenda) to capture actor registry boundaries, actor package responsibilities, dependency on provider registry + `ContextService`, default pointer storage, built-in immutability, and removal of `--model/--provider` in favor of `--actor`.
- [ ] Include migrated API documentation from git's v2 tag describing actor configuration fields, supported options, graph descriptor semantics, unsafe detection rules, and how actor package outputs map to provider/model selection and LangGraph invocation.
- [X] Document:
- [X] Update **Phase 2 Notes**, README, and docs (actor/CLI pages) with actor naming rules (`<provider>/<model>` built-ins, `local/<id>` customs), registry storage in config DB (blob + hash + unsafe + graph_descriptor + timestamps + default pointer), default selection behavior, unsafe semantics (`--unsafe`/`--safe` exclusivity), removal guard for defaults, built-in immutability, context flag parity with v2, and the requirement that actor config files remain in the exact v2 format (no new formats/routing).
- [X] Document actor command examples for add/update/set-default/remove/list/show and chat/plan usage, including sample warnings for unsafe actors at verbosity ≥ warning, default resolution examples, failure cases (missing config, missing prefix, attempting to remove default, unsafe flag required), runtime not requiring `--unsafe`, and explicit statements that actor config files must conform to the v2 format without extensions or alternative schemas.
- [X] Replace CLI help/man output and README/guide snippets to show actor-only flags, removing provider/model examples and legacy option mentions before finalizing the actor-first surface.
- [X] Update architecture references/ADRs (ADR-008/ADR-011 or addenda) to capture actor registry boundaries, actor package responsibilities, dependency on provider registry + `ContextService`, default pointer storage, built-in immutability, and removal of `--model/--provider` in favor of `--actor`.
- [X] Include migrated API documentation from git's v2 tag describing actor configuration fields, supported options, graph descriptor semantics, unsafe detection rules, and how actor package outputs map to provider/model selection and LangGraph invocation.
- [ ] Tests:
- [X] Add v2-format actor config parsing coverage (Behave + Robot) for YAML inference of provider/model/graph/options (format unchanged between v2 and v3).
- [ ] Port git v2's tag unit coverage into Behave features covering actor configuration parsing (valid/invalid blobs, option normalization), actor package outputs (graph_descriptor, provider/model requirements), unsafe detection, registry CRUD (hash stability, default guard, removal requiring `local/<id>`), built-in enumeration, default selection, warning emission at verbosity ≥ warning, and chat/plan flows with `--actor` plus context flags.
+8 -1
View File
@@ -17,7 +17,14 @@ from cleveragents.core.exceptions import (
)
from cleveragents.domain.models.core import Actor
app = typer.Typer(help="Manage actor configurations")
app = typer.Typer(
help=(
"Manage actor configurations. "
"Built-ins use <provider>/<model>; customs use local/<id>. "
"Default or built-in actors cannot be removed; "
"use --unsafe when configs are marked unsafe."
)
)
console = Console()
+6 -1
View File
@@ -25,7 +25,12 @@ if TYPE_CHECKING:
from cleveragents.domain.models.core import Change, Plan, Project
# Create sub-app for plan commands
app = typer.Typer(help="Plan management commands")
app = typer.Typer(
help=(
"Plan management commands (actor required; set default via "
"'agents actor set-default')"
)
)
console = Console()
+32 -6
View File
@@ -56,7 +56,12 @@ err_console = get_err_console()
# Create the main Typer app
app: Any = typer.Typer(
name="cleveragents",
help="AI-powered development assistant",
help=(
"AI-powered development assistant (actor-first). "
"Pass --actor <name> or set a default with 'agents actor set-default'. "
"Built-in actors use <provider>/<model>; custom actors use local/<id>. "
"Configs marked unsafe require --unsafe during add/update."
),
add_completion=True,
pretty_exceptions_enable=True,
pretty_exceptions_show_locals=False,
@@ -75,8 +80,22 @@ def _register_subcommands() -> None:
app.add_typer(project.app, name="project", help="Project management")
app.add_typer(context.app, name="context", help="Context management")
app.add_typer(plan.app, name="plan", help="Plan operations")
app.add_typer(actor.app, name="actor", help="Actor management")
app.add_typer(
plan.app,
name="plan",
help=(
"Plan operations (actor required; set default via "
"'agents actor set-default')"
),
)
app.add_typer(
actor.app,
name="actor",
help=(
"Actor management (built-ins <provider>/<model>; customs local/<id>; "
"unsafe requires --unsafe)"
),
)
app.add_typer(auto_debug_app, name="auto-debug", help="Auto-debug operations")
_subcommands_registered = True
@@ -93,19 +112,26 @@ cli = app
def _print_basic_help() -> None:
"""Print a lightweight help message without heavy imports."""
typer.echo("CleverAgents - AI-powered development assistant")
typer.echo("CleverAgents - AI-powered development assistant (actor-first)")
typer.echo("Usage: cleveragents [OPTIONS] COMMAND [ARGS]...")
typer.echo("\nCommon commands:")
typer.echo(" project Project management")
typer.echo(" context Context management")
typer.echo(" plan Plan operations")
typer.echo(" actor Actor management")
typer.echo(" plan Plan operations (actor required)")
typer.echo(" actor Actor management and defaults")
typer.echo(" init Initialize a project")
typer.echo(" tell Create a plan (shortcut)")
typer.echo(" build Build the current plan")
typer.echo(" apply Apply plan changes")
typer.echo(" auto-debug Auto-debug operations")
typer.echo(" version Show version")
typer.echo("")
typer.echo("Actors: set a default with 'agents actor set-default <name>'.")
typer.echo("Built-ins are <provider>/<model>; custom actors use local/<id>.")
typer.echo(
"Default or built-in actors cannot be removed; "
"use --unsafe when the config is marked unsafe."
)
def version_callback(value: bool) -> None: