fix: preserve ansi output history on resize replay

This commit is contained in:
LeonSGP43 2026-05-12 17:37:27 +08:00 committed by Teknium
parent 6244535682
commit ac64d0c2ca
2 changed files with 17 additions and 8 deletions

9
cli.py
View file

@ -1415,9 +1415,6 @@ _OUTPUT_HISTORY_REPLAYING = False
_OUTPUT_HISTORY_SUPPRESSED = False
_OUTPUT_HISTORY_MAX_LINES = 200
_OUTPUT_HISTORY = deque(maxlen=_OUTPUT_HISTORY_MAX_LINES)
_ANSI_CONTROL_RE = re.compile(
r"\x1b(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1b\\))"
)
def _coerce_output_history_limit(value) -> int:
@ -1459,10 +1456,10 @@ def _record_output_history_entry(entry) -> None:
def _record_output_history(text: str) -> None:
if not _OUTPUT_HISTORY_ENABLED or _OUTPUT_HISTORY_REPLAYING or _OUTPUT_HISTORY_SUPPRESSED:
return
clean = _ANSI_CONTROL_RE.sub("", str(text)).replace("\r", "").rstrip("\n")
if not clean:
normalized = str(text).replace("\r", "").rstrip("\n")
if not normalized:
return
for line in clean.splitlines():
for line in normalized.splitlines():
_record_output_history_entry(line)

View file

@ -215,13 +215,15 @@ def test_cprint_swallows_prompt_toolkit_import_error(monkeypatch):
assert direct_prints == ["fallback2"]
def test_output_history_strips_ansi_and_keeps_recent_lines():
def test_output_history_preserves_ansi_and_keeps_recent_lines():
cli._configure_output_history(True, 10)
for idx in range(12):
cli._record_output_history(f"\x1b[31mline-{idx}\x1b[0m")
assert list(cli._OUTPUT_HISTORY) == [f"line-{idx}" for idx in range(2, 12)]
assert list(cli._OUTPUT_HISTORY) == [
f"\x1b[31mline-{idx}\x1b[0m" for idx in range(2, 12)
]
def test_replay_output_history_does_not_record_replayed_lines(monkeypatch):
@ -277,6 +279,16 @@ def test_replay_output_history_batches_rendered_lines_into_one_print(monkeypatch
assert printed == ["first line\nsecond line\nthird line\nfourth line"]
def test_chat_console_records_rich_ansi_for_resize_replay(monkeypatch):
cli._configure_output_history(True, 10)
monkeypatch.setattr(cli, "_pt_print", lambda *_args, **_kwargs: None)
cli.ChatConsole().print("[bold red]Hello[/]")
assert cli._OUTPUT_HISTORY
assert any("\x1b[" in line for line in cli._OUTPUT_HISTORY)
def test_suspend_output_history_blocks_recording():
cli._configure_output_history(True, 10)