docs: Added documentation of the new timeout settings

2026-08-14 15:37:08 -06:00
parent 57571768cc
commit c666b53565
4 changed files with 46 additions and 7 deletions
+19 -4
@@ -449,7 +449,22 @@ for each flow.
# Extra Settings # Extra Settings
Coyote also lets you customize some extra settings for interacting with APIs: Coyote also lets you customize some extra settings for interacting with APIs:
| Setting | Description | | Setting | Description | Default |
|-------------------|-------------------------------------------------------| |-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
| `proxy` | Set a proxy to use | | `proxy` | Set a proxy to use | - |
| `connect_timeout` | Set the timeout in seconds for connections to the API | | `connect_timeout` | Timeout in seconds for *establishing* a connection to the API | `10` |
| `read_timeout` | Stall detector: maximum seconds allowed between successive reads from the API before the request is aborted. <br>Streaming-safe; the clock resets on every chunk received, so long streaming responses are fine as long as data keeps flowing. <br>Set to `0` to disable entirely (e.g. for very slow local models or large non-streaming embedding calls). | `300` |
```yaml
clients:
- type: openai
extra:
proxy: socks5://127.0.0.1:1080
connect_timeout: 10
read_timeout: 300
```
> [!NOTE]
> Before `read_timeout` existed, a connection that stalled *after* connecting (e.g. a streaming response that
> silently stopped mid-stream) would hang Coyote indefinitely. The default now aborts any request that goes 300
> seconds without receiving a single byte.
+11
@@ -26,6 +26,17 @@ define a CLI.
* A `# @describe` * A `# @describe`
* And a `main` function that writes to `$LLM_OUTPUT` * And a `main` function that writes to `$LLM_OUTPUT`
## Execution Environment
A few things to know about how Coyote runs your tool's subprocess:
* **`stdin` is `/dev/null`.** Tools must not read from standard input. Anything that blocks on stdin (interactive
editors, `read` without `</dev/tty`, watch-mode test runners) will see EOF immediately instead of hanging the
session. Interactive prompts that genuinely need the user should read from `/dev/tty` directly.
* **Every tool call has a wall-clock cap** controlled by the `COYOTE_TOOL_TIMEOUT` environment variable
(default: `1800` seconds; `0` = unlimited). If the tool exceeds it, the process is killed and a `tool_call_error`
is returned to the model, and the session keeps going. See [Environment Variables](Environment-Variables).
The following section explains how you can add parameters to your bash functions and how to test out your scripts. The following section explains how you can add parameters to your bash functions and how to test out your scripts.
--- ---
+1
@@ -59,6 +59,7 @@ The following environment variables are available for clients in Coyote:
| `COYOTE_PLATFORM` | Combine with `{client}_API_KEY` to run Coyote without a configuration file. <br>This variable is ignored if a configuration file exists. | | `COYOTE_PLATFORM` | Combine with `{client}_API_KEY` to run Coyote without a configuration file. <br>This variable is ignored if a configuration file exists. |
| `COYOTE_PATCH_{client}_CHAT_COMPLETIONS` | Patch chat completion requests to models on the corresponding client; Can modify the URL, body, <br>or headers. | | `COYOTE_PATCH_{client}_CHAT_COMPLETIONS` | Patch chat completion requests to models on the corresponding client; Can modify the URL, body, <br>or headers. |
| `COYOTE_SHELL` | Specify the shell that Coyote should be using when executing commands | | `COYOTE_SHELL` | Specify the shell that Coyote should be using when executing commands |
| `COYOTE_TOOL_TIMEOUT` | Wall-clock cap in seconds for any single tool-call subprocess (built-in and custom tools alike). <br>When exceeded, the tool process is killed and a `tool_call_error` is returned to the model instead of hanging the session forever. <br>Set to `0` for unlimited. Default: `1800` (30 minutes). |
# Files and Directory Related Variables # Files and Directory Related Variables
You can also customize the files and directories that Coyote loads its configuration files from: You can also customize the files and directories that Coyote loads its configuration files from:
+15 -3
@@ -130,9 +130,15 @@ nodes:
graph-step cap. If the same node id is entered more than this many times, graph-step cap. If the same node id is entered more than this many times,
execution aborts with `Node 'X' visited N times (max_loop_iterations=...)`. execution aborts with `Node 'X' visited N times (max_loop_iterations=...)`.
Default: 100. Default: 100.
- **`timeout`:** Wall-clock cap on the entire graph run. The executor - **`timeout`:** Wall-clock cap on the entire graph run. Checked before each
checks this between every node transition; nodes that block longer than super-step **and** enforced during super-steps: if the budget elapses while
the timeout will still finish before the check fires. nodes are still running, the in-flight branches are aborted and the run
fails with a `timed out after Ns during super-step` error. Note that a
graph-level timeout is a hard bail. It does **not** route through node
`fallback`s, so any cleanup/reporting nodes are skipped. Prefer per-node
`timeout`s on `llm` nodes (which *do* route via `fallback`) as the
operative bound, and treat the graph-level `timeout` as a generous
backstop.
- **`initial_state`:** A JSON-compatible object. Values are seeded into - **`initial_state`:** A JSON-compatible object. Values are seeded into
state before any node runs and are referenced from any node via `{{key}}` state before any node runs and are referenced from any node via `{{key}}`
templates. templates.
@@ -466,6 +472,12 @@ list; an unknown entry is a startup error.
downstream nodes run, so downstream `{{output}}` references never see error downstream nodes run, so downstream `{{output}}` references never see error
strings; the upstream cause is reported instead. strings; the upstream cause is reported instead.
A node-level `timeout` counts as a failure like any other: it routes via
`fallback` when one is set, and fails the graph otherwise. This makes
per-node `timeout`s the preferred way to bound long-running `llm` nodes.
Unlike the graph-level `settings.timeout`, a node timeout still gives the
graph a chance to recover or report through its `fallback` route.
### Retries (`max_attempts`) ### Retries (`max_attempts`)
`max_attempts` retries the LLM call **only on transient errors**. The `max_attempts` retries the LLM call **only on transient errors**. The