diff --git a/Clients.md b/Clients.md index 1b0142f..79421ce 100644 --- a/Clients.md +++ b/Clients.md @@ -449,7 +449,22 @@ for each flow. # Extra Settings Coyote also lets you customize some extra settings for interacting with APIs: -| Setting | Description | -|-------------------|-------------------------------------------------------| -| `proxy` | Set a proxy to use | -| `connect_timeout` | Set the timeout in seconds for connections to the API | +| Setting | Description | Default | +|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| +| `proxy` | Set a proxy to use | - | +| `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.
Streaming-safe; the clock resets on every chunk received, so long streaming responses are fine as long as data keeps flowing.
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. diff --git a/Custom-Bash-Tools.md b/Custom-Bash-Tools.md index 2f51979..24bf16b 100644 --- a/Custom-Bash-Tools.md +++ b/Custom-Bash-Tools.md @@ -26,6 +26,17 @@ define a CLI. * A `# @describe` * 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 `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,
or headers. | | `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).
When exceeded, the tool process is killed and a `tool_call_error` is returned to the model instead of hanging the session forever.
Set to `0` for unlimited. Default: `1800` (30 minutes). | # Files and Directory Related Variables You can also customize the files and directories that Coyote loads its configuration files from: diff --git a/Graph-Agents.md b/Graph-Agents.md index f0e9753..bd5ebe2 100644 --- a/Graph-Agents.md +++ b/Graph-Agents.md @@ -130,9 +130,15 @@ nodes: 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=...)`. Default: 100. -- **`timeout`:** Wall-clock cap on the entire graph run. The executor - checks this between every node transition; nodes that block longer than - the timeout will still finish before the check fires. +- **`timeout`:** Wall-clock cap on the entire graph run. Checked before each + super-step **and** enforced during super-steps: if the budget elapses while + 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 state before any node runs and are referenced from any node via `{{key}}` templates. @@ -466,6 +472,12 @@ list; an unknown entry is a startup error. downstream nodes run, so downstream `{{output}}` references never see error 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`) `max_attempts` retries the LLM call **only on transient errors**. The