diff --git a/tests/test_cli.py b/tests/test_cli.py index 331e14c..67a2588 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -641,12 +641,17 @@ def test_mixed_batch_cli_exposes_both_modes_and_ordered_results(capsys: Any) -> exit_code = main(["demo", "tool-loop", "--case", "mixed-batch"]) records = _records(capsys.readouterr().out) endings = [record for record in records if record.get("event") == "tool_execution_end"] + parallel_endings = [record for record in endings if record["batch_mode"] == "parallel"] + sequential_endings = [record for record in endings if record["batch_mode"] == "sequential"] assert exit_code == 0 assert {record["batch_mode"] for record in endings} == {"parallel", "sequential"} - assert [record["tool_result"]["call_id"] for record in endings] == [ + assert len(parallel_endings) == 2 + assert {record["tool_result"]["call_id"] for record in parallel_endings} == { "read-a", "read-b", + } + assert [record["tool_result"]["call_id"] for record in sequential_endings] == [ "read-before", "write", "read-after", diff --git a/tests/test_tool_runtime.py b/tests/test_tool_runtime.py index 6f036db..4495497 100644 --- a/tests/test_tool_runtime.py +++ b/tests/test_tool_runtime.py @@ -15,6 +15,24 @@ ) +class _ReadBFirstEnvironment(LocalCodingEnvironment): + def __init__(self, workspace: Path) -> None: + super().__init__(workspace) + self._read_b_completed = asyncio.Event() + + async def read_text( + self, + path: str, + cancel_event: asyncio.Event | None = None, + ) -> str: + if path == "a.txt": + await self._read_b_completed.wait() + content = await super().read_text(path, cancel_event) + if path == "b.txt": + self._read_b_completed.set() + return content + + def test_process_group_helpers_bind_platform_apis_with_explicit_types( monkeypatch: pytest.MonkeyPatch, ) -> None: @@ -98,23 +116,24 @@ def test_pure_read_batch_is_parallel_but_model_results_keep_call_order(tmp_path: workspace = tmp_path (workspace / "a.txt").write_text("A", encoding="utf-8") (workspace / "b.txt").write_text("B", encoding="utf-8") - runtime = ToolRuntime(LocalCodingEnvironment(workspace)) - batch = asyncio.run( - runtime.execute_batch( + async def execute_batch() -> ToolBatchResult: + runtime = ToolRuntime(_ReadBFirstEnvironment(workspace)) + return await runtime.execute_batch( ( - ToolCall("b", "read", {"path": "b.txt"}), - ToolCall("a", "read", {"path": "a.txt"}), + ToolCall("read-a", "read", {"path": "a.txt"}), + ToolCall("read-b", "read", {"path": "b.txt"}), ) ) - ) + + batch = asyncio.run(execute_batch()) assert batch.mode == "parallel" - assert set(batch.completion_order) == {"a", "b"} - assert tuple(result.call_id for result in batch.results) == ("b", "a") + assert batch.completion_order == ("read-b", "read-a") + assert tuple(result.call_id for result in batch.results) == ("read-a", "read-b") assert tuple(result.output for result in batch.results) == ( - {"content": "B"}, {"content": "A"}, + {"content": "B"}, )