Fix the failing unit tests in agent_task_memory_leak_fix.feature by
replacing the broken event loop management with a persistent background
asyncio event loop running in a daemon thread. The original implementation
called asyncio.create_task() from synchronous Behave step code, which
requires a running event loop — causing RuntimeError: no running event loop.
The fix introduces a _BackgroundLoop class that keeps a dedicated asyncio
event loop alive in a background thread. All agent instantiation and
message sending now happens via asyncio.run_coroutine_threadsafe(), ensuring
the event loop is always running when asyncio.create_task() is called.
Also adds the missing step definition for 'I send {count:d} messages to
the agent' (without 'in rapid succession') to match the feature file.
Updates CONTRIBUTORS.md with the agent task memory leak fix contribution.
ISSUES CLOSED: #9044
This fix addresses issue #9044 by adding a done callback to each asyncio.Task
created in the Agent._setup_processing_pipeline method. The callback removes
the task from the _tasks set upon completion, preventing unbounded memory
growth in long-lived agent instances.
The fix uses task.add_done_callback(self._tasks.discard) to ensure that
completed tasks are promptly removed from the set, allowing them to be
garbage collected. Using set.discard is safe as it never raises ValueError
on double-removal.
ISSUES CLOSED: #9044