fix(runner): narrow BaseException catch to Exception in tool execution
The tool execution path caught BaseException, which includes KeyboardInterrupt, SystemExit, MemoryError, and GeneratorExit. These should never be caught and converted into conversational error messages. CancelledError is already handled separately. Change except BaseException to except Exception so fatal signals propagate instead of being swallowed. Adds parametrized regression test for KeyboardInterrupt and SystemExit propagation. Fixes #4788
This commit is contained in:
@@ -3,6 +3,7 @@ session message isolation, and tool result preservation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
@@ -45,6 +46,39 @@ async def test_runner_returns_structured_tool_error():
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("control_error", [KeyboardInterrupt, SystemExit])
|
||||
async def test_runner_propagates_tool_control_flow_exceptions(control_error: type[BaseException]):
|
||||
from nanobot.agent.runner import AgentRunner
|
||||
|
||||
provider = MagicMock(spec=LLMProvider)
|
||||
|
||||
async def execute(_name, _args):
|
||||
raise control_error("stop")
|
||||
|
||||
tools = SimpleNamespace(
|
||||
get_definitions=lambda: [],
|
||||
execute=execute,
|
||||
)
|
||||
runner = AgentRunner()
|
||||
spec = make_run_spec(
|
||||
provider,
|
||||
initial_messages=[],
|
||||
tools=tools,
|
||||
model="test-model",
|
||||
max_iterations=1,
|
||||
max_tool_result_chars=_MAX_TOOL_RESULT_CHARS,
|
||||
)
|
||||
|
||||
with pytest.raises(control_error):
|
||||
await runner._run_tool(
|
||||
spec,
|
||||
ToolCallRequest(id="call_1", name="list_dir", arguments={}),
|
||||
external_lookup_counts={},
|
||||
workspace_violation_counts={},
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_llm_error_not_appended_to_session_messages():
|
||||
"""When LLM returns finish_reason='error', the error content must NOT be
|
||||
|
||||
Reference in New Issue
Block a user