forked from HAL9000/cleveragents-core
411bc3325f
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).
1041 lines
21 KiB
Markdown
1041 lines
21 KiB
Markdown
# 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](#actor-types)
|
|
- [Field Definitions](#field-definitions)
|
|
- [Tool Node Semantics](#tool-node-semantics)
|
|
- [Graph Constraints](#graph-constraints)
|
|
- [Validation Rules](#validation-rules)
|
|
- [Error Messages](#error-messages)
|
|
- [Examples](#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 name
|
|
- `type: llm`
|
|
- `model` - LLM model identifier (e.g., "gpt-4", "claude-3-opus")
|
|
|
|
**Optional Fields:**
|
|
- `system_prompt` - System prompt defining agent behavior
|
|
- `tools` - List of tool references or inline definitions
|
|
- `context_view` - Role-based context filtering
|
|
- `memory` - Conversation history settings
|
|
- `context` - File inclusion settings
|
|
|
|
**Example:**
|
|
```yaml
|
|
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 name
|
|
- `type: tool`
|
|
- `tools` - At least one tool (reference or inline definition)
|
|
|
|
**Optional Fields:**
|
|
- None (tools-only actors don't need LLM configuration)
|
|
|
|
**Example:**
|
|
```yaml
|
|
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 name
|
|
- `type: graph`
|
|
- `model` - LLM model for agent nodes
|
|
- `route` - Complete graph topology definition
|
|
|
|
**Optional Fields:**
|
|
- `system_prompt` - Default prompt for graph-level agents
|
|
- `tools` - Tools available to all agent nodes
|
|
- `context_view` - Context filtering for the entire graph
|
|
- `memory` - Memory settings for the graph
|
|
- `context` - Context settings
|
|
|
|
**Example:**
|
|
```yaml
|
|
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_reviewer`
|
|
- `workflows/test_driven_dev`
|
|
- `utilities/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:**
|
|
```yaml
|
|
tools:
|
|
- namespace/tool_name # Reference to existing tool
|
|
```
|
|
|
|
**Inline Tool Definition:**
|
|
```yaml
|
|
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 description
|
|
- `required` (bool, default=True): Whether parameter is required
|
|
- `default` (any, optional): Default value for optional parameters
|
|
|
|
**Example:**
|
|
```yaml
|
|
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 in `namespace/name` format
|
|
- `description` (str, required): What the tool does
|
|
- `parameters` (list, optional): List of ToolParameter objects
|
|
- `code` (str, required): Python code implementing the tool
|
|
|
|
**Validation:**
|
|
- Tool name must follow `namespace/name` format
|
|
- Code must be valid Python
|
|
- Parameter names must be valid identifiers
|
|
|
|
---
|
|
|
|
### Memory Configuration
|
|
|
|
#### MemoryConfig
|
|
|
|
**Fields:**
|
|
|
|
- `enabled` (bool, default=True): Enable conversation memory
|
|
- `max_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:**
|
|
```yaml
|
|
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 context
|
|
- `include_dirs` (list[str]): Directories to include in context
|
|
- `exclude_patterns` (list[str]): Glob patterns to exclude
|
|
- `max_context_tokens` (int, optional): Maximum context window size
|
|
|
|
**Example:**
|
|
```yaml
|
|
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:**
|
|
```yaml
|
|
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:**
|
|
|
|
1. Keep inline tools simple and focused
|
|
2. Include proper error handling
|
|
3. Add docstrings to the function
|
|
4. Use type hints for all parameters
|
|
5. Validate inputs before processing
|
|
|
|
**Example:**
|
|
```yaml
|
|
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 graph
|
|
- `edges` (list[EdgeDefinition], required): Connections between nodes
|
|
- `entry_node` (str, required): Starting node ID
|
|
- `exit_nodes` (list[str], required): Terminal node IDs
|
|
|
|
### Node Types
|
|
|
|
#### AGENT Node
|
|
|
|
**Type:** `agent`
|
|
**Purpose:** LLM-powered decision making and content generation
|
|
**Configuration:**
|
|
|
|
```yaml
|
|
- 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:**
|
|
|
|
```yaml
|
|
- 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:**
|
|
|
|
```yaml
|
|
- 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:**
|
|
|
|
```yaml
|
|
- 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 ID
|
|
- `to_node` (str, required): Target node ID
|
|
- `condition` (str, optional): Conditional routing expression
|
|
- `priority` (int, default=0): Edge priority (higher = evaluated first)
|
|
|
|
**Example:**
|
|
```yaml
|
|
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:**
|
|
```yaml
|
|
nodes:
|
|
- id: planner
|
|
- id: executor
|
|
- id: reviewer
|
|
```
|
|
|
|
**Invalid:**
|
|
```yaml
|
|
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:**
|
|
```yaml
|
|
nodes:
|
|
- id: start
|
|
- id: process
|
|
entry_node: start # ✅ 'start' exists
|
|
```
|
|
|
|
**Invalid:**
|
|
```yaml
|
|
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:**
|
|
```yaml
|
|
nodes:
|
|
- id: start
|
|
- id: end1
|
|
- id: end2
|
|
exit_nodes:
|
|
- end1
|
|
- end2
|
|
```
|
|
|
|
**Invalid:**
|
|
```yaml
|
|
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:**
|
|
```yaml
|
|
nodes:
|
|
- id: a
|
|
- id: b
|
|
edges:
|
|
- from_node: a
|
|
to_node: b
|
|
```
|
|
|
|
**Invalid:**
|
|
```yaml
|
|
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):**
|
|
```yaml
|
|
edges:
|
|
- from_node: a
|
|
to_node: b
|
|
- from_node: b
|
|
to_node: c
|
|
```
|
|
|
|
**Valid (Branching):**
|
|
```yaml
|
|
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):**
|
|
```yaml
|
|
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:**
|
|
```yaml
|
|
entry_node: start
|
|
edges:
|
|
- from_node: start
|
|
to_node: process
|
|
- from_node: process
|
|
to_node: end
|
|
```
|
|
|
|
**Invalid:**
|
|
```yaml
|
|
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:**
|
|
```yaml
|
|
name: code_reviewer # ❌ Missing namespace
|
|
```
|
|
|
|
**Error:**
|
|
```
|
|
ValueError: Actor name must be namespaced (namespace/name): code_reviewer
|
|
```
|
|
|
|
**Fix:**
|
|
```yaml
|
|
name: assistants/code_reviewer # ✅
|
|
```
|
|
|
|
#### TypeError: Missing Required Field
|
|
|
|
**Cause:** LLM or GRAPH actor missing `model` field
|
|
|
|
**Example:**
|
|
```yaml
|
|
name: assistants/helper
|
|
type: llm
|
|
# ❌ Missing model field
|
|
```
|
|
|
|
**Error:**
|
|
```
|
|
ValueError: LLM actors require 'model' field
|
|
```
|
|
|
|
**Fix:**
|
|
```yaml
|
|
name: assistants/helper
|
|
type: llm
|
|
model: gpt-4 # ✅
|
|
```
|
|
|
|
#### ValueError: Empty Tools List
|
|
|
|
**Cause:** TOOL actor with no tools defined
|
|
|
|
**Example:**
|
|
```yaml
|
|
name: utilities/helpers
|
|
type: tool
|
|
tools: [] # ❌ Empty list
|
|
```
|
|
|
|
**Error:**
|
|
```
|
|
ValueError: TOOL actors require at least one tool
|
|
```
|
|
|
|
**Fix:**
|
|
```yaml
|
|
name: utilities/helpers
|
|
type: tool
|
|
tools:
|
|
- files/read_file # ✅
|
|
```
|
|
|
|
#### ValueError: Missing Route
|
|
|
|
**Cause:** GRAPH actor without route definition
|
|
|
|
**Example:**
|
|
```yaml
|
|
name: workflows/process
|
|
type: graph
|
|
model: gpt-4
|
|
# ❌ Missing route field
|
|
```
|
|
|
|
**Error:**
|
|
```
|
|
ValueError: GRAPH actors require 'route' field
|
|
```
|
|
|
|
**Fix:**
|
|
```yaml
|
|
name: workflows/process
|
|
type: graph
|
|
model: gpt-4
|
|
route: # ✅
|
|
nodes: [...]
|
|
edges: [...]
|
|
entry_node: start
|
|
exit_nodes: [end]
|
|
```
|
|
|
|
---
|
|
|
|
## Examples
|
|
|
|
### Example 1: Simple LLM Actor
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```python
|
|
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
|
|
|
|
```python
|
|
# 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")
|
|
```
|
|
|
|
---
|
|
|
|
## See Also
|
|
|
|
- [ADR-010: Actor and Agent Architecture](../adr/ADR-010-actor-and-agent-architecture.md)
|
|
- [ADR-011: Tool System](../adr/ADR-011-tool-system.md)
|
|
- [Tool Schema Reference](../schema/tool.schema.yaml)
|
|
- [Action Schema Reference](../schema/action.schema.yaml)
|