2026-07-14 18:20:32 +08:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
2026-07-24 14:57:03 +08:00
|
|
|
import asyncio
|
2026-07-14 18:20:32 +08:00
|
|
|
import inspect
|
|
|
|
|
from typing import TYPE_CHECKING, Any, cast
|
|
|
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
from plyngent.agent import ToolDefinition
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def call_sync(definition: ToolDefinition, *args: object, **kwargs: object) -> str:
|
2026-07-24 14:57:03 +08:00
|
|
|
"""Invoke a tool handler from a **sync** test.
|
|
|
|
|
|
|
|
|
|
Async handlers are run with ``asyncio.run``. Inside an already-running
|
|
|
|
|
event loop (async tests), use :func:`call_async` instead.
|
|
|
|
|
"""
|
2026-07-14 18:20:32 +08:00
|
|
|
result: Any = definition.handler(*args, **kwargs)
|
2026-07-24 14:57:03 +08:00
|
|
|
if inspect.isawaitable(result):
|
|
|
|
|
try:
|
|
|
|
|
asyncio.get_running_loop()
|
|
|
|
|
except RuntimeError:
|
|
|
|
|
result = asyncio.run(result)
|
|
|
|
|
else:
|
|
|
|
|
msg = "call_sync cannot await inside a running event loop; use call_async"
|
|
|
|
|
raise RuntimeError(msg)
|
2026-07-14 18:20:32 +08:00
|
|
|
return cast("str", result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def call_async(definition: ToolDefinition, *args: object, **kwargs: object) -> str:
|
|
|
|
|
result: Any = definition.handler(*args, **kwargs)
|
|
|
|
|
if inspect.isawaitable(result):
|
|
|
|
|
result = await result
|
|
|
|
|
return cast("str", result)
|