cli: answer a cancelled slash command at the boundary

This commit is contained in:
2026-11-02 16:30:12 +08:00
parent 770e08e56e
commit 81d443cf40
2 changed files with 24 additions and 2 deletions
+6
View File
@@ -1,5 +1,6 @@
from __future__ import annotations
import asyncio
import os
import shlex
from typing import TYPE_CHECKING, Any, Literal, cast, override
@@ -1639,6 +1640,11 @@ async def handle_slash(state: ReplState, line: str) -> bool:
args[0] = args[0].lower()
try:
await awaitlet.async_def(_run_slash_argv, args, state)
except asyncio.CancelledError:
# A command's own cancellable work was stopped (``/btw``'s side turn, a
# prompt): the interrupt belongs to that command. Letting it through
# would cancel this REPL task and end the session instead.
click.secho("cancelled", fg="yellow")
except ReplExitError:
return False
except click.ClickException as exc:
+18 -2
View File
@@ -1,7 +1,8 @@
from __future__ import annotations
import asyncio
import base64
from typing import TYPE_CHECKING, Literal, overload
from typing import TYPE_CHECKING, Literal, cast, overload
import pytest
import tomlkit
@@ -28,7 +29,7 @@ from plyngent.tools import image_input_refusal
from plyngent.tools.context import bind_instance
if TYPE_CHECKING:
from collections.abc import AsyncIterator
from collections.abc import AsyncIterator, Sequence
from pathlib import Path
@@ -110,6 +111,21 @@ async def test_help(state: ReplState) -> None:
assert await handle_slash(state, "/help") is True
async def test_a_cancelled_slash_command_keeps_the_repl(
monkeypatch: pytest.MonkeyPatch,
capsys: pytest.CaptureFixture[str],
) -> None:
"""A command's own work being cancelled must not cancel the REPL's task."""
from plyngent.cli import slash as slash_module
def cancelled(_args: Sequence[str], _state: object) -> None:
raise asyncio.CancelledError
monkeypatch.setattr(slash_module, "_run_slash_argv", cancelled)
assert await slash_module.handle_slash(cast("ReplState", cast("object", None)), "/btw hello") is True
assert "cancelled" in capsys.readouterr().out
async def test_auto_continue_limits_installs_on_limit(tmp_path: Path) -> None:
from plyngent.cli.limits import auto_continue_enabled, reset_auto_continue