Feature: Reactive application coverage boost
  As a developer
  I want to exercise the remaining uncovered lines in reactive/application.py
  So that code coverage is maximized

  @coverage
  Scenario: Logging adds a handler when root logger has no handlers
    Given a reactive app with all root logger handlers removed
    When I configure logging with verbose level 2
    Then the root logger should have at least one handler
    And the handler format should include the module name pattern

  @coverage
  Scenario: Ensure agent registered creates instance from config when agent not already present
    Given a reactive app with a route referencing an agent not yet registered but present in config
    When I register agents from config triggering deferred registration
    Then the deferred config agent should be registered in the stream router
    And the deferred config agent alias should also be registered

  @coverage
  Scenario: Initialize graph context refreshes stage order when stages are missing
    Given a reactive app with a global context that has a partial stage order list
    When I initialize the graph context
    Then the stage order should be refreshed to the full default list

  @coverage
  Scenario: Initialize graph context resets writing stage when current value is invalid
    Given a reactive app with a global context that has an invalid writing stage
    When I initialize the graph context
    Then the writing stage should be reset to intro

  @coverage
  Scenario: Follow chained edges returns immediately when next node is end
    Given a reactive app configured for chained edge traversal to end node
    When I follow chained edges starting from the end node
    Then the chained edge result should be the current message with should_return true

  @coverage
  Scenario: Follow chained edges falls through when next node becomes falsy
    Given a reactive app configured for chained edge traversal to a falsy node
    When I follow chained edges starting from a node that chains to a falsy node
    Then the chained edge result should be the current message with should_return false

  @coverage
  Scenario: Reactive app resolves skill names and stores tools
    Given a reactive app with skill names resolved via a mock skill service
    When I check the resolved skill tools
    Then the app should have resolved skill tool entries
    And the skill names property should match the input

  @coverage
  Scenario: Reactive app raises error for unknown skill name
    Given a reactive app configured with an unknown skill name
    When I attempt to create the app with the unknown skill
    Then a CleverAgentsException should be raised with skill not found message

  @coverage
  Scenario: Reactive app merges skill tools into agent tool list
    Given a reactive app with skill tools resolved and a config with agents
    When agents are registered from config with skill tools
    Then the agents should have skill tools merged into their tool list

  @coverage
  Scenario: Reactive app works without skill names
    Given a reactive app created without any skill names
    When I check the skill related properties
    Then the skill names should be empty
    And the resolved skill tools should be empty

  @coverage
  Scenario: Reactive app resolves skill with tool overrides
    Given a reactive app with skill names resolved including overrides
    When I check the resolved skill tools
    Then the resolved tool entry should include overrides

  @coverage
  Scenario: Reactive app deduplicates skill names
    Given a reactive app with duplicate skill names resolved via a mock skill service
    When I check the resolved skill tools
    Then the skill names should be deduplicated
    And resolve_tools should be called once per unique skill

  @coverage
  Scenario: Reactive app raises error for empty string skill name
    Given a reactive app configured with an empty string skill name
    When I attempt to create the app with the empty skill
    Then a CleverAgentsException should be raised for resolution failure

  @coverage
  Scenario: Reactive app skill injection skips LLM agents without tools
    Given a reactive app with skill tools and a config with an LLM agent
    When agents are registered from config with skill tools present
    Then the LLM agent should remain a SimpleLLMAgent not a SimpleToolAgent

  @coverage
  Scenario: Reactive app raises error for skill resolution ValueError
    Given a reactive app configured with a skill that triggers a ValueError
    When I attempt to create the app with the ValueError skill
    Then a CleverAgentsException should be raised with resolution failed message

  @coverage
  Scenario: Reactive app handles skill that resolves to zero tools
    Given a reactive app with a skill that resolves to zero tools
    When I check the resolved skill tools after zero tool resolution
    Then the resolved skill tools should be empty
    And the skill names should contain the zero-tool skill

  @coverage
  Scenario: Reactive app rejects skill name exceeding max length
    Given a reactive app configured with an overly long skill name
    When I attempt to create the app with the long skill name
    Then a CleverAgentsException should be raised for invalid name format

  @coverage
  Scenario: Reactive app strips ANSI escape codes from skill names
    Given a reactive app configured with a skill name containing ANSI codes
    When I attempt to create the app with the ANSI skill name
    Then a CleverAgentsException should be raised for invalid name format

  @coverage
  Scenario: Reactive app rejects skill name with disallowed characters
    Given a reactive app configured with a skill name containing special characters
    When I attempt to create the app with the special char skill name
    Then a CleverAgentsException should be raised for invalid name format
