File tree Expand file tree Collapse file tree 3 files changed +30
-1
lines changed Expand file tree Collapse file tree 3 files changed +30
-1
lines changed Original file line number Diff line number Diff line change 6
6
from pydantic import BaseModel , TypeAdapter , create_model
7
7
8
8
from dspy .adapters .types .base_type import BaseType
9
+ from dspy .dsp .utils .settings import settings
9
10
from dspy .utils .callback import with_callbacks
10
11
11
12
if TYPE_CHECKING :
@@ -160,12 +161,26 @@ def format_as_litellm_function_call(self):
160
161
},
161
162
}
162
163
164
+ def _run_async_in_sync (self , coroutine ):
165
+ try :
166
+ loop = asyncio .get_running_loop ()
167
+ except RuntimeError :
168
+ return asyncio .run (coroutine )
169
+
170
+ return loop .run_until_complete (coroutine )
171
+
163
172
@with_callbacks
164
173
def __call__ (self , ** kwargs ):
165
174
parsed_kwargs = self ._validate_and_parse_args (** kwargs )
166
175
result = self .func (** parsed_kwargs )
167
176
if asyncio .iscoroutine (result ):
168
- raise ValueError ("You are calling `__call__` on an async tool, please use `acall` instead." )
177
+ if settings .allow_tool_async_sync_conversion :
178
+ return self ._run_async_in_sync (result )
179
+ else :
180
+ raise ValueError (
181
+ "You are calling `__call__` on an async tool, please use `acall` instead or set "
182
+ "`allow_async=True` to run the async tool in sync mode."
183
+ )
169
184
return result
170
185
171
186
@with_callbacks
Original file line number Diff line number Diff line change 27
27
provide_traceback = False , # Whether to include traceback information in error logs.
28
28
num_threads = 8 , # Number of threads to use for parallel processing.
29
29
max_errors = 10 , # Maximum errors before halting operations.
30
+ # If true, async tools can be called in sync mode by getting converted to sync.
31
+ allow_tool_async_sync_conversion = False ,
30
32
)
31
33
32
34
# Global base configuration and owner tracking
Original file line number Diff line number Diff line change 5
5
from pydantic import BaseModel
6
6
7
7
from dspy .adapters .types .tool import Tool
8
+ import dspy
8
9
9
10
10
11
# Test fixtures
@@ -363,3 +364,14 @@ async def test_async_concurrent_calls():
363
364
# Check that it ran concurrently (should take ~0.1s, not ~0.5s)
364
365
# We use 0.3s as threshold to account for some overhead
365
366
assert end_time - start_time < 0.3
367
+
368
+
369
+ def test_async_tool_call_in_sync_mode ():
370
+ tool = Tool (async_dummy_function )
371
+ with dspy .context (allow_tool_async_sync_conversion = False ):
372
+ with pytest .raises (ValueError ):
373
+ result = tool (x = 1 , y = "hello" )
374
+
375
+ with dspy .context (allow_tool_async_sync_conversion = True ):
376
+ result = tool (x = 1 , y = "hello" )
377
+ assert result == "hello 1"
You can’t perform that action at this time.
0 commit comments