Skip to content

Commit d43bc96

Browse files
authored
feat: throw exception if running sync run/create methods in async context (#741)
* docs: Update README and documentation for synchronous and asynchronous method usage * fix: Prevent calling synchronous methods in async context\ * cleanup * unit tests
1 parent cfbd1ef commit d43bc96

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

src/any_agent/frameworks/any_agent.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,20 @@ def create(
129129
agent_config: AgentConfig,
130130
) -> AnyAgent:
131131
"""Create an agent using the given framework and config."""
132-
return run_async_in_sync(
133-
cls.create_async(
134-
agent_framework=agent_framework,
135-
agent_config=agent_config,
132+
try:
133+
asyncio.get_running_loop()
134+
except RuntimeError:
135+
# No running event loop - this is what we want for sync execution
136+
return run_async_in_sync(
137+
cls.create_async(
138+
agent_framework=agent_framework,
139+
agent_config=agent_config,
140+
)
136141
)
137-
)
142+
143+
# If we get here, there IS a running loop
144+
msg = "Cannot call 'create()' from an async context. Use 'create_async()' instead."
145+
raise RuntimeError(msg)
138146

139147
@classmethod
140148
async def create_async(
@@ -160,7 +168,15 @@ async def _load_tools(
160168

161169
def run(self, prompt: str, **kwargs: Any) -> AgentTrace:
162170
"""Run the agent with the given prompt."""
163-
return run_async_in_sync(self.run_async(prompt, **kwargs))
171+
try:
172+
asyncio.get_running_loop()
173+
except RuntimeError:
174+
# No running event loop - this is what we want for sync execution
175+
return run_async_in_sync(self.run_async(prompt, **kwargs))
176+
177+
# If we get here, there IS a running loop
178+
msg = "Cannot call 'run()' from an async context. Use 'run_async()' instead."
179+
raise RuntimeError(msg)
164180

165181
async def run_async(self, prompt: str, **kwargs: Any) -> AgentTrace:
166182
"""Run the agent asynchronously with the given prompt.

tests/unit/frameworks/test_any_agent.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,27 @@ def test_model_args_streaming(
9292
assert mock_litellm.call_args.kwargs["temperature"] == TEST_TEMPERATURE
9393
assert mock_litellm.call_args.kwargs["frequency_penalty"] == TEST_PENALTY
9494
assert mock_litellm.call_count > 0
95+
96+
97+
@pytest.mark.asyncio
98+
async def test_create_sync_in_async_context() -> None:
99+
with pytest.raises(
100+
RuntimeError,
101+
match=r"Cannot call 'create\(\)' from an async context\. Use 'create_async\(\)' instead\.",
102+
):
103+
AnyAgent.create(
104+
AgentFramework.TINYAGENT,
105+
AgentConfig(model_id="mistral/mistral-small-latest"),
106+
)
107+
108+
109+
@pytest.mark.asyncio
110+
async def test_run_sync_in_async_context() -> None:
111+
agent = await AnyAgent.create_async(
112+
AgentFramework.TINYAGENT, AgentConfig(model_id="mistral/mistral-small-latest")
113+
)
114+
with pytest.raises(
115+
RuntimeError,
116+
match=r"Cannot call 'run\(\)' from an async context\. Use 'run_async\(\)' instead\.",
117+
):
118+
agent.run(TEST_QUERY)

0 commit comments

Comments
 (0)