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.
227 lines
10 KiB
Gherkin
227 lines
10 KiB
Gherkin
Feature: LLM Agent Initialization and Message Processing
|
|
As a developer
|
|
I want LLM agents to initialize correctly across providers, resolve API keys, process messages, and manage conversation history
|
|
So that LLM-powered agents operate reliably with OpenAI, Anthropic, and Google providers
|
|
|
|
Background:
|
|
Given the LLM agent system is initialized
|
|
|
|
Scenario: LLMAgent initialization with default configuration
|
|
Given I have a basic LLM agent configuration
|
|
When I create an LLM agent with default settings
|
|
Then the LLM agent should be initialized successfully
|
|
And the provider should be "openai"
|
|
And the model should be "gpt-3.5-turbo"
|
|
And the temperature should be 0.7
|
|
And the max_tokens should be 1000
|
|
And the system message should be "You are a helpful assistant."
|
|
|
|
Scenario: LLMAgent initialization with custom configuration
|
|
Given I have a custom LLM agent configuration
|
|
When I create an LLM agent with custom settings
|
|
Then the LLM agent should be initialized successfully
|
|
And the custom configuration should be applied
|
|
|
|
Scenario: LLMAgent initialization with missing API key
|
|
Given I have an LLM agent configuration without API key
|
|
When I try to create an LLM agent
|
|
Then an LLM ConfigurationError should be raised
|
|
And the error should mention missing API key
|
|
|
|
Scenario: LLMAgent initialization with unsupported provider
|
|
Given I have an LLM agent configuration with unsupported provider
|
|
When I try to create an LLM agent
|
|
Then an LLM ConfigurationError should be raised
|
|
And the error should mention unsupported provider
|
|
|
|
Scenario: API key resolution from configuration
|
|
Given I have an LLM agent configuration with API key in config
|
|
When I create an LLM agent
|
|
Then the API key should be resolved from configuration
|
|
|
|
Scenario: API key resolution from environment variable
|
|
Given I have an environment variable set for OpenAI API key
|
|
And I have an LLM agent configuration for environment test
|
|
When I create an LLM agent with OpenAI provider
|
|
Then the API key should be resolved from environment
|
|
|
|
Scenario: API key resolution from environment for Anthropic
|
|
Given I have an environment variable set for Anthropic API key
|
|
And I have an LLM agent configuration for Anthropic without API key
|
|
When I create an LLM agent with Anthropic provider
|
|
Then the API key should be resolved from environment
|
|
|
|
Scenario: API key resolution from environment for Google
|
|
Given I have an environment variable set for Google API key
|
|
And I have an LLM agent configuration for Google without API key
|
|
When I create an LLM agent with Google provider
|
|
Then the API key should be resolved from environment
|
|
|
|
Scenario: OpenAI provider configuration setup
|
|
Given I have an LLM agent configuration for OpenAI
|
|
When I create an LLM agent with OpenAI provider
|
|
Then the OpenAI configuration should be set up correctly
|
|
And the base URL should be "https://api.openai.com/v1/chat/completions"
|
|
And the headers should contain authorization bearer token
|
|
|
|
Scenario: Anthropic provider configuration setup
|
|
Given I have an LLM agent configuration for Anthropic
|
|
When I create an LLM agent with Anthropic provider
|
|
Then the Anthropic configuration should be set up correctly
|
|
And the base URL should be "https://api.anthropic.com/v1/messages"
|
|
And the headers should contain x-api-key
|
|
|
|
Scenario: Google provider configuration setup
|
|
Given I have an LLM agent configuration for Google
|
|
When I create an LLM agent with Google provider
|
|
Then the Google configuration should be set up correctly
|
|
And the base URL should contain the model name
|
|
And the API key should be in the URL as query parameter
|
|
|
|
Scenario: Process message without template
|
|
Given I have an initialized LLM agent
|
|
When I process a simple message without template
|
|
Then the message should be processed successfully
|
|
And the response should be returned
|
|
|
|
Scenario: Process message with template
|
|
Given I have an initialized LLM agent with template configuration
|
|
And I have a template renderer with test template
|
|
When I process a message with template variables
|
|
Then the template should be rendered with variables
|
|
And the processed message should be used for LLM call
|
|
|
|
Scenario: Process message with OpenAI API call success
|
|
Given I have an initialized OpenAI LLM agent
|
|
When I process a message and OpenAI API returns success
|
|
Then the OpenAI API should be called with correct payload
|
|
And the response should be extracted from choices
|
|
And the result should be returned
|
|
|
|
Scenario: Process message with OpenAI API call error
|
|
Given I have an initialized OpenAI LLM agent
|
|
When I process a message and OpenAI API returns error
|
|
Then an LLM ExecutionError should be raised
|
|
And the error should contain API error details
|
|
|
|
Scenario: Process message with Anthropic API call success
|
|
Given I have an initialized Anthropic LLM agent
|
|
When I process a message and Anthropic API returns success
|
|
Then the Anthropic API should be called with correct payload
|
|
And the response should be extracted from content
|
|
And the result should be returned
|
|
|
|
Scenario: Process message with Anthropic API call error
|
|
Given I have an initialized Anthropic LLM agent
|
|
When I process a message and Anthropic API returns error
|
|
Then an LLM ExecutionError should be raised
|
|
And the error should contain API error details
|
|
|
|
Scenario: Process message with Google API call success
|
|
Given I have an initialized Google LLM agent
|
|
When I process a message and Google API returns success
|
|
Then the Google API should be called with correct payload
|
|
And the response should be extracted from candidates
|
|
And the result should be returned
|
|
|
|
Scenario: Process message with Google API call error
|
|
Given I have an initialized Google LLM agent
|
|
When I process a message and Google API returns error
|
|
Then an LLM ExecutionError should be raised
|
|
And the error should contain API error details
|
|
|
|
Scenario: Memory enabled - store last message and response
|
|
Given I have an initialized LLM agent with memory enabled
|
|
When I process a message successfully
|
|
Then the last message should be stored in memory
|
|
And the last response should be stored in memory
|
|
|
|
Scenario: Memory disabled - no storage
|
|
Given I have an initialized LLM agent with memory disabled
|
|
When I process a message successfully
|
|
Then no memory updates should occur
|
|
|
|
Scenario: OpenAI conversation history with memory
|
|
Given I have an initialized OpenAI LLM agent with memory enabled
|
|
And I have existing conversation history in memory
|
|
When I process a message
|
|
Then the conversation history should be included in API call
|
|
And the new message should be added to history
|
|
And the response should be added to history
|
|
And history should be limited to max_history setting
|
|
|
|
Scenario: OpenAI conversation history without memory
|
|
Given I have an initialized OpenAI LLM agent with memory disabled
|
|
When I process a message
|
|
Then only system message and current user message should be sent
|
|
And no history should be included
|
|
|
|
Scenario: Get capabilities
|
|
Given I have an initialized LLM agent
|
|
When I request the agent capabilities
|
|
Then the capabilities should include text-generation
|
|
And the capabilities should include conversation
|
|
And the capabilities should include reasoning
|
|
And the capabilities should include analysis
|
|
And the capabilities should include creative-writing
|
|
|
|
Scenario: Get metadata
|
|
Given I have an initialized LLM agent with custom configuration
|
|
When I request the agent metadata
|
|
Then the metadata should include base agent metadata
|
|
And the metadata should include provider information
|
|
And the metadata should include model information
|
|
And the metadata should include temperature setting
|
|
And the metadata should include max_tokens setting
|
|
And the metadata should include memory_enabled setting
|
|
|
|
Scenario: Exception handling in process_message
|
|
Given I have an initialized LLM agent
|
|
When an exception occurs during message processing
|
|
Then an LLM ExecutionError should be raised
|
|
And the LLM error should be logged
|
|
And the original error should be wrapped
|
|
|
|
Scenario: Context parameter handling
|
|
Given I have an initialized LLM agent
|
|
When I process a message with context parameter
|
|
Then the context should be available for template rendering
|
|
And the context should be passed to API calls
|
|
|
|
Scenario: Template variable merging
|
|
Given I have an initialized LLM agent with template
|
|
When I process a message with template_vars in config
|
|
Then the template_vars should be merged with message and context
|
|
And all variables should be available for template rendering
|
|
|
|
Scenario: OpenAI message structure validation
|
|
Given I have an initialized OpenAI LLM agent
|
|
When I process a message
|
|
Then the messages array should have system message first
|
|
And the messages array should have user message last
|
|
And the payload should have required OpenAI fields
|
|
|
|
Scenario: Anthropic message structure validation
|
|
Given I have an initialized Anthropic LLM agent
|
|
When I process a message
|
|
Then the payload should have system field separate
|
|
And the messages array should only contain user message
|
|
And the payload should have required Anthropic fields
|
|
|
|
Scenario: Google message structure validation
|
|
Given I have an initialized Google LLM agent
|
|
When I process a message
|
|
Then the contents should have parts with combined system and user text
|
|
And the generationConfig should have temperature and maxOutputTokens
|
|
And the payload should have required Google fields
|
|
|
|
Scenario: History management edge cases
|
|
Given I have an initialized OpenAI LLM agent with memory enabled
|
|
And I have a conversation history at maximum length
|
|
When I process a new message
|
|
Then the oldest messages should be removed
|
|
And the history length should not exceed max_history
|
|
|
|
# Note: Enhanced conversation history tests removed due to environment compatibility issues
|
|
# These tests require async execution context that conflicts with the test runner
|