Request Configuration & Timeouts

See the Timeouts & Retries guide for usage and rationale.

Timeout, deadline, and retry-budget configuration for UniLM network operations, plus the typed timeout errors.

Configuration

UniLM.RequestConfigType
RequestConfig(; kwargs...)
RequestConfig(base::RequestConfig; kwargs...)

Timeout and retry budget for every UniLM network operation. All time fields are seconds (Float64); Inf disables that bound.

Fields

  • connect_timeout::Float64 = 10.0: per-attempt connection-establishment bound.
  • request_timeout::Float64 = 600.0: per-attempt bound on a whole non-streaming exchange.
  • stream_idle_timeout::Float64 = 120.0: maximum byte-gap between raw chunks of a stream.
  • total_deadline::Float64 = 900.0: bound across ALL attempts including backoff; for streams it applies until the first byte.
  • max_attempts::Int = 3: maximum wire attempts (1 disables retries).
  • mcp_connect_timeout::Float64 = 120.0: MCP spawn → initialize handshake bound.
  • mcp_request_timeout::Float64 = 120.0: per MCP exchange bound.

The constructor throws ArgumentError for NaN or non-positive time values (NaN is rejected explicitly because it compares false against every bound and would silently disable the timeout), and for max_attempts < 1.

`connect_timeout = Inf` is unsupported on the HTTP 1.x major

A task-mode watchdog abandons its worker on breach instead of killing it, which is safe only because the same attempt carries a native bound that ends that worker on its own. On the 1.x major connect_timeout is the only native bound covering connection acquisition (the native read bound starts after the request is written), so disabling it leaves an abandoned worker with nothing to terminate it, and the wait is genuinely unbounded. Disable it only on the 2.x major, whose per-attempt request bound also covers acquisition.

The two-argument form copies base with the named fields overridden, under the same validation.

See also with_request_config, set_default_config!, current_config.

source
UniLM.with_request_configFunction
with_request_config(f; kwargs...)

Run f() with a RequestConfig pinned in dynamic scope and return f()'s value. The given fields are merged over current_config once at entry; the resulting complete struct governs every UniLM call inside f, including tasks spawned inside the scope (scoped values propagate into Threads.@spawn). Mutating the process default while the scope is active does not affect it.

with_request_config(request_timeout=30.0, max_attempts=1) do
    chatrequest!(chat)
end
source
UniLM.set_default_config!Function
set_default_config!(cfg::RequestConfig) -> RequestConfig
set_default_config!(; kwargs...) -> RequestConfig

Set the process-wide default RequestConfig and return it. The keyword form merges the given fields over the CURRENT process default (never over an active scope). Intended for REPL/notebook sessions, which cannot hold a dynamic scope across cells; prefer with_request_config in programs.

The keyword form is a read-modify-write and retries on a compare-and-swap miss: a plain read-then-write loses one of two concurrent calls, because the loser installs a snapshot taken before the winner's write and silently drops its field.

source

Timeout Errors

UniLM.UniLMTimeoutType
UniLMTimeout <: Exception

A configured UniLM time bound was exceeded.

Fields

  • phase::Symbol: which bound fired — :connect, :request, :stream_idle, or :deadline (the total budget across attempts).
  • elapsed::Float64: seconds elapsed when the timeout surfaced (monotonic clock).
  • limit::Float64: the configured bound in seconds.

Configure the bounds via RequestConfig. Value-returning surfaces (chat, embeddings, responses) deliver this inside their error results rather than throwing; see each surface's documentation.

source
UniLM.MCPTimeoutErrorType
MCPTimeoutError <: Exception

An MCP operation exceeded its configured time bound. The MCP surface is throw-based, so this surfaces as an exception rather than a failure value.

Fields

  • phase::Symbol: :connect (spawn → initialize handshake) or :request (one MCP exchange).
  • elapsed::Float64: seconds elapsed when the timeout fired (monotonic clock).
  • limit::Float64: the configured bound in seconds.
  • msg::String: human-readable message naming the applicable override (the mcp_connect_timeout/mcp_request_timeout field or a per-call timeout keyword).
source

Resolution Precedence

A request resolves its RequestConfig struct-wise (whichever channel wins supplies every field):

  1. A per-call config keyword (a complete struct wins outright).
  2. The innermost active with_request_config scope.
  3. The process default set by set_default_config!.
  4. The built-in field defaults.