fd6d41b371
CI / lint (pull_request) Successful in 14s
CI / typecheck (pull_request) Successful in 26s
CI / security (pull_request) Successful in 21s
CI / quality (pull_request) Successful in 16s
CI / integration_tests (pull_request) Successful in 4m15s
CI / build (pull_request) Successful in 16s
CI / unit_tests (pull_request) Successful in 7m41s
CI / docker (pull_request) Successful in 39s
CI / lint (push) Successful in 13s
CI / coverage (pull_request) Successful in 5m38s
CI / typecheck (push) Successful in 26s
CI / security (push) Successful in 22s
CI / quality (push) Successful in 15s
CI / integration_tests (push) Successful in 4m10s
CI / build (push) Successful in 15s
CI / unit_tests (push) Successful in 8m17s
CI / docker (push) Successful in 41s
CI / coverage (push) Successful in 5m30s
295 lines
12 KiB
Markdown
295 lines
12 KiB
Markdown
# Action Domain Model
|
|
|
|
The `Action` is a YAML-defined, reusable plan template in CleverAgents.
|
|
It specifies actors, typed arguments, completion criteria, and optional
|
|
invariants. Actions are project-agnostic until bound to one or more
|
|
projects via `agents plan use`, which instantiates a Plan in Strategize phase.
|
|
|
|
Actions are created via CLI with a required `--config` YAML file:
|
|
|
|
```
|
|
agents action create --config ./actions/code-coverage.yaml
|
|
```
|
|
|
|
## State Lifecycle
|
|
|
|
Actions have only two states with no draft phase:
|
|
|
|
| State | Description |
|
|
|-------------|--------------------------------------------------|
|
|
| AVAILABLE | Default state; action can be used to create plans |
|
|
| ARCHIVED | Action is retired and cannot create new plans |
|
|
|
|
There is no draft state. Actions are created directly in `available` state
|
|
from a validated YAML config file.
|
|
|
|
## Fields Reference
|
|
|
|
### Identity
|
|
|
|
| Field | Type | Required | Description |
|
|
|--------------------|------------------|----------|------------------------------------------|
|
|
| `namespaced_name` | `NamespacedName` | Yes | Unique identifier (`[server:][namespace/]<name>`) |
|
|
|
|
The namespaced name is the sole identity for an action -- there is no
|
|
separate ULID. This enables cross-server action references.
|
|
|
|
### Descriptions
|
|
|
|
| Field | Type | Required | Description |
|
|
|---------------------|--------------|----------|------------------------------------------|
|
|
| `description` | `str` | Yes | Short description (min 1 char) |
|
|
| `long_description` | `str \| None`| No | Detailed description for reusable actions|
|
|
| `definition_of_done`| `str` | Yes | Explicit, testable completion criteria |
|
|
|
|
### Actor References
|
|
|
|
| Field | Type | Required | Description |
|
|
|--------------------|---------------|----------|--------------------------------------|
|
|
| `strategy_actor` | `str` | Yes | Actor for the Strategize phase |
|
|
| `execution_actor` | `str` | Yes | Actor for the Execute phase |
|
|
| `review_actor` | `str \| None` | No | Actor for reviewing results |
|
|
| `apply_actor` | `str \| None` | No | Actor for the Apply phase |
|
|
| `estimation_actor` | `str \| None` | No | Actor for effort/cost estimation |
|
|
| `invariant_actor` | `str \| None` | No | Actor for invariant reconciliation |
|
|
|
|
`strategy_actor` and `execution_actor` are required. All actor fields accept
|
|
namespaced names.
|
|
|
|
### Behavior Flags
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------------|--------|---------|------------------------------------------|
|
|
| `reusable` | `bool` | `True` | If true, action remains available after use |
|
|
| `read_only` | `bool` | `False` | If true, action only performs read operations |
|
|
|
|
### Metadata
|
|
|
|
| Field | Type | Description |
|
|
|--------------|---------------|--------------------------------|
|
|
| `created_at` | `datetime` | Creation timestamp |
|
|
| `updated_at` | `datetime` | Last update timestamp |
|
|
| `created_by` | `str \| None` | User/session that created the action |
|
|
| `tags` | `list[str]` | Tags for organization |
|
|
|
|
## Arguments System
|
|
|
|
Actions accept typed arguments defined as `ActionArgument` instances.
|
|
Arguments are injected into description/definition-of-done templates and
|
|
passed into actor context. Users supply values via `--arg name=value`.
|
|
|
|
### ActionArgument Fields
|
|
|
|
| Field | Type | Default | Description |
|
|
|----------------------|-------------------------------|------------|--------------------------------------|
|
|
| `name` | `str` | -- | Valid Python identifier (1-64 chars) |
|
|
| `arg_type` | `ArgumentType` | `STRING` | Type of the argument |
|
|
| `requirement` | `ArgumentRequirement` | `REQUIRED` | Required or optional |
|
|
| `description` | `str` | `""` | Human-readable description (max 500) |
|
|
| `default_value` | `str\|int\|float\|bool\|list\|None` | `None` | Default for optional arguments |
|
|
| `validation_pattern` | `str \| None` | `None` | Regex pattern for string validation |
|
|
| `min_value` | `float \| None` | `None` | Minimum value for numeric arguments |
|
|
| `max_value` | `float \| None` | `None` | Maximum value for numeric arguments |
|
|
|
|
### Argument Types
|
|
|
|
| Type | Python Type | Description |
|
|
|-----------|-------------|------------------------|
|
|
| `string` | `str` | Text value |
|
|
| `integer` | `int` | Whole number |
|
|
| `float` | `float` | Decimal number |
|
|
| `boolean` | `bool` | True/false value |
|
|
| `list` | `list[str]` | Comma-separated values |
|
|
|
|
Legacy short names (`str`, `int`, `bool`) are accepted and mapped to their
|
|
full equivalents via `ArgumentType._missing_()`.
|
|
|
|
### Argument Requirement
|
|
|
|
| Value | Description |
|
|
|------------|--------------------------------------------|
|
|
| `required` | Must be provided when using the action |
|
|
| `optional` | May be omitted; default_value used if set |
|
|
|
|
### Parsing: CLI String Format
|
|
|
|
`ActionArgument.parse()` accepts colon-delimited strings:
|
|
|
|
```
|
|
name:type:required|optional[:description]
|
|
```
|
|
|
|
Examples:
|
|
|
|
```
|
|
target_coverage:integer:required:Target coverage percentage
|
|
test_framework:string:optional:Test framework to use
|
|
```
|
|
|
|
### Parsing: YAML Mapping
|
|
|
|
`ActionArgument.from_mapping()` builds an argument from a YAML dict:
|
|
|
|
```yaml
|
|
name: target_coverage
|
|
type: integer
|
|
required: true
|
|
description: Target coverage percentage
|
|
default: 80
|
|
min_value: 0
|
|
max_value: 100
|
|
```
|
|
|
|
The `required` key is a boolean (default `false`). The `type` key is
|
|
case-insensitive and supports legacy short names.
|
|
|
|
### Type Coercion: CLI Values
|
|
|
|
`ActionArgument.coerce_value(raw)` converts a raw CLI string to the
|
|
declared type:
|
|
|
|
| Type | Coercion Behavior |
|
|
|-----------|-----------------------------------------------------------|
|
|
| `string` | Returned as-is |
|
|
| `integer` | `int(raw)`; raises `ValueError` on failure |
|
|
| `float` | `float(raw)`; raises `ValueError` on failure |
|
|
| `boolean` | Truthy: `true`, `1`, `yes`, `on`. Falsy: `false`, `0`, `no`, `off` |
|
|
| `list` | Split on `,`, strip whitespace, drop empty items |
|
|
|
|
### Argument Validation
|
|
|
|
`Action.validate_arguments(provided_args)` checks provided values against
|
|
the action's argument schema and returns a list of error messages (empty
|
|
if valid). Checks performed:
|
|
|
|
1. Missing required arguments
|
|
2. Unknown argument names
|
|
3. Type mismatches (including `min_value`/`max_value` for integers)
|
|
|
|
Convenience properties:
|
|
|
|
- `action.required_arguments` -- list of arguments where requirement is `REQUIRED`
|
|
- `action.optional_arguments` -- list of arguments where requirement is `OPTIONAL`
|
|
|
|
## YAML-First Configuration
|
|
|
|
Actions are loaded from YAML config dicts via `Action.from_config(config)`.
|
|
|
|
### Required Config Keys
|
|
|
|
| Key | Description |
|
|
|---------------------|--------------------------------------|
|
|
| `name` | Namespaced name (parsed via `NamespacedName.parse()`) |
|
|
| `description` | Short description |
|
|
| `definition_of_done`| Completion criteria |
|
|
| `strategy_actor` | Strategize phase actor |
|
|
| `execution_actor` | Execute phase actor |
|
|
|
|
Missing any of these raises `ValueError`.
|
|
|
|
### Optional Config Keys
|
|
|
|
| Key | Default | Description |
|
|
|----------------------|---------------|------------------------------------|
|
|
| `long_description` | `None` | Detailed description |
|
|
| `review_actor` | `None` | Review actor |
|
|
| `apply_actor` | `None` | Apply phase actor |
|
|
| `estimation_actor` | `None` | Estimation actor |
|
|
| `invariant_actor` | `None` | Invariant reconciliation actor |
|
|
| `arguments` | `[]` | List of argument mappings |
|
|
| `inputs_schema` | `None` | JSON Schema dict |
|
|
| `reusable` | `True` | Whether action persists after use |
|
|
| `read_only` | `False` | Read-only mode |
|
|
| `state` | `"available"` | Initial state |
|
|
| `automation_profile` | `None` | Default automation profile name |
|
|
| `invariants` | `[]` | List of invariant strings |
|
|
| `tags` | `[]` | Organization tags |
|
|
| `created_by` | `None` | Creator identifier |
|
|
|
|
## Automation Profile
|
|
|
|
Actions can specify a default automation profile via the `automation_profile`
|
|
field. This is a namespaced name string resolved at plan-use time.
|
|
|
|
Cross-field validation trims the value and converts empty/whitespace-only
|
|
strings to `None`.
|
|
|
|
## Invariants
|
|
|
|
Actions carry a list of invariant constraint strings (`invariants: list[str]`).
|
|
When the action is used to create a plan, these are carried forward as
|
|
plan-level invariants with `ACTION` scope.
|
|
|
|
### Sanitization
|
|
|
|
The `invariants` field is sanitized on assignment via a Pydantic
|
|
`field_validator` (mode `"before"`):
|
|
|
|
1. **Trim** -- leading/trailing whitespace stripped from each entry
|
|
2. **Blank rejection** -- empty strings after trimming are dropped
|
|
3. **Deduplication** -- duplicate entries removed while preserving insertion order
|
|
4. **None coercion** -- `None` input is normalized to an empty list
|
|
|
|
## inputs_schema
|
|
|
|
An optional `dict[str, Any]` field for advanced input validation via
|
|
JSON Schema. Validated on assignment to ensure the value is a `dict`
|
|
(or `None`). This provides a schema-based alternative to the typed
|
|
`arguments` list for complex input structures.
|
|
|
|
## CLI Rendering
|
|
|
|
`Action.as_cli_dict()` returns a stable-ordered dict for deterministic
|
|
CLI output. Key ordering:
|
|
|
|
1. `name`, `description`, `state`
|
|
2. `strategy_actor`, `execution_actor`
|
|
3. `long_description` (if set)
|
|
4. `definition_of_done`
|
|
5. Optional actors: `review_actor`, `apply_actor`, `estimation_actor`, `invariant_actor` (if set)
|
|
6. `arguments` (if non-empty) -- each as `{name, type, required, description}`
|
|
7. `reusable`, `read_only`
|
|
8. `automation_profile` (if set), `invariants` (if non-empty)
|
|
9. `created_at`
|
|
10. `tags` (if non-empty)
|
|
|
|
## Templating
|
|
|
|
Actions support `${placeholder}` syntax (Python `string.Template`) for
|
|
injecting argument values into text fields.
|
|
|
|
### render_template(template_text, args)
|
|
|
|
Core method. Scans for `${name}` and `$name` placeholders, verifies all
|
|
are present in the `args` dict, and substitutes using `safe_substitute`.
|
|
Raises `ValueError` if any placeholder is missing from `args`.
|
|
|
|
### render_description(args)
|
|
|
|
Shorthand for `render_template(self.description, args)`.
|
|
|
|
### render_definition_of_done(args)
|
|
|
|
Shorthand for `render_template(self.definition_of_done, args)`.
|
|
|
|
### Example
|
|
|
|
Given an action with:
|
|
|
|
```yaml
|
|
description: "Increase test coverage to ${target_coverage}%"
|
|
definition_of_done: "All modules have >= ${target_coverage}% line coverage"
|
|
```
|
|
|
|
Calling `render_description({"target_coverage": "90"})` produces:
|
|
|
|
```
|
|
Increase test coverage to 90%
|
|
```
|
|
|
|
## Source Location
|
|
|
|
- Model: `src/cleveragents/domain/models/core/action.py`
|
|
- Plan model: `src/cleveragents/domain/models/core/plan.py`
|
|
- Plan lifecycle service: `src/cleveragents/application/services/plan_lifecycle_service.py`
|