@@ -306,6 +306,56 @@ async def test_process_with_tool_calls_swallowed(self, middleware, mock_reactor)
306306 assert result .metadata ["original" ] == "metadata"
307307 assert result .metadata ["tool_call_reactor" ]["handler" ] == "test_handler"
308308
309+ @pytest .mark .asyncio
310+ async def test_process_with_tool_calls_swallowed_empty_replacement (
311+ self , middleware , mock_reactor
312+ ):
313+ """Empty replacement strings should still create a new response."""
314+
315+ tool_call_response = {
316+ "choices" : [
317+ {
318+ "message" : {
319+ "tool_calls" : [
320+ {
321+ "id" : "call_123" ,
322+ "type" : "function" ,
323+ "function" : {
324+ "name" : "test_tool" ,
325+ "arguments" : '{"arg": "value"}' ,
326+ },
327+ }
328+ ]
329+ }
330+ }
331+ ]
332+ }
333+
334+ response = ProcessedResponse (
335+ content = json .dumps (tool_call_response ),
336+ usage = {"tokens" : 100 },
337+ metadata = {"original" : "metadata" },
338+ )
339+
340+ swallow_result = ToolCallReactionResult (
341+ should_swallow = True ,
342+ replacement_response = "" ,
343+ metadata = {"handler" : "test_handler" },
344+ )
345+
346+ mock_reactor .process_tool_call .return_value = swallow_result
347+
348+ result = await middleware .process (
349+ response = response ,
350+ session_id = "test_session" ,
351+ context = {"backend_name" : "test" , "model_name" : "test" },
352+ )
353+
354+ assert isinstance (result , ProcessedResponse )
355+ assert result .content == ""
356+ assert result .metadata ["replacement_provided" ] is True
357+ assert result .metadata ["tool_call_reactor" ]["handler" ] == "test_handler"
358+
309359 @pytest .mark .asyncio
310360 async def test_process_with_tool_calls_swallowed_merges_metadata (
311361 self , middleware , mock_reactor
0 commit comments