feat: add configurable HTTP timeout for tool execution#166
feat: add configurable HTTP timeout for tool execution#166
Conversation
httpx.request() was called without a timeout, defaulting to 5s.
Slow providers (e.g. Workday) regularly exceed this, causing
ReadTimeout errors.
- Add `timeout` field to `ExecuteConfig` (default 30s)
- Pass it through to `httpx.request()`
- Add `timeout` to `ExecuteToolsConfig` so users can set it at init:
`StackOneToolSet(execute={"account_ids": [...], "timeout": 60})`
- Thread timeout from toolset config through `_StackOneRpcTool`
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR makes tool execution HTTP requests more resilient by adding a configurable timeout (defaulting to 30s) and wiring it through the toolset and tool execution path to avoid ReadTimeout on slower providers.
Changes:
- Added
timeouttoExecuteConfig(default30.0) and passed it tohttpx.request()during tool execution. - Added
timeouttoExecuteToolsConfigand propagated it into RPC tool construction (_StackOneRpcTool).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
stackone_ai/toolset.py |
Adds execute.timeout config and passes it into _StackOneRpcTool via ExecuteConfig(timeout=...). |
stackone_ai/models.py |
Extends ExecuteConfig with timeout and forwards it into httpx.request(...) during StackOneTool.execute(). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| class ExecuteToolsConfig(TypedDict, total=False): | ||
| """Execution configuration for the StackOneToolSet constructor. | ||
|
|
||
| Controls default account scoping for tool execution. | ||
|
|
||
| When set to ``None`` (default), no account scoping is applied. | ||
| When provided, ``account_ids`` flow through to ``openai(mode="search_and_execute")`` | ||
| and ``fetch_tools()`` as defaults. | ||
| """ | ||
|
|
||
| account_ids: list[str] | ||
| """Account IDs to scope tool discovery and execution.""" | ||
|
|
||
| timeout: float | ||
| """HTTP request timeout in seconds for tool execution. Defaults to 30.""" | ||
|
|
There was a problem hiding this comment.
The ExecuteToolsConfig docstring still describes only account scoping, but this config now also controls HTTP execution timeout. Update the class docstring/constructor docs to mention the new timeout option so users discover it and understand what it affects (e.g., tool execution requests).
| request_kwargs["data"] = body_params | ||
|
|
||
| if query_params: | ||
| request_kwargs["params"] = query_params | ||
|
|
||
| response = httpx.request(**request_kwargs) | ||
| response = httpx.request(**request_kwargs, timeout=self._execute_config.timeout) | ||
| response_status = response.status_code | ||
| response.raise_for_status() |
There was a problem hiding this comment.
New behavior passes timeout=self._execute_config.timeout into httpx.request(), but the test suite doesn’t currently assert that the timeout is forwarded (or that the default 30s is applied). Add/adjust a unit test to verify httpx.request is called with the expected timeout value, and that overriding ExecuteConfig(timeout=...) changes the value passed through.
| parameters = ToolParameters( | ||
| type=str(schema.get("type") or "object"), | ||
| properties=self._normalize_schema_properties(schema), | ||
| ) | ||
| timeout = ( | ||
| self._execute_config.get("timeout", 30.0) if self._execute_config else 30.0 | ||
| ) | ||
| return _StackOneRpcTool( | ||
| name=tool_def.name, | ||
| description=tool_def.description or "", | ||
| parameters=parameters, | ||
| api_key=self.api_key, | ||
| base_url=self.base_url, | ||
| account_id=account_id, | ||
| timeout=timeout, | ||
| ) |
There was a problem hiding this comment.
The new toolset-level execute.timeout is used when constructing _StackOneRpcTool, but there’s no test ensuring that a configured timeout actually propagates into each tool’s ExecuteConfig (and therefore into HTTP execution). Add a toolset test that creates StackOneToolSet(execute={"timeout": ...}), fetches a tool (mocking MCP catalog if needed), and asserts the resulting tool executes with that timeout.
Summary
httpx.request()inStackOneTool.execute()was called without atimeoutparameter, defaulting to httpx's 5s. Slow providers (e.g. Workday, which regularly takes 10-15s) causeReadTimeouterrors.timeoutfield toExecuteConfig(default 30s) and passes it tohttpx.request()timeouttoExecuteToolsConfigso users can configure it at the toolset levelUsage
Test plan
test_models.py)timeout=60🤖 Generated with Claude Code
Summary by cubic
Adds a configurable HTTP timeout for tool execution to reduce ReadTimeouts with slow providers. Default is 30s and applied to all tool HTTP requests, overridable per toolset.
timeouttoExecuteConfig(default 30s) and pass it tohttpx.request(...).timeoutinExecuteToolsConfigso it can be set on init, e.g.StackOneToolSet(execute={"account_ids": ["..."], "timeout": 60}).Written for commit a329c46. Summary will update on new commits.