Feature: Consolidated Ai Models Providers
  Combined scenarios from: aimodelscredentials_coverage, aimodelserrors_coverage, aimodelsproviders_coverage, anthropic_provider, google_provider, langsmith_config, openrouter_provider

  # ============================================================
  # Originally from: aimodelscredentials_coverage.feature
  # Feature: AI Models Credentials Domain Model Coverage
  # ============================================================

  Scenario: Import and instantiate ModelProviderOption with all fields
    Given the cleveragents package is available
        When I import ModelProviderOption from aimodelscredentials
        Then the ModelProviderOption class should be available
        And I can create a ModelProviderOption with publishers, config, and priority


  Scenario: Create ModelProviderOption with minimal required fields
    Given the cleveragents package is available
        When I create a ModelProviderOption with only priority set to 1
        Then the ModelProviderOption should have priority 1
        And the publishers dictionary should be empty
        And the config should be None


  Scenario: Create ModelProviderOption with publishers dictionary
    Given the cleveragents package is available
        When I create a ModelProviderOption with complex publishers structure
        Then the publishers field should contain the expected dictionary structure
        And the ModelPublisher enum values should be properly handled


  Scenario: Create ModelProviderOption with ModelProviderConfigSchema
    Given the cleveragents package is available
        When I create a ModelProviderOption with a config object
        Then the config field should contain the ModelProviderConfigSchema instance
        And the config should be properly validated


  Scenario: Validate ModelProviderOption strips whitespace
    Given the cleveragents package is available
        When I create a ModelProviderOption with strings containing whitespace
        Then the string fields should have whitespace stripped


  Scenario: Validate ModelProviderOption assignment validation
    Given the cleveragents package is available
        When I create a ModelProviderOption instance
        And I update its fields with new values
        Then the assignment validation should be triggered
        And the values should be properly validated


  Scenario: Validate ModelProviderOption populate by name
    Given the cleveragents package is available
        When I create a ModelProviderOption using field aliases
        Then the fields should be populated correctly by name


  Scenario: Validate ModelProviderOption use enum values
    Given the cleveragents package is available
        When I create a ModelProviderOption with ModelPublisher enums
        Then the enum values should be used in serialization
        And the model should handle enum values properly


  Scenario: Test ModelProviderOption field defaults
    Given the cleveragents package is available
        When I create a ModelProviderOption with default fields
        Then publishers should default to an empty dictionary
        And config should default to None


  Scenario: Test ModelProviderOption field validation with invalid data
    Given the cleveragents package is available
        When I try to create a ModelProviderOption with invalid priority
        Then a ModelProviderOption validation error should be raised
        And the error should indicate the priority field issue


  Scenario: Test ModelProviderOption model config settings
    Given the cleveragents package is available
        When I examine the ModelProviderOption model_config
        Then the ModelProviderOption str_strip_whitespace should be True
        And the ModelProviderOption validate_assignment should be True
        And the ModelProviderOption arbitrary_types_allowed should be False
        And the ModelProviderOption populate_by_name should be True
        And the ModelProviderOption use_enum_values should be True


  Scenario: Test ModelProviderOption with nested publisher structures
    Given the cleveragents package is available
        When I create a ModelProviderOption with nested publisher dictionaries
        Then the nested structure should be properly maintained
        And the ModelPublisher boolean values should work correctly


  Scenario: Test ModelProviderOption serialization and deserialization
    Given the cleveragents package is available
        When I serialize a ModelProviderOption to dict
        And I deserialize it back to ModelProviderOption
        Then the round-trip should preserve all data


  Scenario: Test ModelProviderOption with None config field
    Given the cleveragents package is available
        When I explicitly set config to None in ModelProviderOption
        Then the config field should accept None value
        And the model should be valid


  Scenario: Test ModelProviderOption priority field requirement
    Given the cleveragents package is available
        When I try to create a ModelProviderOption without priority
        Then a ModelProviderOption validation error should be raised for missing required field

  # ============================================================
  # Originally from: aimodelserrors_coverage.feature
  # Feature: AI Models Errors Coverage
  # ============================================================

  Scenario: Create ModelError with overloaded error type
    Given I import the ModelError class
    When I create a ModelError with kind "OVERLOADED"
    And I set retriable to true
    And I set retryafterseconds to 30
    Then the ModelError instance should be created successfully
    And the kind should be "ErrOverloaded"
    And the retriable flag should be true
    And the retry after seconds should be 30


  Scenario: Create ModelError with context too long error
    Given I import the ModelError class
    When I create a ModelError with kind "CONTEXT_TOO_LONG"
    And I set retriable to false
    And I set retryafterseconds to 0
    Then the ModelError instance should be created successfully
    And the kind should be "ErrContextTooLong"
    And the retriable flag should be false
    And the retry after seconds should be 0


  Scenario: Create ModelError with rate limited error
    Given I import the ModelError class
    When I create a ModelError with kind "RATE_LIMITED"
    And I set retriable to true
    And I set retryafterseconds to 60
    Then the ModelError instance should be created successfully
    And the kind should be "ErrRateLimited"
    And the retriable flag should be true
    And the retry after seconds should be 60


  Scenario: Create ModelError with subscription quota exhausted
    Given I import the ModelError class
    When I create a ModelError with kind "SUBSCRIPTION_QUOTA_EXHAUSTED"
    And I set retriable to false
    And I set retryafterseconds to 3600
    Then the ModelError instance should be created successfully
    And the kind should be "ErrSubscriptionQuotaExhausted"
    And the retriable flag should be false
    And the retry after seconds should be 3600


  Scenario: Create ModelError with other error type
    Given I import the ModelError class
    When I create a ModelError with kind "OTHER"
    And I set retriable to true
    And I set retryafterseconds to 10
    Then the ModelError instance should be created successfully
    And the kind should be "ErrOther"
    And the retriable flag should be true
    And the retry after seconds should be 10


  Scenario: Create ModelError with cache support error
    Given I import the ModelError class
    When I create a ModelError with kind "CACHE_SUPPORT"
    And I set retriable to false
    And I set retryafterseconds to 0
    Then the ModelError instance should be created successfully
    And the kind should be "ErrCacheSupport"
    And the retriable flag should be false
    And the retry after seconds should be 0


  Scenario: Validate ModelError configuration
    Given I import the ModelError class
    When I create a ModelError with valid data
    Then the model configuration should have str_strip_whitespace as true
    And the model configuration should have validate_assignment as true
    And the model configuration should have arbitrary_types_allowed as false
    And the model configuration should have populate_by_name as true
    And the model configuration should have use_enum_values as true


  Scenario: Create FallbackResult with error fallback type
    Given I import the FallbackResult class
    When I create a FallbackResult with fallback type "ERROR"
    And I set isfallback to true
    And I set modelroleconfig to None
    And I set basemodelconfig to None
    Then the FallbackResult instance should be created successfully
    And the fallback type should be "FallbackTypeError"
    And the is fallback flag should be true
    And the model role config should be None
    And the base model config should be None


  Scenario: Create FallbackResult with context fallback type
    Given I import the FallbackResult class
    When I create a FallbackResult with fallback type "CONTEXT"
    And I set isfallback to true
    And I set modelroleconfig to None
    And I set basemodelconfig to None
    Then the FallbackResult instance should be created successfully
    And the fallback type should be "FallbackTypeContext"
    And the is fallback flag should be true


  Scenario: Create FallbackResult with provider fallback type
    Given I import the FallbackResult class
    When I create a FallbackResult with fallback type "PROVIDER"
    And I set isfallback to false
    And I set modelroleconfig to None
    And I set basemodelconfig to None
    Then the FallbackResult instance should be created successfully
    And the fallback type should be "FallbackTypeProvider"
    And the is fallback flag should be false


  Scenario: Create FallbackResult with model role config
    Given I import the FallbackResult class
    And I have a valid ModelRoleConfig instance
    When I create a FallbackResult with fallback type "ERROR"
    And I set isfallback to true
    And I set modelroleconfig to the valid instance
    And I set basemodelconfig to None
    Then the FallbackResult instance should be created successfully
    And the model role config should not be None
    And the model role config role should be "assistant"


  Scenario: Create FallbackResult with base model config
    Given I import the FallbackResult class
    And I have a valid BaseModelConfig instance
    When I create a FallbackResult with fallback type "CONTEXT"
    And I set isfallback to true
    And I set modelroleconfig to None
    And I set basemodelconfig to the valid instance
    Then the FallbackResult instance should be created successfully
    And the base model config should not be None
    And the base model config model_tag should be "gpt-4"


  Scenario: Create FallbackResult with both configs
    Given I import the FallbackResult class
    And I have a valid ModelRoleConfig instance
    And I have a valid BaseModelConfig instance
    When I create a FallbackResult with fallback type "PROVIDER"
    And I set isfallback to false
    And I set modelroleconfig to the valid instance
    And I set basemodelconfig to the valid instance
    Then the FallbackResult instance should be created successfully
    And the model role config should not be None
    And the base model config should not be None


  Scenario: Validate FallbackResult configuration
    Given I import the FallbackResult class
    When I create a FallbackResult with valid data
    Then the model configuration should have str_strip_whitespace as true
    And the model configuration should have validate_assignment as true
    And the model configuration should have arbitrary_types_allowed as false
    And the model configuration should have populate_by_name as true
    And the model configuration should have use_enum_values as true


  Scenario: ModelError with invalid kind raises validation error
    Given I import the ModelError class
    When I try to create a ModelError with invalid kind "INVALID_KIND"
    Then a validation error should be raised
    And the error should mention "Input should be"


  Scenario: FallbackResult with invalid fallback type raises error
    Given I import the FallbackResult class
    When I try to create a FallbackResult with invalid fallback type "INVALID_TYPE"
    Then a validation error should be raised
    And the error should mention "Input should be"


  Scenario: Test ModelError field aliases
    Given I import the ModelError class
    When I create a ModelError using field aliases
    Then the ModelError should accept the aliased fields
    And the values should be properly mapped


  Scenario: Test FallbackResult field aliases
    Given I import the FallbackResult class
    When I create a FallbackResult using field aliases
    Then the FallbackResult should accept the aliased fields
    And the values should be properly mapped


  Scenario: ModelError strips whitespace from string fields
    Given I import the ModelError class
    When I create a ModelError with whitespace in enum values
    Then the whitespace should be stripped from strings
    And the model should be created successfully


  Scenario: FallbackResult strips whitespace from string fields
    Given I import the FallbackResult class
    When I create a FallbackResult with whitespace in enum values
    Then the whitespace should be stripped from strings
    And the model should be created successfully

  # ============================================================
  # Originally from: aimodelsproviders_coverage.feature
  # Feature: AI Models Providers Coverage
  # ============================================================

  @unit @models
  Scenario: Create ModelProviderExtraAuthVars with all fields
    Given I import the ModelProviderExtraAuthVars class
    When I create a ModelProviderExtraAuthVars with var "AWS_REGION"
    And I set maybeJSONFilePath to true
    And I set required to true
    And I set default to "us-east-1"
    Then the var field should equal "AWS_REGION"
    And the maybe_j_s_o_n_file_path field should be true
    And the required field should be true
    And the default field should equal "us-east-1"


  @unit @models
  Scenario: Create ModelProviderExtraAuthVars with minimal fields
    Given I import the ModelProviderExtraAuthVars class
    When I create a ModelProviderExtraAuthVars with only var "API_KEY"
    Then the var field should equal "API_KEY"
    And the maybe_j_s_o_n_file_path field should be None
    And the required field should be None
    And the default field should be None


  @unit @models
  Scenario: ModelProviderExtraAuthVars field validation
    Given I import the ModelProviderExtraAuthVars class
    When I create a ModelProviderExtraAuthVars with var "  TRIMMED_VAR  "
    Then the var field should equal "TRIMMED_VAR"
    And the model should strip whitespace from string fields


  @unit @models
  Scenario: ModelProviderExtraAuthVars alias support
    Given I import the ModelProviderExtraAuthVars class
    When I create a ModelProviderExtraAuthVars using alias "maybeJSONFilePath"
    Then the field should be accessible as maybe_j_s_o_n_file_path
    And the model should populate by name


  @unit @models
  Scenario: ModelProviderExtraAuthVars dict export
    Given I have a ModelProviderExtraAuthVars instance
    When I export it to dict with aliases
    Then the dict should contain "maybeJSONFilePath" key
    And the dict should not contain "maybe_j_s_o_n_file_path" key


  @unit @models
  Scenario: Create ModelProviderConfigSchema with all fields
    Given I import the ModelProviderConfigSchema class
    When I create a ModelProviderConfigSchema with provider "ModelProviderOpenAI"
    And I set base_url to "https://api.openai.com"
    And I set custom_provider to "custom-gpt"
    And I set has_a_w_s_auth to true
    And I set has_claude_max_auth to false
    And I set skip_auth to false
    And I set local_only to false
    And I set api_key_env_var to "OPENAI_API_KEY"
    And I add extra_auth_vars list
    Then the provider field should equal "ModelProviderOpenAI"
    And the base_url field should equal "https://api.openai.com"
    And the custom_provider field should equal "custom-gpt"
    And the has_a_w_s_auth field should be true
    And the has_claude_max_auth field should be false
    And the skip_auth field should be false
    And the local_only field should be false
    And the api_key_env_var field should equal "OPENAI_API_KEY"
    And the extra_auth_vars should be a list


  @unit @models
  Scenario: Create ModelProviderConfigSchema with minimal fields
    Given I import the ModelProviderConfigSchema class
    When I create a ModelProviderConfigSchema with only required fields
    Then the provider field should be set
    And the base_url field should be set
    And all optional fields should be None


  @unit @models
  Scenario: ModelProviderConfigSchema with ModelProvider enum
    Given I import the ModelProviderConfigSchema class
    And I import the ModelProvider enum for provider config
    When I create a ModelProviderConfigSchema with ModelProvider.ANTHROPIC
    Then the provider field should equal "ModelProviderAnthropic"
    And the model should use enum values


  @unit @models
  Scenario: ModelProviderConfigSchema field validation
    Given I import the ModelProviderConfigSchema class
    When I create a ModelProviderConfigSchema with whitespace in fields
    Then all string fields should have whitespace stripped
    And the model should validate assignment


  @unit @models
  Scenario: ModelProviderConfigSchema alias support
    Given I import the ModelProviderConfigSchema class
    When I create a ModelProviderConfigSchema using aliases
    Then "baseUrl" should map to base_url
    And "customProvider" should map to custom_provider
    And "hasAWSAuth" should map to has_a_w_s_auth
    And "hasClaudeMaxAuth" should map to has_claude_max_auth
    And "skipAuth" should map to skip_auth
    And "localOnly" should map to local_only
    And "apiKeyEnvVar" should map to api_key_env_var
    And "extraAuthVars" should map to extra_auth_vars


  @unit @models
  Scenario: ModelProviderConfigSchema dict export with aliases
    Given I have a ModelProviderConfigSchema instance
    When I export it to dict with aliases
    Then the dict should use camelCase keys
    And "baseUrl" should be in the dict
    And "hasAWSAuth" should be in the dict


  @unit @models
  Scenario: ModelProviderConfigSchema with empty extra_auth_vars
    Given I import the ModelProviderConfigSchema class
    When I create a ModelProviderConfigSchema with empty extra_auth_vars list
    Then the extra_auth_vars should be an empty list
    And the model should accept empty lists


  @unit @models
  Scenario: ModelProviderConfigSchema with multiple extra_auth_vars
    Given I import the ModelProviderConfigSchema class
    When I create a ModelProviderConfigSchema with multiple extra_auth_vars
    Then each extra_auth_var should be a ModelProviderExtraAuthVars instance
    And the list should maintain order


  @unit @models
  Scenario: ModelProviderConfigSchema JSON serialization
    Given I have a ModelProviderConfigSchema instance
    When I serialize it to JSON
    Then the JSON should be valid
    And it should contain all set fields
    And it should use aliases in the output


  @unit @models
  Scenario: ModelProviderConfigSchema JSON deserialization
    Given I have a JSON string with provider config
    When I deserialize it to ModelProviderConfigSchema
    Then the object should be correctly populated
    And aliases should be resolved to field names


  @unit @models
  Scenario: ModelProviderExtraAuthVars model config validation
    Given I import the ModelProviderExtraAuthVars class
    When I check the model configuration
    Then str_strip_whitespace should be True
    And validate_assignment should be True
    And arbitrary_types_allowed should be False
    And populate_by_name should be True
    And use_enum_values should be True


  @unit @models
  Scenario: ModelProviderConfigSchema model config validation
    Given I import the ModelProviderConfigSchema class
    When I check the model configuration
    Then str_strip_whitespace should be True
    And validate_assignment should be True
    And arbitrary_types_allowed should be False
    And populate_by_name should be True
    And use_enum_values should be True


  @unit @models
  Scenario: ModelProviderExtraAuthVars field update
    Given I have a ModelProviderExtraAuthVars instance
    When I update the var field to "NEW_VAR"
    Then the var field should equal "NEW_VAR"
    And the update should be validated


  @unit @models
  Scenario: ModelProviderConfigSchema field update
    Given I have a ModelProviderConfigSchema instance
    When I update the base_url field to "https://new-api.com"
    Then the base_url field should equal "https://new-api.com"
    And the update should be validated


  @unit @models
  Scenario: ModelProviderExtraAuthVars copy with update
    Given I have a ModelProviderExtraAuthVars instance
    When I create a copy with updated fields
    Then the copy should have new values
    And the original should remain unchanged


  @unit @models
  Scenario: ModelProviderConfigSchema copy with update
    Given I have a ModelProviderConfigSchema instance
    When I create a copy with updated fields
    Then the copy should have new values
    And the original should remain unchanged


  @unit @models
  Scenario: ModelProviderExtraAuthVars equality comparison
    Given I have two ModelProviderExtraAuthVars instances
    When I compare them for equality
    Then identical instances should be equal
    And different instances should not be equal


  @unit @models
  Scenario: ModelProviderConfigSchema equality comparison
    Given I have two ModelProviderConfigSchema instances
    When I compare them for equality
    Then identical instances should be equal
    And different instances should not be equal


  @unit @models
  Scenario: ModelProviderExtraAuthVars are not hashable
    Given I have ModelProviderExtraAuthVars instances
    When I try to use them as dictionary keys
    Then the instances should not work as dictionary keys
    And a TypeError should be raised when hashing


  @unit @models
  Scenario: ModelProviderConfigSchema validation error
    Given I import the ModelProviderConfigSchema class
    When I try to create an instance with missing required fields
    Then a validation error should be raised for missing fields
    And the error should indicate missing fields

  # ============================================================
  # Originally from: anthropic_provider.feature
  # Feature: Anthropic chat provider coverage
  # ============================================================

  @unit @providers @anthropic
  Scenario: Anthropic provider rejects missing API key
    Given I have sample provider domain inputs
    When I attempt to create an Anthropic chat provider without an API key
    Then the Anthropic provider creation should fail with "Anthropic API key is required"


  @unit @providers @anthropic
  Scenario: Anthropic provider forwards keyword overrides to ChatAnthropic
    Given I have sample provider domain inputs
    When I create an Anthropic chat provider with API key "sk-anthropic-unit" and model "claude-3-5-sonnet-20241022" with custom overrides
    And I request plan generation from the Anthropic provider
    Then the Anthropic provider should construct ChatAnthropic with api key "sk-anthropic-unit" and model "claude-3-5-sonnet-20241022"
    And the Anthropic provider should apply the custom overrides to ChatAnthropic
    And the Anthropic provider metadata should report name "anthropic" and model "claude-3-5-sonnet-20241022"


  # ============================================================
  # Originally from: google_provider.feature
  # Feature: Google provider adapter coverage
  # ============================================================

  @unit @providers @google
  Scenario: Google provider instantiates ChatGoogleGenerativeAI with provided credentials
    Given I have sample provider domain inputs
    When I create a Google chat provider with API key "sk-google-unit" and model "gemini-2.0-flash"
    And I request plan generation from the Google provider
    Then the Google provider should construct ChatGoogleGenerativeAI with api key "sk-google-unit" and model "gemini-2.0-flash"
    And the Google provider metadata should report name "google" and model "gemini-2.0-flash"


  @unit @providers @google
  Scenario: Google provider forwards extra kwargs to ChatGoogleGenerativeAI
    Given I have sample provider domain inputs
    And I set the Google provider extra kwargs "temperature=0.25,max_output_tokens=2048"
    When I create a Google chat provider with API key "sk-google-unit" and model "gemini-2.0-pro"
    And I request plan generation from the Google provider
    Then the Google provider should construct ChatGoogleGenerativeAI with api key "sk-google-unit" and model "gemini-2.0-pro"
    And the Google provider should include kwargs "temperature=0.25,max_output_tokens=2048" in the ChatGoogleGenerativeAI call
    And the Google provider metadata should report name "google" and model "gemini-2.0-pro"


  @unit @providers @google
  Scenario: Google provider returns generated changes with token count
    Given I have sample provider domain inputs
    And the plan generation graph returns a generated change for "app/google_provider.py"
    And the Google provider token estimator returns 256 tokens
    When I create a Google chat provider with API key "sk-google-unit" and model "gemini-2.0-flash"
    And I request plan generation from the Google provider
    Then the Google provider response should include 1 generated change for "app/google_provider.py"
    And the Google provider response token count should equal 256


  @unit @providers @google
  Scenario: Google provider rejects missing API key
    Given I have sample provider domain inputs
    When I attempt to create a Google chat provider without an API key
    Then the Google provider creation should fail with error "Google API key is required"


  # ============================================================
  # Originally from: langsmith_config.feature
  # Feature: LangSmith configuration detection
  # ============================================================

  Scenario: LangSmith tracing disabled by default
    Given LangSmith environment is clean
    When I load CleverAgents settings for LangSmith
    Then LangSmith tracing should be disabled


  Scenario: LangSmith tracing enabled via LangChain env vars
    Given LangSmith environment is clean
    Given I set environment variable "LANGCHAIN_TRACING_V2" to "true"
    And I set environment variable "LANGCHAIN_API_KEY" to "demo-key"
    And I set environment variable "LANGCHAIN_PROJECT" to "langchain-env-project"
    When I load CleverAgents settings for LangSmith
    Then LangSmith tracing should be enabled


  Scenario: Building LangSmith config metadata
    Given LangSmith environment is clean
    Given I set environment variable "CLEVERAGENTS_LANGSMITH_ENABLED" to "true"
    And I set environment variable "CLEVERAGENTS_LANGSMITH_PROJECT" to "cleveragents-core"
    And I set environment variable "CLEVERAGENTS_LANGSMITH_API_KEY" to "demo-key"
    When I load CleverAgents settings for LangSmith
    And I build a LangSmith config with run name "demo-run"
    Then the LangSmith config should include tag "context-analysis"
    And the LangSmith config should include metadata key "langsmith_project"


  Scenario: LangSmith validation fails without API key
    Given LangSmith environment is clean
    Given I set environment variable "CLEVERAGENTS_LANGSMITH_ENABLED" to "true"
    When I load CleverAgents settings for LangSmith
    Then LangSmith tracing should be disabled
    And the LangSmith validation errors should mention "API key"


  Scenario: LangSmith detects LangChain variables
    Given LangSmith environment is clean
    Given I set environment variable "LANGCHAIN_TRACING_V2" to "true"
    And I set environment variable "LANGCHAIN_API_KEY" to "demo-key"
    And I set environment variable "LANGCHAIN_PROJECT" to "observability-demo"
    When I load CleverAgents settings for LangSmith
    And I build a LangSmith config with run name "auto-detected"
    Then LangSmith tracing should be enabled
    And the LangSmith config should include metadata key "langsmith_project"
    And the LangSmith config should include metadata value "observability-demo" for key "langsmith_project"


  Scenario: LangSmith synchronization sets LangChain env vars
    Given LangSmith environment is clean
    Given I set environment variable "CLEVERAGENTS_LANGSMITH_ENABLED" to "true"
    And I set environment variable "CLEVERAGENTS_LANGSMITH_API_KEY" to "sync-key"
    And I set environment variable "CLEVERAGENTS_LANGSMITH_PROJECT" to "sync-project"
    When I load CleverAgents settings for LangSmith
    Then the environment variable "LANGCHAIN_TRACING_V2" should equal "true"
    And the environment variable "LANGCHAIN_PROJECT" should equal "sync-project"
    And the environment variable "LANGCHAIN_API_KEY" should equal "sync-key"


  Scenario: LangSmith config includes user metadata
    Given LangSmith environment is clean
    Given I set environment variable "CLEVERAGENTS_LANGSMITH_ENABLED" to "true"
    And I set environment variable "CLEVERAGENTS_LANGSMITH_API_KEY" to "user-key"
    And I set environment variable "CLEVERAGENTS_LANGSMITH_PROJECT" to "user-project"
    And I set environment variable "CLEVERAGENTS_LANGSMITH_USER_ID" to "user-123"
    When I load CleverAgents settings for LangSmith
    And I build a LangSmith config with run name "user-run"
    Then the LangSmith config should include metadata key "user_id"
    And the LangSmith config should include metadata value "user-123" for key "user_id"


  # ============================================================
  # Originally from: openrouter_provider.feature
  # Feature: OpenRouter provider adapter coverage
  # ============================================================

  @unit @providers @openrouter
  Scenario: OpenRouter provider instantiates ChatOpenAI with provided credentials
    Given I have sample provider domain inputs
    When I create an OpenRouter chat provider with API key "sk-openrouter-unit" and model "anthropic/claude-sonnet-4-20250514"
    And I request plan generation from the OpenRouter provider
    Then the OpenRouter provider should construct ChatOpenAI with api key "sk-openrouter-unit", model "anthropic/claude-sonnet-4-20250514", and base url "https://openrouter.ai/api/v1"
    And the OpenRouter provider metadata should report name "openrouter" and model "anthropic/claude-sonnet-4-20250514"


  @unit @providers @openrouter
  Scenario: OpenRouter provider forwards extra kwargs and reports token usage
    Given I have sample provider domain inputs
    And the plan generation graph returns a generated change for "app/openrouter_provider.py"
    And the OpenRouter provider token estimator returns 512 tokens
    And I set the OpenRouter provider extra kwargs "temperature=0.15,max_tokens=2048"
    When I create an OpenRouter chat provider with API key "sk-openrouter-unit" and model "anthropic/claude-sonnet-4-20250514"
    And I request plan generation from the OpenRouter provider
    Then the OpenRouter provider should construct ChatOpenAI with api key "sk-openrouter-unit", model "anthropic/claude-sonnet-4-20250514", and base url "https://openrouter.ai/api/v1"
    And the OpenRouter provider should include kwargs "temperature=0.15,max_tokens=2048" in the ChatOpenAI call
    And the OpenRouter provider response should include 1 generated change for "app/openrouter_provider.py"
    And the OpenRouter provider response token count should equal 512


  @unit @providers @openrouter
  Scenario: OpenRouter provider attaches organization headers when provided
    Given I have sample provider domain inputs
    And I set the OpenRouter provider default headers "X-Trace-ID=trace-openrouter"
    And I set the OpenRouter provider organization "cleveragents.dev"
    When I create an OpenRouter chat provider with API key "sk-openrouter-unit" and model "anthropic/claude-sonnet-4-20250514"
    And I request plan generation from the OpenRouter provider
    Then the OpenRouter provider should include headers "X-Trace-ID=trace-openrouter,HTTP-Referer=cleveragents.dev,X-Title=cleveragents.dev" in the ChatOpenAI call


  @unit @providers @openrouter
  Scenario: OpenRouter provider rejects missing API key
    Given I have sample provider domain inputs
    When I attempt to create an OpenRouter chat provider without an API key
    Then the OpenRouter provider creation should fail with error "OpenRouter API key is required"

