Skip to content

Commit d42f29e

Browse files
authored
Avoid unwanted exception chaining when running async tool in sync context (#9092)
Running async tool under sync context (require `settings.allow_tool_async_sync_conversion`) is handled by `Tool._run_async_in_sync`. If there's no running event loop, we used to run the coroutine directly when handling the `RuntimeError` raised by `asyncio.get_running_loop()`. This resulted in exception chaining, where the error raised by the tool will be chained with the `RuntimeError` raised by `asyncio`. Since the result will be passed to the LM as tool call result, such behavior is regarded as unnecessary leak of implementation detail, and will diverge the result of running with `async` and in sync. Move the real call outside of the `except` block will resolve the problem. ## Before ``` Execution error in retrieve: Traceback (most recent call last): File ".venv\Lib\site-packages\dspy\adapters\types\tool.py", line 167, in _run_async_in_sync loop = asyncio.get_running_loop() RuntimeError: no running event loop During handling of the above exception, another exception occurred: Traceback (most recent call last): File ".venv\Lib\site-packages\dspy\predict\react.py", line 111, in forward trajectory[f"observation_{idx}"] = self.tools[pred.next_tool_name](**pred.next_tool_args) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^ File ".venv\Lib\site-packages\dspy\utils\callback.py", line 326, in sync_wrapper return fn(instance, *args, **kwargs) File ".venv\Lib\site-packages\dspy\adapters\types\tool.py", line 176, in __call__ result = self.func(**parsed_kwargs) File "src\retrieval\tool.py", line 169, in retrieve result = run_request(kwargs) ~~~~~~~~~~~^^^^^^^^ ValueError: Invalid request ``` ## After ``` Execution error in retrieve: Traceback (most recent call last): File ".venv\Lib\site-packages\dspy\predict\react.py", line 111, in forward trajectory[f"observation_{idx}"] = self.tools[pred.next_tool_name](**pred.next_tool_args) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^ File ".venv\Lib\site-packages\dspy\utils\callback.py", line 326, in sync_wrapper return fn(instance, *args, **kwargs) File ".venv\Lib\site-packages\dspy\adapters\types\tool.py", line 176, in __call__ result = self.func(**parsed_kwargs) File "src\retrieval\tool.py", line 169, in retrieve result = run_request(kwargs) ~~~~~~~~~~~^^^^^^^^ ValueError: Invalid request ```
1 parent 3183260 commit d42f29e

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

dspy/adapters/types/tool.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,11 @@ def _run_async_in_sync(self, coroutine):
166166
try:
167167
loop = asyncio.get_running_loop()
168168
except RuntimeError:
169-
return asyncio.run(coroutine)
169+
# Run the coroutine outside of "except" block to avoid propagation
170+
loop = None
170171

172+
if loop is None:
173+
return asyncio.run(coroutine)
171174
return loop.run_until_complete(coroutine)
172175

173176
@with_callbacks

0 commit comments

Comments
 (0)