caf146e132
CI / benchmark-publish (push) Failing after 39s
CI / helm (push) Successful in 38s
CI / build (push) Successful in 54s
CI / lint (push) Successful in 1m2s
CI / push-validation (push) Successful in 21s
CI / quality (push) Successful in 1m26s
CI / typecheck (push) Successful in 1m46s
CI / security (push) Successful in 1m51s
CI / integration_tests (push) Successful in 4m16s
CI / unit_tests (push) Successful in 4m56s
CI / e2e_tests (push) Successful in 4m56s
CI / docker (push) Successful in 1m49s
CI / coverage (push) Successful in 10m51s
CI / status-check (push) Successful in 3s
CI / benchmark-publish (pull_request) Has been skipped
CI / coverage (pull_request) Successful in 14m50s
CI / docker (pull_request) Successful in 1m58s
CI / quality (pull_request) Successful in 1m18s
CI / e2e_tests (pull_request) Successful in 3m53s
CI / integration_tests (pull_request) Successful in 6m34s
CI / unit_tests (pull_request) Successful in 8m47s
CI / push-validation (pull_request) Successful in 20s
CI / lint (pull_request) Successful in 1m19s
CI / typecheck (pull_request) Successful in 1m26s
CI / security (pull_request) Successful in 1m31s
CI / helm (pull_request) Successful in 36s
CI / build (pull_request) Successful in 43s
CI / status-check (pull_request) Successful in 5s
Two bugs prevented built-in LLM actors from working with models that lack a '/'
separator (e.g. claude-sonnet-4-20250514):
1. _generate_builtin_actor_yaml (actor/registry.py) was constructing the model
field as '{provider}/{model}' (e.g. 'anthropic/claude-sonnet-4-20250514').
The Anthropic API expects just the bare model ID, causing 404 errors. Fixed
by using the bare model identifier and lowercasing the provider field to
match ProviderType enum values.
2. _build_from_v3 (reactive/config_parser.py) always inferred the provider from
the model string via infer_provider_from_model(). For models without a '/'
separator this returned 'custom', an invalid ProviderType, causing
'Unknown provider type: custom' at runtime. Fixed by checking for an
explicit top-level 'provider' field in the v3 YAML data (per spec resolution
order step 2) before falling back to inference.
As a side effect, these fixes also resolve issue #10861: agents actor run now
successfully invokes the LLM when using built-in actors. The @tdd_expected_fail
tag has been removed from features/tdd_actor_run_response.feature accordingly.
New BDD scenarios added to features/builtin_actor_v3_yaml.feature and
features/actor_v3_route_synthesis.feature validate both fixes and the fallback
inference behaviour for models with '/' separators.
All quality gates pass: lint, typecheck, 671 feature files (15673 scenarios),
1997 Robot integration tests, coverage 97.12%.
ISSUES CLOSED: #10926
134 lines
6.6 KiB
Gherkin
134 lines
6.6 KiB
Gherkin
Feature: v3 actor config parser synthesises execution routes
|
|
As a developer using v3 actor YAML configs
|
|
I want ReactiveConfigParser to automatically create graph routes for agents
|
|
So that run_single_shot() can invoke the LLM instead of silently returning empty
|
|
|
|
# --- Fix A: _build_from_v3() route synthesis for type:llm / type:tool --------
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: v3 flat LLM actor build produces non-empty routes
|
|
Given a flat v3 LLM actor config for route synthesis
|
|
When I build the flat v3 config through ReactiveConfigParser
|
|
Then the reactive config routes should not be empty
|
|
And the reactive config should have exactly one route
|
|
And the synthesised route should be a graph route
|
|
And the synthesised route entry point should be the router
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: v3 flat tool actor build produces non-empty routes
|
|
Given a flat v3 tool actor config for route synthesis
|
|
When I build the flat v3 config through ReactiveConfigParser
|
|
Then the reactive config routes should not be empty
|
|
And the reactive config should have exactly one route
|
|
And the synthesised route should be a graph route
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: v3 flat LLM route has router-plus-actor graph structure
|
|
Given a flat v3 LLM actor config for route synthesis
|
|
When I build the flat v3 config through ReactiveConfigParser
|
|
Then the synthesised route should have exactly two nodes
|
|
And the synthesised route should have a message router node
|
|
And the synthesised route node should reference the actor name
|
|
And the synthesised route should have an edge to end
|
|
|
|
# --- Fix B: _build() route synthesis for nested actors: map format -----------
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: Nested actors map format produces non-empty routes
|
|
Given a nested actors map config with cleveragents version 3
|
|
When I build the nested actors config through ReactiveConfigParser
|
|
Then the reactive config routes should not be empty
|
|
And the reactive config should have exactly one route
|
|
And the synthesised route should be a graph route
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: Nested actors map uses default_actor for route actor node
|
|
Given a nested actors map config with default_actor set
|
|
When I build the nested actors config through ReactiveConfigParser
|
|
Then the synthesised route should target the default actor
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: Nested actors map without default_actor uses first agent
|
|
Given a nested actors map config without default_actor
|
|
When I build the nested actors config through ReactiveConfigParser
|
|
Then the reactive config routes should not be empty
|
|
And the synthesised route should target the first agent
|
|
|
|
# --- Fix C: nested actors: map translates actor key to provider/model -------
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: Nested actors map with actor key infers provider and model
|
|
Given a nested actors map config with actor key "anthropic/claude-sonnet-4-5"
|
|
When I build the nested actors config through ReactiveConfigParser
|
|
Then the agent config should have provider "anthropic"
|
|
And the agent config should have model "claude-sonnet-4-5"
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: Nested actors map with actor key without slash sets model only
|
|
Given a nested actors map config with actor key "gpt-4"
|
|
When I build the nested actors config through ReactiveConfigParser
|
|
Then the agent config should have model "gpt-4"
|
|
And the agent config should not have provider set
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: Nested actors map with explicit provider keeps it unchanged
|
|
Given a nested actors map config with explicit provider "openai" and model "gpt-4o"
|
|
When I build the nested actors config through ReactiveConfigParser
|
|
Then the agent config should have provider "openai"
|
|
And the agent config should have model "gpt-4o"
|
|
|
|
# --- Existing route configs are not affected --------------------------------
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: Config with explicit routes does not get extra synthesised routes
|
|
Given a config with agents and explicit routes
|
|
When I build the explicit routes config through ReactiveConfigParser
|
|
Then the reactive config should have exactly one route
|
|
And the route should be the explicitly defined one
|
|
|
|
# --- End-to-end: run_single_shot with synthesised route ---------------------
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: run_single_shot returns non-empty output with synthesised v3 LLM route
|
|
Given a ReactiveCleverAgentsApp configured from a flat v3 LLM config
|
|
When I call run_single_shot with a test prompt
|
|
Then the result should be non-empty
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: run_single_shot returns non-empty output with nested actors map config
|
|
Given a ReactiveCleverAgentsApp configured from a nested actors map config
|
|
When I call run_single_shot with a test prompt
|
|
Then the result should be non-empty
|
|
|
|
# --- v3 graph actors still work (regression guard) --------------------------
|
|
|
|
@tdd_issue @tdd_issue_10807
|
|
Scenario: v3 graph actor build still produces routes as before
|
|
Given a v3 graph actor config dict with route for regression check
|
|
When I build the v3 graph config through ReactiveConfigParser
|
|
Then the reactive config routes should not be empty
|
|
And the reactive config should have exactly one route
|
|
|
|
# --- Fix: _build_from_v3 respects explicit provider field (issue #10926) ---
|
|
|
|
@tdd_issue @tdd_issue_10926
|
|
Scenario: v3 actor with explicit provider field uses it without inference
|
|
Given a flat v3 LLM actor config with explicit provider and model without slash
|
|
When I build the flat v3 config through ReactiveConfigParser
|
|
Then the agent config should have provider "anthropic"
|
|
And the agent config should have model "claude-sonnet-4-20250514"
|
|
|
|
@tdd_issue @tdd_issue_10926
|
|
Scenario: v3 actor without explicit provider falls back to inference from model with slash
|
|
Given a flat v3 LLM actor config with model containing slash and no explicit provider
|
|
When I build the flat v3 config through ReactiveConfigParser
|
|
Then the agent config should have provider "openrouter"
|
|
And the agent config should have model "openrouter/anthropic-claude-sonnet"
|
|
|
|
@tdd_issue @tdd_issue_10926
|
|
Scenario: v3 actor with model without slash and no explicit provider gets custom provider
|
|
Given a flat v3 LLM actor config with model without slash and no explicit provider
|
|
When I build the flat v3 config through ReactiveConfigParser
|
|
Then the agent config should have provider "custom"
|
|
And the agent config should have model "gpt-4-turbo"
|