#2657·agentscope

[Bug]: launch_console swallows caller cancellation while a reply is running

Author: wangtaotaotao95Created Sep 16, 2026Updated Sep 16, 2026

Prerequisites

  • I searched existing open and closed issues and pull requests for launch_console, _run_reply, CancelledError, and console cancellation.
  • This reproduces on current main (0b157a31).

Description

agentscope.console._console._run_reply catches every asyncio.CancelledError raised while awaiting its internal reply consumer. That catch is intended for Ctrl+C, where the SIGINT handler cancels the internal consumer task. It also catches cancellation of _run_reply itself, however, because task cancellation propagates into the awaited consumer.

As a result, an application cancelling launch_console during shutdown, or a caller enforcing a timeout around _run_reply, sees a successful None return instead of cancellation. The outer console loop can then continue waiting for input rather than stopping.

Reproduction

python
import asyncio

from agentscope.console._console import _run_reply


class Agent:
    async def reply_stream(self, inputs):
        await asyncio.sleep(3600)
        if False:
            yield None


class Renderer:
    def render(self, event):
        pass


async def main():
    task = asyncio.create_task(_run_reply(Agent(), Renderer(), object()))
    await asyncio.sleep(0)
    task.cancel()
    try:
        result = await task
    except asyncio.CancelledError:
        print("cancel propagated")
    else:
        print("cancel swallowed", result)


asyncio.run(main())

Current output:

cancel swallowed None

Expected behavior

Only the internal consumer cancellation initiated by the SIGINT handler should be swallowed. If the current _run_reply task is itself cancelling, CancelledError should propagate to its caller. A regression test should cover both cases so Ctrl+C behavior remains intact.

Source: agentscope-ai/agentscope