from __future__ import annotations from typing import Any import pytest from langgraph.store.base import BaseStore from langgraph.types import StreamWriter from langgraph.utils.runnable import RunnableCallable pytestmark = pytest.mark.anyio def test_runnable_callable_func_accepts(): def sync_func(x: Any) -> str: return f"{x}" async def async_func(x: Any) -> str: return f"{x}" def func_with_store(x: Any, store: BaseStore) -> str: return f"{x}" def func_with_writer(x: Any, writer: StreamWriter) -> str: return f"{x}" async def afunc_with_store(x: Any, store: BaseStore) -> str: return f"{x}" async def afunc_with_writer(x: Any, writer: StreamWriter) -> str: return f"{x}" runnables = { "sync": RunnableCallable(sync_func), "async": RunnableCallable(func=None, afunc=async_func), "with_store": RunnableCallable(func_with_store), "with_writer": RunnableCallable(func_with_writer), "awith_store": RunnableCallable(afunc_with_store), "awith_writer": RunnableCallable(afunc_with_writer), } expected_store = {"with_store": True, "awith_store": True} expected_writer = {"with_writer": True, "awith_writer": True} for name, runnable in runnables.items(): assert runnable.func_accepts["writer"] == expected_writer.get(name, False) assert runnable.func_accepts["store"] == expected_store.get(name, False) async def test_runnable_callable_basic(): def sync_func(x: Any) -> str: return f"{x}" async def async_func(x: Any) -> str: return f"{x}" runnable_sync = RunnableCallable(sync_func) runnable_async = RunnableCallable(func=None, afunc=async_func) result_sync = runnable_sync.invoke("test") assert result_sync == "test" # Test asynchronous ainvoke result_async = await runnable_async.ainvoke("test") assert result_async == "test"