diff --git a/src/kimi_cli/ui/print/__init__.py b/src/kimi_cli/ui/print/__init__.py index aa9b01fd52..3fa9562451 100644 --- a/src/kimi_cli/ui/print/__init__.py +++ b/src/kimi_cli/ui/print/__init__.py @@ -16,6 +16,7 @@ ) from kosong.message import Message from rich import print +from rich.markup import escape from kimi_cli.background.models import is_terminal_status from kimi_cli.cli import ExitCode, InputFormat, OutputFormat @@ -88,7 +89,7 @@ def _handler(): if command: logger.info("Running agent with command: {command}", command=command) if self.output_format == "text" and not self.final_only: - print(command) + print(escape(command)) runtime = self.soul.runtime if isinstance(self.soul, KimiSoul) else None await run_soul( self.soul, diff --git a/tests/ui_and_conv/test_print_exit_code.py b/tests/ui_and_conv/test_print_exit_code.py index 2f978c2281..d567bd26ee 100644 --- a/tests/ui_and_conv/test_print_exit_code.py +++ b/tests/ui_and_conv/test_print_exit_code.py @@ -3,6 +3,7 @@ from __future__ import annotations import asyncio +import io from pathlib import Path from unittest.mock import AsyncMock, MagicMock @@ -112,6 +113,29 @@ def test_success_on_normal_run(self, tmp_path: Path): code = asyncio.run(p.run(command="hello")) assert code == ExitCode.SUCCESS + @pytest.mark.parametrize( + "command", + [ + "hello", + '* WRONG: `A[/login]` or `B[/ home]`\n* CORRECT: `A["/login"]`', + ], + ) + def test_stdin_prompt_is_printed_literally_and_sent_unchanged( + self, command: str, tmp_path: Path, monkeypatch, capsys + ): + soul = _make_soul() + p = _make_print(soul, tmp_path) + run_soul = AsyncMock() + monkeypatch.setattr("kimi_cli.ui.print.run_soul", run_soul) + monkeypatch.setattr("sys.stdin", io.StringIO(command)) + + code = asyncio.run(p.run()) + + assert code == ExitCode.SUCCESS + assert capsys.readouterr().out.rstrip("\n") == command + assert run_soul.await_args is not None + assert run_soul.await_args.args[1] == command + def test_llm_not_set_returns_failure(self, tmp_path: Path, monkeypatch): soul = _make_soul() p = _make_print(soul, tmp_path)