mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
test: pin the capped turn that carries only the refused call
This commit is contained in:
parent
0d1e2a5b11
commit
6760379b4a
1 changed files with 34 additions and 0 deletions
|
|
@ -213,6 +213,40 @@ class TestCappedLoopReturnsTerminalResponse:
|
|||
|
||||
assert _block_types(result) == ["server_tool_use", "web_search_tool_result", "text"]
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_turn_carrying_only_the_refused_call_still_ends_cleanly(self):
|
||||
"""
|
||||
The refused call can be every block the model produced, which leaves the
|
||||
turn with no content once it is dropped. That still has to come back as a
|
||||
finished turn rather than as the leaked call, so the client stops instead
|
||||
of waiting on a tool it cannot run, and the rest of the message survives
|
||||
so the request is still billed and traceable.
|
||||
|
||||
An empty turn renders as nothing, which is the ceiling being set too low
|
||||
for the question rather than a malformed response.
|
||||
"""
|
||||
nothing_but_the_refused_call = {
|
||||
"id": "msg_123",
|
||||
"type": "message",
|
||||
"role": "assistant",
|
||||
"model": "claude-sonnet-4-5",
|
||||
"content": [_internal_tool_use_block()],
|
||||
"stop_reason": "tool_use",
|
||||
"usage": {"input_tokens": 10, "output_tokens": 5},
|
||||
}
|
||||
|
||||
result = await _run_hooks(
|
||||
self.handler,
|
||||
self.callback,
|
||||
kwargs={"_agentic_loop_depth": 3, "max_agentic_loops": 3},
|
||||
response=nothing_but_the_refused_call,
|
||||
)
|
||||
|
||||
assert result["content"] == []
|
||||
assert result["stop_reason"] == "end_turn"
|
||||
assert result["usage"] == {"input_tokens": 10, "output_tokens": 5}
|
||||
assert result["id"] == "msg_123"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_no_follow_up_model_call_is_planned(self):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue