CleverActors — pure Python library for declarative actor definitions: YAML schema, Jinja2 preprocessing, validation, and LangGraph compilation. Extracted from cleveragents-core.
  • Python 83%
  • Gherkin 15.8%
  • RobotFramework 0.7%
  • Shell 0.5%
Find a file
CleverThis Engineering 974577fea2
Some checks failed
CI / integration_tests (push) Successful in 1m9s
CI / unit_tests (push) Failing after 3m52s
CI / coverage (push) Has been skipped
CI / status-check (push) Failing after 3s
CI / quality (push) Successful in 1m0s
CI / build (push) Successful in 1m0s
CI / lint (push) Successful in 1m14s
CI / typecheck (push) Successful in 1m15s
CI / security (push) Failing after 1m14s
fix(runtime): CleverAgents v2.0 graph execution and stateless state
This commit fixes several critical issues when executing CleverAgents
v2.0 graph actors via the runtime API:

1. TemplateRenderer initialization: TemplateRenderer({}) was passing
   a dict to the constructor which expects a TemplateEngine enum.
   Fixed all call sites to use TemplateRenderer().

2. Exception handling in renderer: .format() raises IndexError and
   ValueError in addition to KeyError. Broadened except clauses.

3. Graph type detection: Configs with 'routes' key but no 'type'
   were misclassified. Added 'routes' detection in execute(). Actor-
   level validation (implicit type inference, graph/llm/tool/
   multi_actor field checks) lives in validation/_actor.py and is
   reached via the existing validate_dict() public API.

4. Graph config normalization: Added _normalize_graph_config() to
   support both legacy route={} and v2.0 routes={main={}} formats.

5. Agent node mapping: Node IDs matching actor names now correctly
   resolve to agents even without explicit 'agent' field.

6. Agent type correction: Nodes mapped to agents are now typed as
   AGENT instead of FUNCTION so the graph executes them properly.

7. Credential injection: _build_factory_config() now copies the
   'actors' block into 'agents' for AgentFactory discovery.

8. Context merging: Graph execution now merges actor config context
   into global_context so stage_order, paper_details, etc. are
   available to tool agents.

9. Router default target: MESSAGE_ROUTER nodes with no rules now
   default to 'workflow_controller' instead of returning {}.

10. GOTO command parsing: Agent outputs containing GOTO_ or ROUTE_
    prefixes are now parsed to set next_node metadata.

11. Client-carried state: PureLangGraph.execute() now accepts
    initial_state, restores metadata before execution, and returns
    a captured state dict alongside the output text. This enables
    fully stateless graph execution where the client carries the
    opaque state blob between requests.

12. Validation module — new validation/_actor.py: the six actor-level
    validation features (implicit graph/multi_actor type inference,
    v2.0 routes.main.* structure checks, llm provider+model, tool
    list, multi-actor node-count limit) are implemented here and
    wired into validate_dict() as the actor-level path (triggered
    when the 'agents' top-level key is absent).

    Duplicate validate_dict() and merge_configs()/_deep_merge_two()
    implementations that were incorrectly placed in runtime.py have
    been removed; the canonical versions in validation/__init__.py
    and config_utils.py are used instead.

Refs: ADR-2026
2026-06-09 06:21:59 +00:00
.forgejo/workflows ci: Initial CI setup 2026-05-26 22:14:06 +01:00
benchmarks feat(registry): implement async RegistryClient using httpx 2026-06-05 22:01:21 +00:00
docs docs: Setup project documentation 2026-05-26 22:13:33 +01:00
features feat(credentials): refactor LLMAgent/AgentFactory for per-request credential injection and extended provider routing 2026-06-08 11:10:46 +00:00
hooks chore: apply end-of-file and trailing-whitespace fixes to config files 2026-05-27 21:41:39 +00:00
robot feat(credentials): refactor LLMAgent/AgentFactory for per-request credential injection and extended provider routing 2026-06-08 11:10:46 +00:00
scripts chore: Base repo structure commit 2026-05-26 21:45:54 +01:00
src/cleveractors fix(runtime): CleverAgents v2.0 graph execution and stateless state 2026-06-09 06:21:59 +00:00
tests test: apply formatting fixes to integration and fixture files 2026-05-27 21:41:13 +00:00
.bumpversion.cfg chore: Update some repo configurations and documents 2026-05-26 22:12:25 +01:00
.copier-answers.base-oss.yml chore: Update some repo configurations and documents 2026-05-26 22:12:25 +01:00
.copier-answers.base-python.yml chore: Update some repo configurations and documents 2026-05-26 22:12:25 +01:00
.editorconfig chore: Update some repo configurations and documents 2026-05-26 22:12:25 +01:00
.gitignore feat(validate_dict): expose public validate_dict(config_dict, platform_limits) API 2026-06-05 09:23:44 +00:00
.pre-commit-config.yaml chore: fix pre-commit hooks — update paths and lint/format issues 2026-05-27 21:27:36 +00:00
.semgrep.yml chore: Update some repo configurations and documents 2026-05-26 22:12:25 +01:00
asv.conf.json perf(asv): update benchmark Python target from 3.11 to 3.13 2026-05-27 21:49:29 +00:00
ATTRIBUTIONS.md chore: Update some repo configurations and documents 2026-05-26 22:12:25 +01:00
behave.ini chore: Base repo structure commit 2026-05-26 21:45:54 +01:00
CHANGELOG.md feat(credentials): refactor LLMAgent/AgentFactory for per-request credential injection and extended provider routing 2026-06-08 11:10:46 +00:00
CODE_OF_CONDUCT.md chore: Update some repo configurations and documents 2026-05-26 22:12:25 +01:00
CONTRIBUTING.md chore: apply end-of-file and trailing-whitespace fixes to config files 2026-05-27 21:41:39 +00:00
CONTRIBUTORS.md feat(merge_configs): expose public merge_configs(*dicts) API per §3.1 deep-merge algorithm 2026-06-03 14:44:18 +00:00
LICENSE chore: Base repo structure commit 2026-05-26 21:45:54 +01:00
mkdocs.yml chore: apply end-of-file and trailing-whitespace fixes to config files 2026-05-27 21:41:39 +00:00
NOTICE chore: Update some repo configurations and documents 2026-05-26 22:12:25 +01:00
noxfile.py chore: fix pre-commit hooks — update paths and lint/format issues 2026-05-27 21:27:36 +00:00
pyproject.toml feat(registry): implement async RegistryClient using httpx 2026-06-05 22:01:21 +00:00
pyrightconfig.json chore: apply end-of-file and trailing-whitespace fixes to config files 2026-05-27 21:41:39 +00:00
README.md chore: Update some repo configurations and documents 2026-05-26 22:12:25 +01:00
SECURITY.md chore: Base repo structure commit 2026-05-26 21:45:54 +01:00
vulture_whitelist.py chore: fix pre-commit hooks — update paths and lint/format issues 2026-05-27 21:27:36 +00:00

CleverActors

CleverActors is the reactive agent framework used by CleverAgents and CleverRouter.

It provides a Python library that lets a host application:

  • Parse CleverAgents v2 YAML configuration files (with Jinja2 templates and ${ENV_VAR} interpolation).
  • Validate configuration against the built-in schema validator.
  • Create reactive agent networks with RxPy streams, LangGraph graphs, or hybrid pipelines of both.
  • Run single-shot prompts, interactive CLI sessions, or stream-based processing via the ReactiveCleverAgentsApp orchestrator.

Install

pip install "cleveractors @ git+https://git.cleverthis.com/cleverlibre/cleveractors@master"

Quick start

from cleveractors import ReactiveCleverAgentsApp

app = ReactiveCleverAgentsApp(config_files=["config.yaml"])
result = await app.run_single_shot("Hello, agents!")
print(result)

Using agents directly

from cleveractors import Agent
from cleveractors.agents.llm import LLMAgent

agent = LLMAgent(
    name="assistant",
    config={"provider": "openai", "model": "gpt-4o", "system_prompt": "Be helpful."},
)
response = await agent.process_message("What is 2+2?")
print(response)

LangGraph workflows

from cleveractors.langgraph import LangGraph, Node, NodeType, GraphState

graph = LangGraph(name="my_workflow", config={})
graph.add_node(Node(name="start", node_type=NodeType.AGENT, agent="assistant"))
graph.add_node(Node(name="end", node_type=NodeType.END))
graph.add_edge("start", "end")
result = await graph.execute({"message": "Hello"})

Reactive stream routing

from cleveractors.reactive.stream_router import ReactiveStreamRouter, StreamType

router = ReactiveStreamRouter()
stream = router.create_stream({"name": "pipeline", "type": StreamType.HOT})
router.send_message("pipeline", "Process this message")

Package structure

Module Purpose
cleveractors Top-level exports: Agent, ContextManager, ReactiveCleverAgentsApp, CleverAgentsException
cleveractors.agents Agent implementations: LLMAgent, ToolAgent, CompositeAgent, ChainAgent, AgentFactory
cleveractors.core Core framework: ReactiveCleverAgentsApp, ConfigurationManager, ProgressBarManager, exceptions
cleveractors.langgraph LangGraph integration: LangGraph, PureLangGraph, Node, GraphState, StateManager, RxPyLangGraphBridge
cleveractors.reactive RxPy streams: ReactiveStreamRouter, StreamMessage, RouteConfig, ReactiveConfigParser
cleveractors.templates Jinja2+YAML template system: BaseTemplate, TemplateRegistry, AgentTemplate, GraphTemplate, StreamTemplate

Key exports

from cleveractors import Agent, ContextManager, ReactiveCleverAgentsApp, CleverAgentsException
from cleveractors.core.exceptions import ConfigurationError, TemplateError, RoutingError, ExecutionError
from cleveractors.core.config import ConfigurationManager
from cleveractors.agents.factory import AgentFactory
from cleveractors.langgraph import LangGraph, Node, NodeType, GraphState, StateManager
from cleveractors.langgraph.pure_graph import PureLangGraph, create_pure_langgraph
from cleveractors.reactive.stream_router import ReactiveStreamRouter, StreamType, StreamMessage
from cleveractors.templates import BaseTemplate, TemplateType, TemplateParameter, TemplateRegistry

License

MIT — see LICENSE.

See also CleverAgents Operations Code (CONTRIBUTING) for commit, PR, and testing conventions.