Add complete reference documentation for actor YAML schema: Documentation Sections: - Actor types overview (LLM, TOOL, GRAPH) - Complete field definitions for all models - Tool node semantics (references vs inline definitions) - Graph constraints and topology rules - Comprehensive validation rules with examples - Error messages with causes and fixes Field Definitions: - Top-level actor fields (name, type, model, etc.) - ToolParameter and ToolDefinition fields - MemoryConfig and ContextConfigSchema fields - ContextView enum (strategist, executor, reviewer, full) Graph Documentation: - Node types (AGENT, TOOL, CONDITIONAL, SUBGRAPH) - Edge definition and conditional routing - RouteDefinition structure - Cycle detection explanation Validation Rules: 1. Unique node IDs 2. Entry node existence 3. Exit nodes existence 4. Edge reference validity 5. Acyclic graph requirement 6. Node reachability Examples: - Simple LLM actor - LLM with inline tools - Simple graph workflow - Complex graph with conditionals - Error examples with fixes Part 6 of C1.schema implementation (Actor YAML Schema Models).
21 KiB
Actor YAML Schema Reference
Overview
Actors are the v3 replacement for v2's reactive stream configurations, providing a simpler, more declarative way to define AI agent behaviors. An actor defines what an agent can do, how it processes information, and how it interacts with tools and other actors.
Module: cleveragents.actor.schema
Schema Version: 1.0
Table of Contents
- Actor Types
- Field Definitions
- Tool Node Semantics
- Graph Constraints
- Validation Rules
- Error Messages
- Examples
Actor Types
Actors come in three types, each serving different purposes:
LLM Actor
Type: llm
Purpose: Single LLM agent with system prompt and optional tools
Use Case: Simple conversational agents, code reviewers, assistants
Required Fields:
name- Namespaced actor nametype: llmmodel- LLM model identifier (e.g., "gpt-4", "claude-3-opus")
Optional Fields:
system_prompt- System prompt defining agent behaviortools- List of tool references or inline definitionscontext_view- Role-based context filteringmemory- Conversation history settingscontext- File inclusion settings
Example:
name: assistants/code_reviewer
type: llm
model: gpt-4
system_prompt: "You are an expert code reviewer..."
TOOL Actor
Type: tool
Purpose: Collection of callable tools without LLM interaction
Use Case: Utility tool bundles, shared tool libraries
Required Fields:
name- Namespaced actor nametype: tooltools- At least one tool (reference or inline definition)
Optional Fields:
- None (tools-only actors don't need LLM configuration)
Example:
name: utilities/file_ops
type: tool
tools:
- files/read_file
- files/write_file
GRAPH Actor
Type: graph
Purpose: Multi-node workflow with conditional routing
Use Case: Complex workflows, multi-step processes, agentic loops
Required Fields:
name- Namespaced actor nametype: graphmodel- LLM model for agent nodesroute- Complete graph topology definition
Optional Fields:
system_prompt- Default prompt for graph-level agentstools- Tools available to all agent nodescontext_view- Context filtering for the entire graphmemory- Memory settings for the graphcontext- Context settings
Example:
name: workflows/test_driven_dev
type: graph
model: gpt-4
route:
nodes: [...]
edges: [...]
entry_node: planner
exit_nodes: [review]
Field Definitions
Top-Level Fields
name (required)
Type: str
Format: namespace/actor_name
Description: Unique identifier for the actor in namespaced format
Validation:
- Must contain exactly one forward slash (
/) - Namespace and name must not be empty
- Should use snake_case for both parts
Valid:
assistants/code_reviewerworkflows/test_driven_devutilities/file_operations
Invalid:
code_reviewer(missing namespace)assistants/code/reviewer(too many slashes)assistants/(empty name)
type (required)
Type: ActorType enum
Values: llm, tool, graph
Description: Determines actor execution behavior and compilation target
description (required)
Type: str
Description: Human-readable description of what the actor does
Best Practices:
- Start with a verb ("Reviews code...", "Processes documents...")
- Keep under 200 characters
- Be specific about the actor's purpose
version (optional)
Type: str
Default: "1.0"
Description: Schema version for backward compatibility
model (conditional)
Type: str
Required for: llm, graph actors
Optional for: tool actors (not used)
Description: LLM model identifier
Common Values:
- OpenAI:
gpt-4,gpt-4-turbo,gpt-3.5-turbo - Anthropic:
claude-3-opus,claude-3-sonnet,claude-3-haiku - Open source:
mistral-large,llama-3-70b
system_prompt (optional)
Type: str
Description: System prompt defining agent behavior and guidelines
Best Practices:
- Use multi-line YAML strings (
|) for readability - Include role definition ("You are an expert...")
- List specific tasks and constraints
- Provide output format guidance
tools (optional/required)
Type: list[str | ToolDefinition]
Required for: tool actors
Optional for: llm, graph actors
Description: Tools available to the actor
Tool Reference Format:
tools:
- namespace/tool_name # Reference to existing tool
Inline Tool Definition:
tools:
- name: utils/count_lines
description: Count lines in a file
parameters:
- name: file_path
type: str
required: true
code: |
def count_lines(file_path: str) -> int:
with open(file_path, 'r') as f:
return len(f.readlines())
Tool Definition Fields
ToolParameter
Fields:
name(str, required): Parameter name (must be valid Python identifier)type(str, required): Python type annotation (e.g.,str,int,list[str])description(str, required): Parameter descriptionrequired(bool, default=True): Whether parameter is requireddefault(any, optional): Default value for optional parameters
Example:
parameters:
- name: input_file
type: str
description: Path to input file
required: true
- name: encoding
type: str
description: File encoding
required: false
default: utf-8
ToolDefinition
Fields:
name(str, required): Tool name innamespace/nameformatdescription(str, required): What the tool doesparameters(list, optional): List of ToolParameter objectscode(str, required): Python code implementing the tool
Validation:
- Tool name must follow
namespace/nameformat - Code must be valid Python
- Parameter names must be valid identifiers
Memory Configuration
MemoryConfig
Fields:
enabled(bool, default=True): Enable conversation memorymax_messages(int, optional): Maximum messages to retain (None = unlimited)max_tokens(int, optional): Maximum tokens in history (None = unlimited)summarize_old(bool, default=False): Summarize old messages to save tokens
Example:
memory:
enabled: true
max_messages: 50
max_tokens: 4000
summarize_old: false
Use Cases:
- Short conversations:
max_messages: 10-20 - Medium conversations:
max_messages: 50,max_tokens: 4000-8000 - Long workflows:
summarize_old: true,max_tokens: 16000
Context Configuration
ContextConfigSchema
Fields:
include_files(list[str]): Specific files to include in contextinclude_dirs(list[str]): Directories to include in contextexclude_patterns(list[str]): Glob patterns to excludemax_context_tokens(int, optional): Maximum context window size
Example:
context:
include_files:
- README.md
- pyproject.toml
include_dirs:
- src/
- tests/
exclude_patterns:
- "**/__pycache__/**"
- "*.pyc"
- "**/.git/**"
max_context_tokens: 8000
ContextView
Type: enum
Values: strategist, executor, reviewer, full
Description: Role-based context filtering
Context Views:
-
strategist: High-level planning view
- Project structure
- Goals and constraints
- Architecture decisions
- No implementation details
-
executor: Implementation view
- Source code
- File contents
- Specific tasks
- Implementation details
-
reviewer: Validation view
- Changes and diffs
- Test results
- Code quality metrics
- Review feedback
-
full: Complete view (use sparingly)
- All available context
- Can exceed token limits
- Only for critical decision points
Tool Node Semantics
Tool References
Tool references point to existing tools in the tool registry. Use references when:
- The tool is shared across multiple actors
- The tool is complex and tested separately
- The tool requires specific dependencies
Format: namespace/tool_name
Example:
tools:
- files/read_file
- testing/run_pytest
- analysis/extract_entities
Inline Tool Definitions
Inline tools are defined directly in the actor YAML. Use inline tools when:
- The tool is actor-specific
- The tool is simple (< 50 lines of code)
- The tool doesn't require external dependencies
Best Practices:
- Keep inline tools simple and focused
- Include proper error handling
- Add docstrings to the function
- Use type hints for all parameters
- Validate inputs before processing
Example:
tools:
- name: utils/count_words
description: Count words in a text file
parameters:
- name: file_path
type: str
description: Path to text file
required: true
code: |
def count_words(file_path: str) -> dict:
"""Count words in a file and return statistics."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
words = content.split()
return {
"word_count": len(words),
"char_count": len(content),
"line_count": content.count('\n') + 1
}
except FileNotFoundError:
return {"error": f"File not found: {file_path}"}
except Exception as e:
return {"error": str(e)}
Graph Constraints
Graph Topology
A graph actor's route field defines the complete workflow topology.
RouteDefinition
Fields:
nodes(list[NodeDefinition], required): All nodes in the graphedges(list[EdgeDefinition], required): Connections between nodesentry_node(str, required): Starting node IDexit_nodes(list[str], required): Terminal node IDs
Node Types
AGENT Node
Type: agent
Purpose: LLM-powered decision making and content generation
Configuration:
- id: planner
type: agent
name: Task Planner
description: Plans tasks based on requirements
config:
model: gpt-4 # Can override graph-level model
prompt: "You are a task planning expert..."
tools:
- files/read_file
- analysis/extract_requirements
TOOL Node
Type: tool
Purpose: Execute specific tools or functions
Configuration:
- id: run_tests
type: tool
name: Test Runner
description: Executes pytest test suite
config:
tool_name: testing/run_pytest
parameters:
verbose: true
coverage: true
CONDITIONAL Node
Type: conditional
Purpose: Route execution based on conditions
Configuration:
- id: check_results
type: conditional
name: Result Checker
description: Routes based on test results
config:
conditions:
- check: "state.get('tests_passed') == True"
route_to: code_review
- check: "state.get('tests_passed') == False"
route_to: fix_errors
Conditional Expressions:
- Access state with
state.get('key') - Use Python comparison operators (
==,!=,<,>,<=,>=) - Combine with boolean operators (
and,or,not) - Conditions are evaluated in order; first match wins
SUBGRAPH Node
Type: subgraph
Purpose: Embed another actor as a nested workflow
Configuration:
- id: code_review
type: subgraph
name: Code Reviewer
description: Runs full code review workflow
config:
actor_path: actors/code_reviewer.yaml
Subgraph Rules:
- Subgraph actors can be of any type (llm, tool, graph)
- State is passed to and from the subgraph
- Subgraphs enable workflow composition and reuse
- Maximum nesting depth: 5 levels
Edge Definition
Fields:
from_node(str, required): Source node IDto_node(str, required): Target node IDcondition(str, optional): Conditional routing expressionpriority(int, default=0): Edge priority (higher = evaluated first)
Example:
edges:
# Unconditional edge
- from_node: planner
to_node: executor
# Conditional edge
- from_node: executor
to_node: retry
condition: "state.get('retry_count', 0) < 3"
priority: 10
# Default edge (lower priority)
- from_node: executor
to_node: escalate
priority: 1
Validation Rules
Graph Validation
The schema automatically validates graph topology when loading YAML files.
1. Unique Node IDs
Rule: All node IDs must be unique within a graph.
Valid:
nodes:
- id: planner
- id: executor
- id: reviewer
Invalid:
nodes:
- id: planner
- id: executor
- id: planner # ❌ Duplicate ID
Error:
ValueError: Duplicate node IDs found: {'planner'}
2. Entry Node Exists
Rule: The entry_node must reference a valid node ID.
Valid:
nodes:
- id: start
- id: process
entry_node: start # ✅ 'start' exists
Invalid:
nodes:
- id: start
- id: process
entry_node: init # ❌ 'init' doesn't exist
Error:
ValueError: Entry node 'init' not found in nodes
3. Exit Nodes Exist
Rule: All exit_nodes must reference valid node IDs.
Valid:
nodes:
- id: start
- id: end1
- id: end2
exit_nodes:
- end1
- end2
Invalid:
nodes:
- id: start
- id: end1
exit_nodes:
- end1
- finish # ❌ 'finish' doesn't exist
Error:
ValueError: Exit node 'finish' not found in nodes
4. Edge References Valid
Rule: All edge from_node and to_node must reference valid node IDs.
Valid:
nodes:
- id: a
- id: b
edges:
- from_node: a
to_node: b
Invalid:
nodes:
- id: a
- id: b
edges:
- from_node: a
to_node: c # ❌ 'c' doesn't exist
Error:
ValueError: Edge to_node 'c' not found in nodes
5. No Cycles
Rule: Graphs must be acyclic (no circular dependencies).
Valid (Linear):
edges:
- from_node: a
to_node: b
- from_node: b
to_node: c
Valid (Branching):
edges:
- from_node: a
to_node: b
- from_node: a
to_node: c
- from_node: b
to_node: d
- from_node: c
to_node: d
Invalid (Cycle):
edges:
- from_node: a
to_node: b
- from_node: b
to_node: c
- from_node: c
to_node: a # ❌ Cycle: a → b → c → a
Error:
ValueError: Graph contains cycles involving nodes: ['a']
Note: Conditional edges with retry logic can appear cyclic but are validated at runtime.
6. All Nodes Reachable
Rule: All nodes must be reachable from the entry node.
Valid:
entry_node: start
edges:
- from_node: start
to_node: process
- from_node: process
to_node: end
Invalid:
entry_node: start
nodes:
- id: start
- id: process
- id: orphan # ❌ Not reachable from 'start'
edges:
- from_node: start
to_node: process
Error:
ValueError: Unreachable nodes detected: {'orphan'}
Error Messages
Common Validation Errors
NameError: Invalid Actor Name
Cause: Actor name doesn't follow namespace/name format
Example:
name: code_reviewer # ❌ Missing namespace
Error:
ValueError: Actor name must be namespaced (namespace/name): code_reviewer
Fix:
name: assistants/code_reviewer # ✅
TypeError: Missing Required Field
Cause: LLM or GRAPH actor missing model field
Example:
name: assistants/helper
type: llm
# ❌ Missing model field
Error:
ValueError: LLM actors require 'model' field
Fix:
name: assistants/helper
type: llm
model: gpt-4 # ✅
ValueError: Empty Tools List
Cause: TOOL actor with no tools defined
Example:
name: utilities/helpers
type: tool
tools: [] # ❌ Empty list
Error:
ValueError: TOOL actors require at least one tool
Fix:
name: utilities/helpers
type: tool
tools:
- files/read_file # ✅
ValueError: Missing Route
Cause: GRAPH actor without route definition
Example:
name: workflows/process
type: graph
model: gpt-4
# ❌ Missing route field
Error:
ValueError: GRAPH actors require 'route' field
Fix:
name: workflows/process
type: graph
model: gpt-4
route: # ✅
nodes: [...]
edges: [...]
entry_node: start
exit_nodes: [end]
Examples
Example 1: Simple LLM Actor
name: assistants/code_reviewer
type: llm
description: Reviews Python code for best practices
version: "1.0"
model: gpt-4
system_prompt: |
You are an expert Python code reviewer.
Review code for:
- PEP 8 compliance
- Design patterns
- Potential bugs
- Performance issues
context_view: reviewer
memory:
enabled: true
max_messages: 20
Example 2: LLM with Inline Tools
name: assistants/file_analyzer
type: llm
description: Analyzes files and generates reports
version: "1.0"
model: gpt-4-turbo
system_prompt: "Analyze files and provide insights..."
tools:
- files/read_file # Tool reference
- name: utils/count_lines # Inline tool
description: Count lines in a file
parameters:
- name: file_path
type: str
required: true
code: |
def count_lines(file_path: str) -> int:
with open(file_path, 'r') as f:
return len(f.readlines())
Example 3: Simple Graph Workflow
name: workflows/doc_processor
type: graph
description: Processes documents through multiple stages
version: "1.0"
model: gpt-3.5-turbo
route:
nodes:
- id: extract
type: tool
name: Text Extractor
description: Extracts text from documents
config:
tool_name: documents/extract_text
- id: analyze
type: agent
name: Analyzer
description: Analyzes content
config:
model: gpt-3.5-turbo
prompt: "Analyze the document content..."
- id: summarize
type: agent
name: Summarizer
description: Creates summary
config:
model: gpt-3.5-turbo
prompt: "Summarize in 3-5 bullet points..."
edges:
- from_node: extract
to_node: analyze
- from_node: analyze
to_node: summarize
entry_node: extract
exit_nodes:
- summarize
Example 4: Complex Graph with Conditionals
name: workflows/ci_pipeline
type: graph
description: CI/CD pipeline with test and deploy stages
version: "1.0"
model: gpt-4
route:
nodes:
- id: build
type: tool
name: Builder
description: Builds the project
config:
tool_name: ci/build
- id: test
type: tool
name: Test Runner
description: Runs test suite
config:
tool_name: ci/run_tests
- id: check_tests
type: conditional
name: Test Result Checker
description: Check if tests passed
config:
conditions:
- check: "state.get('tests_passed') == True"
route_to: deploy
- check: "state.get('tests_passed') == False"
route_to: notify_failure
- id: deploy
type: tool
name: Deployer
description: Deploys to production
config:
tool_name: ci/deploy
- id: notify_failure
type: tool
name: Notifier
description: Sends failure notification
config:
tool_name: notifications/send_alert
edges:
- from_node: build
to_node: test
- from_node: test
to_node: check_tests
# Conditional routing handled by check_tests node
entry_node: build
exit_nodes:
- deploy
- notify_failure
Usage
Loading Actor Configuration
from cleveragents.actor.schema import ActorConfigSchema
# Load from YAML file
actor = ActorConfigSchema.from_yaml_file("actors/code_reviewer.yaml")
# Access fields
print(actor.name) # assistants/code_reviewer
print(actor.type) # ActorType.LLM
print(actor.model) # gpt-4
# Validate graph (automatic on load)
if actor.type == ActorType.GRAPH:
# Validation already done:
# - All nodes have unique IDs
# - Entry/exit nodes exist
# - All edges reference valid nodes
# - No cycles detected
# - All nodes reachable
pass
Saving Actor Configuration
# Create actor programmatically
actor = ActorConfigSchema(
name="assistants/helper",
type=ActorType.LLM,
description="A helpful assistant",
model="gpt-4",
system_prompt="You are a helpful assistant."
)
# Save to YAML file
actor.to_yaml_file("actors/helper.yaml")