mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-06 06:52:20 +02:00
fix bounded recovery after repeated failed calls
This commit is contained in:
@@ -4138,6 +4138,7 @@ async def stream_preview(*, endpoint_url, model, messages, headers, turn_contrac
|
||||
discovered_web_sources = []
|
||||
browser_navigation_outcomes = {}
|
||||
failed_call_counts = {}
|
||||
blocked_failed_call_counts = {}
|
||||
semantic_attempt_counts = {}
|
||||
successful_semantic_scopes = set()
|
||||
successful_target_write_counts = {}
|
||||
@@ -5146,6 +5147,28 @@ async def stream_preview(*, endpoint_url, model, messages, headers, turn_contrac
|
||||
)
|
||||
if failed_call_counts.get(call_signature, 0) >= 2:
|
||||
calls += 1
|
||||
blocked_count = (
|
||||
blocked_failed_call_counts.get(call_signature, 0) + 1
|
||||
)
|
||||
blocked_failed_call_counts[call_signature] = blocked_count
|
||||
# Keep one blocked reminder permissive: the model may still
|
||||
# correct the arguments on its next turn. If it ignores that
|
||||
# reminder and emits the same failed call again, continuing to
|
||||
# offer the tool only creates an unbounded no-op loop. Suppress
|
||||
# that tool for the remainder of this turn and enter the normal
|
||||
# evidence-only completion path instead.
|
||||
if blocked_count >= 2:
|
||||
terminal_suppression_violation = True
|
||||
permanently_suppressed_tools.add(canonical(name))
|
||||
round_recovery_messages.append(
|
||||
f'{name} was disabled for this turn after repeatedly emitting '
|
||||
'the same call that had already failed twice. Finish from '
|
||||
'existing evidence or state the remaining limitation.'
|
||||
)
|
||||
raise ValueError(
|
||||
'This exact failed call was repeated after a correction reminder; '
|
||||
'the tool is disabled for this turn. Finish from existing evidence.'
|
||||
)
|
||||
round_recovery_messages.append(
|
||||
f'This exact {name} call failed twice and is blocked. '
|
||||
'The tool remains available with corrected arguments; use the returned '
|
||||
|
||||
@@ -5388,7 +5388,12 @@ async def test_native_stream_stops_reexecuting_an_identical_failed_call(monkeypa
|
||||
assert len(executions) == 2
|
||||
assert any(event.get('type') == 'tool_loop_recovery' for event in events)
|
||||
assert any(s['function']['name'] == 'inspect_media' for s in requests[3]['tools'])
|
||||
assert len(requests) == 5
|
||||
# Two execution failures plus two ignored correction prompts terminate
|
||||
# instead of consuming the remaining round budget with the same no-op call.
|
||||
assert len(requests) == 4
|
||||
final = [event for event in events if event.get('type') == 'final_response']
|
||||
assert len(final) == 1
|
||||
assert 'could not complete' in final[0]['content'].lower()
|
||||
assert any(
|
||||
event.get('type') == 'tool_output'
|
||||
and 'already failed twice' in event.get('output', '')
|
||||
|
||||
Reference in New Issue
Block a user