Files
cleveractors-core/features/runtime_extended_coverage.feature
hurui200320 76c4c74201
CI / lint (pull_request) Successful in 36s
CI / quality (pull_request) Successful in 40s
CI / build (pull_request) Successful in 44s
CI / security (pull_request) Successful in 51s
CI / typecheck (pull_request) Successful in 52s
CI / integration_tests (pull_request) Successful in 1m3s
CI / unit_tests (pull_request) Successful in 3m38s
CI / coverage (pull_request) Successful in 3m36s
CI / status-check (pull_request) Successful in 3s
CI / lint (push) Successful in 1m2s
CI / typecheck (push) Successful in 1m2s
CI / security (push) Successful in 1m2s
CI / quality (push) Successful in 40s
CI / integration_tests (push) Successful in 1m8s
CI / build (push) Successful in 49s
CI / unit_tests (push) Successful in 3m40s
CI / coverage (push) Successful in 3m36s
CI / status-check (push) Successful in 3s
feat(create_executor): implement create_executor() factory and Executor.execute() returning ActorResult
- **`src/cleveractors/runtime_types.py`** — `ActorResult` and `NodeUsage` dataclasses
  extracted to break circular imports (CONTRIBUTING.md §Import Guidelines). 100% coverage.
- **`src/cleveractors/runtime.py`** — `create_executor()` factory, `Executor` class
  with `execute()` dispatching to module-level functions in `runtime_dispatch`.
  Imports `_execute_*` at module level (no function-local imports). 100% coverage.
- **`src/cleveractors/runtime_dispatch.py`** — Four dispatch functions: `_execute_llm`,
  `_execute_graph`, `_execute_tool`, `_execute_multi_actor`. All imports at module
  level except `from cleveractors.runtime import Executor` inside `_execute_multi_actor`
  (the only remaining circular dep — Executor calls _execute_multi_actor which creates
  a new Executor; cannot be resolved without further restructuring). 99.69% coverage
  (only the `if TYPE_CHECKING:` guard line is uncovered — not a real gap).
- **`src/cleveractors/runtime_tokens.py`** — Token estimation via tiktoken with
  heuristic fallback. 100% coverage.

Key design decisions and fixes:
- **Circular import resolution**: `ActorResult`/`NodeUsage` moved to `runtime_types.py`;
  both `runtime.py` and `runtime_dispatch.py` import from it at module level.
- **`messages` forwarded to `_execute_llm`**: builds `context={"conversation_history":[...]}`
  passed to `LLMAgent.process_message` for multi-turn support.
- **`parallel_execution` aligned with `PureGraphConfig` default (True)**:
  reads from legacy `route` dict or v2.0 `routes.main` dict; defaults to True.
- **Factory normalization**: always merges `actors` into `agents` (actors take
  precedence) so configs using both keys work correctly.
- **Generic exception in agent creation re-raised as `ConfigurationError`**:
  no double-logging; exception message preserved in `ConfigurationError`.
- **`cleveragents_block` guarded against `None`**: uses `or {}` coercion.
- **Type annotations added**: `top_provider`, `top_model`, `top_sp`,
  `temperature_raw`, `max_tokens_raw`, `config_block`, `tools` in dispatch functions.
- **No `finally` in `_execute_tool`**: documented with comment (ToolAgent has no cleanup).
- **Dead step removed**: `step_rxe_invalid_node_type` was unreferenced and incorrect.
- **BDD coverage**: `parallel_execution=False` override verified via `PureGraphConfig`
  constructor args; conversation history forwarding verified; AC7 immutability for
  multi-actor path verified.

-  `nox -e lint` — passes
-  `nox -e format` — passes
-  `nox -e typecheck` — passes (0 errors, 1 expected warning)
-  `nox -e unit_tests` — 2113 scenarios pass, 0 failures, 0 skipped
-  `nox -e integration_tests` — 76 tests pass
-  `nox -e coverage_report` — 97.21% (9870 covered, 283 missing, 10153 total)
  PR-modified files: `runtime_types.py` 100%, `runtime.py` 100%,
  `runtime_dispatch.py` 99.69% (1 uncoverable TYPE_CHECKING guard), `runtime_tokens.py` 100%

ISSUES CLOSED: #13
2026-06-10 09:41:39 +00:00

115 lines
6.6 KiB
Gherkin

Feature: Runtime Executor Extended Coverage
As a developer
I want the runtime executor to handle additional edge cases in graph, tool, and multi-actor execution
So that all code paths in the runtime module are exercised
Background:
Given the runtime extended test context is initialized (rxe)
Scenario: execute detects graph type from routes key in CleverAgents v2.0 format
Given a config dict with routes key but no type field (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test v2 graph" (rxe)
Then the execution should return an ActorResult (rxe)
Scenario: _normalize_graph_config handles v2.0 routes with dict nodes
Given a config dict with type graph and v2.0 routes format with dict nodes (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test v2 dict nodes" (rxe)
Then the execution should return an ActorResult (rxe)
Scenario: _normalize_graph_config handles v2.0 routes with list nodes
Given a config dict with type graph and v2.0 routes format with list nodes (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test v2 list nodes" (rxe)
Then the execution should return an ActorResult (rxe)
Scenario: _execute_llm builds conversation history from messages
Given a config dict with type llm provider model and system_prompt in config block (rxe)
And credentials dict with openai provider (rxe)
And conversation history messages are provided (rxe)
When I execute the extended runtime actor with message "test conversation" (rxe)
Then the execution should return an ActorResult (rxe)
Scenario: _execute_llm picks up provider from config block when not at top level
Given a config dict with type llm and provider model in nested config block (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test config block" (rxe)
Then the execution should return an ActorResult (rxe)
Scenario: _execute_graph handles agent name from node ID in v2.0 actors block
Given a config dict with type graph and v2.0 routes with actors block (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test agents block" (rxe)
Then the execution should return an ActorResult (rxe)
Scenario: _execute_graph raises ConfigurationError for unexpected agent creation failure
Given a config dict with type graph and route with agents block having missing agent (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test missing agent" (rxe)
Then a ConfigurationError should be raised about agent creation failure (rxe)
Scenario: _execute_graph merges global context from config with conversation history
Given a config dict with type graph and route with global context (rxe)
And credentials dict with openai provider (rxe)
And conversation history messages are provided (rxe)
When I execute the extended runtime actor with message "test global context" (rxe)
Then the execution should return an ActorResult (rxe)
Scenario: _execute_tool builds conversation history from messages
Given a config dict with type tool and tools list (rxe)
And credentials dict with openai provider (rxe)
And conversation history messages are provided (rxe)
When I execute the extended runtime actor with message "test tool with history" (rxe)
Then the execution should return an ActorResult (rxe)
Scenario: _execute_multi_actor uses default actor from cleveragents block
Given a multi-actor config dict with cleveragents default_actor (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test default actor" (rxe)
Then the execution should return an ActorResult (rxe)
And the node usage IDs should be prefixed with the default actor name (rxe)
Scenario: _execute_graph handles actor context without global key
Given a config dict with type graph and route with actor context without global key (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test actor context" (rxe)
Then the execution should return an ActorResult (rxe)
Scenario: _execute_graph handles missing credential provider gracefully
Given a config dict with type llm and unknown provider (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test missing creds" (rxe)
Then a ConfigurationError should be raised about missing credentials (rxe)
# ---------------------------------------------------------------------------
# M3: parallel_execution override for legacy route format
# ---------------------------------------------------------------------------
Scenario: _execute_graph passes parallel_execution=False to PureGraphConfig for legacy route
Given a config dict with type graph and route with parallel_execution false (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor and capture PureGraphConfig args (rxe)
Then PureGraphConfig should have received parallel_execution=False (rxe)
# ---------------------------------------------------------------------------
# M4: conversation history forwarding verified by call_args assertion
# ---------------------------------------------------------------------------
Scenario: _execute_llm forwards conversation history to LLMAgent.process_message
Given a config dict with type llm provider model and system_prompt in config block (rxe)
And credentials dict with openai provider (rxe)
And conversation history messages are provided (rxe)
When I execute the LLM actor and capture process_message call args (rxe)
Then process_message should have received conversation_history in context (rxe)
# ---------------------------------------------------------------------------
# m5: AC7 immutability for multi-actor path
# ---------------------------------------------------------------------------
Scenario: _execute_multi_actor does not mutate the stored config_dict (AC7)
Given a multi-actor config dict with cleveragents default_actor (rxe)
And credentials dict with openai provider (rxe)
When I execute the extended runtime actor with message "test ac7 multi" (rxe)
Then the multi-actor config_dict should be unchanged after execution (rxe)