Skip to content

Router reliability controls

Start a pause investigation with anvil-serving router diagnose --active --json. Use request and session diagnostics to connect a request to retained metadata and the owning serve's logs.

Waits, streaming and cancellation

The following [server] settings are seconds. These defaults apply to chat requests in OpenAI Chat Completions, Responses and Anthropic Messages dialects:

[server]
admission_timeout_s = 30
startup_timeout_s = 300
idle_timeout_s = 60
total_timeout_s = 900
heartbeat_interval_s = 15

Admission has a bounded wait. Expiry returns HTTP 503 with Retry-After: 1 before streaming headers are committed. Startup bounds the wait for upstream activity after dispatch; idle bounds subsequent gaps. The total deadline is absolute and never resets. After streaming headers, errors use the dialect's terminal error frame and close the stream. The router never retries a partial completion or substitutes another model.

SSE comment heartbeats keep an admitted, silent stream alive. They do not count as upstream progress or reset a deadline. A downstream disconnect interrupts the upstream transport and releases admission after the worker exits. Expected disconnects produce one bounded event instead of a Python traceback. Upstream failures remain separate events. Embedding, reranking and audio routes retain their existing controls; these chat settings do not change those contracts.

Harness protocol contracts

The reliability controls apply to the router protocol, not to a particular agent. Hermes uses OpenAI Chat Completions. OpenClaw can use the configured OpenAI or Anthropic Messages adapter. Pi uses OpenAI Chat Completions and the supported stateless Responses subset. Tool-call continuations remain ordinary messages in each dialect, so they retain the same admission, deadline, heartbeat, cancellation, and terminal-error behavior as text turns.

For an optional retained session view, clients may send one bounded opaque X-Anvil-Session-Id; X-Session-Affinity remains the compatible alias. The header is read before dialect parsing, so its behavior is identical for Chat Completions, Messages, and Responses. It is router metadata only and is never forwarded to the model upstream. GET /v1/requests?session_id=...&history=1 returns its retained terminal records.

Pi's managed Anvil provider enables its documented session-affinity compatibility setting and uses the compatible header. OpenClaw's documented custom-provider headers and Hermes's documented custom-provider headers are static provider settings. They must not be populated with a session value: a static value would merge unrelated conversations. Enable X-Anvil-Session-Id for Hermes or OpenClaw only through a client feature that supplies that client's existing per-conversation opaque ID on each request. An unmodified client remains fully supported; its requests are individually diagnosable by the router-generated request ID but have no session-history grouping.

Client concurrency budgets

Use the existing scoped authorization policy with inference:use credentials. Keep credentials in protected files or environment references. For example:

[server]
auth_env = "ANVIL_ROUTER_TOKEN"
authorization_policy_path = "/etc/anvil-serving/authorization.json"
client_limits = { desktop = 2, automation = 1, _legacy = 2 }

The policy uses the existing version-1 schema, with client entries containing id, scopes and either credential_env or credential_file. A configured budget counts active and waiting chat requests for the credential's client ID. Exhaustion returns HTTP 429 with Retry-After: 1; it does not wait in another queue. Unlisted clients retain the global admission limit. _legacy groups callers sharing the legacy router credential. Client-supplied headers cannot choose this identity. Caps prevent a configured client from consuming the whole pool; this is not weighted scheduling or a per-client reservation.

inference:use grants chat and model discovery access, not management or diagnostic access. The separate workloads:read scope grants request diagnostics. The legacy operator credential retains its existing authority. Scope files load at startup; changing them requires a managed router restart.

Engine metrics

Routing uses declared endpoints, capabilities and dialects. The metrics adapter recognizes these public Prometheus metric families without changing selection:

Engine Normalized observations when exposed
vLLM Running/waiting requests, KV utilization, completion counters, prefix-cache hits and queries.
SGLang Running/waiting requests, token/KV utilization, generation throughput, cache hit rate and available counters.
llama.cpp Processing/deferred requests, KV utilization, prediction counters and throughput.

Separate scheduler replicas are aggregated; tensor/pipeline-rank copies are deduplicated. Missing or conflicting measurements remain unknown. Counters are cumulative engine observations and can reset after restart. They are not per-request token usage. Metrics support is covered by fixtures for all three engines; a deployment still needs a live check against its installed engine version and enabled metrics. SGLang metadata prefers /server_info, with the deprecated /get_server_info retained only as a compatibility fallback.

Retention and optional traces

Set server.decision_log_path to a private persistent mounted file for request history across router recreation. Rotated files are the source of retained history; no separate database or model payload store is introduced.

server.trace_export_url = "http://127.0.0.1:4318/v1/traces" enables optional OTLP/HTTP JSON export to an explicitly configured private IP collector. URLs cannot contain credentials. Redirects and proxy environment settings are disabled. Export uses a bounded queue, one background worker, and no retries; collector failure never blocks inference. Transport timeouts bound individual blocking operations, not the whole export when a collector trickles headers.

Spans contain allowlisted request IDs, session/client IDs, route, timing, token counts and outcome. They contain no prompt, response, tool payload, credential, or raw upstream error. These are standalone request spans correlated by IDs; W3C parent trace propagation is not implemented.