Replace the DB-persistence approach for built-in actors with in-memory virtual
resolution. Built-in actors (e.g. openai/gpt-4o, anthropic/claude-sonnet) are
now resolved on-demand from ProviderRegistry at query time and merged with
persisted custom actors — no database writes occur for built-in actors.
Key changes:
- Add ActorRegistry._resolve_virtual_builtin_actors(): generates virtual Actor
objects in-memory from configured providers (is_built_in=True, id=None)
- ActorRegistry.list()/list_actors(): merges virtual built-ins with custom DB
actors; custom actors win on name collision; result sorted alphabetically
- ActorRegistry.get()/get_actor(): DB-first, virtual built-in fallback,
NotFoundError if neither
- ActorRegistry.remove()/remove_actor(): rejects virtual built-in names with
ValidationError
- ActorRegistry.set_default_actor(): stores only the actor name string via new
actor_preferences singleton table; no actor row created for virtual built-ins
- ActorRegistry.get_default_actor(): reads preference name, resolves via
DB→virtual chain, returns actor with is_default=True
- Remove ensure_built_in_actors() entirely — 20+ call sites cleaned up including
plan.py
- Remove ActorRepository.upsert_built_in() — no longer needed
- Remove is_built_in from ActorModel DB column (kept on Actor domain model for
virtual actors)
- New Alembic migration m10_001_virtual_builtin_actors: drops is_built_in column,
adds actor_preferences singleton table
- Add ActorService.set_default_actor_name() and get_default_actor_name() for
preference storage without requiring a DB actor row
- Update 15+ Behave step files and 5 feature files; add new
features/virtual_builtin_actors.feature with 8 scenarios covering list, show,
remove, set-default, get-default, no-DB-writes guarantees
- Rewrite tests/actor/test_registry_builtin_yaml.py: TestEnsureBuiltInActorsWithYaml
→ TestResolveVirtualBuiltinActors plus new TestListActors, TestGetActor,
TestRemoveActor, TestDefaultActor test classes
Quality gates: lint ✓, typecheck ✓, unit_tests ✓ (15674 scenarios), coverage ✓
(97.10%), integration_tests ✓ (1997 tests)
ISSUES CLOSED: #10923
Route the 'agents actor add' CLI command through ActorRegistry.add() instead
of the legacy registry.upsert_actor() path. This ensures the original YAML
text, schema_version, and compiled_metadata are preserved in the database.
Changes:
- src/cleveragents/cli/commands/actor.py: Add _load_config_text() helper that
returns both raw text and parsed dict. Refactor add() to call registry.add()
with the raw yaml_text and update=update_existing flag when a registry is
available. The service fallback path (no registry) is unchanged.
- features/steps/actor_cli_steps.py: Update add command step definitions to
mock registry.add() instead of registry.upsert_actor(). Update 'the actor
add should pass the loaded config' assertion to verify registry.add() is
called with a non-empty yaml_text string.
- features/steps/actor_cli_yaml_steps.py: Update add command steps to mock
registry.add() instead of registry.upsert_actor().
- features/steps/actor_add_rich_output_steps.py: Update add command steps to
mock registry.add() instead of registry.upsert_actor().
- robot/helper_actor_add_rich_output.py: Update helper to mock registry.add()
instead of registry.upsert_actor().
- features/actor_add_yaml_first_path.feature: New Behave feature verifying
the YAML-first persistence path is used by actor add.
- features/steps/actor_add_yaml_first_path_steps.py: Step definitions for
the new YAML-first path feature.
- robot/actor_add_yaml_first_path.robot: New Robot integration tests verifying
yaml_text is preserved and upsert_actor is not called.
- robot/helper_actor_add_yaml_first_path.py: Helper script for Robot tests.
Fixes#3426
ISSUES CLOSED: #3426
Replaces hardcoded 0 values in the Impact panel of `agents actor remove` with real DB-backed counts for sessions, active plans, and actions referencing the removed actor.
ISSUES CLOSED: #3420
Co-authored-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
Co-committed-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
The spec (docs/reference/actor_cli.md) defines the synopsis for
`agents actor add` as:
agents actor add <NAME> --config <FILE> [--update] [--unsafe]
[--set-default] [--option key=value] [--format FORMAT]
The implementation was missing the required <NAME> positional argument,
silently reading the actor name from the config file's `name` field
instead. This deviates from the spec and breaks the expected CLI UX.
Changes:
- Add `name` as a required positional Argument to the `add` command
- Update docstring to match spec synopsis exactly
- The positional NAME takes precedence over any `name` field in config
- Remove the now-redundant config-file name validation (name comes from CLI)
- Add Behave BDD feature + steps for the NAME positional argument (TDD)
- Update all existing Behave step invocations to pass NAME positional arg
- Update Robot Framework helpers to pass NAME positional arg
ISSUES CLOSED: #2905
Remove the <NAME> positional argument from `actor add` command. The actor
name is now derived from the `name` field inside the config YAML file, per
the specification: `agents actor add (--config|-c) <FILE> [--update]`.
Updated all BDD and integration tests to pass name via config file.
ISSUES CLOSED: #914