Skip to main content

dynamo_runtime/config/
environment_names.rs

1// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Environment variable name constants for centralized management across the codebase
5//!
6//! This module provides centralized environment variable name constants to ensure
7//! consistency and avoid duplication across the codebase, similar to how
8//! `prometheus_names.rs` manages metric names.
9//!
10//! ## Organization
11//!
12//! Environment variables are organized by functional area:
13//! - **Logging**: Log level, configuration, and OTLP tracing
14//! - **Runtime**: Tokio runtime configuration and system server settings
15//! - **NATS**: NATS client connection and authentication
16//! - **ETCD**: ETCD client connection and authentication
17//! - **TCP Response Stream**: TCP response stream server (CallHome) port and host
18//! - **Event Plane**: Event transport selection (NATS)
19//! - **KVBM**: Key-Value Block Manager configuration
20//! - **LLM**: Language model inference configuration
21//! - **Model**: Model loading and caching
22//! - **Worker**: Worker lifecycle and shutdown
23//! - **Testing**: Test-specific configuration
24//! - **Mocker**: Mocker (mock scheduler/KV manager) configuration
25
26/// Logging and tracing environment variables
27pub mod logging {
28    /// Log level (e.g., "debug", "info", "warn", "error")
29    pub const DYN_LOG: &str = "DYN_LOG";
30
31    /// Path to logging configuration file
32    pub const DYN_LOGGING_CONFIG_PATH: &str = "DYN_LOGGING_CONFIG_PATH";
33
34    /// Enable JSONL logging format
35    pub const DYN_LOGGING_JSONL: &str = "DYN_LOGGING_JSONL";
36
37    /// Console log format: "readable" or "jsonl"; blank uses the legacy fallback
38    pub const DYN_LOGGING_CONSOLE_FORMAT: &str = "DYN_LOGGING_CONSOLE_FORMAT";
39
40    /// Disable ANSI terminal colors in logs
41    pub const DYN_SDK_DISABLE_ANSI_LOGGING: &str = "DYN_SDK_DISABLE_ANSI_LOGGING";
42
43    /// Use local timezone for logging timestamps (default is UTC)
44    pub const DYN_LOG_USE_LOCAL_TZ: &str = "DYN_LOG_USE_LOCAL_TZ";
45
46    /// Enable span event logging (create/close events)
47    pub const DYN_LOGGING_SPAN_EVENTS: &str = "DYN_LOGGING_SPAN_EVENTS";
48
49    /// OTLP (OpenTelemetry Protocol) tracing and logging configuration
50    pub mod otlp {
51        /// Enable OTLP export for traces and logs (set to "1" to enable)
52        pub const OTEL_EXPORT_ENABLED: &str = "OTEL_EXPORT_ENABLED";
53
54        /// OTLP exporter transport protocol. Supported values: "grpc", "http/protobuf".
55        pub const OTEL_EXPORTER_OTLP_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_PROTOCOL";
56
57        /// OTLP exporter transport protocol for traces. Defaults to OTEL_EXPORTER_OTLP_PROTOCOL.
58        pub const OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL";
59
60        /// OTLP exporter transport protocol for logs. Defaults to OTEL_EXPORTER_OTLP_PROTOCOL.
61        pub const OTEL_EXPORTER_OTLP_LOGS_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL";
62
63        /// Generic OTLP exporter endpoint URL used when signal-specific endpoints are unset.
64        pub const OTEL_EXPORTER_OTLP_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_ENDPOINT";
65
66        /// OTLP exporter endpoint URL for traces
67        /// Spec: <https://opentelemetry.io/docs/specs/otel/protocol/exporter/>
68        pub const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
69
70        /// OTLP exporter endpoint URL for logs. Falls back to OTEL_EXPORTER_OTLP_ENDPOINT or the protocol default when unset.
71        pub const OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT";
72
73        /// Trace sampling ratio used when set. Example: "0.01" samples roughly 1% of traces.
74        pub const OTEL_TRACES_SAMPLE_RATIO: &str = "OTEL_TRACES_SAMPLE_RATIO";
75
76        /// Service name for OTLP traces and logs
77        pub const OTEL_SERVICE_NAME: &str = "OTEL_SERVICE_NAME";
78    }
79}
80
81/// Runtime configuration environment variables
82///
83/// These control the Tokio runtime, system health/metrics server, and worker behavior
84pub mod runtime {
85    /// Number of async worker threads for Tokio runtime
86    pub const DYN_RUNTIME_NUM_WORKER_THREADS: &str = "DYN_RUNTIME_NUM_WORKER_THREADS";
87
88    /// Maximum number of blocking threads for Tokio runtime
89    pub const DYN_RUNTIME_MAX_BLOCKING_THREADS: &str = "DYN_RUNTIME_MAX_BLOCKING_THREADS";
90
91    /// Maximum time to wait for graceful endpoint drain during runtime shutdown.
92    pub const DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS: &str =
93        "DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS";
94
95    /// Maximum duration for local worker inhibition after a request failure. Zero disables it.
96    pub const DYN_RUNTIME_INHIBITED_DURATION_SECS: &str = "DYN_RUNTIME_INHIBITED_DURATION_SECS";
97
98    /// Enable Tokio task poll-time histogram (calls enable_metrics_poll_time_histogram on builder).
99    /// Set to "1", "true", or "yes" to enable. Adds ~2× overhead of Instant::now() per task poll.
100    pub const DYN_ENABLE_POLL_HISTOGRAM: &str = "DYN_ENABLE_POLL_HISTOGRAM";
101
102    /// System status server configuration
103    pub mod system {
104        /// Enable system status server for health and metrics endpoints
105        /// ⚠️ DEPRECATED: will be removed soon
106        pub const DYN_SYSTEM_ENABLED: &str = "DYN_SYSTEM_ENABLED";
107
108        /// System status server host
109        pub const DYN_SYSTEM_HOST: &str = "DYN_SYSTEM_HOST";
110
111        /// System status server port
112        pub const DYN_SYSTEM_PORT: &str = "DYN_SYSTEM_PORT";
113
114        /// Use endpoint health status for system health
115        /// ⚠️ DEPRECATED: No longer used
116        pub const DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS: &str =
117            "DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS";
118
119        /// Starting health status for the system
120        pub const DYN_SYSTEM_STARTING_HEALTH_STATUS: &str = "DYN_SYSTEM_STARTING_HEALTH_STATUS";
121
122        /// Health check endpoint path
123        pub const DYN_SYSTEM_HEALTH_PATH: &str = "DYN_SYSTEM_HEALTH_PATH";
124
125        /// Liveness check endpoint path
126        pub const DYN_SYSTEM_LIVE_PATH: &str = "DYN_SYSTEM_LIVE_PATH";
127    }
128
129    /// Compute configuration
130    pub mod compute {
131        /// Prefix for compute-related environment variables
132        pub const PREFIX: &str = "DYN_COMPUTE_";
133    }
134
135    /// Canary deployment configuration
136    pub mod canary {
137        /// Wait time in seconds for canary deployments
138        pub const DYN_CANARY_WAIT_TIME: &str = "DYN_CANARY_WAIT_TIME";
139    }
140}
141
142/// Worker lifecycle environment variables
143pub mod worker {
144    /// Graceful shutdown timeout in seconds
145    pub const DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT: &str = "DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT";
146}
147
148/// NATS transport environment variables
149pub mod nats {
150    /// NATS server address (e.g., "nats://localhost:4222")
151    pub const NATS_SERVER: &str = "NATS_SERVER";
152
153    /// NATS request/reply timeout in seconds. Unset = async-nats default (10 s).
154    pub const DYN_NATS_REQUEST_TIMEOUT_SECS: &str = "DYN_NATS_REQUEST_TIMEOUT_SECS";
155
156    /// NATS authentication environment variables (checked in priority order)
157    pub mod auth {
158        /// Username for NATS authentication (use with NATS_AUTH_PASSWORD)
159        pub const NATS_AUTH_USERNAME: &str = "NATS_AUTH_USERNAME";
160
161        /// Password for NATS authentication (use with NATS_AUTH_USERNAME)
162        pub const NATS_AUTH_PASSWORD: &str = "NATS_AUTH_PASSWORD";
163
164        /// Token for NATS authentication
165        pub const NATS_AUTH_TOKEN: &str = "NATS_AUTH_TOKEN";
166
167        /// NKey for NATS authentication
168        pub const NATS_AUTH_NKEY: &str = "NATS_AUTH_NKEY";
169
170        /// Path to NATS credentials file
171        pub const NATS_AUTH_CREDENTIALS_FILE: &str = "NATS_AUTH_CREDENTIALS_FILE";
172    }
173
174    /// NATS stream configuration
175    pub mod stream {
176        /// Maximum age for messages in NATS stream (in seconds)
177        pub const DYN_NATS_STREAM_MAX_AGE: &str = "DYN_NATS_STREAM_MAX_AGE";
178    }
179
180    /// NATS TLS configuration
181    pub mod tls {
182        /// Path to the PEM CA certificate used to verify the NATS server's certificate.
183        /// When set, a custom TLS config with this CA is applied to the NATS connection.
184        pub const NATS_TLS_CA_CERT_PATH: &str = "NATS_TLS_CA_CERT_PATH";
185
186        /// Path to the PEM client certificate presented to the NATS server for
187        /// mutual TLS (mTLS). Must be set together with `NATS_TLS_CLIENT_KEY_PATH`.
188        pub const NATS_TLS_CLIENT_CERT_PATH: &str = "NATS_TLS_CLIENT_CERT_PATH";
189
190        /// Path to the PEM client private key for NATS mutual TLS (mTLS).
191        /// Must be set together with `NATS_TLS_CLIENT_CERT_PATH`.
192        pub const NATS_TLS_CLIENT_KEY_PATH: &str = "NATS_TLS_CLIENT_KEY_PATH";
193
194        /// Disable TLS certificate verification. Set to a truthy value to skip.
195        /// WARNING: Only for local development. Never use in production.
196        pub const NATS_TLS_INSECURE: &str = "NATS_TLS_INSECURE";
197    }
198}
199
200/// ETCD transport environment variables
201pub mod etcd {
202    /// ETCD endpoints (comma-separated list of URLs)
203    pub const ETCD_ENDPOINTS: &str = "ETCD_ENDPOINTS";
204
205    /// ETCD lease TTL in seconds (default: 10)
206    pub const ETCD_LEASE_TTL: &str = "ETCD_LEASE_TTL";
207
208    /// ETCD authentication environment variables
209    pub mod auth {
210        /// Username for ETCD authentication
211        pub const ETCD_AUTH_USERNAME: &str = "ETCD_AUTH_USERNAME";
212
213        /// Password for ETCD authentication
214        pub const ETCD_AUTH_PASSWORD: &str = "ETCD_AUTH_PASSWORD";
215
216        /// Path to CA certificate for ETCD TLS
217        pub const ETCD_AUTH_CA: &str = "ETCD_AUTH_CA";
218
219        /// Path to client certificate for ETCD TLS
220        pub const ETCD_AUTH_CLIENT_CERT: &str = "ETCD_AUTH_CLIENT_CERT";
221
222        /// Path to client key for ETCD TLS
223        pub const ETCD_AUTH_CLIENT_KEY: &str = "ETCD_AUTH_CLIENT_KEY";
224    }
225}
226
227/// Key-Value Block Manager (KVBM) environment variables
228pub mod kvbm {
229    /// Enable KVBM metrics endpoint
230    pub const DYN_KVBM_METRICS: &str = "DYN_KVBM_METRICS";
231
232    /// KVBM metrics endpoint port
233    pub const DYN_KVBM_METRICS_PORT: &str = "DYN_KVBM_METRICS_PORT";
234
235    /// Enable KVBM recording for debugging.
236    pub const DYN_KVBM_ENABLE_RECORD: &str = "DYN_KVBM_ENABLE_RECORD";
237
238    /// Disable disk offload filter
239    pub const DYN_KVBM_DISABLE_DISK_OFFLOAD_FILTER: &str = "DYN_KVBM_DISABLE_DISK_OFFLOAD_FILTER";
240
241    /// CPU cache configuration
242    pub mod cpu_cache {
243        /// CPU cache size in GB
244        pub const DYN_KVBM_CPU_CACHE_GB: &str = "DYN_KVBM_CPU_CACHE_GB";
245
246        /// CPU cache size in number of blocks (override)
247        pub const DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS: &str =
248            "DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS";
249    }
250
251    /// Disk cache configuration
252    pub mod disk_cache {
253        /// Disk cache size in GB
254        pub const DYN_KVBM_DISK_CACHE_GB: &str = "DYN_KVBM_DISK_CACHE_GB";
255
256        /// Disk cache size in number of blocks (override)
257        pub const DYN_KVBM_DISK_CACHE_OVERRIDE_NUM_BLOCKS: &str =
258            "DYN_KVBM_DISK_CACHE_OVERRIDE_NUM_BLOCKS";
259    }
260
261    /// Object storage configuration
262    pub mod object_storage {
263        /// Enable object storage. Set to "1" to enable.
264        pub const DYN_KVBM_OBJECT_ENABLED: &str = "DYN_KVBM_OBJECT_ENABLED";
265
266        /// Bucket name for object storage cache
267        /// Supports `{worker_id}` template for per-worker buckets
268        /// Example: "kv-cache-{worker_id}"
269        pub const DYN_KVBM_OBJECT_BUCKET: &str = "DYN_KVBM_OBJECT_BUCKET";
270
271        /// Endpoint for object storage
272        pub const DYN_KVBM_OBJECT_ENDPOINT: &str = "DYN_KVBM_OBJECT_ENDPOINT";
273
274        /// Region for object storage
275        pub const DYN_KVBM_OBJECT_REGION: &str = "DYN_KVBM_OBJECT_REGION";
276
277        /// Access key for authentication
278        pub const DYN_KVBM_OBJECT_ACCESS_KEY: &str = "DYN_KVBM_OBJECT_ACCESS_KEY";
279
280        /// Secret key for authentication
281        pub const DYN_KVBM_OBJECT_SECRET_KEY: &str = "DYN_KVBM_OBJECT_SECRET_KEY";
282
283        /// Number of blocks to store in object storage
284        pub const DYN_KVBM_OBJECT_NUM_BLOCKS: &str = "DYN_KVBM_OBJECT_NUM_BLOCKS";
285    }
286    /// Transfer configuration
287    pub mod transfer {
288        /// Maximum number of blocks per transfer batch
289        pub const DYN_KVBM_TRANSFER_BATCH_SIZE: &str = "DYN_KVBM_TRANSFER_BATCH_SIZE";
290    }
291
292    /// KVBM leader (distributed mode) configuration
293    pub mod leader {
294        /// Timeout in seconds for KVBM leader and worker initialization
295        pub const DYN_KVBM_LEADER_WORKER_INIT_TIMEOUT_SECS: &str =
296            "DYN_KVBM_LEADER_WORKER_INIT_TIMEOUT_SECS";
297
298        /// ZMQ host for KVBM leader
299        pub const DYN_KVBM_LEADER_ZMQ_HOST: &str = "DYN_KVBM_LEADER_ZMQ_HOST";
300
301        /// ZMQ publish port for KVBM leader
302        pub const DYN_KVBM_LEADER_ZMQ_PUB_PORT: &str = "DYN_KVBM_LEADER_ZMQ_PUB_PORT";
303
304        /// ZMQ acknowledgment port for KVBM leader
305        pub const DYN_KVBM_LEADER_ZMQ_ACK_PORT: &str = "DYN_KVBM_LEADER_ZMQ_ACK_PORT";
306    }
307
308    /// NIXL backend configuration
309    pub mod nixl {
310        /// Prefix for NIXL backend environment variables
311        /// Pattern: `DYN_KVBM_NIXL_BACKEND_<backend>`=true/false
312        /// Example: DYN_KVBM_NIXL_BACKEND_UCX=true
313        pub const PREFIX: &str = "DYN_KVBM_NIXL_BACKEND_";
314    }
315}
316
317/// LLM (Language Model) inference environment variables
318pub mod llm {
319    /// HTTP body size limit in MB
320    pub const DYN_HTTP_BODY_LIMIT_MB: &str = "DYN_HTTP_BODY_LIMIT_MB";
321
322    pub const DYN_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_SECS: &str =
323        "DYN_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_SECS";
324
325    /// HTTP status code returned when the frontend rejects a request because
326    /// all workers are overloaded. Defaults to 529 ("Site is overloaded"); set
327    /// to 503 for Service Unavailable retry semantics. Status codes from 200
328    /// through 999 are accepted; an informational value from 100 through 199,
329    /// an unparseable value, or an out-of-range value falls back to 529. The
330    /// value is read and cached on first use.
331    pub const DYN_HTTP_OVERLOAD_STATUS_CODE: &str = "DYN_HTTP_OVERLOAD_STATUS_CODE";
332
333    /// Emit an SSE comment at this interval while a streaming response has no
334    /// data. Unset, `0`, invalid, or unrepresentable values keep SSE comments
335    /// disabled.
336    pub const DYN_HTTP_SSE_KEEP_ALIVE_INTERVAL_MS: &str = "DYN_HTTP_SSE_KEEP_ALIVE_INTERVAL_MS";
337
338    /// Enable LoRA adapter support (set to "true" to enable)
339    pub const DYN_LORA_ENABLED: &str = "DYN_LORA_ENABLED";
340
341    /// LoRA cache directory path
342    pub const DYN_LORA_PATH: &str = "DYN_LORA_PATH";
343
344    /// Enable the experimental Anthropic Messages API endpoint (/v1/messages)
345    pub const DYN_ENABLE_ANTHROPIC_API: &str = "DYN_ENABLE_ANTHROPIC_API";
346
347    /// Master switch for the `nvext` extension protocol on the frontend.
348    /// The protocol is **enabled by default**; this variable disables it.
349    /// Truthy values (`1` / `true` / `yes` / `on`, case-insensitive) cause
350    /// the frontend to drop non-salt request NvExt fields, ignore supported
351    /// routing-override headers, and silently ignore the response-side
352    /// `extra_fields` opt-in. Cache isolation is exempt: supported
353    /// `cache_salt` and `x-tenant-id` inputs remain active.
354    pub const DYN_DISABLE_FRONTEND_NVEXT: &str = "DYN_DISABLE_FRONTEND_NVEXT";
355
356    /// Ignore unknown OpenAI frontend request fields. Unknown fields are dropped,
357    /// not handled; known pass-through fields remain type-validated.
358    pub const DYN_IGNORE_OPENAI_FE_UNSUPPORTED_FIELDS: &str =
359        "DYN_IGNORE_OPENAI_FE_UNSUPPORTED_FIELDS";
360
361    /// Master switch for the frontend's HTTP admin API surface.
362    /// The admin API is **enabled by default**; this variable disables it.
363    /// Truthy values (`1` / `true` / `yes` / `on`, case-insensitive) prevent
364    /// registration of `GET` / `POST /busy_threshold`. Inference, metrics,
365    /// models, health, and liveness routes are unaffected.
366    pub const DYN_DISABLE_FRONTEND_ADMIN_API: &str = "DYN_DISABLE_FRONTEND_ADMIN_API";
367
368    /// Strip the Claude Code billing preamble (`x-anthropic-billing-header: ...`)
369    /// from the system prompt before forwarding to the target model. The preamble
370    /// varies per session and per release, wasting tokens and breaking prompt caching.
371    pub const DYN_STRIP_ANTHROPIC_PREAMBLE: &str = "DYN_STRIP_ANTHROPIC_PREAMBLE";
372
373    /// When truthy, force usage in streaming chat and text-completion responses
374    /// regardless of the request's `stream_options.include_usage` value.
375    /// Unset or false preserves request-controlled defaults.
376    pub const DYN_ENABLE_FORCE_INCLUDE_USAGE: &str = "DYN_ENABLE_FORCE_INCLUDE_USAGE";
377
378    /// Enable streaming tool call dispatch (`event: tool_call_dispatch` SSE events)
379    pub const DYN_ENABLE_STREAMING_TOOL_DISPATCH: &str = "DYN_ENABLE_STREAMING_TOOL_DISPATCH";
380
381    /// Enable streaming reasoning dispatch (`event: reasoning_dispatch` SSE events)
382    pub const DYN_ENABLE_STREAMING_REASONING_DISPATCH: &str =
383        "DYN_ENABLE_STREAMING_REASONING_DISPATCH";
384
385    /// OpenAI-compatible response field used for emitted reasoning content.
386    /// Accepted values: "reasoning_content" (default) or "reasoning".
387    pub const DYN_REASONING_FIELD_NAME: &str = "DYN_REASONING_FIELD_NAME";
388
389    /// \[EXPERIMENTAL\] Use `dynamo-parsers-v2` instead of the v1 tool-call jail, for
390    /// BOTH the batch and the streaming path. Off by default.
391    ///
392    /// Which v2 shape a request gets is decided by the configured parsers, not by a
393    /// second flag:
394    /// * tool-call parser only (Qwen3-Coder, DeepSeek-V4) -> the v2 TOOL parser owns
395    ///   incremental tool-call emission and drops values truncated at EOF.
396    /// * tool-call AND reasoning parser naming the same family (`qwen3_coder` +
397    ///   `qwen3`) -> the v2 UNIFIED parser owns reasoning, visible text and tool calls
398    ///   in one ordered stream, so reasoning that followed a tool call stays after it
399    ///   instead of being hoisted to the front and fused with the first thought.
400    ///
401    /// One switch, because both are the same decision: stop using v1.
402    pub const DYN_ENABLE_EXPERIMENTAL_PARSERS_V2: &str = "DYN_ENABLE_EXPERIMENTAL_PARSERS_V2";
403
404    /// Rollback lever for incremental guided-tool-call streaming.
405    ///
406    /// A forced `tool_choice` (`required` or a named tool) installs a JSON grammar,
407    /// so by default the jail releases tool-call chunks as they arrive instead of
408    /// buffering the whole response. The grammar-constrained decoding itself lives
409    /// in the published `dynamo-parsers` dependency, not in this repo, so if a
410    /// backend in production doesn't correctly honor the grammar the only other
411    /// rollback is a dependency repin and a new release. On by default; set this
412    /// to a falsy value (`0`/`false`) to fall back to the old buffer-to-completion
413    /// behavior at runtime, no redeploy required.
414    pub const DYN_ENABLE_GUIDED_TOOL_STREAMING: &str = "DYN_ENABLE_GUIDED_TOOL_STREAMING";
415
416    /// Backend stream inactivity timeout in seconds.
417    ///
418    /// When set to a positive integer, the frontend will kill the engine context
419    /// and drop the inflight guard if no SSE event is received from the backend
420    /// within this many seconds. Acts as a circuit breaker for zombie workers
421    /// that hold a live TCP connection but never produce output.
422    ///
423    /// Set to `0` or leave unset to disable the timeout (default: disabled).
424    pub const DYN_HTTP_BACKEND_STREAM_TIMEOUT_SECS: &str = "DYN_HTTP_BACKEND_STREAM_TIMEOUT_SECS";
425
426    /// Pre-commit peek window in milliseconds for the streaming chat/responses
427    /// paths. Controls how long the frontend polls the engine stream for a
428    /// synchronous backend error before committing HTTP 200.
429    /// Trades a small first-token latency budget
430    /// for the ability to surface `Backend(InvalidArgument)` and other
431    /// request-validation errors as HTTP 4xx instead of an SSE error frame.
432    ///
433    /// Default: unset → peek disabled (matches pre-fix behavior; all errors
434    /// surface as SSE frames post-HTTP-200). Set to a value ≥ observed
435    /// request-parse / admission p99 latency to opt in — request-validation
436    /// errors within the window surface as HTTP 4xx; anything past the window
437    /// stays as an SSE error frame. Setting to `0` also disables the peek.
438    pub const DYN_HTTP_PRE_COMMIT_ERROR_PEEK_MS: &str = "DYN_HTTP_PRE_COMMIT_ERROR_PEEK_MS";
439
440    /// Enable the LoRA allocation controller (set to "true" to enable)
441    pub const DYN_LORA_ALLOCATION_ENABLED: &str = "DYN_LORA_ALLOCATION_ENABLED";
442
443    /// LoRA allocation algorithm ("hrw", "random", or "mcf")
444    pub const DYN_LORA_ALLOCATION_ALGORITHM: &str = "DYN_LORA_ALLOCATION_ALGORITHM";
445
446    /// JSON configuration for the MCF (min-cost flow) placement solver.
447    /// Example: '{"candidate_m":16,"gamma_load":2000,"beta_keep":500}'
448    /// Omitted fields use defaults. Only relevant when algorithm is "mcf".
449    pub const DYN_LORA_MCF_CONFIG: &str = "DYN_LORA_MCF_CONFIG";
450
451    /// LoRA allocation controller recompute interval in seconds
452    pub const DYN_LORA_ALLOCATION_TIMESTEP_SECS: &str = "DYN_LORA_ALLOCATION_TIMESTEP_SECS";
453
454    /// Ticks to wait before scaling down a LoRA's replicas
455    pub const DYN_LORA_ALLOCATION_SCALE_DOWN_COOLDOWN_TICKS: &str =
456        "DYN_LORA_ALLOCATION_SCALE_DOWN_COOLDOWN_TICKS";
457
458    /// Multiplier for the load estimator's rate window relative to the controller timestep.
459    pub const DYN_LORA_ALLOCATION_RATE_WINDOW_MULTIPLIER: &str =
460        "DYN_LORA_ALLOCATION_RATE_WINDOW_MULTIPLIER";
461
462    /// Number of counter buckets per second in the BucketedRateCounter.
463    pub const DYN_LORA_ALLOCATION_BUCKETS_PER_SECOND: &str =
464        "DYN_LORA_ALLOCATION_BUCKETS_PER_SECOND";
465
466    /// Load predictor type: "none" (raw counts) or "ema" (exponential moving average).
467    pub const DYN_LORA_ALLOCATION_PREDICTOR_TYPE: &str = "DYN_LORA_ALLOCATION_PREDICTOR_TYPE";
468
469    /// EMA smoothing factor (alpha) for the EMA predictor. Range [0.0, 1.0].
470    pub const DYN_LORA_ALLOCATION_EMA_ALPHA: &str = "DYN_LORA_ALLOCATION_EMA_ALPHA";
471
472    /// Metrics configuration
473    pub mod metrics {
474        /// Custom metrics prefix (overrides default "dynamo_frontend")
475        pub const DYN_METRICS_PREFIX: &str = "DYN_METRICS_PREFIX";
476
477        /// Histogram bucket configuration (pattern: `<PREFIX>_MIN`, `<PREFIX>_MAX`, `<PREFIX>_COUNT`)
478        /// Example: DYN_HISTOGRAM_TTFT_MIN, DYN_HISTOGRAM_TTFT_MAX, DYN_HISTOGRAM_TTFT_COUNT
479        pub const HISTOGRAM_PREFIX: &str = "DYN_HISTOGRAM_";
480    }
481
482    /// Forward-pass-metrics trace configuration.
483    pub mod fpm_trace {
484        /// Master switch. Truthy values persist locally produced FPM events.
485        pub const DYN_FPM_TRACE: &str = "DYN_FPM_TRACE";
486
487        /// Local gzip JSONL segment prefix. A sanitized producer id is appended
488        /// before the segment index so multiple producers do not share files.
489        pub const DYN_FPM_OUTPUT_PATH: &str = "DYN_FPM_OUTPUT_PATH";
490
491        /// Capture mode: `sampled` (latest event per DP rank each interval) or
492        /// `full` (every event reaching the producer-side trace tap).
493        pub const DYN_FPM_MODE: &str = "DYN_FPM_MODE";
494
495        /// Sampling interval in milliseconds when `DYN_FPM_MODE=sampled`.
496        pub const DYN_FPM_SAMPLE_INTERVAL_MS: &str = "DYN_FPM_SAMPLE_INTERVAL_MS";
497
498        /// Rotating gzip JSONL threshold in uncompressed bytes.
499        pub const DYN_FPM_JSONL_GZ_ROLL_BYTES: &str = "DYN_FPM_JSONL_GZ_ROLL_BYTES";
500
501        /// Maximum number of gzip JSONL segments retained per producer,
502        /// including the active segment.
503        pub const DYN_FPM_MAX_SEGMENTS: &str = "DYN_FPM_MAX_SEGMENTS";
504    }
505
506    /// Deprecated audit payload logging aliases. Prefer `llm::request_trace`.
507    pub mod audit {
508        /// Deprecated alias for `DYN_REQUEST_TRACE_SINKS`. Legacy values
509        /// `jsonl` and `jsonl_gz` map to the request trace `file` sink.
510        pub const DYN_AUDIT_SINKS: &str = "DYN_AUDIT_SINKS";
511
512        /// Deprecated migration shim for `DYN_REQUEST_TRACE_RECORDS=request_payload`.
513        pub const DYN_AUDIT_FORCE_LOGGING: &str = "DYN_AUDIT_FORCE_LOGGING";
514
515        /// Deprecated alias for `DYN_REQUEST_TRACE_CAPACITY`.
516        pub const DYN_AUDIT_CAPACITY: &str = "DYN_AUDIT_CAPACITY";
517
518        /// Deprecated alias for `DYN_REQUEST_TRACE_NATS_SUBJECT`.
519        pub const DYN_AUDIT_NATS_SUBJECT: &str = "DYN_AUDIT_NATS_SUBJECT";
520
521        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_PATH`.
522        pub const DYN_AUDIT_OUTPUT_PATH: &str = "DYN_AUDIT_OUTPUT_PATH";
523
524        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_BUFFER_BYTES`.
525        pub const DYN_AUDIT_JSONL_BUFFER_BYTES: &str = "DYN_AUDIT_JSONL_BUFFER_BYTES";
526
527        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS`.
528        pub const DYN_AUDIT_JSONL_FLUSH_INTERVAL_MS: &str = "DYN_AUDIT_JSONL_FLUSH_INTERVAL_MS";
529
530        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_ROLL_BYTES`.
531        pub const DYN_AUDIT_JSONL_GZ_ROLL_BYTES: &str = "DYN_AUDIT_JSONL_GZ_ROLL_BYTES";
532
533        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_ROLL_LINES`.
534        pub const DYN_AUDIT_JSONL_GZ_ROLL_LINES: &str = "DYN_AUDIT_JSONL_GZ_ROLL_LINES";
535
536        /// Deprecated alias for `DYN_REQUEST_TRACE_OTEL_MAX_PAYLOAD_BYTES`.
537        pub const DYN_AUDIT_OTEL_MAX_PAYLOAD_BYTES: &str = "DYN_AUDIT_OTEL_MAX_PAYLOAD_BYTES";
538    }
539
540    /// Request trace and request payload logging configuration.
541    pub mod request_trace {
542        /// Master switch. Truthy enables request trace emission.
543        pub const DYN_REQUEST_TRACE: &str = "DYN_REQUEST_TRACE";
544
545        /// Request trace sink selection. Comma-separated values: `file`,
546        /// `stderr`, `nats`, `otel`, `s3`.
547        ///
548        /// Legacy values map as follows: `jsonl` => `file` with `jsonl` format,
549        /// `jsonl_gz` => `file` with `jsonl_gz` format, `stderr` => `stderr`,
550        /// `nats` => `nats`, and `otel` => `otel`.
551        pub const DYN_REQUEST_TRACE_SINKS: &str = "DYN_REQUEST_TRACE_SINKS";
552
553        /// Local output path for request trace file records.
554        ///
555        /// With `DYN_REQUEST_TRACE_FILE_FORMAT=jsonl`, this is the literal JSONL
556        /// path. With `jsonl_gz`, this is the segment prefix used to derive
557        /// `<prefix>.<index>.jsonl.gz` files.
558        pub const DYN_REQUEST_TRACE_FILE_PATH: &str = "DYN_REQUEST_TRACE_FILE_PATH";
559
560        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_PATH`.
561        pub const DYN_REQUEST_TRACE_OUTPUT_PATH: &str = "DYN_REQUEST_TRACE_OUTPUT_PATH";
562
563        /// Request trace file record format. Supported values: `jsonl`, `jsonl_gz`.
564        pub const DYN_REQUEST_TRACE_FILE_FORMAT: &str = "DYN_REQUEST_TRACE_FILE_FORMAT";
565
566        /// In-process trace bus capacity.
567        pub const DYN_REQUEST_TRACE_CAPACITY: &str = "DYN_REQUEST_TRACE_CAPACITY";
568
569        /// Request trace record selection. Comma-separated values: `request_end`,
570        /// `request_payload`, `tool`.
571        pub const DYN_REQUEST_TRACE_RECORDS: &str = "DYN_REQUEST_TRACE_RECORDS";
572
573        /// NATS subject the request trace sink publishes to.
574        pub const DYN_REQUEST_TRACE_NATS_SUBJECT: &str = "DYN_REQUEST_TRACE_NATS_SUBJECT";
575
576        /// Maximum serialized OTEL payload bytes. Oversized request payload
577        /// records emit an incomplete marker payload instead of the full request/response.
578        pub const DYN_REQUEST_TRACE_OTEL_MAX_PAYLOAD_BYTES: &str =
579            "DYN_REQUEST_TRACE_OTEL_MAX_PAYLOAD_BYTES";
580
581        /// Request trace file sink buffer size in bytes.
582        pub const DYN_REQUEST_TRACE_FILE_BUFFER_BYTES: &str = "DYN_REQUEST_TRACE_FILE_BUFFER_BYTES";
583
584        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_BUFFER_BYTES`.
585        pub const DYN_REQUEST_TRACE_JSONL_BUFFER_BYTES: &str =
586            "DYN_REQUEST_TRACE_JSONL_BUFFER_BYTES";
587
588        /// Request trace file sink periodic flush interval in milliseconds.
589        pub const DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS: &str =
590            "DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS";
591
592        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS`.
593        pub const DYN_REQUEST_TRACE_JSONL_FLUSH_INTERVAL_MS: &str =
594            "DYN_REQUEST_TRACE_JSONL_FLUSH_INTERVAL_MS";
595
596        /// Gzip file sink roll threshold in uncompressed bytes.
597        pub const DYN_REQUEST_TRACE_FILE_ROLL_BYTES: &str = "DYN_REQUEST_TRACE_FILE_ROLL_BYTES";
598
599        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_ROLL_BYTES`.
600        pub const DYN_REQUEST_TRACE_JSONL_GZ_ROLL_BYTES: &str =
601            "DYN_REQUEST_TRACE_JSONL_GZ_ROLL_BYTES";
602
603        /// Gzip file sink roll threshold in record lines.
604        pub const DYN_REQUEST_TRACE_FILE_ROLL_LINES: &str = "DYN_REQUEST_TRACE_FILE_ROLL_LINES";
605
606        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_ROLL_LINES`.
607        pub const DYN_REQUEST_TRACE_JSONL_GZ_ROLL_LINES: &str =
608            "DYN_REQUEST_TRACE_JSONL_GZ_ROLL_LINES";
609
610        /// Local ZMQ PULL endpoint Dynamo binds for harness tool events.
611        pub const DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_ENDPOINT: &str =
612            "DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_ENDPOINT";
613
614        /// First-frame ZMQ topic filter override for harness tool events.
615        pub const DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_TOPIC: &str =
616            "DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_TOPIC";
617
618        /// Comma/whitespace-separated allowlist of HTTP request header names to
619        /// record in request payload records. Unset/empty captures none. Values
620        /// are recorded unredacted; avoid credential-bearing headers.
621        pub const DYN_REQUEST_TRACE_HTTP_HEADER_CAPTURE_LIST: &str =
622            "DYN_REQUEST_TRACE_HTTP_HEADER_CAPTURE_LIST";
623
624        /// S3 bucket for the S3 request-trace sink. Required when
625        /// `DYN_REQUEST_TRACE_SINKS` includes `s3`.
626        pub const DYN_REQUEST_TRACE_S3_BUCKET: &str = "DYN_REQUEST_TRACE_S3_BUCKET";
627
628        /// AWS region for the S3 request-trace sink. When unset the AWS SDK
629        /// default region resolution is used (env, profile, IMDS).
630        pub const DYN_REQUEST_TRACE_S3_REGION: &str = "DYN_REQUEST_TRACE_S3_REGION";
631
632        /// Optional object key prefix for the S3 request-trace sink. When unset
633        /// records land at the bucket root.
634        pub const DYN_REQUEST_TRACE_S3_PREFIX: &str = "DYN_REQUEST_TRACE_S3_PREFIX";
635
636        /// S3 batch roll threshold in uncompressed bytes. When the pending
637        /// batch reaches this size, it is finalized and uploaded. Default
638        /// `67108864` (64 MiB).
639        pub const DYN_REQUEST_TRACE_S3_ROLL_UNCOMPRESSED_BYTES: &str =
640            "DYN_REQUEST_TRACE_S3_ROLL_UNCOMPRESSED_BYTES";
641
642        /// S3 periodic flush interval in milliseconds. Any partial batch is
643        /// finalized and uploaded when this elapses, so low-volume traces
644        /// still land in S3. Default `10000` (10 s).
645        pub const DYN_REQUEST_TRACE_S3_FLUSH_INTERVAL_MS: &str =
646            "DYN_REQUEST_TRACE_S3_FLUSH_INTERVAL_MS";
647    }
648}
649
650/// Model loading and caching environment variables
651pub mod model {
652    /// Model Express configuration
653    pub mod model_express {
654        /// Model Express server endpoint URL
655        pub const MODEL_EXPRESS_URL: &str = "MODEL_EXPRESS_URL";
656
657        /// Model Express cache path
658        pub const MODEL_EXPRESS_CACHE_PATH: &str = "MODEL_EXPRESS_CACHE_PATH";
659
660        /// Disable shared-storage mode for the Model Express client. When set,
661        /// the client streams model files from the server over gRPC instead of
662        /// relying on a shared filesystem path. Required when the Model Express
663        /// server and worker pods do not share a filesystem (e.g. RWO PVCs,
664        /// cross-namespace deployments). Set to "1" or "true" to enable.
665        pub const MODEL_EXPRESS_NO_SHARED_STORAGE: &str = "MODEL_EXPRESS_NO_SHARED_STORAGE";
666    }
667
668    /// Hugging Face configuration
669    pub mod huggingface {
670        /// Hugging Face authentication token
671        pub const HF_TOKEN: &str = "HF_TOKEN";
672
673        /// Deprecated alias for the Hugging Face authentication token
674        pub const HUGGING_FACE_HUB_TOKEN: &str = "HUGGING_FACE_HUB_TOKEN";
675
676        /// Path to the stored Hugging Face authentication token
677        pub const HF_TOKEN_PATH: &str = "HF_TOKEN_PATH";
678
679        /// Hugging Face Hub cache directory
680        pub const HF_HUB_CACHE: &str = "HF_HUB_CACHE";
681
682        /// Hugging Face home directory
683        pub const HF_HOME: &str = "HF_HOME";
684
685        /// Override the Hugging Face Hub API endpoint
686        pub const HF_ENDPOINT: &str = "HF_ENDPOINT";
687
688        /// Offline mode - skip API calls when model is cached
689        /// Set to "1", "true", "on", or "yes" to enable
690        pub const HF_HUB_OFFLINE: &str = "HF_HUB_OFFLINE";
691    }
692}
693
694/// KV Router configuration environment variables
695pub mod router {
696    /// Scale applied to adjusted prompt-side prefill load after overlap/cache-hit credits.
697    pub const DYN_ROUTER_PREFILL_LOAD_SCALE: &str = "DYN_ROUTER_PREFILL_LOAD_SCALE";
698
699    /// Queue threshold fraction for prefill token capacity.
700    /// When set, requests are queued if all workers exceed this fraction of max_num_batched_tokens.
701    pub const DYN_ROUTER_QUEUE_THRESHOLD: &str = "DYN_ROUTER_QUEUE_THRESHOLD";
702
703    /// Scheduling policy for the router queue ("fcfs" or "wspt").
704    pub const DYN_ROUTER_QUEUE_POLICY: &str = "DYN_ROUTER_QUEUE_POLICY";
705    pub const DYN_ROUTER_POLICY_CONFIG: &str = "DYN_ROUTER_POLICY_CONFIG";
706
707    /// Stale active-request cleanup guard in seconds; this is not a request timeout.
708    pub const DYN_ROUTER_ACTIVE_REQUEST_EXPIRY_SECS: &str = "DYN_ROUTER_ACTIVE_REQUEST_EXPIRY_SECS";
709}
710
711/// Request plane transport environment variables
712pub mod request_plane {
713    /// Request-plane transport selection: `"tcp"` (default) or `"nats"`. Read by the
714    /// runtime in `distributed.rs` and by the Python launch layer.
715    pub const DYN_REQUEST_PLANE: &str = "DYN_REQUEST_PLANE";
716
717    /// Preferred payload codec advertised by every request-plane endpoint in this process.
718    /// The process-wide value is cached on first use and defaults to "msgpack". Outbound requests
719    /// use the destination endpoint's advertised codec, or "json" for a legacy destination.
720    pub const DYN_REQUEST_PLANE_CODEC: &str = "DYN_REQUEST_PLANE_CODEC";
721}
722
723/// TCP response stream server (CallHome listener) environment variables
724pub mod tcp_response_stream {
725    /// Port for the TCP response stream server.
726    /// If unset or 0, the OS assigns a free ephemeral port.
727    pub const DYN_TCP_RESPONSE_STREAM_PORT: &str = "DYN_TCP_RESPONSE_STREAM_PORT";
728
729    /// Host/interface for the TCP response stream server.
730    /// If unset, the server auto-detects a routable local IP.
731    pub const DYN_TCP_RESPONSE_STREAM_HOST: &str = "DYN_TCP_RESPONSE_STREAM_HOST";
732
733    /// TCP request-plane TLS configuration
734    pub mod tls {
735        /// Path to the PEM certificate used by the TCP server.
736        /// When set together with DYN_TCP_TLS_KEY_PATH, TLS is enabled on the
737        /// TCP server. To enable TLS on the client side, also set
738        /// DYN_TCP_TLS_CA_CERT_PATH (or DYN_TCP_TLS_INSECURE for dev).
739        pub const DYN_TCP_TLS_CERT_PATH: &str = "DYN_TCP_TLS_CERT_PATH";
740
741        /// Path to the PEM private key for the TCP server certificate.
742        pub const DYN_TCP_TLS_KEY_PATH: &str = "DYN_TCP_TLS_KEY_PATH";
743
744        /// Path to the PEM CA certificate used by TCP clients to verify the server.
745        /// Required on the client side when the server uses a self-signed or internal CA.
746        pub const DYN_TCP_TLS_CA_CERT_PATH: &str = "DYN_TCP_TLS_CA_CERT_PATH";
747
748        /// Disable TLS certificate verification on the TCP client. Set to "true" to skip.
749        /// WARNING: Only for local development. Never use in production.
750        pub const DYN_TCP_TLS_INSECURE: &str = "DYN_TCP_TLS_INSECURE";
751
752        /// Override the TLS server name (SNI) used by TCP clients when verifying the
753        /// server certificate. When unset, the hostname extracted from the connection
754        /// address is used. Useful when connecting by IP to a server whose certificate
755        /// uses a DNS SAN.
756        pub const DYN_TCP_TLS_SERVER_NAME: &str = "DYN_TCP_TLS_SERVER_NAME";
757
758        /// Path to the PEM client certificate presented by TCP clients to the
759        /// server for mutual TLS (mTLS). Must be set together with
760        /// `DYN_TCP_TLS_CLIENT_KEY_PATH`.
761        pub const DYN_TCP_TLS_CLIENT_CERT_PATH: &str = "DYN_TCP_TLS_CLIENT_CERT_PATH";
762
763        /// Path to the PEM private key for the TCP client certificate (mTLS).
764        pub const DYN_TCP_TLS_CLIENT_KEY_PATH: &str = "DYN_TCP_TLS_CLIENT_KEY_PATH";
765
766        /// Path to the PEM CA certificate the TCP server uses to verify client
767        /// certificates. When set, the server requires clients to present a
768        /// certificate signed by this CA (mTLS is enforced).
769        pub const DYN_TCP_TLS_CLIENT_CA_CERT_PATH: &str = "DYN_TCP_TLS_CLIENT_CA_CERT_PATH";
770
771        /// TLS handshake timeout in seconds (default: 3).
772        pub const DYN_TCP_TLS_HANDSHAKE_TIMEOUT_SECS: &str = "DYN_TCP_TLS_HANDSHAKE_TIMEOUT_SECS";
773    }
774}
775
776/// Event Plane transport environment variables
777pub mod event_plane {
778    /// Event transport selection: "zmq" or "nats".
779    ///
780    /// When unset the default depends on the discovery backend:
781    /// - `file` / `mem` backends: defaults to `zmq` (no external services required).
782    /// - `etcd` / `kubernetes` backends: defaults to `nats`.
783    ///
784    /// Set this explicitly to override the context-aware default.
785    pub const DYN_EVENT_PLANE: &str = "DYN_EVENT_PLANE";
786
787    /// Event plane codec selection: "json" or "msgpack".
788    pub const DYN_EVENT_PLANE_CODEC: &str = "DYN_EVENT_PLANE_CODEC";
789
790    /// Bounded capacity of the direct ZMQ event-subscriber's merged event channel.
791    ///
792    /// Many peer publishers (e.g. every other frontend under replica-sync) feed
793    /// this single-consumer channel; an unbounded channel grows RSS without limit
794    /// when the consumer can't keep up. When the channel is full, new events are
795    /// dropped — the event plane is already best-effort/lossy (ZMQ RCVHWM), so a
796    /// dropped event costs routing-estimate freshness, not correctness.
797    /// Default: 100_000 (matches ZMQ_RCVHWM). Applies only to the direct ZMQ
798    /// subscriber path.
799    pub const DYN_ZMQ_EVENT_SUBSCRIBER_CHANNEL_CAPACITY: &str =
800        "DYN_ZMQ_EVENT_SUBSCRIBER_CHANNEL_CAPACITY";
801}
802
803/// ZMQ Broker environment variables
804pub mod zmq_broker {
805    /// Explicit ZMQ broker URL (takes precedence over discovery)
806    /// Format: `"xsub=<url1>[;<url2>...] , xpub=<url1>[;<url2>...]"`
807    /// Example: "xsub=tcp://broker:5555 , xpub=tcp://broker:5556"
808    pub const DYN_ZMQ_BROKER_URL: &str = "DYN_ZMQ_BROKER_URL";
809
810    /// Enable ZMQ broker discovery mode
811    pub const DYN_ZMQ_BROKER_ENABLED: &str = "DYN_ZMQ_BROKER_ENABLED";
812
813    /// XSUB bind address (broker binary only)
814    pub const ZMQ_BROKER_XSUB_BIND: &str = "ZMQ_BROKER_XSUB_BIND";
815
816    /// XPUB bind address (broker binary only)
817    pub const ZMQ_BROKER_XPUB_BIND: &str = "ZMQ_BROKER_XPUB_BIND";
818
819    /// Namespace for broker discovery registration
820    pub const ZMQ_BROKER_NAMESPACE: &str = "ZMQ_BROKER_NAMESPACE";
821}
822
823/// Discovery environment variables
824pub mod discovery {
825    /// Discovery backend: "kubernetes" or "etcd" (default)
826    pub const DYN_DISCOVERY_BACKEND: &str = "DYN_DISCOVERY_BACKEND";
827
828    /// Kube discovery mode: "pod" (default) or "container" (each container registers independently)
829    pub const DYN_KUBE_DISCOVERY_MODE: &str = "DYN_KUBE_DISCOVERY_MODE";
830}
831
832/// CUDA and GPU environment variables
833pub mod cuda {
834    /// Path to custom CUDA fatbin file.
835    ///
836    /// Note: build.rs files cannot import this constant at build time,
837    /// so they must define local constants with the same value.
838    pub const DYN_FATBIN_PATH: &str = "DYN_FATBIN_PATH";
839}
840
841/// Build-time environment variables
842pub mod build {
843    /// Cargo output directory for build artifacts
844    ///
845    /// Note: This constant cannot be used with the `env!()` macro,
846    /// which requires a string literal at compile time.
847    /// Build scripts (build.rs) also cannot import this constant.
848    pub const OUT_DIR: &str = "OUT_DIR";
849}
850
851/// Mocker (mock scheduler/KV manager) environment variables
852pub mod mocker {
853    /// Enable structured KV cache allocation/eviction trace logs (set to "1" or "true" to enable)
854    pub const DYN_MOCKER_KV_CACHE_TRACE: &str = "DYN_MOCKER_KV_CACHE_TRACE";
855
856    /// Use the original direct() code path in the mocker request dispatch.
857    ///
858    /// This path is race-prone during startup; prefer leaving it unset unless you are
859    /// explicitly trying to reproduce the original behavior.
860    pub const DYN_MOCKER_SYNC_DIRECT: &str = "DYN_MOCKER_SYNC_DIRECT";
861}
862
863/// Testing environment variables
864pub mod testing {
865    /// Enable queued-up request processing in tests
866    pub const DYN_QUEUED_UP_PROCESSING: &str = "DYN_QUEUED_UP_PROCESSING";
867
868    /// Soak test run duration (e.g., "3s", "5m")
869    pub const DYN_SOAK_RUN_DURATION: &str = "DYN_SOAK_RUN_DURATION";
870
871    /// Soak test batch load size
872    pub const DYN_SOAK_BATCH_LOAD: &str = "DYN_SOAK_BATCH_LOAD";
873}
874
875#[cfg(test)]
876mod tests {
877    use super::*;
878
879    #[test]
880    fn test_no_duplicate_env_var_names() {
881        use std::collections::HashSet;
882
883        let mut seen = HashSet::new();
884        let vars = [
885            // Logging
886            logging::DYN_LOG,
887            logging::DYN_LOGGING_CONFIG_PATH,
888            logging::DYN_LOGGING_JSONL,
889            logging::DYN_LOGGING_CONSOLE_FORMAT,
890            logging::DYN_SDK_DISABLE_ANSI_LOGGING,
891            logging::DYN_LOG_USE_LOCAL_TZ,
892            logging::DYN_LOGGING_SPAN_EVENTS,
893            logging::otlp::OTEL_EXPORT_ENABLED,
894            logging::otlp::OTEL_EXPORTER_OTLP_PROTOCOL,
895            logging::otlp::OTEL_EXPORTER_OTLP_TRACES_PROTOCOL,
896            logging::otlp::OTEL_EXPORTER_OTLP_LOGS_PROTOCOL,
897            logging::otlp::OTEL_EXPORTER_OTLP_ENDPOINT,
898            logging::otlp::OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
899            logging::otlp::OTEL_SERVICE_NAME,
900            logging::otlp::OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
901            logging::otlp::OTEL_TRACES_SAMPLE_RATIO,
902            // Runtime
903            runtime::DYN_RUNTIME_NUM_WORKER_THREADS,
904            runtime::DYN_RUNTIME_MAX_BLOCKING_THREADS,
905            runtime::DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS,
906            runtime::DYN_RUNTIME_INHIBITED_DURATION_SECS,
907            runtime::system::DYN_SYSTEM_ENABLED,
908            runtime::system::DYN_SYSTEM_HOST,
909            runtime::system::DYN_SYSTEM_PORT,
910            runtime::system::DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS,
911            runtime::system::DYN_SYSTEM_STARTING_HEALTH_STATUS,
912            runtime::system::DYN_SYSTEM_HEALTH_PATH,
913            runtime::system::DYN_SYSTEM_LIVE_PATH,
914            runtime::canary::DYN_CANARY_WAIT_TIME,
915            // Worker
916            worker::DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT,
917            // NATS
918            nats::NATS_SERVER,
919            nats::DYN_NATS_REQUEST_TIMEOUT_SECS,
920            nats::auth::NATS_AUTH_USERNAME,
921            nats::auth::NATS_AUTH_PASSWORD,
922            nats::auth::NATS_AUTH_TOKEN,
923            nats::auth::NATS_AUTH_NKEY,
924            nats::auth::NATS_AUTH_CREDENTIALS_FILE,
925            nats::stream::DYN_NATS_STREAM_MAX_AGE,
926            nats::tls::NATS_TLS_CA_CERT_PATH,
927            nats::tls::NATS_TLS_CLIENT_CERT_PATH,
928            nats::tls::NATS_TLS_CLIENT_KEY_PATH,
929            nats::tls::NATS_TLS_INSECURE,
930            // ETCD
931            etcd::ETCD_ENDPOINTS,
932            etcd::ETCD_LEASE_TTL,
933            etcd::auth::ETCD_AUTH_USERNAME,
934            etcd::auth::ETCD_AUTH_PASSWORD,
935            etcd::auth::ETCD_AUTH_CA,
936            etcd::auth::ETCD_AUTH_CLIENT_CERT,
937            etcd::auth::ETCD_AUTH_CLIENT_KEY,
938            // KVBM
939            kvbm::DYN_KVBM_METRICS,
940            kvbm::DYN_KVBM_METRICS_PORT,
941            kvbm::DYN_KVBM_ENABLE_RECORD,
942            kvbm::DYN_KVBM_DISABLE_DISK_OFFLOAD_FILTER,
943            kvbm::cpu_cache::DYN_KVBM_CPU_CACHE_GB,
944            kvbm::cpu_cache::DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS,
945            kvbm::disk_cache::DYN_KVBM_DISK_CACHE_GB,
946            kvbm::disk_cache::DYN_KVBM_DISK_CACHE_OVERRIDE_NUM_BLOCKS,
947            kvbm::leader::DYN_KVBM_LEADER_WORKER_INIT_TIMEOUT_SECS,
948            kvbm::leader::DYN_KVBM_LEADER_ZMQ_HOST,
949            kvbm::leader::DYN_KVBM_LEADER_ZMQ_PUB_PORT,
950            kvbm::leader::DYN_KVBM_LEADER_ZMQ_ACK_PORT,
951            // LLM
952            llm::DYN_HTTP_BODY_LIMIT_MB,
953            llm::DYN_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_SECS,
954            llm::DYN_HTTP_OVERLOAD_STATUS_CODE,
955            llm::DYN_HTTP_BACKEND_STREAM_TIMEOUT_SECS,
956            llm::DYN_HTTP_PRE_COMMIT_ERROR_PEEK_MS,
957            llm::DYN_LORA_ENABLED,
958            llm::DYN_LORA_PATH,
959            llm::DYN_ENABLE_ANTHROPIC_API,
960            llm::DYN_DISABLE_FRONTEND_NVEXT,
961            llm::DYN_IGNORE_OPENAI_FE_UNSUPPORTED_FIELDS,
962            llm::DYN_DISABLE_FRONTEND_ADMIN_API,
963            llm::DYN_STRIP_ANTHROPIC_PREAMBLE,
964            llm::DYN_ENABLE_FORCE_INCLUDE_USAGE,
965            llm::DYN_ENABLE_STREAMING_TOOL_DISPATCH,
966            llm::DYN_ENABLE_STREAMING_REASONING_DISPATCH,
967            llm::DYN_REASONING_FIELD_NAME,
968            llm::DYN_ENABLE_EXPERIMENTAL_PARSERS_V2,
969            llm::DYN_ENABLE_GUIDED_TOOL_STREAMING,
970            llm::DYN_LORA_ALLOCATION_ENABLED,
971            llm::DYN_LORA_ALLOCATION_ALGORITHM,
972            llm::DYN_LORA_ALLOCATION_TIMESTEP_SECS,
973            llm::DYN_LORA_ALLOCATION_SCALE_DOWN_COOLDOWN_TICKS,
974            llm::DYN_LORA_ALLOCATION_RATE_WINDOW_MULTIPLIER,
975            llm::DYN_LORA_ALLOCATION_BUCKETS_PER_SECOND,
976            llm::DYN_LORA_ALLOCATION_PREDICTOR_TYPE,
977            llm::DYN_LORA_ALLOCATION_EMA_ALPHA,
978            llm::DYN_LORA_MCF_CONFIG,
979            llm::DYN_HTTP_SSE_KEEP_ALIVE_INTERVAL_MS,
980            llm::metrics::DYN_METRICS_PREFIX,
981            llm::audit::DYN_AUDIT_SINKS,
982            llm::audit::DYN_AUDIT_FORCE_LOGGING,
983            llm::audit::DYN_AUDIT_CAPACITY,
984            llm::audit::DYN_AUDIT_NATS_SUBJECT,
985            llm::audit::DYN_AUDIT_OUTPUT_PATH,
986            llm::audit::DYN_AUDIT_JSONL_BUFFER_BYTES,
987            llm::audit::DYN_AUDIT_JSONL_FLUSH_INTERVAL_MS,
988            llm::audit::DYN_AUDIT_JSONL_GZ_ROLL_BYTES,
989            llm::audit::DYN_AUDIT_JSONL_GZ_ROLL_LINES,
990            llm::request_trace::DYN_REQUEST_TRACE,
991            llm::request_trace::DYN_REQUEST_TRACE_SINKS,
992            llm::request_trace::DYN_REQUEST_TRACE_FILE_PATH,
993            llm::request_trace::DYN_REQUEST_TRACE_OUTPUT_PATH,
994            llm::request_trace::DYN_REQUEST_TRACE_FILE_FORMAT,
995            llm::request_trace::DYN_REQUEST_TRACE_CAPACITY,
996            llm::request_trace::DYN_REQUEST_TRACE_RECORDS,
997            llm::request_trace::DYN_REQUEST_TRACE_NATS_SUBJECT,
998            llm::request_trace::DYN_REQUEST_TRACE_OTEL_MAX_PAYLOAD_BYTES,
999            llm::request_trace::DYN_REQUEST_TRACE_FILE_BUFFER_BYTES,
1000            llm::request_trace::DYN_REQUEST_TRACE_JSONL_BUFFER_BYTES,
1001            llm::request_trace::DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS,
1002            llm::request_trace::DYN_REQUEST_TRACE_JSONL_FLUSH_INTERVAL_MS,
1003            llm::request_trace::DYN_REQUEST_TRACE_FILE_ROLL_BYTES,
1004            llm::request_trace::DYN_REQUEST_TRACE_JSONL_GZ_ROLL_BYTES,
1005            llm::request_trace::DYN_REQUEST_TRACE_FILE_ROLL_LINES,
1006            llm::request_trace::DYN_REQUEST_TRACE_JSONL_GZ_ROLL_LINES,
1007            llm::request_trace::DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_ENDPOINT,
1008            llm::request_trace::DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_TOPIC,
1009            llm::request_trace::DYN_REQUEST_TRACE_HTTP_HEADER_CAPTURE_LIST,
1010            llm::audit::DYN_AUDIT_OTEL_MAX_PAYLOAD_BYTES,
1011            // Model
1012            model::model_express::MODEL_EXPRESS_URL,
1013            model::model_express::MODEL_EXPRESS_CACHE_PATH,
1014            model::model_express::MODEL_EXPRESS_NO_SHARED_STORAGE,
1015            model::huggingface::HF_TOKEN,
1016            model::huggingface::HUGGING_FACE_HUB_TOKEN,
1017            model::huggingface::HF_TOKEN_PATH,
1018            model::huggingface::HF_HUB_CACHE,
1019            model::huggingface::HF_HOME,
1020            model::huggingface::HF_ENDPOINT,
1021            model::huggingface::HF_HUB_OFFLINE,
1022            // Router
1023            router::DYN_ROUTER_PREFILL_LOAD_SCALE,
1024            router::DYN_ROUTER_QUEUE_THRESHOLD,
1025            router::DYN_ROUTER_QUEUE_POLICY,
1026            router::DYN_ROUTER_POLICY_CONFIG,
1027            router::DYN_ROUTER_ACTIVE_REQUEST_EXPIRY_SECS,
1028            request_plane::DYN_REQUEST_PLANE,
1029            request_plane::DYN_REQUEST_PLANE_CODEC,
1030            // TCP Response Stream
1031            tcp_response_stream::DYN_TCP_RESPONSE_STREAM_PORT,
1032            tcp_response_stream::DYN_TCP_RESPONSE_STREAM_HOST,
1033            tcp_response_stream::tls::DYN_TCP_TLS_CERT_PATH,
1034            tcp_response_stream::tls::DYN_TCP_TLS_KEY_PATH,
1035            tcp_response_stream::tls::DYN_TCP_TLS_CA_CERT_PATH,
1036            tcp_response_stream::tls::DYN_TCP_TLS_INSECURE,
1037            tcp_response_stream::tls::DYN_TCP_TLS_SERVER_NAME,
1038            tcp_response_stream::tls::DYN_TCP_TLS_CLIENT_CERT_PATH,
1039            tcp_response_stream::tls::DYN_TCP_TLS_CLIENT_KEY_PATH,
1040            tcp_response_stream::tls::DYN_TCP_TLS_CLIENT_CA_CERT_PATH,
1041            tcp_response_stream::tls::DYN_TCP_TLS_HANDSHAKE_TIMEOUT_SECS,
1042            // Event Plane
1043            event_plane::DYN_EVENT_PLANE,
1044            event_plane::DYN_EVENT_PLANE_CODEC,
1045            event_plane::DYN_ZMQ_EVENT_SUBSCRIBER_CHANNEL_CAPACITY,
1046            // ZMQ Broker
1047            zmq_broker::DYN_ZMQ_BROKER_URL,
1048            zmq_broker::DYN_ZMQ_BROKER_ENABLED,
1049            zmq_broker::ZMQ_BROKER_XSUB_BIND,
1050            zmq_broker::ZMQ_BROKER_XPUB_BIND,
1051            zmq_broker::ZMQ_BROKER_NAMESPACE,
1052            // Discovery
1053            discovery::DYN_DISCOVERY_BACKEND,
1054            discovery::DYN_KUBE_DISCOVERY_MODE,
1055            // CUDA
1056            cuda::DYN_FATBIN_PATH,
1057            // Build
1058            build::OUT_DIR,
1059            // Mocker
1060            mocker::DYN_MOCKER_KV_CACHE_TRACE,
1061            mocker::DYN_MOCKER_SYNC_DIRECT,
1062            // Testing
1063            testing::DYN_QUEUED_UP_PROCESSING,
1064            testing::DYN_SOAK_RUN_DURATION,
1065            testing::DYN_SOAK_BATCH_LOAD,
1066        ];
1067
1068        for var in &vars {
1069            if !seen.insert(var) {
1070                panic!("Duplicate environment variable name: {}", var);
1071            }
1072        }
1073    }
1074
1075    #[test]
1076    fn test_naming_conventions() {
1077        // Dynamo-specific vars should start with DYN_
1078        assert!(runtime::DYN_RUNTIME_NUM_WORKER_THREADS.starts_with("DYN_"));
1079        assert!(runtime::DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS.starts_with("DYN_"));
1080        assert!(runtime::system::DYN_SYSTEM_ENABLED.starts_with("DYN_"));
1081        assert!(kvbm::DYN_KVBM_METRICS.starts_with("DYN_"));
1082        assert!(worker::DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT.starts_with("DYN_"));
1083
1084        // NATS vars should start with NATS_
1085        assert!(nats::NATS_SERVER.starts_with("NATS_"));
1086        assert!(nats::auth::NATS_AUTH_USERNAME.starts_with("NATS_AUTH_"));
1087
1088        // ETCD vars should start with ETCD_
1089        assert!(etcd::ETCD_ENDPOINTS.starts_with("ETCD_"));
1090        assert!(etcd::ETCD_LEASE_TTL.starts_with("ETCD_"));
1091        assert!(etcd::auth::ETCD_AUTH_USERNAME.starts_with("ETCD_AUTH_"));
1092
1093        // OpenTelemetry vars should start with OTEL_
1094        assert!(logging::otlp::OTEL_EXPORT_ENABLED.starts_with("OTEL_"));
1095        assert!(logging::otlp::OTEL_EXPORTER_OTLP_ENDPOINT.starts_with("OTEL_"));
1096        assert!(logging::otlp::OTEL_SERVICE_NAME.starts_with("OTEL_"));
1097    }
1098}