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.RequestConfig — Type
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 (1disables retries).mcp_connect_timeout::Float64 = 120.0: MCP spawn →initializehandshake 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.
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.
UniLM.current_config — Function
current_config() -> RequestConfigThe ambient RequestConfig: the innermost active with_request_config scope if any, otherwise the process default set by set_default_config! (initially the field defaults).
UniLM.with_request_config — Function
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)
endUniLM.set_default_config! — Function
set_default_config!(cfg::RequestConfig) -> RequestConfig
set_default_config!(; kwargs...) -> RequestConfigSet 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.
Timeout Errors
UniLM.UniLMTimeout — Type
UniLMTimeout <: ExceptionA 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.
UniLM.MCPTimeoutError — Type
MCPTimeoutError <: ExceptionAn 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 →initializehandshake) 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 (themcp_connect_timeout/mcp_request_timeoutfield or a per-calltimeoutkeyword).
Resolution Precedence
A request resolves its RequestConfig struct-wise (whichever channel wins supplies every field):
- A per-call
configkeyword (a complete struct wins outright). - The innermost active
with_request_configscope. - The process default set by
set_default_config!. - The built-in field defaults.