Clever Actors only accepts GRAPH actors, not LLM actors. #2

Open
opened 2026-05-19 00:49:44 +00:00 by brent.edwards · 2 comments
Member

Summary

Creating an LLM actor throws an exception.

Metadata

  • Commit message: fix(actors): Allow LLM actors
  • Branch: fix/llm-actors

Details

From a new Docker image, type the following:

mkdir -p ~/test/20260518
cd ~/test/20260518
uv venv
source .venv/bin/activate
cd /app
uv pip install "cleveractors @ git+https://git.cleverthis.com/cleveragents/cleveractors-core@master"
cd ~/test/20260518
cat << EOF > actor.py
from cleveractors.actor import compile_actor
from cleveractors.actor.schema import ActorConfigSchema
from cleveractors.actor.yaml_loader import load_yaml_text

raw = load_yaml_text(open("my-actor.yaml").read())
config = ActorConfigSchema.model_validate(raw)
compiled = compile_actor(config)
print(compiled.metadata.node_ids)
EOF
cat << EOF > my-actor.yaml
# Simple LLM Actor Example
# Demonstrates the most basic actor configuration with just an LLM and system prompt

name: assistants/proofreader
type: llm
description: This assistant proofreads text.
version: "1.0.0"

# LLM configuration
provider: openai
model: gpt-4
system_prompt: |
    You are an expert proofreader. Read the given text and correct:
        - misspellings
        - incorrect grammar
        - incorrect punctuation
        - incorrect capitalizations
        - duplicate words
        - misplaced modifiers

    Provide constructive feedback with specific suggestions for improvement.

# Context and memory settings
context_view: reviewer
memory:
    enabled: true
    max_messages: 20
    max_tokens: 4000

context:
    include_files:
        - "*.txt"
    include_dirs:
        - "src/"
    max_context_tokens: 8000
EOF
python actor.py

The results will be:

Traceback (most recent call last):
  File "/home/devuser/test/20260518/actor.py", line 7, in <module>
    compiled = compile_actor(config)
  File "/app/src/cleveractors/actor/compiler.py", line 253, in compile_actor
    raise ActorCompilationError(
        f"Only GRAPH actors can be compiled; got type={config.type.value}"
    )
cleveractors.actor.compiler.ActorCompilationError: Only GRAPH actors can be compiled; got type=llm
# Summary Creating an LLM actor throws an exception. # Metadata - Commit message: fix(actors): Allow LLM actors - Branch: fix/llm-actors # Details From a new Docker image, type the following: ``` mkdir -p ~/test/20260518 cd ~/test/20260518 uv venv source .venv/bin/activate cd /app uv pip install "cleveractors @ git+https://git.cleverthis.com/cleveragents/cleveractors-core@master" cd ~/test/20260518 cat << EOF > actor.py from cleveractors.actor import compile_actor from cleveractors.actor.schema import ActorConfigSchema from cleveractors.actor.yaml_loader import load_yaml_text raw = load_yaml_text(open("my-actor.yaml").read()) config = ActorConfigSchema.model_validate(raw) compiled = compile_actor(config) print(compiled.metadata.node_ids) EOF cat << EOF > my-actor.yaml # Simple LLM Actor Example # Demonstrates the most basic actor configuration with just an LLM and system prompt name: assistants/proofreader type: llm description: This assistant proofreads text. version: "1.0.0" # LLM configuration provider: openai model: gpt-4 system_prompt: | You are an expert proofreader. Read the given text and correct: - misspellings - incorrect grammar - incorrect punctuation - incorrect capitalizations - duplicate words - misplaced modifiers Provide constructive feedback with specific suggestions for improvement. # Context and memory settings context_view: reviewer memory: enabled: true max_messages: 20 max_tokens: 4000 context: include_files: - "*.txt" include_dirs: - "src/" max_context_tokens: 8000 EOF python actor.py ``` The results will be: ``` Traceback (most recent call last): File "/home/devuser/test/20260518/actor.py", line 7, in <module> compiled = compile_actor(config) File "/app/src/cleveractors/actor/compiler.py", line 253, in compile_actor raise ActorCompilationError( f"Only GRAPH actors can be compiled; got type={config.type.value}" ) cleveractors.actor.compiler.ActorCompilationError: Only GRAPH actors can be compiled; got type=llm ```
Member

The root cause here runs deeper than just suppressing the exception. The suggested commit message (fix(actors): Allow LLM actors) is underspecified — the correct fix is for compile_actor() to auto-expand type: llm into a single-node graph, not just relax the guard.

Architectural basis

ADR-003 is explicit:

"Every custom actor IS a graph. This is not a metaphor... Even a simple actor wrapping a single LLM is a graph with one agent node."
"This unification means the library needs exactly one schema, one validation path, and one compilation path for all actor types."

The spec's own consumer integration example confirms this — it calls compile_actor() on every actor without a type check:

for cfg in configs:
    compiled = compile_actor(cfg)   # no type filter
    my_actor_service.persist(cfg, compiled)

The if config.type != ActorType.GRAPH: raise guard in the compiler is inconsistent with this and should be treated as an incomplete implementation from the LLM-assisted extraction.

Correct approach

compile_actor() should dispatch by type. For type: llm, synthesize a single-agent-node CompiledActor from the actor's flat fields:

Input  (type: llm):
  provider:      openai
  model:         gpt-4
  system_prompt: "..."
  tools:         [...]

Output (CompiledActor):
  nodes:       {"llm_agent": NodeConfig(type=AGENT,
                   metadata={"provider": "openai", "model": "gpt-4",
                              "system_prompt": "..."})}
  edges:       []
  entry_point: "llm_agent"
  exit_nodes:  ["llm_agent"]

A degenerate one-node, zero-edge graph where entry == exit — valid and consistent with the actor-as-graph principle.

Suggested revision

  • Commit message: fix(compiler): auto-expand type:llm actors into single-node CompiledActor
  • Branch: fix/compiler-expand-llm-actor

Relationship to #6

Issue #6 tracks system_prompt not being threaded into CompiledActor for type: graph actors. The auto-expansion approach here naturally resolves that gap for type: llm actors as well — the synthesized node carries system_prompt in its metadata from the start. The two fixes are complementary but independent; #6 is not blocking this issue.

The root cause here runs deeper than just suppressing the exception. The suggested commit message (`fix(actors): Allow LLM actors`) is underspecified — the correct fix is for `compile_actor()` to **auto-expand `type: llm` into a single-node graph**, not just relax the guard. ### Architectural basis ADR-003 is explicit: > "Every custom actor IS a graph. This is not a metaphor... Even a simple actor wrapping a single LLM is a graph with one agent node." > "This unification means the library needs exactly **one schema, one validation path, and one compilation path** for all actor types." The spec's own consumer integration example confirms this — it calls `compile_actor()` on every actor without a type check: ```python for cfg in configs: compiled = compile_actor(cfg) # no type filter my_actor_service.persist(cfg, compiled) ``` The `if config.type != ActorType.GRAPH: raise` guard in the compiler is inconsistent with this and should be treated as an incomplete implementation from the LLM-assisted extraction. ### Correct approach `compile_actor()` should dispatch by type. For `type: llm`, synthesize a single-agent-node `CompiledActor` from the actor's flat fields: ``` Input (type: llm): provider: openai model: gpt-4 system_prompt: "..." tools: [...] Output (CompiledActor): nodes: {"llm_agent": NodeConfig(type=AGENT, metadata={"provider": "openai", "model": "gpt-4", "system_prompt": "..."})} edges: [] entry_point: "llm_agent" exit_nodes: ["llm_agent"] ``` A degenerate one-node, zero-edge graph where entry == exit — valid and consistent with the actor-as-graph principle. ### Suggested revision - **Commit message:** `fix(compiler): auto-expand type:llm actors into single-node CompiledActor` - **Branch:** `fix/compiler-expand-llm-actor` ### Relationship to #6 Issue #6 tracks `system_prompt` not being threaded into `CompiledActor` for `type: graph` actors. The auto-expansion approach here naturally resolves that gap for `type: llm` actors as well — the synthesized node carries `system_prompt` in its metadata from the start. The two fixes are complementary but independent; #6 is not blocking this issue.
Member

Note the ADR-003 is in PR #5, which syncs design docs from cleveragents-core to this repo

Note the ADR-003 is in PR #5, which syncs design docs from cleveragents-core to this repo
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveractors-core#2
No description provided.