# Actor Loading and Discovery

The actor loader discovers, validates, and caches actor YAML configuration files from configurable search roots.

## Discovery Rules

The `ActorLoader` scans one or more **search root** directories for actor YAML files:

| Rule | Detail |
|------|--------|
| **File extensions** | Only `*.yaml` and `*.yml` files are loaded |
| **Recursive scan** | Subdirectories are scanned recursively |
| **Non-YAML ignored** | Files with other extensions (`.json`, `.txt`, etc.) are silently skipped |
| **Invalid YAML rejected** | Files that fail YAML parsing or schema validation raise `ValidationError` |

### Search Roots

Search roots are directories passed to the loader at construction time. Common roots include:

- `actors/` — project-level actor definitions
- `examples/actors/` — example actor files shipped with CleverAgents

## Namespace Handling

All actors must have a namespaced name in `<namespace>/<name>` format.

| Input | Result |
|-------|--------|
| `assistants/reviewer` | Kept as-is |
| `my-agent` (no slash) | Automatically becomes `local/my-agent` |

The `local/` namespace is the default for local-only actors. See the [Namespace System](../specification.md#namespaces) for the full namespace hierarchy.

## Duplicate Detection

When the same actor name appears in multiple files (within a single search root or across roots), the loader emits a **single consolidated error** listing all conflicting file paths:

```
Actor discovery failed:
Duplicate actor 'assistants/writer' found in: /path/a/writer.yaml, /path/b/writer.yaml
```

## Content Hash Caching

The loader caches loaded actors using a SHA-256 content hash to avoid redundant parsing:

| Condition | Behavior |
|-----------|----------|
| File content unchanged | Actor is served from cache (no re-parse) |
| File content modified | Actor is re-parsed and cache is updated |
| File deleted | Actor is removed from cache on next discovery |

This means calling `discover()` multiple times is efficient — only changed files trigger re-parsing.

## Tool Registry Integration

When a `ToolRegistry` is provided, the loader verifies tool references at load time:

- **Resolved tools**: Tool references that exist in the registry are validated silently.
- **Unresolved tools**: Missing tool references emit a warning but do not block loading. This allows actors to be loaded before all tools are registered.

## API Reference

### `ActorLoader`

```python
from cleveragents.actor.loader import ActorLoader

loader = ActorLoader(
    search_roots=[Path("actors/"), Path("examples/actors/")],
    tool_registry=tool_registry,  # optional
)
```

| Method | Description |
|--------|-------------|
| `discover()` | Scan search roots and load/reload actors. Returns list of `ActorConfigSchema`. |
| `get(name)` | Retrieve a loaded actor by namespaced name. Returns `None` if not found. |
| `list_actors(namespace=None)` | List actors with optional namespace filter. |
| `clear()` | Drop all cached actors and content hashes. |
| `warnings` | List of warnings emitted during the last discovery run. |
