diff --git a/tools/lazy_deps.py b/tools/lazy_deps.py index 02e3038d4d3..3aeace33b70 100644 --- a/tools/lazy_deps.py +++ b/tools/lazy_deps.py @@ -174,11 +174,11 @@ LAZY_DEPS: dict[str, tuple[str, ...]] = { "uvicorn[standard]==0.41.0", "starlette==1.0.1", # CVE-2026-48710 (BadHost) — keep lazy-install in sync with pyproject [web] ), - # Vision image-resize recovery (Pillow). Soft dependency: vision_tools and - # conversation_compression degrade gracefully without it, but the byte AND - # pixel-dimension shrink paths no-op when it's absent, so an oversized - # image can brick a session on Anthropic's non-retryable 400. Keep in sync - # with pyproject [vision]. + # Vision image-resize recovery (Pillow). Pillow is now a CORE dependency + # (pyproject `dependencies`), so this entry is a belt-and-suspenders fallback + # for stripped/source-build installs that somehow dropped it. The vision + # call site uses prompt=False so it can never raise a blocking input() + # prompt mid-session (#40490). "tool.vision": ("Pillow==12.2.0",), } diff --git a/tools/transcription_tools.py b/tools/transcription_tools.py index 492f04cb83d..2c8b8f75fc3 100644 --- a/tools/transcription_tools.py +++ b/tools/transcription_tools.py @@ -214,7 +214,11 @@ def _try_lazy_install_stt() -> bool: """ try: from tools.lazy_deps import ensure - ensure("stt.faster_whisper") + # prompt=False: never raise a blocking input() prompt mid-session. + # Under the interactive CLI prompt_toolkit owns stdin, so a bare + # input() deadlocks the terminal (#40490). The install is already + # gated by security.allow_lazy_installs, so reaching here is opt-in. + ensure("stt.faster_whisper", prompt=False) # Re-check dynamically after install import importlib.util as _iu if _iu.find_spec("faster_whisper"): diff --git a/tools/vision_tools.py b/tools/vision_tools.py index 3187f54763b..cfc933dae0f 100644 --- a/tools/vision_tools.py +++ b/tools/vision_tools.py @@ -422,7 +422,11 @@ def _resize_image_for_vision(image_path: Path, mime_type: Optional[str] = None, # the raw bytes and let the caller raise the size error. try: from tools.lazy_deps import ensure as _ensure_dep - _ensure_dep("tool.vision") + # prompt=False: never raise a blocking input() prompt mid-session. + # Under the interactive CLI prompt_toolkit owns stdin, so a bare + # input() deadlocks the terminal (#40490). The install is already + # gated by security.allow_lazy_installs, so reaching here is opt-in. + _ensure_dep("tool.vision", prompt=False) from PIL import Image import io as _io except Exception: