9753b31c7e
CI / quality (push) Successful in 36s
CI / lint (push) Successful in 38s
CI / typecheck (push) Successful in 49s
CI / security (push) Successful in 51s
CI / integration_tests (push) Successful in 55s
CI / unit_tests (push) Successful in 3m35s
CI / build (push) Successful in 33s
CI / coverage (push) Successful in 3m36s
CI / status-check (push) Successful in 3s
Add 13 BDD scenarios covering previously uncovered code paths: - SAFE_BUILTINS validation (sandbox.py: 0% → 100%) - ConfigurationError re-raise path (config.py: 99.3% → 100%) - CLI hello/main functions (cli.py: 72.7% → 90.9%) - GraphState message truncation (state.py: 98.7% → 100%) - ProgressBarManager update/context rendering (progress.py: 0% → 87.7%) - MessageRouter regex/exact/contains routing (message_router.py: 0% → 59.4%) - RoutingAdapter parse_routing_command (routing_adapter.py) - DynamicRouterNode pattern-based routing (dynamic_router.py) - EnhancedTemplateRegistry unknown template type (enhanced_registry.py: 99.2%) - CompositeAgent null-graph error path (composite.py: 97.8% → 98.6%) Cover routing_adapter.py (17% → 100%): all GOTO/ROUTE patterns, create_routing_node, create_conditional_router, dynamic config conversion. Cover dynamic_router.py (21% → 87%): execute with empty/dict/string messages, extract_message with colon parsing, config creation, graph extension with edge generation. Cover message_router.py (59% → 78%): regex, exact, contains, prefix, suffix match types, invalid regex handling, non-string message, set_state. Exercise Node._prepare_conversation_history with invalid configs, _runtime error paths, _execute_message_router with rules, _execute_agent with current_message and metadata propagation, _execute_function with dynamic_router, and _execute_conditional with content_contains/content_not_contains/content_starts_with and custom condition types. Improves nodes.py from 71.3% to 72.5%. Exercise PureGraphConfig, PureLangGraph init with dict/config, RxPyLangGraphBridge registration/connection/lookup, ReactiveStreamRouter operator creation and condition functions, ReactiveConfigParser config/route/graph parsing, ToolAgent tool execution with JSON, space-separated, single, file_read, progress_bar invocations, and ReactiveCleverAgentsApp init/dispose/visualization.
207 lines
8.4 KiB
Gherkin
207 lines
8.4 KiB
Gherkin
Feature: Agent Lifecycle and Message Processing
|
|
As a developer
|
|
I want agents to handle initialization, message processing, memory, streaming, and disposal correctly
|
|
So that agent lifecycle and RxPy integration behave reliably in production
|
|
|
|
Background:
|
|
Given I have a clean test environment for agents base
|
|
|
|
Scenario: Test Agent class initialization
|
|
Given I have agent configuration with name and config
|
|
And I have a template renderer
|
|
When I create an Agent instance
|
|
Then the agent should be initialized correctly
|
|
And input and output streams should be created
|
|
And the processing pipeline should be set up
|
|
|
|
Scenario: Test Agent message processing with context
|
|
Given I have an initialized Agent instance
|
|
When I send a message with context to the agent
|
|
Then the message should be processed with context
|
|
And the output stream should emit the result
|
|
|
|
Scenario: Test Agent message processing without context
|
|
Given I have an initialized Agent instance
|
|
When I send a message without context to the agent
|
|
Then the message should be processed with empty context
|
|
And the output stream should emit the result
|
|
|
|
Scenario: Test Agent processing error handling
|
|
Given I have an Agent instance that raises errors
|
|
When I send a message that causes processing error
|
|
Then an ExecutionError should be raised
|
|
And the error message should contain agent name
|
|
|
|
Scenario: Test Agent get_capabilities method
|
|
Given I have an initialized Agent instance
|
|
When I call get_capabilities
|
|
Then a list of capabilities should be returned
|
|
|
|
Scenario: Test Agent get_metadata method
|
|
Given I have an initialized Agent instance with model and provider
|
|
When I call get_metadata
|
|
Then metadata should include name type and capabilities
|
|
And metadata should include model and provider if configured
|
|
|
|
Scenario: Test Agent legacy process method
|
|
Given I have an initialized Agent instance
|
|
When I call the legacy process method
|
|
Then it should delegate to process_message
|
|
|
|
Scenario: Test Agent subscribe_to_output method
|
|
Given I have an initialized Agent instance
|
|
And I have an observer
|
|
When I subscribe the observer to output
|
|
Then the observer should receive output messages
|
|
|
|
Scenario: Test Agent create_observable method
|
|
Given I have an initialized Agent instance
|
|
When I create an observable from the agent
|
|
Then an observable should be returned
|
|
|
|
Scenario: Test Agent dispose method
|
|
Given I have an initialized Agent instance
|
|
When I dispose the agent
|
|
Then streams should be disposed properly
|
|
|
|
Scenario: Test AgentWithMemory initialization
|
|
Given I have agent configuration for memory agent
|
|
And I have a template renderer
|
|
When I create an AgentWithMemory instance
|
|
Then the agent should have empty memory
|
|
And a memory lock should be created
|
|
|
|
Scenario: Test AgentWithMemory save_memory
|
|
Given I have an AgentWithMemory instance with data
|
|
When I save the memory
|
|
Then a deep copy of memory should be returned
|
|
|
|
Scenario: Test AgentWithMemory load_memory success
|
|
Given I have an AgentWithMemory instance
|
|
When I load valid memory data
|
|
Then the memory should be updated
|
|
|
|
Scenario: Test AgentWithMemory load_memory with invalid data
|
|
Given I have an AgentWithMemory instance
|
|
When I load non-dict memory data
|
|
Then an AgentCreationError should be raised
|
|
|
|
Scenario: Test AgentWithMemory update_memory
|
|
Given I have an AgentWithMemory instance
|
|
When I update memory with key and value
|
|
Then the memory should be updated asynchronously
|
|
And memory lock should be used
|
|
|
|
Scenario: Test AgentWithMemory get_memory with existing key
|
|
Given I have an AgentWithMemory instance with data
|
|
When I get memory for existing key
|
|
Then the correct value should be returned
|
|
|
|
Scenario: Test AgentWithMemory get_memory with missing key
|
|
Given I have an AgentWithMemory instance
|
|
When I get memory for missing key with default
|
|
Then the default value should be returned
|
|
|
|
Scenario: Test AgentWithMemory process wrapper with lock
|
|
Given I have an AgentWithMemory instance
|
|
When I process a message through the agent
|
|
Then memory lock should be acquired during processing
|
|
|
|
Scenario: Test StreamableAgent as_operator method
|
|
Given I have a StreamableAgent instance
|
|
When I create an operator from the agent
|
|
Then an RxPy operator should be returned
|
|
And the operator should process messages through agent
|
|
|
|
Scenario: Test StreamableAgent map_operator method
|
|
Given I have a StreamableAgent instance
|
|
When I create a map operator from the agent
|
|
Then a map operator should be returned
|
|
And the operator should process values asynchronously
|
|
|
|
Scenario: Test StreamableAgent filter_operator method
|
|
Given I have a StreamableAgent instance
|
|
And I have a filter condition function
|
|
When I create a filter operator from the agent
|
|
Then a filter operator should be returned
|
|
And the operator should filter based on agent output
|
|
|
|
Scenario: Test Agent tuple message data handling
|
|
Given I have an initialized Agent instance
|
|
When I send a tuple message data with context
|
|
Then the message and context should be extracted correctly
|
|
|
|
Scenario: Test Agent non-tuple message data handling
|
|
Given I have an initialized Agent instance
|
|
When I send non-tuple message data
|
|
Then the message should be processed with empty context
|
|
|
|
Scenario: Test StreamableAgent operator subscription flow
|
|
Given I have a StreamableAgent instance
|
|
And I have a source observable
|
|
When I apply the agent as operator to source
|
|
Then the agent should subscribe to source
|
|
And output should be forwarded to observer
|
|
|
|
Scenario: Test StreamableAgent operator error propagation
|
|
Given I have a StreamableAgent instance
|
|
And I have a source observable that errors
|
|
When I apply the agent as operator to source
|
|
Then errors should be propagated to observer
|
|
|
|
Scenario: Test StreamableAgent operator completion
|
|
Given I have a StreamableAgent instance
|
|
And I have a source observable that completes
|
|
When I apply the agent as operator to source
|
|
Then completion should be propagated to observer
|
|
|
|
Scenario: Test StreamableAgent map_operator result handling
|
|
Given I have a StreamableAgent instance
|
|
When I use map_operator with observable
|
|
Then results should be awaited from future
|
|
And only first result should be used
|
|
|
|
Scenario: Test StreamableAgent filter_operator result handling
|
|
Given I have a clean test environment for agents base
|
|
Given I have a StreamableAgent instance
|
|
And I have a condition that returns boolean
|
|
When I use filter_operator with observable
|
|
Then condition should be applied to agent output
|
|
And boolean result should determine filtering
|
|
|
|
Scenario: Test Agent send_message method directly with RxPy pipeline
|
|
Given I have a clean test environment for agents base
|
|
Given I have an initialized Agent instance
|
|
When I use send_message method with the RxPy pipeline
|
|
Then the message should be sent to input stream
|
|
And RxPy pipeline should process the message
|
|
|
|
Scenario: Test Agent actual RxPy pipeline integration
|
|
Given I have a clean test environment for agents base
|
|
Given I have an initialized Agent instance with working pipeline
|
|
When I send a message using the actual RxPy pipeline
|
|
Then the pipeline should process the message asynchronously
|
|
And the result should be emitted to output stream
|
|
|
|
Scenario: Test Agent dispose method with actual streams
|
|
Given I have a clean test environment for agents base
|
|
Given I have an initialized Agent instance
|
|
When I dispose the agent with real streams
|
|
Then stream dispose methods should be called properly
|
|
And resources should be cleaned up
|
|
|
|
Scenario: Test Agent process_wrapper exception handling
|
|
Given I have a clean test environment for agents base
|
|
Given I have an Agent instance that throws processing exceptions
|
|
When I test the process_wrapper exception handling
|
|
Then ExecutionError should be raised with agent name
|
|
And original exception should be wrapped
|
|
|
|
Scenario: Test StreamableAgent operator creation and usage
|
|
Given I have a clean test environment for agents base
|
|
Given I have a StreamableAgent instance
|
|
When I create and test all operator methods
|
|
Then as_operator should return functional operator
|
|
And map_operator should return functional map operator
|
|
And filter_operator should return functional filter operator
|