TestSyncAsyncMiddlewareComposition Class — langchain Architecture
Architecture documentation for the TestSyncAsyncMiddlewareComposition class in test_sync_async_wrappers.py from the langchain codebase.
Entity Profile
Dependency Diagram
graph TD d334b1be_8897_4ab4_029f_9ac431676ef8["TestSyncAsyncMiddlewareComposition"] 6d9956c5_7c84_9ec3_58a3_b6b89f42fd0b["AgentMiddleware"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|extends| 6d9956c5_7c84_9ec3_58a3_b6b89f42fd0b 4318b819_4fe9_65b0_5369_424ec9518efe["ToolMessage"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|extends| 4318b819_4fe9_65b0_5369_424ec9518efe f9fb0cbf_6df7_5614_132d_6f7399bc253c["test_sync_async_wrappers.py"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|defined in| f9fb0cbf_6df7_5614_132d_6f7399bc253c 9448558c_c642_c256_c486_99245045b43f["test_sync_only_middleware_works_on_sync_path()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| 9448558c_c642_c256_c486_99245045b43f ffcad92c_990b_c157_b600_27586dbd9a39["test_sync_only_middleware_raises_on_async_path()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| ffcad92c_990b_c157_b600_27586dbd9a39 4ca6133f_fd61_1f62_b233_9f082dd8765a["test_async_only_middleware_works_on_async_path()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| 4ca6133f_fd61_1f62_b233_9f082dd8765a cc50bcc6_b0ba_b172_3503_f338f07c51b1["test_async_only_middleware_raises_on_sync_path()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| cc50bcc6_b0ba_b172_3503_f338f07c51b1 908404c4_5253_feb0_7b9f_8fce0e2cdcba["test_both_sync_and_async_middleware_uses_appropriate_path()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| 908404c4_5253_feb0_7b9f_8fce0e2cdcba eee7797c_f6fd_023a_7988_e6af943493ab["test_both_sync_and_async_middleware_uses_appropriate_path_async()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| eee7797c_f6fd_023a_7988_e6af943493ab 1eab7f7b_cc22_f702_4805_9cc4224a7aad["test_mixed_middleware_composition_async_path_fails_with_sync_only()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| 1eab7f7b_cc22_f702_4805_9cc4224a7aad e744b264_3b74_003e_1e6d_d90d39987233["test_mixed_middleware_composition_sync_path_with_async_only_fails()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| e744b264_3b74_003e_1e6d_d90d39987233 217c558f_2c38_2a06_7383_ae62fb7482e8["test_decorator_sync_only_works_both_paths()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| 217c558f_2c38_2a06_7383_ae62fb7482e8 159409ff_f9e8_b4b8_ab92_71010abe1f33["test_decorator_sync_only_raises_on_async_path()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| 159409ff_f9e8_b4b8_ab92_71010abe1f33 267d8d25_6524_c761_685a_ec24aaa8a34e["test_decorator_async_only_works_async_path()"] d334b1be_8897_4ab4_029f_9ac431676ef8 -->|method| 267d8d25_6524_c761_685a_ec24aaa8a34e
Relationship Graph
Source Code
libs/langchain_v1/tests/unit_tests/agents/middleware/core/test_sync_async_wrappers.py lines 35–490
class TestSyncAsyncMiddlewareComposition:
"""Test sync/async middleware composition behavior."""
def test_sync_only_middleware_works_on_sync_path(self) -> None:
"""Middleware with only sync wrap_tool_call works on sync path."""
call_log = []
class SyncOnlyMiddleware(AgentMiddleware):
def wrap_tool_call(
self,
request: ToolCallRequest,
handler: Callable[[ToolCallRequest], ToolMessage | Command[Any]],
) -> ToolMessage | Command[Any]:
call_log.append("sync_called")
return handler(request)
model = FakeToolCallingModel(
tool_calls=[
[ToolCall(name="search", args={"query": "test"}, id="1")],
[],
]
)
agent = create_agent(
model=model,
tools=[search],
middleware=[SyncOnlyMiddleware()],
checkpointer=InMemorySaver(),
)
result = agent.invoke(
{"messages": [HumanMessage("Search")]},
{"configurable": {"thread_id": "test"}},
)
assert "sync_called" in call_log
tool_messages = [m for m in result["messages"] if isinstance(m, ToolMessage)]
assert len(tool_messages) == 1
assert "Results for: test" in tool_messages[0].content
async def test_sync_only_middleware_raises_on_async_path(self) -> None:
"""Middleware with only sync wrap_tool_call raises NotImplementedError on async path."""
class SyncOnlyMiddleware(AgentMiddleware):
def wrap_tool_call(
self,
request: ToolCallRequest,
handler: Callable[[ToolCallRequest], ToolMessage | Command[Any]],
) -> ToolMessage | Command[Any]:
return handler(request)
model = FakeToolCallingModel(
tool_calls=[
[ToolCall(name="search", args={"query": "test"}, id="1")],
[],
]
)
agent = create_agent(
model=model,
tools=[search],
middleware=[SyncOnlyMiddleware()],
checkpointer=InMemorySaver(),
)
# Should raise NotImplementedError because SyncOnlyMiddleware doesn't support async path
with pytest.raises(NotImplementedError):
await agent.ainvoke(
{"messages": [HumanMessage("Search")]},
{"configurable": {"thread_id": "test"}},
)
async def test_async_only_middleware_works_on_async_path(self) -> None:
"""Middleware with only async awrap_tool_call works on async path."""
call_log = []
class AsyncOnlyMiddleware(AgentMiddleware):
async def awrap_tool_call(
self,
request: ToolCallRequest,
handler: Callable[[ToolCallRequest], Awaitable[ToolMessage | Command[Any]]],
Extends
Source
Frequently Asked Questions
What is the TestSyncAsyncMiddlewareComposition class?
TestSyncAsyncMiddlewareComposition is a class in the langchain codebase, defined in libs/langchain_v1/tests/unit_tests/agents/middleware/core/test_sync_async_wrappers.py.
Where is TestSyncAsyncMiddlewareComposition defined?
TestSyncAsyncMiddlewareComposition is defined in libs/langchain_v1/tests/unit_tests/agents/middleware/core/test_sync_async_wrappers.py at line 35.
What does TestSyncAsyncMiddlewareComposition extend?
TestSyncAsyncMiddlewareComposition extends AgentMiddleware, ToolMessage.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free