Spaces:
Running
Running
File size: 2,995 Bytes
9f9d3dc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | from __future__ import annotations
import unittest
from unittest.mock import patch
from agents import executor as executor_module
from agents.executor import Executor
class FailingMemory:
async def save_episode(self, *_args, **_kwargs) -> None:
raise RuntimeError("memory unavailable")
class RecordingMemory:
def __init__(self) -> None:
self.calls = 0
async def save_episode(self, *_args, **_kwargs) -> None:
self.calls += 1
class ExecutorSideEffectRetryTests(unittest.IsolatedAsyncioTestCase):
async def test_memory_failure_does_not_retry_completed_side_effect(self) -> None:
calls = 0
async def non_idempotent_tool(**_inputs):
nonlocal calls
calls += 1
return {"created_id": "resource-1"}
with patch.dict(
executor_module.TOOL_REGISTRY,
{"non_idempotent_tool": {"required_inputs": [], "fallbacks": [], "_fn": non_idempotent_tool}},
clear=False,
):
result = await Executor(llm_client=object(), memory=FailingMemory(), max_retries=2).run_tool(
"non_idempotent_tool", {}, timeout=2, worker_hint="test",
)
self.assertTrue(result["success"])
self.assertEqual(result["attempt"], 1)
self.assertEqual(calls, 1)
self.assertFalse(result["memory_persisted"])
self.assertIn("memory unavailable", result["memory_error"])
async def test_tool_failure_still_retries_before_any_side_effect_result(self) -> None:
calls = 0
async def flaky_tool(**_inputs):
nonlocal calls
calls += 1
if calls == 1:
raise RuntimeError("transient tool failure")
return {"ok": True}
with patch.dict(
executor_module.TOOL_REGISTRY,
{"flaky_tool": {"required_inputs": [], "fallbacks": [], "_fn": flaky_tool}},
clear=False,
):
result = await Executor(llm_client=object(), memory=None, max_retries=2).run_tool(
"flaky_tool", {}, timeout=2, worker_hint="test",
)
self.assertTrue(result["success"])
self.assertEqual(result["attempt"], 2)
self.assertEqual(calls, 2)
async def test_successful_memory_persistence_is_reported(self) -> None:
memory = RecordingMemory()
async def safe_tool(**_inputs):
return "done"
with patch.dict(
executor_module.TOOL_REGISTRY,
{"safe_tool": {"required_inputs": [], "fallbacks": [], "_fn": safe_tool}},
clear=False,
):
result = await Executor(llm_client=object(), memory=memory, max_retries=0).run_tool(
"safe_tool", {}, timeout=2, worker_hint="test",
)
self.assertTrue(result["success"])
self.assertTrue(result["memory_persisted"])
self.assertEqual(memory.calls, 1)
if __name__ == "__main__":
unittest.main()
|