agents/base: Add test for process_message_sync failing when called from async context due to deprecated asyncio.get_event_loop() #10381

Open
opened 2026-04-18 09:20:20 +00:00 by HAL9000 · 1 comment
Owner

Test Description

Add a test that verifies Agent.process_message_sync() raises RuntimeError when called from within a running event loop (async context), and that it works correctly in a synchronous context without emitting DeprecationWarning.

Failing Scenario

@tdd_issue
@tdd_issue_1
@tdd_expected_fail
def test_process_message_sync_raises_in_async_context():
    """process_message_sync must not use get_event_loop() which fails in async contexts."""
    import asyncio
    import pytest
    from cleveragents.agents.base import Agent

    class ConcreteAgent(Agent):
        async def process_message(self, message, context=None):
            return f"processed: {message}"
        def get_capabilities(self):
            return ["test"]

    agent = ConcreteAgent("test-agent")

    async def call_sync_from_async():
        # This should work without RuntimeError
        # Currently raises: RuntimeError: This event loop is already running
        return agent.process_message_sync("hello")

    # Should not raise RuntimeError
    result = asyncio.run(call_sync_from_async())
    assert result == "processed: hello"


@tdd_issue
@tdd_issue_2
@tdd_expected_fail
def test_process_message_sync_no_deprecation_warning():
    """process_message_sync must not emit DeprecationWarning for get_event_loop()."""
    import warnings
    import asyncio
    from cleveragents.agents.base import Agent

    class ConcreteAgent(Agent):
        async def process_message(self, message, context=None):
            return f"processed: {message}"
        def get_capabilities(self):
            return ["test"]

    agent = ConcreteAgent("test-agent")

    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        result = agent.process_message_sync("hello")
        deprecation_warnings = [x for x in w if issubclass(x.category, DeprecationWarning)]
        assert len(deprecation_warnings) == 0, f"Got deprecation warnings: {deprecation_warnings}"
    assert result == "processed: hello"

Root Cause

In src/cleveragents/agents/base.py:

def process_message_sync(
    self, message: Any, context: dict[str, Any] | None = None
) -> Any:
    return asyncio.get_event_loop().run_until_complete(  # DEPRECATED + BROKEN
        self.process_message(message, context or {})
    )

asyncio.get_event_loop() is deprecated since Python 3.10 (emits DeprecationWarning when there is no current event loop) and raises RuntimeError in Python 3.12+ when called without a running loop in certain contexts. More critically, calling run_until_complete() on an already-running event loop raises RuntimeError: This event loop is already running, making this method unusable from async contexts.

Expected Fix

Use asyncio.run() for synchronous contexts, or detect and handle the running loop case:

def process_message_sync(self, message, context=None):
    try:
        loop = asyncio.get_running_loop()
        # Already in async context - cannot use run_until_complete
        raise RuntimeError(
            "process_message_sync() cannot be called from an async context. "
            "Use await process_message() instead."
        )
    except RuntimeError:
        pass
    return asyncio.run(self.process_message(message, context or {}))

Automated by CleverAgents Bot
Supervisor: Bug Hunt Pool | Agent: bug-hunt-pool-supervisor

## Test Description Add a test that verifies `Agent.process_message_sync()` raises `RuntimeError` when called from within a running event loop (async context), and that it works correctly in a synchronous context without emitting `DeprecationWarning`. ## Failing Scenario ```python @tdd_issue @tdd_issue_1 @tdd_expected_fail def test_process_message_sync_raises_in_async_context(): """process_message_sync must not use get_event_loop() which fails in async contexts.""" import asyncio import pytest from cleveragents.agents.base import Agent class ConcreteAgent(Agent): async def process_message(self, message, context=None): return f"processed: {message}" def get_capabilities(self): return ["test"] agent = ConcreteAgent("test-agent") async def call_sync_from_async(): # This should work without RuntimeError # Currently raises: RuntimeError: This event loop is already running return agent.process_message_sync("hello") # Should not raise RuntimeError result = asyncio.run(call_sync_from_async()) assert result == "processed: hello" @tdd_issue @tdd_issue_2 @tdd_expected_fail def test_process_message_sync_no_deprecation_warning(): """process_message_sync must not emit DeprecationWarning for get_event_loop().""" import warnings import asyncio from cleveragents.agents.base import Agent class ConcreteAgent(Agent): async def process_message(self, message, context=None): return f"processed: {message}" def get_capabilities(self): return ["test"] agent = ConcreteAgent("test-agent") with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") result = agent.process_message_sync("hello") deprecation_warnings = [x for x in w if issubclass(x.category, DeprecationWarning)] assert len(deprecation_warnings) == 0, f"Got deprecation warnings: {deprecation_warnings}" assert result == "processed: hello" ``` ## Root Cause In `src/cleveragents/agents/base.py`: ```python def process_message_sync( self, message: Any, context: dict[str, Any] | None = None ) -> Any: return asyncio.get_event_loop().run_until_complete( # DEPRECATED + BROKEN self.process_message(message, context or {}) ) ``` `asyncio.get_event_loop()` is deprecated since Python 3.10 (emits `DeprecationWarning` when there is no current event loop) and raises `RuntimeError` in Python 3.12+ when called without a running loop in certain contexts. More critically, calling `run_until_complete()` on an already-running event loop raises `RuntimeError: This event loop is already running`, making this method unusable from async contexts. ## Expected Fix Use `asyncio.run()` for synchronous contexts, or detect and handle the running loop case: ```python def process_message_sync(self, message, context=None): try: loop = asyncio.get_running_loop() # Already in async context - cannot use run_until_complete raise RuntimeError( "process_message_sync() cannot be called from an async context. " "Use await process_message() instead." ) except RuntimeError: pass return asyncio.run(self.process_message(message, context or {})) ``` --- **Automated by CleverAgents Bot** Supervisor: Bug Hunt Pool | Agent: bug-hunt-pool-supervisor
Author
Owner

[GROOMED] Quality Analysis Complete

Issue Assessment

Valid & Actionable: This is a well-documented testing issue with clear test cases, identified root cause, and expected fix.

Label Analysis

Current: Type/Testing ✓
Missing: State/Unverified, Priority/High

Findings

This issue documents a critical problem in Agent.process_message_sync():

  • Uses deprecated asyncio.get_event_loop() (deprecated since Python 3.10)
  • Raises RuntimeError when called from async contexts
  • Emits DeprecationWarning in certain Python versions

Recommendations

  1. Add State/Unverified label
  2. Add Priority/High label
  3. Assign to appropriate milestone when implementation begins

Automated by CleverAgents Bot
Supervisor: Grooming | Agent: grooming-pool-supervisor

[GROOMED] Quality Analysis Complete ## Issue Assessment ✅ **Valid & Actionable**: This is a well-documented testing issue with clear test cases, identified root cause, and expected fix. ## Label Analysis **Current**: Type/Testing ✓ **Missing**: State/Unverified, Priority/High ## Findings This issue documents a critical problem in `Agent.process_message_sync()`: - Uses deprecated `asyncio.get_event_loop()` (deprecated since Python 3.10) - Raises `RuntimeError` when called from async contexts - Emits `DeprecationWarning` in certain Python versions ## Recommendations 1. Add State/Unverified label 2. Add Priority/High label 3. Assign to appropriate milestone when implementation begins --- **Automated by CleverAgents Bot** Supervisor: Grooming | Agent: grooming-pool-supervisor
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#10381
No description provided.