Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyagentspec/src/pyagentspec/adapters/_tools_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def _remote_tool(**kwargs: Any) -> Any:
data=data,
json=json_data,
content=content,
timeout=remote_tool.timeout,
)
return response.json()

Expand Down
4 changes: 4 additions & 0 deletions pyagentspec/src/pyagentspec/tools/remotetool.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class RemoteTool(Tool):
"""Additional headers for the API call.
These headers are intended to be used for sensitive information such as
authentication tokens and will be excluded form exported JSON configs."""
timeout: Optional[float] = None
"""Timeout in seconds for the HTTP request.
Defaults to None, which uses the httpx default timeout (5 seconds).
Set to a higher value for slow endpoints (e.g. transcription, inference)."""

def _get_inferred_inputs(self) -> List["Property"]:
return get_placeholder_properties_from_json_object(
Expand Down
41 changes: 41 additions & 0 deletions pyagentspec/tests/adapters/langgraph/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,3 +698,44 @@ def double_tool_func(x: int) -> int:
),
):
app.invoke(bad, config=config)


def test_remote_tool_timeout_is_forwarded_to_httpx() -> None:
"""Verify that the timeout field on RemoteTool is forwarded to httpx.request."""
from pyagentspec.adapters.langgraph import AgentSpecLoader

remote_tool = RemoteTool(
name="slow_service",
description="A slow remote service",
url="https://example.com/api",
http_method="GET",
timeout=300.0,
)

lang_tool = AgentSpecLoader().load_component(remote_tool)

with patch("pyagentspec.adapters._tools_common.httpx.request") as mock_request:
mock_request.return_value = DummyResponse({"result": "ok"})
lang_tool.func()
_, called_kwargs = mock_request.call_args
assert called_kwargs["timeout"] == 300.0


def test_remote_tool_default_timeout_is_none() -> None:
"""Verify that timeout defaults to None when not set on RemoteTool."""
from pyagentspec.adapters.langgraph import AgentSpecLoader

remote_tool = RemoteTool(
name="default_service",
description="A remote service with default timeout",
url="https://example.com/api",
http_method="GET",
)

lang_tool = AgentSpecLoader().load_component(remote_tool)

with patch("pyagentspec.adapters._tools_common.httpx.request") as mock_request:
mock_request.return_value = DummyResponse({"result": "ok"})
lang_tool.func()
_, called_kwargs = mock_request.call_args
assert called_kwargs["timeout"] is None