# Actor Compiler The actor compiler translates hierarchical YAML-defined GRAPH actors into LangGraph `StateGraph` node/edge structures that can be executed by the CleverAgents runtime. ## Compilation Pipeline 1. **Input validation** — The compiler accepts an `ActorConfigSchema` with `type=GRAPH` and a populated `route` field. Non-GRAPH types are rejected with `ActorCompilationError`. 2. **Reference validation** — All node IDs referenced in edges, entry, and exit points are checked against the declared node set. 3. **Intra-graph cycle detection** — The route's `detect_cycles()` method verifies the node graph is acyclic. 4. **Cross-actor subgraph cycle detection** — When an optional `actor_resolver` is provided, the compiler follows `SUBGRAPH` node references recursively and detects cycles across actor boundaries (e.g. actor A → actor B → actor A). 5. **Node mapping** — Each `NodeDefinition` is mapped to a LangGraph `NodeConfig` with the appropriate `NodeType` (AGENT, TOOL, CONDITIONAL, SUBGRAPH). 6. **Edge mapping** — Each `EdgeDefinition` is mapped to a LangGraph `Edge`. Conditional expressions are preserved in `edge.condition`. 7. **LSP binding extraction** — Per-node `lsp_bindings` config entries are extracted into `LspBinding` objects and stored in compilation metadata. 8. **Metadata assembly** — The compiler returns a `CompiledActor` containing the node map, edge list, entry point, and a `CompilationMetadata` object for diagnostics and CLI inspection. ## Node Binding | Actor Node Type | LangGraph NodeType | Notes | |---|---|---| | `agent` | `AGENT` | LLM invocation node | | `tool` | `TOOL` | Tool execution node | | `conditional` | `CONDITIONAL` | Routing node | | `subgraph` | `SUBGRAPH` | Nested actor reference | LSP bindings are declared per-node in the `config.lsp_bindings` list: ```yaml nodes: - id: coder type: agent name: Code Writer description: Writes Python code config: agent: coder_agent lsp_bindings: - lsp_server_name: local/pyright languages: [python] auto_detect: true ``` ## Error Modes | Error | Class | When | |---|---|---| | Non-GRAPH type | `ActorCompilationError` | `config.type != GRAPH` | | Missing route | `ActorCompilationError` | `config.route is None` | | Missing node | `MissingNodeError` | Edge references unknown node | | Invalid entry/exit | `InvalidEntryExitError` | Entry/exit node not in graph | | Intra-graph cycle | `SubgraphCycleError` | Nodes form a cycle | | Cross-actor cycle | `SubgraphCycleError` | Subgraph refs form a cycle | ## API Reference ### `compile_actor(config, *, actor_resolver=None) -> CompiledActor` Compile an `ActorConfigSchema` into a LangGraph-ready bundle. **Parameters:** - `config` — The actor configuration (must be `ActorType.GRAPH`). - `actor_resolver` — Optional callable `(name: str) -> ActorConfigSchema | None` for resolving subgraph references. **Returns:** `CompiledActor` with nodes, edges, and metadata. ### `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 |