Skip to content

Commit ebe55fe

Browse files
authored
Update input.py
1 parent a098974 commit ebe55fe

1 file changed

Lines changed: 28 additions & 2 deletions

File tree

‎python_agent_harness/tui/input.py‎

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import sys
99
import threading
1010
from collections.abc import Callable, Iterable
11+
from contextlib import contextmanager
1112
from typing import TYPE_CHECKING, Any
1213

1314
from prompt_toolkit import PromptSession
@@ -21,6 +22,20 @@
2122

2223
from .. import config
2324

25+
26+
@contextmanager
27+
def _safe_patch_stdout():
28+
"""patch_stdout that degrades to a no-op when the terminal output
29+
cannot be created (e.g. headless Windows CI without a console)."""
30+
try:
31+
proxy = patch_stdout()
32+
except Exception:
33+
yield
34+
return
35+
with proxy:
36+
yield
37+
38+
2439
if TYPE_CHECKING:
2540
from ..session import Session
2641

@@ -97,6 +112,16 @@ def _make_prompt_session(
97112
the completion state just before the Tab-triggered task runs, which
98113
then bails out without inserting the common part). Tab must be the
99114
single, deterministic trigger.
115+
116+
``enable_suspend`` is off on Windows: Ctrl-Z (suspend) is a Unix
117+
terminal feature with no Windows equivalent.
118+
119+
On Windows without a real console (headless CI, redirected stdout),
120+
prompt_toolkit raises ``NoConsoleScreenBufferError`` while creating
121+
the default ``Win32Output``. The fallback rebuilds the session with
122+
a no-op ``DummyOutput`` so the TUI can still be constructed; on a
123+
real terminal the first attempt succeeds and the fallback is never
124+
reached.
100125
"""
101126
try:
102127
return PromptSession(
@@ -109,6 +134,7 @@ def _make_prompt_session(
109134
**kwargs,
110135
)
111136
except Exception:
137+
# No console available (headless Windows CI): use a no-op output.
112138
from prompt_toolkit.output import DummyOutput
113139

114140
return PromptSession(
@@ -313,7 +339,7 @@ def _input_prompt(self) -> FormattedText:
313339

314340
def _read_multiline(self) -> str | None:
315341
try:
316-
with patch_stdout():
342+
with _safe_patch_stdout():
317343
text = self.prompt_session.prompt(self._input_prompt())
318344
except EOFError:
319345
# Ctrl-D: quit
@@ -361,7 +387,7 @@ def _ask_question_blocking(self) -> None:
361387
else:
362388
prompt = q.prompt + " > "
363389
try:
364-
with patch_stdout():
390+
with _safe_patch_stdout():
365391
answer = self.prompt_session.prompt(prompt, multiline=False)
366392
except (EOFError, KeyboardInterrupt):
367393
answer = ""

0 commit comments

Comments
 (0)