Boundary fix: - Delete src/cleveractors/acms/index.py (ACMSIndex, FileTraversalEngine, IndexEntry, FileType, TierLevel) — these are CLI/storage concerns that belong in cleveragents-core per ADR-001; the file already exists there at cleveragents/acms/index.py - Clean src/cleveractors/acms/__init__.py: remove all index.py imports and re-exports; __all__ now derives purely from uko.__all__ ProviderRegistryPort (ADR-005): - Add src/cleveractors/ports/provider_registry.py: ProviderRegistryPort Protocol with get(provider, model) -> Agent | None; structural typing, no host imports, mirrors the shape of ToolRegistryPort - Update src/cleveractors/ports/__init__.py: export ProviderRegistryPort alongside ToolRegistryPort; update module docstring Wire provider resolution into the node executor: - compiler.py: _map_node now accepts actor_provider/actor_model defaults and merges them into AGENT node metadata (setdefault so per-node config values still win); compile_actor passes config.provider/config.model - nodes.py: Node.__init__ gains optional provider_registry parameter; _execute_agent resolution order is now: (1) pre-resolved agents dict, (2) ProviderRegistryPort.get(provider, model) from node metadata, (3) graceful synthetic fallback — the ValueError guard for missing config.agent is removed since the registry is a valid alternative path Documentation: - Port ADR-003 (actor abstraction definition) from cleveragents-core ADR-031 - Port ADR-004 (Jinja2 YAML template preprocessing) from cleveragents-core ADR-032 - Add ADR-005 (Provider Registry Protocol) for the new provider_registry port - Port five reference docs: actors_schema.md, actor_compiler.md, actor_config.md, actor_hierarchy.md, actors_examples.md - Port API reference: api/actor.md - Add provider field to all YAML examples in actors_examples.md, actor_hierarchy.md, and actor_config.md - Update error messages in actor_config.md to match actual validator output - Add graph-level provider/model propagation docs to actor_compiler.md - Add ADR-005 cross-references to ADR-001, ADR-002, and actors_schema.md - Fix ADR-005 status section to reflect that implementation is in this PR - Fix ADR-004 to reference actual test files (smoke.feature, not phantom ones) - Remove fabricated reserved-namespace constraint from ADR-003 Constraints - Fix broken LICENSE link in docs/index.md for MkDocs rendering - Add provider field to ActorConfigSchema table in api/actor.md - Add internal modules section to docs/specification.md (ticket item 7) - Fix markdown formatting in actors_schema.md provider field definition - Add ADR-005 cross-reference to actors_schema.md provider field section BDD coverage (7 scenarios, 30 steps): - ProviderRegistryPort happy-path resolution - Graceful fallback when provider registry returns None - Graceful fallback when no provider registry is supplied - Pre-resolved agents dict takes precedence over provider registry - Compile a minimal graph actor, reject missing provider, render template Post-review fixes applied in amend: - actors_examples.md and actor_hierarchy.md: added provider to all examples - ADR-003: removed fabricated reserved-namespace constraint - ADR-004: corrected phantom test file references - ADR-005: updated status to reflect implementation is included - Added 'no registry' and 'agents dict precedence' BDD scenarios - Added provider to api/actor.md ActorConfigSchema fields table - ADR-001 and ADR-002: added ADR-005 cross-references - actor_config.md: fixed error message to match validator - actor_compiler.md: documented graph-level provider/model propagation - index.md: fixed broken LICENSE link - actors_schema.md: added ADR-005 cross-reference ISSUES CLOSED: #4
7.4 KiB
Actor Configuration Reference
Practical guide to writing actor YAML configuration files with hierarchical graph examples and common error cases.
Module: cleveractors.actor.schema / cleveractors.actor.loader
Related references:
- Actor YAML Schema — full field listing
- Actor Hierarchy Extensions — LSP bindings and tool sources
- Actor Compiler — compilation pipeline and error types
Table of Contents
Basic Structure
Every actor YAML file must include name, type, and description.
The name must follow the namespace/identifier format.
name: local/my-actor # Required — namespaced
type: llm # Required — llm | tool | graph
description: What it does # Required
version: "1.0" # Optional
provider: openai # Required for llm and graph types
model: gpt-4 # Required for llm and graph types
Hierarchical Graph Example
A graph actor defines a multi-node workflow with conditional routing, per-node LSP bindings, and tool-source references.
name: workflows/dev-pipeline
type: graph
description: Multi-agent development pipeline
version: "1.0"
provider: openai
model: gpt-4
# Actor-level skill and LSP declarations
skills:
- local/file-ops
- local/git-ops
lsp:
- local/pyright
route:
nodes:
- id: planner
type: agent
name: Planner
description: Plans the implementation strategy
config:
model: gpt-4
prompt: "Analyze requirements and create a plan."
# Per-node LSP binding (overrides actor-level default)
lsp_binding:
server: local/pyright
languages:
- python
capabilities:
- diagnostics
# Per-node tool sources
tool_sources:
- type: skill
name: local/file-ops
- id: implementer
type: agent
name: Implementer
description: Implements the plan
config:
model: gpt-4
prompt: "Implement the changes per the plan."
lsp_binding:
auto: true
tool_sources:
- type: skill
name: local/file-ops
- type: skill
name: local/git-ops
- type: mcp
name: local/filesystem
- id: reviewer
type: subgraph
name: Code Reviewer
description: Delegates to the code-review actor
actor_ref: local/code-reviewer # namespaced reference to another actor
- id: gate
type: conditional
name: Quality Gate
description: Routes to reviewer or re-plans based on lint result
config:
conditions:
- check: "state.get('lint_ok') == True"
route_to: reviewer
- check: "state.get('lint_ok') == False"
route_to: planner
edges:
- from_node: planner
to_node: implementer
- from_node: implementer
to_node: gate
- from_node: gate
to_node: planner # explicit back-edge for retry path
- from_node: gate
to_node: reviewer
entry_node: planner
exit_nodes:
- reviewer
Node Types
| Type | Purpose | Key config fields |
|---|---|---|
agent |
LLM-driven reasoning node | provider, model, prompt, tools |
tool |
Runs a specific tool call | tool_name, parameters |
conditional |
Routes to different nodes based on state | conditions[].check, conditions[].route_to |
subgraph |
Delegates to another actor entirely | actor_ref |
Conditional Node Routing
Conditional nodes use Python expressions over state to route the workflow.
The route_to targets are counted as reachable even without explicit edges.
- id: branch
type: conditional
name: Branch
description: Decides next step
config:
conditions:
- check: "state.get('success') == True"
route_to: done
- check: "state.get('success') == False"
route_to: retry
Subgraph Node
Subgraph nodes delegate execution to another actor by namespaced name.
Use actor_ref (not config.actor_path).
- id: review_step
type: subgraph
name: Review
description: Runs the review sub-workflow
actor_ref: local/reviewer # correct: namespaced actor reference
Graph Topology Rules
The loader enforces these constraints on every graph actor:
| Rule | Error trigger |
|---|---|
| Unique node IDs | Two nodes share the same id |
| Entry node exists | entry_node references an id not in nodes |
| Exit nodes exist | Any exit_nodes entry references a missing id |
| Edge targets exist | from_node or to_node reference a missing id |
| Nodes are reachable | A node has no path from entry_node via edges or conditional routing |
| No cycles | A non-conditional cycle exists in the edge graph |
Error Cases
Naming Errors
Actor name missing namespace:
name: my-actor # wrong — must be namespace/name
Error: Actor name must be namespaced (namespace/name): my-actor
Fix: use a namespaced name like local/my-actor or workflows/my-actor.
LLM Actor Without Model
name: local/my-actor
type: llm
description: Assistant
# model: missing
Error: LLM actors require 'model' field
LLM/GRAPH Actor Without Provider
name: local/my-actor
type: llm
description: Assistant
model: gpt-4
# provider: missing
Error: LLM and GRAPH actors require 'provider' field
GRAPH Actor Without Route
name: local/pipeline
type: graph
description: Pipeline
provider: openai
model: gpt-4
# route: missing
Error: GRAPH actors require 'route' field
Duplicate Node IDs
nodes:
- id: step_a
...
- id: step_a # duplicate
...
Error: Duplicate node IDs: 'step_a'
Fix: give each node a unique id.
Missing Entry Node
route:
nodes:
- id: node_a
...
entry_node: node_x # node_x does not exist
Error: Entry node 'node_x' not found in route.entry_node
Invalid Edge Target
edges:
- from_node: node_a
to_node: node_z # node_z does not exist
Error: Edge to_node 'node_z' not found at route.edges[0]
Unreachable Node
nodes:
- id: node_a
- id: node_b
- id: node_c # no edge or conditional route_to points here
edges:
- from_node: node_a
to_node: node_b
entry_node: node_a
Error: route: nodes 'node_c' are unreachable from entry node 'node_a'
Fix: add an edge from a reachable node to node_c, or remove node_c from
nodes if it is not needed.
YAML Parse Error
A malformed YAML file produces a parse error with the location:
Invalid YAML in bad.yaml at line 3, column 5: mapping values are not allowed here
Fix: check the indicated line and correct the YAML syntax.
Schema Validation Error Format
When a YAML file is syntactically valid but fails schema validation, the loader reports precise field paths:
Schema validation failed for actor.yaml:
type: Input should be 'llm', 'tool' or 'graph'
route.nodes.0.id: String should match pattern '^[a-zA-Z0-9_-]+$'
Hint: see docs/reference/actor_config.md for the correct schema format.
Each line shows the dotted field path and the validation message.