Files
cleveractors-core/docs/reference/actor_hierarchy.md
hurui200320 15e81e58f1
CI / dead_code (pull_request) Successful in 40s
CI / security (pull_request) Successful in 1m10s
CI / coverage (pull_request) Successful in 1m11s
CI / typecheck (pull_request) Successful in 1m19s
CI / unit_tests (pull_request) Successful in 1m18s
CI / lint (pull_request) Successful in 1m20s
CI / build (pull_request) Successful in 23s
CI / lint (push) Successful in 51s
CI / typecheck (push) Successful in 47s
CI / unit_tests (push) Successful in 49s
CI / coverage (push) Successful in 53s
CI / dead_code (push) Successful in 26s
CI / build (push) Successful in 26s
CI / security (push) Successful in 42s
fix: sync doc with extraction scope, remove boundary violation, add ProviderRegistryPort
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
2026-05-21 10:10:37 +00:00

6.3 KiB

Actor Hierarchy and Advanced YAML Extensions

This document covers the advanced actor YAML schema extensions: per-node LSP bindings, tool-source references, subgraph actor references, and actor-level skill/LSP fields.

Module: cleveractors.actor.schema

Overview

Actor YAML configurations can define multi-node graph workflows. These extensions add fine-grained control over:

Feature Scope Purpose
lsp_binding Per-node Bind specific LSP servers to individual graph nodes
tool_sources Per-node Declare where a node's tools come from (skills, MCP, builtins)
actor_ref Per-node (subgraph) Reference another actor by namespaced name
skills Actor-level List of skill references available to the actor
lsp Actor-level Default LSP server bindings for the actor
lsp_capabilities Actor-level Filter which LSP capabilities are exposed
lsp_context_enrichment Actor-level Control automatic context injection

Per-Node LSP Binding

Different nodes in a graph can have different LSP configurations:

nodes:
  - id: strategist
    type: agent
    name: Strategy Planner
    description: Plans with read-only LSP
    lsp_binding:
      server: local/pyright
      languages:
        - python
      capabilities:
        - diagnostics
        - hover

  - id: implementer
    type: agent
    name: Implementer
    description: Full LSP auto-binding
    lsp_binding:
      auto: true

NodeLspBinding Fields

Field Type Default Description
server string null Namespaced LSP server name (e.g. local/pyright)
languages list[string] [] Languages for language-based resolution
auto bool false Auto-resolve from project resources
capabilities list[string] null Capability filter for this node

The LspBinding objects extracted from per-node configurations are available on CompiledActor.metadata.lsp_bindings after compilation. The host application is responsible for starting the LSP servers at runtime.

Tool-Source References

Nodes can declare their tool sources explicitly:

nodes:
  - id: executor
    type: agent
    name: Executor
    description: Has multiple tool sources
    tool_sources:
      - type: skill
        name: local/file-ops
      - type: mcp
        name: local/filesystem
      - type: builtin
        group: git_operations

ToolSourceRef Fields

Field Type Required Description
type string Yes skill, mcp, builtin, or custom
name string No Namespaced name (for skill and mcp)
group string No Group identifier (for builtin)

Subgraph Actor References

Subgraph nodes reference other actors by namespaced name using the actor_ref field (not config.actor_path):

nodes:
  - id: review
    type: subgraph
    name: Code Review
    description: Delegates to code-reviewer
    actor_ref: local/code-reviewer

The actor_ref field must be in namespace/name format. The compiler records this reference in CompiledActor.metadata.subgraph_refs for cross-actor cycle detection; the host resolves the actual actor at execution time.

Actor-Level Fields

skills

List of skill references available to the actor and its nodes:

skills:
  - local/file-ops
  - local/git-ops

lsp

Explicit binding (list of server names):

lsp:
  - local/pyright
  - local/clangd

Auto binding:

lsp:
  auto: true

lsp_capabilities

Filter which LSP capabilities are exposed to this actor:

lsp_capabilities:
  - diagnostics
  - hover
  - definitions

Or expose all:

lsp_capabilities: all

lsp_context_enrichment

Control automatic context injection from LSP:

lsp_context_enrichment:
  diagnostics: true
  type_annotations: false
  max_diagnostics_per_file: 50

Validation Error Messages

Validation errors include field-path context:

Error Example Message
Bad entry node Entry node 'missing' not found in route.entry_node. Valid node IDs: [a, b]
Bad exit node Exit node 'missing' not found in route.exit_nodes. Valid node IDs: [a, b]
Bad edge ref Edge from_node 'ghost' not found at route.edges[0]. Valid node IDs: [a, b]
Duplicate IDs route.nodes: Duplicate node IDs found: ['dup']. Each node ID must be unique.
Cycle route: graph contains a cycle involving nodes: [a → b]. Hint: remove or redirect edges.

Complete Example

name: workflows/dev-pipeline
type: graph
description: Multi-agent development pipeline with LSP and tool-source control
version: "1.0"
provider: openai
model: gpt-4

# Actor-level declarations
skills:
  - local/file-ops
  - local/git-ops
lsp:
  - local/pyright
lsp_capabilities:
  - diagnostics
  - hover

route:
  nodes:
    - id: planner
      type: agent
      name: Planner
      description: Plans the implementation strategy
      config:
        model: gpt-4
        prompt: "Analyze requirements and create a plan."
      lsp_binding:
        server: local/pyright
        languages:
          - python
        capabilities:
          - diagnostics
      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

  edges:
    - from_node: planner
      to_node: implementer
    - from_node: implementer
      to_node: reviewer

  entry_node: planner
  exit_nodes:
    - reviewer

See Also