# `cleveractors.actor` — Actor System The `actor` package provides the actor YAML configuration schema, loader, and compiler. Actors are the primary units parsed and compiled by this library — they encapsulate an LLM reference, a set of tool declarations, and a LangGraph execution graph. See [ADR-003](../adr/ADR-003-actor-abstraction-definition.md) for the actor abstraction definition and [ADR-001](../adr/ADR-001-library-boundary-and-extraction-scope.md) for the library boundary decisions. !!! note "Lazy imports" The `actor` package uses lazy imports to avoid pulling in heavy transitive dependencies (LangChain, LangSmith) when only lightweight submodules such as `role_validation` or `schema` are needed. --- ## `ActorConfigSchema` ```python from cleveractors.actor.schema import ActorConfigSchema ``` Pydantic model representing a fully-parsed actor YAML file. Key fields: | Field | Type | Description | |-------|------|-------------| | `name` | `str` | Actor identifier in `namespace/name` format | | `type` | `ActorType` | `llm`, `tool`, or `graph` | | `description` | `str` | Human-readable description | | `version` | `str` | Schema version (default `"1.0"`) | | `provider` | `str \| None` | LLM provider identifier (required for `llm`/`graph`; see ADR-005) | | `model` | `str \| None` | LLM model identifier (required for `llm`/`graph`) | | `system_prompt` | `str \| None` | System prompt; may contain Jinja2 templates | | `tools` | `list` | Tool references and inline tool definitions | | `route` | `RouteDefinition \| None` | Graph topology (required for `graph`) | | `memory` | `MemoryConfig \| None` | Conversation memory settings | | `context` | `ContextConfigSchema \| None` | File inclusion settings | | `context_view` | `ContextView \| None` | Role-based context filtering hint | | `skills` | `list[str]` | Skill references for capability acquisition | | `lsp` | `... \| None` | Actor-level LSP server bindings | See [Actor YAML Schema](../reference/actors_schema.md) for the full field reference. --- ## `ActorConfiguration` ```python from cleveractors.actor.config import ActorConfiguration ``` Pydantic model representing a fully-parsed actor YAML file with compiled graph configuration. Used internally by the compiler; surface-level consumers typically work with `ActorConfigSchema` and `CompiledActor`. | Field | Type | Description | |-------|------|-------------| | `name` | `str` | Actor identifier (namespaced) | | `entry_node` | `str` | Graph entry node name | | `nodes` | `dict[str, NodeConfig]` | Node definitions | | `edges` | `list[Edge]` | Graph edges | | `lsp_binding` | `LspBinding \| None` | Per-node LSP server binding | | `tool_sources` | `list[str]` | Tool source references | --- ## `ActorLoader` ```python from cleveractors.actor.loader import ActorLoader from pathlib import Path loader = ActorLoader( search_roots=[Path("./actors/")], tool_registry=my_tool_registry, # optional: ToolRegistryPort ) configs = loader.discover() ``` Discovers and loads actor YAML files from a directory tree. Validates graph reachability (all nodes reachable from `entry_node`) and reports YAML line/column positions on error. The optional `tool_registry` parameter accepts any object satisfying [`ToolRegistryPort`](../adr/ADR-002-tool-registry-protocol.md). Unknown tool references produce warnings rather than errors, so the loader degrades gracefully when running without a fully populated tool registry. ### Methods | Method | Description | |--------|-------------| | `discover()` | Scan all `search_roots` for actor YAML files; returns `list[ActorConfigSchema]` | | `load(path)` | Load and validate a single actor YAML file | | `validate(config)` | Validate an `ActorConfigSchema` without loading from disk | --- ## `compile_actor` / `CompiledActor` ```python from cleveractors.actor.compiler import compile_actor, CompiledActor compiled: CompiledActor = compile_actor(config) # or, with subgraph cycle detection: compiled = compile_actor(config, actor_resolver=my_registry.get) ``` Compiles an `ActorConfigSchema` into a `CompiledActor` by validating the graph, mapping nodes and edges to LangGraph data classes, and extracting LSP bindings. See [Actor Compiler](../reference/actor_compiler.md) for the full pipeline description. **Parameters:** - `config` — `ActorConfigSchema` (must be `ActorType.GRAPH`) - `actor_resolver` — Optional `(name: str) -> ActorConfigSchema | None` for cross-actor subgraph cycle detection **Returns:** `CompiledActor` ### `CompiledActor` | Field | Type | Description | |-------|------|-------------| | `name` | `str` | Actor name | | `nodes` | `dict[str, NodeConfig]` | LangGraph node configs | | `edges` | `list[Edge]` | LangGraph edges | | `entry_point` | `str` | Entry node ID | | `metadata` | `CompilationMetadata` | Diagnostic metadata | ### `CompilationMetadata` | Field | Type | Description | |-------|------|-------------| | `node_ids` | `list[str]` | All node IDs (sorted) | | `tool_nodes` | `list[str]` | Tool-type node IDs | | `lsp_bindings` | `list[LspBinding]` | Per-node LSP bindings | | `subgraph_refs` | `dict[str, str]` | Subgraph node → actor name | | `entry_node` | `str` | Entry point node ID | | `exit_nodes` | `list[str]` | Exit point node IDs | --- ## Compilation Errors ```python from cleveractors.actor import ( ActorCompilationError, MissingNodeError, InvalidEntryExitError, SubgraphCycleError, ) ``` | Exception | Description | |-----------|-------------| | `ActorCompilationError` | General compilation failure (base class) | | `MissingNodeError` | Edge or entry/exit references a node not in the graph | | `InvalidEntryExitError` | Entry or exit node configuration is invalid | | `SubgraphCycleError` | Cycle detected within the graph or across subgraph references | --- ## Extension Points (Ports) ```python from cleveractors.ports import ToolRegistryPort, ProviderRegistryPort ``` | Protocol | Used by | Purpose | |----------|---------|---------| | `ToolRegistryPort` | `ActorLoader` | Verify tool references at load time | | `ProviderRegistryPort` | `Node._execute_agent()` | Resolve `(provider, model)` to an `Agent` instance at execution time | See [ADR-002](../adr/ADR-002-tool-registry-protocol.md) and [ADR-005](../adr/ADR-005-provider-registry-protocol.md) for the design rationale behind each port. --- ## Supporting Types ### `LspBinding` ```python from cleveractors.lsp.models import LspBinding ``` Data class describing an LSP server binding extracted during compilation. Consumed by the host application to start the appropriate language server. ### `VocabularyRegistry` ```python from cleveractors.acms.uko import VocabularyRegistry ``` Registry of UKO (Universal Knowledge Ontology) vocabulary data used for context enrichment. Pure data; no I/O. ### `Agent` ```python from cleveractors.agents.base import Agent ``` Minimal abstract base class for LLM-backed agents. Host applications subclass `Agent` to wrap their concrete LangChain model instances and return them from `ProviderRegistryPort.get()`. ### Error Types ```python from cleveractors.core import ValidationError, NotFoundError ``` | Exception | Description | |-----------|-------------| | `ValidationError` | Schema or semantic validation failure | | `NotFoundError` | A named resource (actor, tool, skill) could not be found | --- ## Example: Loading and Compiling an Actor ```python from pathlib import Path from cleveractors.actor.loader import ActorLoader from cleveractors.actor.compiler import compile_actor from cleveractors.ports import ToolRegistryPort # Provide a tool registry (any object with .get(name) -> spec | None) loader = ActorLoader( search_roots=[Path("actors/")], tool_registry=my_tool_registry, # satisfies ToolRegistryPort ) for config in loader.discover(): compiled = compile_actor(config) # Hand compiled.nodes / compiled.edges to your LangGraph executor print(compiled.name, compiled.metadata.node_ids) ```