Feature: Consolidated Routing Combined scenarios from: message_router_new_coverage, reactive_registry_adapter_coverage, reactive_routing_port, route_bridge_coverage, route_bridge_uncovered_lines, route_coverage_comprehensive, routing_adapter_coverage, routing_langgraph_port, stream_router_additional_coverage, stream_router_agent_tool_coverage, stream_router_coverage, stream_router_misc_uncovered, stream_router_new_branches, stream_router_remaining_coverage, stream_router_uncovered_paths, stream_router_unsafe_and_llm_coverage # ============================================================ # Originally from: message_router_new_coverage.feature # Feature: Message router new coverage # ============================================================ Scenario: build_message_router_node creates NodeConfig with correct type When I build a message router node named "router1" with rules Then the node name should be "router1" And the node type should be MESSAGE_ROUTER And the node metadata should contain rules Scenario: build_message_router_edges creates edges from rules When I build message router edges for "router1" with two target rules Then the edge count should be 3 And the last edge target should be "end" Scenario: build_message_router_edges handles empty rules When I build message router edges for "router1" with no rules Then the edge count should be 1 And the last edge target should be "end" Scenario: build_message_router_edges skips rules without target When I build message router edges for "router1" with a rule missing target Then the edge count should be 1 # ============================================================ # Originally from: reactive_registry_adapter_coverage.feature # Feature: Reactive registry adapter coverage # ============================================================ Scenario: Registry list failure propagates to caller Given a reactive stream router and route bridge And an actor registry that raises on list When I attempt to register registry actors with the adapter Then a RuntimeError is raised Scenario: Registers only actors with processing methods Given a reactive stream router and route bridge And an actor registry with mixed capabilities When I register registry actors with the adapter Then only actors with processing are registered on the stream router And the route bridge agents cache includes all listed actors Scenario: Route bridge refresh failure propagates to caller Given a reactive stream router and route bridge And an actor registry that returns actors without names When I attempt to register registry actors with the adapter Then an AttributeError is raised Scenario: Route bridge refresh failure propagates when registry returns none Given a reactive stream router and route bridge And an actor registry that returns none When I attempt to register registry actors with the adapter Then a TypeError is raised # ============================================================ # Originally from: reactive_routing_port.feature # Feature: Reactive routing and route bridge port # ============================================================ Scenario: Create a cold stream and send a message Given a reactive stream router When I create a cold stream named "alpha" And I send message "hello" to stream "alpha" Then the stream "alpha" should exist Scenario: Initialize route bridge with dummy registry Given a reactive stream router And a dummy actor registry When I create a route bridge Then the route bridge should include agent "dummy" Scenario: Convert stream route to graph config via bridge Given a reactive stream router And a dummy actor registry And a stream route config named "s1" with a map agent operator When I create a route bridge And I convert the stream route to a graph config Then the graph config should contain nodes # ============================================================ # Originally from: route_bridge_coverage.feature # Feature: Route Bridge Module Coverage # ============================================================ Scenario: Test RouteBridge initialization Given I have a clean test environment for route bridge Given I have a route bridge stream router and agents When I create the route bridge instance Then the route bridge should be initialized correctly And the route bridge logger should be set up And route bridge active conversions should be empty Scenario: Test RouteBridge initialization with scheduler Given I have a clean test environment for route bridge Given I have a route bridge stream router and agents And I have an AsyncIO scheduler When I create a RouteBridge instance with scheduler Then the route bridge should be initialized with scheduler And the route bridge scheduler should be stored correctly Scenario: Test check_upgrade_conditions - no bridge config Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a route config without bridge configuration And I have a stream message When I check upgrade conditions Then the route bridge upgrade result should be False Scenario: Test check_upgrade_conditions - wrong route type Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a graph route config with bridge configuration And I have a stream message When I check upgrade conditions Then the route bridge upgrade result should be False Scenario: Test check_upgrade_conditions - needs_state condition Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a stream route config with needs_state upgrade condition And I have a stream message with requires_state metadata When I check upgrade conditions Then the route bridge upgrade result should be True Scenario: Test check_upgrade_conditions - message_count condition Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a stream route config with message_count upgrade condition And I have processed enough messages to trigger upgrade When I check upgrade conditions Then the route bridge upgrade result should be True And the route bridge message count should be at least 5 Scenario: Test check_upgrade_conditions - complexity_threshold condition Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a stream route config with complexity_threshold upgrade condition And I have a complex route configuration When I check upgrade conditions Then the route bridge upgrade result should be True Scenario: Test check_upgrade_conditions - non-callable predicate Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a stream route config with non-callable custom_predicate And I have a stream message When I check upgrade conditions Then the route bridge upgrade result should be False Scenario: Test check_downgrade_conditions - no bridge config Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a route config without bridge configuration And I have a graph state When I check downgrade conditions Then the downgrade result should be False Scenario: Test check_downgrade_conditions - wrong route type Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a stream route config with bridge configuration And I have a graph state When I check downgrade conditions Then the downgrade result should be False Scenario: Test check_downgrade_conditions - idle_time condition Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a graph route config with idle_time downgrade condition And I have a graph state that has been idle too long When I check downgrade conditions Then the downgrade result should be True Scenario: Test check_downgrade_conditions - state_size condition Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a graph route config with state_size downgrade condition And I have a graph state with minimal messages When I check downgrade conditions Then the downgrade result should be True Scenario: Test check_downgrade_conditions - no_conditionals_used condition Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a graph route config with no_conditionals_used downgrade condition And I have a graph state with no conditional edges used When I check downgrade conditions Then the downgrade result should be True Scenario: Test _get_message_count functionality Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I seed a message count for the route When I get message count for a route Then the route bridge message count should be returned And the route bridge message count result should be a valid integer Scenario: Test error handling in downgrade_graph_to_stream Given I have a clean test environment for route bridge Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a graph route config for downgrade And I have a corrupted LangGraph instance When I attempt to downgrade graph to stream Then route bridge error handling should occur And the route bridge system should remain stable Scenario: Test complex upgrade downgrade cycle Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a route config that supports both upgrade and downgrade And I have a stream message with requires_state metadata When I perform an upgrade and then downgrade cycle Then the cycle should complete successfully And the final configuration should be consistent And active conversions should be tracked correctly # ============================================================ # Originally from: route_bridge_uncovered_lines.feature # Feature: Additional route bridge uncovered lines coverage # ============================================================ Scenario: Bridge falls back to empty agents on registry failure Given I have a clean test environment for route bridge Given I have a failing agent registry for route bridge When I create the route bridge instance Then the route bridge should be initialized correctly And the route bridge agents should be empty Scenario: Upgrade conditions not met when below message_count threshold Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a stream route config with message_count upgrade condition And I have a pending message count below threshold And I have a stream message When I check upgrade conditions Then the route bridge upgrade result should be False Scenario: Complexity threshold too high prevents upgrade Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a simple stream route config with high complexity threshold And I have a stream message When I check upgrade conditions Then the route bridge upgrade result should be False Scenario: Callable custom predicate triggers upgrade Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a stream route config with callable custom_predicate And I have a stream message When I check upgrade conditions synchronously Then the route bridge upgrade result should be True Scenario: Upgrade applies state extractor and preserves subscriptions loop Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a stream route config with state extractor and subscriptions And I have a stream message When I upgrade the stream route to graph Then the graph initial state should include extracted data Scenario: Downgrade uses flattener and checkpointing Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a graph route config with flattener and checkpointing And I have a LangGraph instance with checkpointing When I downgrade the graph with flattener Then the state flattener should run And the checkpoint should be saved Scenario: _create_graph_from_stream uses function node when no agent Given I have a clean test environment for route bridge Given I have a clean test environment for route bridge Given I have a RouteBridge instance When I create a graph config from a stream without agents Then the resulting graph should use function nodes Scenario: _get_message_count falls back to update_count attribute Given I have a clean test environment for route bridge Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I seed a fallback update_count conversion When I get message count for a route Then the route bridge fallback message count should be returned Scenario: Downgrade conditions not met when idle time short Given I have a clean test environment for route bridge Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a graph route config with idle_time not exceeded And I have a graph state When I check downgrade conditions Then the downgrade result should be False Scenario: Downgrade conditions not met when state size large Given I have a clean test environment for route bridge Given I have a clean test environment for route bridge Given I have a RouteBridge instance And I have a graph route config with large state size And I have a graph state with multiple messages When I check downgrade conditions Then the downgrade result should be False # ============================================================ # Originally from: route_coverage_comprehensive.feature # Feature: Route Module Comprehensive Coverage # ============================================================ Scenario: RouteConfig validation for graph routes without nodes Given the route system is available Given I create a RouteConfig with graph type but no nodes When I validate the configuration Then I should get a ConfigurationError about missing nodes Scenario: RouteConfig to_stream_config conversion error Given the route system is available Given I create a RouteConfig with graph type When I try to convert it to StreamConfig Then I should get a ValueError about invalid conversion Scenario: RouteConfig to_graph_config conversion error Given the route system is available Given I create a RouteConfig with stream type When I try to convert it to GraphConfig Then I should get a ValueError about invalid conversion Scenario: RouteConfig from_stream_config class method Given the route system is available Given I have a valid StreamConfig When I create a RouteConfig from the StreamConfig Then the RouteConfig should have stream type And it should preserve all stream configuration details Scenario: RouteConfig from_graph_config class method Given the route system is available Given I have a valid GraphConfig with nodes and edges When I create a RouteConfig from the GraphConfig Then the RouteConfig should have graph type And it should preserve all graph configuration details And node configurations should be converted to dictionaries And edge configurations should be converted to dictionaries Scenario: RouteComplexityAnalyzer bridge type analysis Given the route system is available Given I have a RouteConfig with bridge type When I analyze the route complexity Then it should return bridge complexity analysis And the complexity should be "bridge" And the score should be 0 Scenario: Stream complexity analysis with various features Given the route system is available Given I have stream routes with different features When I analyze each route complexity Then routes with more operators should have higher complexity scores And routes with routing connections should get additional score And hot streams should get additional score And the complexity classification should match the score ranges Scenario: Graph complexity analysis with conditional edges Given the route system is available Given I have graph routes with conditional edges When I analyze the graph complexity Then conditional edges should increase the complexity score And the features should include conditional edge information And checkpointing should increase the score And time travel should increase the score Scenario: Stream complexity recommendation logic Given the route system is available Given I have streams with different complexity scores When I get recommendations for each stream Then simple streams should get simple transformation recommendation And moderate streams should get multi-step processing recommendation And complex streams should get graph consideration recommendation Scenario: Graph complexity recommendation logic Given the route system is available Given I have graphs with different complexity scores When I get recommendations for each graph Then moderate graphs should get conditional logic recommendation And complex graphs should get stateful workflow recommendation And advanced graphs should get feature evaluation recommendation Scenario: Route type suggestion based on requirements Given the route system is available Given I have different requirement scenarios When I ask for route type suggestions Then persistence requirements should suggest graph And state with conditionals should suggest graph And conditionals without continuous should suggest graph And stateless continuous should suggest stream And simple cases should default to stream Scenario: RouteConfig post_init stream type defaulting Given the route system is available Given I create a stream RouteConfig without specifying stream_type When the post_init validation runs Then the stream_type should default to COLD Scenario: RouteConfig to_graph_config with complex node types Given the route system is available Given I have a RouteConfig with various node types and configurations When I convert it to GraphConfig Then all node types should be properly converted And all node properties should be preserved And retry policies and timeouts should be included And conditions and subgraphs should be handled And node metadata should be preserved in conversion # ============================================================ # Originally from: routing_adapter_coverage.feature # Feature: Routing adapter coverage # ============================================================ Scenario: Map operator creates agent node chain Given route operators include a map agent and function When I build route nodes from that stream Then it creates an agent node and chained edges to end And the function node is created with its type Scenario: Map without agent falls back to function node Given route operators include a map without agent When I build route nodes from that stream Then it treats the map as function and terminates chain with end node # ============================================================ # Originally from: routing_langgraph_port.feature # Feature: Actor-first port of v2 routing and LangGraph suites # ============================================================ Scenario: Route bridge converts stream to graph configuration Given the routing system is initialized for actor-first operation Given I have a stream route configuration """ name: "test-stream" type: "stream" stream_type: "sequential" batch_size: 10 """ When I bridge the route to graph type Then the bridged route should be a graph configuration And the graph should have sequential execution And the graph should preserve batch settings Scenario: Unified route handles actor-only context variables Given the routing system is initialized for actor-first operation Given I have a unified route with context """ name: "actor-route" type: "graph" actor: "openai/gpt-4" context_vars: temperature: 0.7 max_tokens: 2000 """ When I process the unified route Then the route should use the specified actor And the context should include temperature and max_tokens And no provider/model fields should exist Scenario: Stream router validates actor configuration Given the routing system is initialized for actor-first operation Given I have a stream router configuration """ routes: - name: "primary" actor: "anthropic/claude-3" stream_type: "parallel" - name: "fallback" actor: "openai/gpt-3.5-turbo" stream_type: "sequential" """ When I initialize the stream router Then the router should have 2 routes And each route should use its configured actor And the router should support actor-based fallback Scenario: LangGraph bridge handles state management Given the routing system is initialized for actor-first operation Given I have a LangGraph configuration with state """ name: "stateful-graph" type: "graph" actor: "local/custom-agent" enable_checkpointing: true state_schema: current_task: "string" completed_steps: "array" """ When I create a LangGraph bridge Then the bridge should enable checkpointing And the state schema should be preserved And the bridge should use the custom actor Scenario: Route complexity analysis with actor paths Given the routing system is initialized for actor-first operation Given I have a complex actor route configuration """ name: "complex-route" type: "graph" nodes: - name: "analyze" actor: "openai/gpt-4" type: "llm" - name: "generate" actor: "anthropic/claude-3" type: "llm" - name: "validate" actor: "local/validator" type: "tool" edges: - from: "analyze" to: "generate" - from: "generate" to: "validate" """ When I analyze the actor route complexity Then the complexity score should reflect multi-actor coordination And the analysis should identify 3 nodes and 2 edges And each node should use its assigned actor Scenario: Stream router handles parallel actor execution Given the routing system is initialized for actor-first operation Given I have parallel stream routes """ routes: - name: "fast-route" actor: "openai/gpt-3.5-turbo" stream_type: "parallel" priority: 1 - name: "accurate-route" actor: "anthropic/claude-3-opus" stream_type: "parallel" priority: 2 execution_mode: "race" """ When I execute the parallel streams Then both actors should be invoked concurrently And the first completion should be used And unused results should be properly cleaned up Scenario: Conditional routing based on actor capabilities Given the routing system is initialized for actor-first operation Given I have conditional routing configuration """ name: "conditional-graph" type: "graph" nodes: - name: "router" type: "conditional" conditions: - if: "requires_vision" then: "vision_node" - if: "requires_code" then: "code_node" - else: "default_node" - name: "vision_node" actor: "openai/gpt-4-vision" type: "llm" - name: "code_node" actor: "anthropic/claude-3-opus" type: "llm" - name: "default_node" actor: "openai/gpt-3.5-turbo" type: "llm" """ When I route with vision requirements Then the vision actor should be selected And the routing decision should be logged Scenario: Route validation rejects invalid actors Given the routing system is initialized for actor-first operation Given I have a route with invalid actor """ name: "invalid-route" type: "stream" actor: "nonexistent/model" """ When I validate the route configuration Then validation should fail with actor not found error And the error should suggest available actors Scenario: Bridge preserves actor-specific options Given the routing system is initialized for actor-first operation Given I have a route with actor options """ name: "options-route" type: "stream" actor: "openai/gpt-4" actor_options: temperature: 0.9 top_p: 0.95 frequency_penalty: 0.5 """ When I bridge to a different route type Then the actor options should be preserved And the options should override defaults And the bridged route should maintain actor identity Scenario: Reactive streams with actor-based transformations Given the routing system is initialized for actor-first operation Given I have a reactive stream configuration """ name: "transform-stream" type: "stream" stream_type: "transform" transformations: - stage: "parse" actor: "local/parser" - stage: "enrich" actor: "openai/gpt-3.5-turbo" - stage: "format" actor: "local/formatter" """ When I process data through the stream Then each transformation should use its actor And the data should flow through all stages And errors should be handled per-actor # ============================================================ # Originally from: stream_router_additional_coverage.feature # Feature: Stream Router additional uncovered branches # ============================================================ Scenario: Copying stream message with metadata override uses provided metadata Given the CleverAgents reactive system is available And I have a base stream message with context metadata Given I have a base stream message with context metadata When I copy the message with explicit metadata override Then the copy should use the provided metadata Scenario: Creating a hot stream initializes with initial value Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I create a hot stream named "hot_stream" with initial value 5 Then the hot stream should store the initial value Scenario: Creating a replay stream uses buffer size Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I create a replay stream named "replay_stream" with buffer size 3 Then the replay stream should be created with buffer size 3 Scenario: LangGraph operator without bridge raises routing error Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I build a langgraph operator "graph_execute" without bridge Then I should get a stream routing error about missing langgraph bridge Scenario: Map operator with unknown agent raises routing error Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I build a map operator targeting unknown agent "ghost" Then I should get a stream routing error about missing agent Scenario: Debounce, throttle, and delay operators are created Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I build debounce, throttle, and delay operators Then the temporal operators should be created successfully Scenario: Buffer and window operators with count are created Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I build buffer and window operators with count 2 Then the buffer and window operators should be created successfully Scenario: Take and skip operators are created Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I build take and skip operators Then the take and skip operators should be created successfully Scenario: Merge operator merges existing streams Given the CleverAgents reactive system is available And I have a base stream message with context metadata Given I have two source streams named "merge_x" and "merge_y" When I create a merge operator for those streams Then the merge operator should be usable Scenario: Accumulate operator with sum processes numbers Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I build an accumulate operator with sum Then the accumulate operator should sum incoming numbers Scenario: Transform extract_field returns field value Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I apply an extract_field transform to a dictionary message Then the extracted field should be returned Scenario: Evaluate condition equals and empty cases Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I evaluate empty and equals conditions against messages Then the empty condition should be true and equals should match Scenario: Agent mapper uses sync processor and handles errors Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I map messages through agent mapper success and failure paths Then the mapper should emit processed content and blank on error Scenario: Append accumulator with non-list leaves accumulator unchanged Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I apply append accumulator to non-list accumulator Then the accumulator should remain unchanged Scenario: Setup subscriptions ignores missing sources Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I setup subscriptions including a missing source Then no subscription should be added for the missing source Scenario: Split stream routes message when condition matches Given the CleverAgents reactive system is available And I have a base stream message with context metadata Given I have a stream "source_split" and target "target_split" When I split the source stream with a matching condition Then the target stream should receive the routed message Scenario: Subscribing to output and error streams delivers messages Given the CleverAgents reactive system is available And I have a base stream message with context metadata When I subscribe to output and error streams and emit messages Then the observers should receive the respective messages Scenario: Dispose handles stream dispose errors gracefully Given the CleverAgents reactive system is available And I have a base stream message with context metadata Given I have a stream router with disposable streams and subscriptions that may fail When I dispose the stream router with failing disposables Then the stream router internals should be cleared even on dispose errors # ============================================================ # Originally from: stream_router_agent_tool_coverage.feature # Feature: Stream Router agent and tool coverage # ============================================================ Scenario: SimpleToolAgent returns content when tool code is missing Given a SimpleToolAgent with a tool missing code When I process "payload" through the SimpleToolAgent Then the SimpleToolAgent result should be "payload" Scenario: SimpleToolAgent rejects tool with code block Given a SimpleToolAgent with a code block tool When I process "payload" through the SimpleToolAgent expecting rejection Then the SimpleToolAgent should raise a routing error about code blocks Scenario: SimpleToolAgent rejects code block via process_message_sync Given a SimpleToolAgent with a code block tool When I call process_message_sync with "payload" expecting rejection Then the SimpleToolAgent should raise a routing error about code blocks # TODO: Uncomment when step definitions are implemented # Scenario: SimpleLLMAgent returns empty prompt for blank template # Given a SimpleLLMAgent for prompt rendering # When I render the template "" with context: # | key | value | # | name | Ada | # Then the rendered prompt should be "" # # TODO: Uncomment when step definitions are implemented # Scenario: SimpleLLMAgent returns raw template when environment is missing # Given a SimpleLLMAgent for prompt rendering # And the SimpleLLMAgent template environment is "none" # When I render the template "Hello" with context: # | key | value | # | name | Ada | # Then the rendered prompt should be "Hello" # # TODO: Uncomment when step definitions are implemented # Scenario: SimpleLLMAgent renders template when environment succeeds # Given a SimpleLLMAgent for prompt rendering # And the SimpleLLMAgent template environment is "working" # When I render the template "Hello {{ name }}" with context: # | key | value | # | name | Ada | # Then the rendered prompt should be "Hello Ada" # # TODO: Uncomment when step definitions are implemented # Scenario: SimpleLLMAgent falls back to template on render failure # Given a SimpleLLMAgent for prompt rendering # And the SimpleLLMAgent template environment is "failing" # When I render the template "Hello {{ name }}" with context: # | key | value | # | name | Ada | # Then the rendered prompt should be "Hello {{ name }}" Scenario: SimpleLLMAgent resolves LLM with configured kwargs and caching Given a SimpleLLMAgent with provider config And a stub provider registry is installed When I resolve the LLM twice Then the registry should be called once with the configured kwargs And the resolved LLM should be cached Scenario: SimpleLLMAgent raises when LangChain messages are unavailable Given a SimpleLLMAgent with provider config And a stub provider registry is installed And LangChain message classes are unavailable When I process "ping" through the LLM agent Then I should receive a stream routing error about missing messages Scenario: SimpleLLMAgent process_message_sync returns LLM content Given a SimpleLLMAgent with system prompt and provider config And a stub provider registry is installed And LangChain message stubs are installed When I process 123 through the LLM agent via process_message_sync Then the LLM should receive system and human messages And the LLM agent result should be "llm-output" # ============================================================ # Originally from: stream_router_coverage.feature # Feature: Stream Router Coverage # ============================================================ # ============================================================ # Originally from: stream_router_misc_uncovered.feature # Feature: Stream Router remaining uncovered lines # ============================================================ Scenario: Converting dict route config uses defaults Given the CleverAgents reactive system is available When I convert a dict route config with only a name Then the stream config should use default values Scenario: Converting object route config uses defaults for missing attrs Given the CleverAgents reactive system is available When I convert a minimal object route config Then the stream config should use default values Scenario: Transform operator with type parameter applies replace Given the CleverAgents reactive system is available When I apply a transform operator with type replace Then the transform operator should update the field Scenario: Switch operator emits original message with no matches or defaults Given the CleverAgents reactive system is available When I run a switch operator with no matches and no defaults Then the switch operator should emit the original message Scenario: Unsupported condition returns false Given the CleverAgents reactive system is available When I evaluate an unsupported condition Then the unsupported condition result should be false Scenario: Agent mapper falls back when no processing methods exist Given the CleverAgents reactive system is available When I map a message with an agent lacking processors Then the mapper should return the original content with metadata # ============================================================ # Originally from: stream_router_new_branches.feature # Feature: Stream Router additional uncovered branches # ============================================================ Scenario: LangGraph operator uses bridge factory when available Given the CleverAgents reactive system is available Given a LangGraph bridge stub is registered on the stream router When I build a graph_execute operator through the bridge Then the bridge factory should be invoked and map data Scenario: Map operator processes message through registered agent Given the CleverAgents reactive system is available Given a dummy agent is registered on the stream router When I map a message using that agent Then the agent-mapped content should be returned with metadata Scenario: Filter operator passes matching condition Given the CleverAgents reactive system is available When I build a filter operator with equals condition Then the filter should emit only matching values Scenario: Transform operator rejects unregistered fn string Given the CleverAgents reactive system is available When I build a transform operator with an unregistered function string Then I should get a stream routing error about unregistered transform Scenario: Switch operator handles case operators pipeline Given the CleverAgents reactive system is available When I run a switch operator with a case operator pipeline Then the switch case should apply its operators Scenario: Switch operator routes to a target stream case Given the CleverAgents reactive system is available Given I have an existing target stream named "case_target" When I run a switch operator that routes to that case target Then the case target stream should receive the message Scenario: Unknown operator raises routing error Given the CleverAgents reactive system is available When I build an operator with an unknown type Then I should get a stream routing error about unknown operator Scenario: Extract field transform returns requested value and fallback Given the CleverAgents reactive system is available When I apply an extract_field transform to different message types Then the transform should return the field value or original message Scenario: Evaluate condition supports equals and field branches Given the CleverAgents reactive system is available When I evaluate equals and field conditions Then both condition checks should return true Scenario: Append accumulator returns unchanged when accumulator is not a list Given the CleverAgents reactive system is available When I apply the append accumulator to a non-list accumulator Then the accumulator should be returned unchanged Scenario: Setup subscriptions skips missing sources and subscribes existing Given the CleverAgents reactive system is available Given I prepare stream config with existing and missing subscriptions When I setup subscriptions for that config Then only existing sources should be subscribed # ============================================================ # Originally from: stream_router_remaining_coverage.feature # Feature: Reactive Stream Router Edge Cases # ============================================================ Scenario: Registering an operation with non-alphanumeric characters is rejected Given a fresh SimpleToolAgent registry When I register an operation named "bad-name!" with a lambda Then a ValueError should be raised about operation name format Scenario: A tool agent with a malformed tool entry passes content through unchanged Given a SimpleToolAgent whose tools list contains a non-dict entry When I process content "hello" through that SimpleToolAgent Then the SimpleToolAgent should return "hello" unchanged Scenario: A tool agent with an unrecognised operation name passes content through unchanged Given a SimpleToolAgent with an unknown operation "nonexistent_op" When I process content "data" through that SimpleToolAgent Then the SimpleToolAgent should return "data" unchanged Scenario: A tool agent safely returns empty output when an operation throws Given a SimpleToolAgent with an operation that raises an exception When I process content "boom" through that SimpleToolAgent Then the SimpleToolAgent should return an empty string # Transform registration safety Scenario: Registering a transform with non-alphanumeric characters is rejected Given a fresh ReactiveStreamRouter registry When I register a transform named "bad@name" with a lambda Then a ValueError should be raised about transform name format # Operator construction validation Scenario: A transform operator created without a function or type is rejected Given a reactive stream router for coverage And a stream named "transform_test" exists on the router When I create a transform operator with neither fn nor type Then a StreamRoutingError should be raised about missing transform params # LLM agent provider resolution Scenario: An LLM agent resolves its provider without forwarding absent optional parameters Given a SimpleLLMAgent with no temperature or max_tokens or max_retries And a stub provider registry is active When I resolve the LLM on that agent Then the LLM should be resolved without optional kwargs Scenario: An LLM agent with no system prompt sends only the user message to the model Given a SimpleLLMAgent with an empty system prompt And a stub provider registry is active When I process content "test input" through that SimpleLLMAgent Then the LLM should receive only a HumanMessage # LangGraph bridge delegation Scenario: A graph operator delegates to the bridge factory when the method exists Given a reactive stream router for coverage And a LangGraph bridge stub with a graph_execute factory is registered When I create a graph_execute operator via the bridge Then the bridge factory method should produce a valid operator Scenario: A graph operator raises a clear error when the bridge lacks the factory method Given a reactive stream router for coverage And a LangGraph bridge stub without the requested factory method is registered When I attempt to create a graph_execute operator via the bridge Then a StreamRoutingError should be raised about LangGraph bridge # Switch operator resilience Scenario: A switch case pipeline tolerates an operator that resolves to nothing Given a reactive stream router for coverage And a stream named "switch_null_op" exists on the router When I run a switch operator whose case pipeline includes a None operator Then the switch should still emit the message through the pipeline Scenario: A switch case with a nonexistent target stream falls through to the default Given a reactive stream router for coverage And a stream named "switch_missing_target" exists on the router When I run a switch with a matching case whose target stream does not exist Then the switch should fall through to the default Scenario: A switch default pipeline tolerates an operator that resolves to nothing Given a reactive stream router for coverage And a stream named "switch_default_null" exists on the router When I run a switch operator whose default pipeline includes a None operator Then the switch should still emit the message through the default pipeline # Message transformation edge cases Scenario: A replace transform on a non-dictionary message passes it through unchanged Given a reactive stream router for coverage When I apply a replace transform to a non-dict message Then the message should be returned unchanged Scenario: An extract-field transform retrieves the named value from a dictionary message Given a reactive stream router for coverage When I apply an extract_field transform to a dict message with the field Then the extracted field value should be returned Scenario: An extract-field transform on a non-dictionary message passes it through Given a reactive stream router for coverage When I apply an extract_field transform to a non-dict message Then the non-dict message should be returned from extract_field Scenario: An unrecognised transform type passes the message through unchanged Given a reactive stream router for coverage When I apply a transform with unknown type to a message Then the original message should be returned # Condition evaluation edge cases Scenario: A field condition matches when the dictionary message contains the field Given a reactive stream router for coverage When I evaluate a field condition against a dict message containing the field Then the condition should return true Scenario: A field condition does not match when the dictionary message lacks the field Given a reactive stream router for coverage When I evaluate a field condition against a dict message missing the field Then the condition should return false Scenario: A field condition does not match against a non-dictionary message Given a reactive stream router for coverage When I evaluate a field condition against a non-dict message Then the condition should return false # Stream splitting and merging edge cases Scenario: Splitting a stream ignores condition targets that do not exist Given a reactive stream router for coverage And a stream named "split_source" exists on the router When I split the stream with a condition targeting a nonexistent stream Then no error should occur and the message should not route Scenario: Merging streams into a nonexistent target auto-creates it Given a reactive stream router for coverage And a stream named "merge_src_a" exists on the router And a stream named "merge_src_b" exists on the router When I merge streams into a target that does not exist yet Then the target stream should be created and receive merged messages Scenario: Merging streams silently skips source streams that do not exist Given a reactive stream router for coverage And a stream named "merge_src_c" exists on the router When I merge streams including a nonexistent source into an existing target Then only the existing source should be subscribed # Router disposal Scenario: Disposing the router tolerates streams that lack a dispose method Given a reactive stream router for coverage And a stream that lacks a dispose method is injected into the router When I dispose the router Then the router should be fully cleared without errors # ============================================================ # Originally from: stream_router_uncovered_paths.feature # Feature: Stream Router uncovered branches # ============================================================ Scenario: Copying stream message without metadata override deep copies entries Given the CleverAgents reactive system is available Given I have a base stream message with context metadata When I copy the message without metadata override Then the metadata should be deep-copied except context Scenario: Map operator without params should raise routing error Given the CleverAgents reactive system is available When I build a map operator without required params Then I should get a stream routing error about missing map params Scenario: Buffer operator without count should raise routing error Given the CleverAgents reactive system is available When I build a buffer operator without count Then I should get a stream routing error about buffer count Scenario: Window operator without count should raise routing error Given the CleverAgents reactive system is available When I build a window operator without count Then I should get a stream routing error about window count Scenario: Condition check for missing field returns false Given the CleverAgents reactive system is available When I evaluate a field condition against a message without that field Then the condition result should be false Scenario: Accumulator append initializes list and appends items Given the CleverAgents reactive system is available When I apply the append accumulator with list initialization Then the accumulator should return a list with the item Scenario: Sending message to unknown stream raises routing error Given the CleverAgents reactive system is available When I send a message to an unknown stream Then I should get a stream routing error about missing stream Scenario: Splitting from unknown source raises routing error Given the CleverAgents reactive system is available When I split a stream from an unknown source Then I should get a stream routing error about missing source Scenario: Creating stream using string name initializes config Given the CleverAgents reactive system is available When I create a stream from the string name "string_stream" Then the stream should exist in the router Scenario: Duplicate stream creation raises routing error Given the CleverAgents reactive system is available Given I have already created a stream named "dup_stream" When I try to create the stream "dup_stream" again Then I should get a stream routing error about duplicate stream Scenario: Map operator with function param uses fallback Given the CleverAgents reactive system is available When I map a message using function param "noop_function" Then the mapped result should equal the original message Scenario: Transform operator with unregistered fn raises error Given the CleverAgents reactive system is available When I build a transform operator with an invalid function string Then I should get a stream routing error about unregistered transform fn Scenario: Filter operator without condition raises routing error Given the CleverAgents reactive system is available When I build a filter operator without condition Then I should get a stream routing error about missing filter condition Scenario: Switch operator applies default operators pipeline Given the CleverAgents reactive system is available When I run a switch operator with default operators against a message Then the switch operator should output the transformed value Scenario: Switch operator routes to default stream subject Given the CleverAgents reactive system is available When I run a switch operator that targets a default stream subject Then the default stream should emit its initial value Scenario: Apply replace transform updates dictionary field Given the CleverAgents reactive system is available When I apply a replace transform to a dictionary message Then the dictionary field should be updated Scenario: Sum accumulator initializes and sums numeric messages Given the CleverAgents reactive system is available When I apply the sum accumulator to numeric messages Then the accumulator should produce the summed value Scenario: Merge streams creates target when missing Given the CleverAgents reactive system is available Given I have two source streams named "merge_a" and "merge_b" When I merge the streams into a new target "merge_output" Then the merged target stream should exist Scenario: Dispose cleans up subscriptions and stream disposables Given the CleverAgents reactive system is available Given I have a stream router with disposable streams and subscriptions When I dispose the stream router Then the stream router internals should be cleared # ============================================================ # Originally from: stream_router_unsafe_and_llm_coverage.feature # Feature: SimpleToolAgent code block rejection and SimpleLLMAgent render_prompt coverage # ============================================================ Scenario: SimpleToolAgent rejects code block even with unsafe flag Given a stream router unsafe tool agent with a valid code block When the stream router unsafe agent processes input expecting rejection Then the stream router unsafe agent should raise StreamRoutingError about code Scenario: SimpleToolAgent rejects failing code block even with unsafe flag Given a stream router unsafe tool agent with a failing code block When the stream router unsafe agent processes input expecting rejection Then the stream router unsafe agent should raise StreamRoutingError about code Scenario: SimpleToolAgent safe mode rejects code blocks Given a stream router safe tool agent with a code block When the stream router safe agent processes input expecting rejection Then the stream router safe agent should raise StreamRoutingError about code Scenario: SimpleLLMAgent render_prompt with no template env returns template as-is Given a stream router llm agent with no template env When the stream router llm agent renders "Hello {{ name }}" with context name "World" Then the stream router llm render result should be "Hello {{ name }}" Scenario: SimpleLLMAgent render_prompt with template env failure returns template Given a stream router llm agent with a failing template env When the stream router llm agent renders "Hello {{ name }}" with context name "World" Then the stream router llm render result should be "Hello {{ name }}" Scenario: SimpleLLMAgent render_prompt with empty template returns empty string Given a stream router llm agent for empty template test When the stream router llm agent renders empty template Then the stream router llm render result should be empty string Scenario: SimpleToolAgent processes named operation successfully Given a stream router tool agent with uppercase operation When the stream router tool agent processes "hello" through operation Then the stream router tool agent operation result should be "HELLO" Scenario: SimpleToolAgent processes unknown operation falls back to identity Given a stream router tool agent with unknown operation "nonexistent_xyz" When the stream router tool agent processes "keep_me" through operation Then the stream router tool agent operation result should be "keep_me" # M5: SimpleLLMAgent._resolve_llm forwards options to registry.create_llm (#11223). @tdd_issue @tdd_issue_11223 Scenario: SimpleLLMAgent forwards options block to LLM constructor Given a stream router llm agent with options block containing custom base url When the stream router llm agent resolves the llm Then the llm constructor should have received the custom base url # M5: actor without options block is unaffected (#11223). @tdd_issue @tdd_issue_11223 Scenario: SimpleLLMAgent without options block calls LLM constructor without extra kwargs Given a stream router llm agent without options block When the stream router llm agent resolves the llm Then the llm constructor should not have received extra kwargs # M5: top-level keys take precedence over duplicates in options (#11223). @tdd_issue @tdd_issue_11223 Scenario: SimpleLLMAgent top-level key takes precedence over options duplicate Given a stream router llm agent with top-level temperature and options block When the stream router llm agent resolves the llm Then the llm constructor should have received the top-level temperature