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    /// Disable ANSI terminal colors in logs
38    pub const DYN_SDK_DISABLE_ANSI_LOGGING: &str = "DYN_SDK_DISABLE_ANSI_LOGGING";
39
40    /// Use local timezone for logging timestamps (default is UTC)
41    pub const DYN_LOG_USE_LOCAL_TZ: &str = "DYN_LOG_USE_LOCAL_TZ";
42
43    /// Enable span event logging (create/close events)
44    pub const DYN_LOGGING_SPAN_EVENTS: &str = "DYN_LOGGING_SPAN_EVENTS";
45
46    /// OTLP (OpenTelemetry Protocol) tracing and logging configuration
47    pub mod otlp {
48        /// Enable OTLP export for traces and logs (set to "1" to enable)
49        pub const OTEL_EXPORT_ENABLED: &str = "OTEL_EXPORT_ENABLED";
50
51        /// OTLP exporter transport protocol. Supported values: "grpc", "http/protobuf".
52        pub const OTEL_EXPORTER_OTLP_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_PROTOCOL";
53
54        /// OTLP exporter transport protocol for traces. Defaults to OTEL_EXPORTER_OTLP_PROTOCOL.
55        pub const OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL";
56
57        /// OTLP exporter transport protocol for logs. Defaults to OTEL_EXPORTER_OTLP_PROTOCOL.
58        pub const OTEL_EXPORTER_OTLP_LOGS_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL";
59
60        /// Generic OTLP exporter endpoint URL used when signal-specific endpoints are unset.
61        pub const OTEL_EXPORTER_OTLP_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_ENDPOINT";
62
63        /// OTLP exporter endpoint URL for traces
64        /// Spec: https://opentelemetry.io/docs/specs/otel/protocol/exporter/
65        pub const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
66
67        /// OTLP exporter endpoint URL for logs. Falls back to OTEL_EXPORTER_OTLP_ENDPOINT or the protocol default when unset.
68        pub const OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT";
69
70        /// Trace sampling ratio used when set. Example: "0.01" samples roughly 1% of traces.
71        pub const OTEL_TRACES_SAMPLE_RATIO: &str = "OTEL_TRACES_SAMPLE_RATIO";
72
73        /// Service name for OTLP traces and logs
74        pub const OTEL_SERVICE_NAME: &str = "OTEL_SERVICE_NAME";
75    }
76}
77
78/// Runtime configuration environment variables
79///
80/// These control the Tokio runtime, system health/metrics server, and worker behavior
81pub mod runtime {
82    /// Number of async worker threads for Tokio runtime
83    pub const DYN_RUNTIME_NUM_WORKER_THREADS: &str = "DYN_RUNTIME_NUM_WORKER_THREADS";
84
85    /// Maximum number of blocking threads for Tokio runtime
86    pub const DYN_RUNTIME_MAX_BLOCKING_THREADS: &str = "DYN_RUNTIME_MAX_BLOCKING_THREADS";
87
88    /// Maximum time to wait for graceful endpoint drain during runtime shutdown.
89    pub const DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS: &str =
90        "DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS";
91
92    /// Enable Tokio task poll-time histogram (calls enable_metrics_poll_time_histogram on builder).
93    /// Set to "1", "true", or "yes" to enable. Adds ~2× overhead of Instant::now() per task poll.
94    pub const DYN_ENABLE_POLL_HISTOGRAM: &str = "DYN_ENABLE_POLL_HISTOGRAM";
95
96    /// System status server configuration
97    pub mod system {
98        /// Enable system status server for health and metrics endpoints
99        /// ⚠️ DEPRECATED: will be removed soon
100        pub const DYN_SYSTEM_ENABLED: &str = "DYN_SYSTEM_ENABLED";
101
102        /// System status server host
103        pub const DYN_SYSTEM_HOST: &str = "DYN_SYSTEM_HOST";
104
105        /// System status server port
106        pub const DYN_SYSTEM_PORT: &str = "DYN_SYSTEM_PORT";
107
108        /// Use endpoint health status for system health
109        /// ⚠️ DEPRECATED: No longer used
110        pub const DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS: &str =
111            "DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS";
112
113        /// Starting health status for the system
114        pub const DYN_SYSTEM_STARTING_HEALTH_STATUS: &str = "DYN_SYSTEM_STARTING_HEALTH_STATUS";
115
116        /// Health check endpoint path
117        pub const DYN_SYSTEM_HEALTH_PATH: &str = "DYN_SYSTEM_HEALTH_PATH";
118
119        /// Liveness check endpoint path
120        pub const DYN_SYSTEM_LIVE_PATH: &str = "DYN_SYSTEM_LIVE_PATH";
121    }
122
123    /// Compute configuration
124    pub mod compute {
125        /// Prefix for compute-related environment variables
126        pub const PREFIX: &str = "DYN_COMPUTE_";
127    }
128
129    /// Canary deployment configuration
130    pub mod canary {
131        /// Wait time in seconds for canary deployments
132        pub const DYN_CANARY_WAIT_TIME: &str = "DYN_CANARY_WAIT_TIME";
133    }
134}
135
136/// Worker lifecycle environment variables
137pub mod worker {
138    /// Graceful shutdown timeout in seconds
139    pub const DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT: &str = "DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT";
140}
141
142/// NATS transport environment variables
143pub mod nats {
144    /// NATS server address (e.g., "nats://localhost:4222")
145    pub const NATS_SERVER: &str = "NATS_SERVER";
146
147    /// NATS request/reply timeout in seconds. Unset = async-nats default (10 s).
148    pub const DYN_NATS_REQUEST_TIMEOUT_SECS: &str = "DYN_NATS_REQUEST_TIMEOUT_SECS";
149
150    /// NATS authentication environment variables (checked in priority order)
151    pub mod auth {
152        /// Username for NATS authentication (use with NATS_AUTH_PASSWORD)
153        pub const NATS_AUTH_USERNAME: &str = "NATS_AUTH_USERNAME";
154
155        /// Password for NATS authentication (use with NATS_AUTH_USERNAME)
156        pub const NATS_AUTH_PASSWORD: &str = "NATS_AUTH_PASSWORD";
157
158        /// Token for NATS authentication
159        pub const NATS_AUTH_TOKEN: &str = "NATS_AUTH_TOKEN";
160
161        /// NKey for NATS authentication
162        pub const NATS_AUTH_NKEY: &str = "NATS_AUTH_NKEY";
163
164        /// Path to NATS credentials file
165        pub const NATS_AUTH_CREDENTIALS_FILE: &str = "NATS_AUTH_CREDENTIALS_FILE";
166    }
167
168    /// NATS stream configuration
169    pub mod stream {
170        /// Maximum age for messages in NATS stream (in seconds)
171        pub const DYN_NATS_STREAM_MAX_AGE: &str = "DYN_NATS_STREAM_MAX_AGE";
172    }
173}
174
175/// ETCD transport environment variables
176pub mod etcd {
177    /// ETCD endpoints (comma-separated list of URLs)
178    pub const ETCD_ENDPOINTS: &str = "ETCD_ENDPOINTS";
179
180    /// ETCD lease TTL in seconds (default: 10)
181    pub const ETCD_LEASE_TTL: &str = "ETCD_LEASE_TTL";
182
183    /// ETCD authentication environment variables
184    pub mod auth {
185        /// Username for ETCD authentication
186        pub const ETCD_AUTH_USERNAME: &str = "ETCD_AUTH_USERNAME";
187
188        /// Password for ETCD authentication
189        pub const ETCD_AUTH_PASSWORD: &str = "ETCD_AUTH_PASSWORD";
190
191        /// Path to CA certificate for ETCD TLS
192        pub const ETCD_AUTH_CA: &str = "ETCD_AUTH_CA";
193
194        /// Path to client certificate for ETCD TLS
195        pub const ETCD_AUTH_CLIENT_CERT: &str = "ETCD_AUTH_CLIENT_CERT";
196
197        /// Path to client key for ETCD TLS
198        pub const ETCD_AUTH_CLIENT_KEY: &str = "ETCD_AUTH_CLIENT_KEY";
199    }
200}
201
202/// Key-Value Block Manager (KVBM) environment variables
203pub mod kvbm {
204    /// Enable KVBM metrics endpoint
205    pub const DYN_KVBM_METRICS: &str = "DYN_KVBM_METRICS";
206
207    /// KVBM metrics endpoint port
208    pub const DYN_KVBM_METRICS_PORT: &str = "DYN_KVBM_METRICS_PORT";
209
210    /// Enable KVBM recording for debugging.
211    pub const DYN_KVBM_ENABLE_RECORD: &str = "DYN_KVBM_ENABLE_RECORD";
212
213    /// Disable disk offload filter
214    pub const DYN_KVBM_DISABLE_DISK_OFFLOAD_FILTER: &str = "DYN_KVBM_DISABLE_DISK_OFFLOAD_FILTER";
215
216    /// CPU cache configuration
217    pub mod cpu_cache {
218        /// CPU cache size in GB
219        pub const DYN_KVBM_CPU_CACHE_GB: &str = "DYN_KVBM_CPU_CACHE_GB";
220
221        /// CPU cache size in number of blocks (override)
222        pub const DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS: &str =
223            "DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS";
224    }
225
226    /// Disk cache configuration
227    pub mod disk_cache {
228        /// Disk cache size in GB
229        pub const DYN_KVBM_DISK_CACHE_GB: &str = "DYN_KVBM_DISK_CACHE_GB";
230
231        /// Disk cache size in number of blocks (override)
232        pub const DYN_KVBM_DISK_CACHE_OVERRIDE_NUM_BLOCKS: &str =
233            "DYN_KVBM_DISK_CACHE_OVERRIDE_NUM_BLOCKS";
234    }
235
236    /// Object storage configuration
237    pub mod object_storage {
238        /// Enable object storage. Set to "1" to enable.
239        pub const DYN_KVBM_OBJECT_ENABLED: &str = "DYN_KVBM_OBJECT_ENABLED";
240
241        /// Bucket name for object storage cache
242        /// Supports `{worker_id}` template for per-worker buckets
243        /// Example: "kv-cache-{worker_id}"
244        pub const DYN_KVBM_OBJECT_BUCKET: &str = "DYN_KVBM_OBJECT_BUCKET";
245
246        /// Endpoint for object storage
247        pub const DYN_KVBM_OBJECT_ENDPOINT: &str = "DYN_KVBM_OBJECT_ENDPOINT";
248
249        /// Region for object storage
250        pub const DYN_KVBM_OBJECT_REGION: &str = "DYN_KVBM_OBJECT_REGION";
251
252        /// Access key for authentication
253        pub const DYN_KVBM_OBJECT_ACCESS_KEY: &str = "DYN_KVBM_OBJECT_ACCESS_KEY";
254
255        /// Secret key for authentication
256        pub const DYN_KVBM_OBJECT_SECRET_KEY: &str = "DYN_KVBM_OBJECT_SECRET_KEY";
257
258        /// Number of blocks to store in object storage
259        pub const DYN_KVBM_OBJECT_NUM_BLOCKS: &str = "DYN_KVBM_OBJECT_NUM_BLOCKS";
260    }
261    /// Transfer configuration
262    pub mod transfer {
263        /// Maximum number of blocks per transfer batch
264        pub const DYN_KVBM_TRANSFER_BATCH_SIZE: &str = "DYN_KVBM_TRANSFER_BATCH_SIZE";
265    }
266
267    /// KVBM leader (distributed mode) configuration
268    pub mod leader {
269        /// Timeout in seconds for KVBM leader and worker initialization
270        pub const DYN_KVBM_LEADER_WORKER_INIT_TIMEOUT_SECS: &str =
271            "DYN_KVBM_LEADER_WORKER_INIT_TIMEOUT_SECS";
272
273        /// ZMQ host for KVBM leader
274        pub const DYN_KVBM_LEADER_ZMQ_HOST: &str = "DYN_KVBM_LEADER_ZMQ_HOST";
275
276        /// ZMQ publish port for KVBM leader
277        pub const DYN_KVBM_LEADER_ZMQ_PUB_PORT: &str = "DYN_KVBM_LEADER_ZMQ_PUB_PORT";
278
279        /// ZMQ acknowledgment port for KVBM leader
280        pub const DYN_KVBM_LEADER_ZMQ_ACK_PORT: &str = "DYN_KVBM_LEADER_ZMQ_ACK_PORT";
281    }
282
283    /// NIXL backend configuration
284    pub mod nixl {
285        /// Prefix for NIXL backend environment variables
286        /// Pattern: DYN_KVBM_NIXL_BACKEND_<backend>=true/false
287        /// Example: DYN_KVBM_NIXL_BACKEND_UCX=true
288        pub const PREFIX: &str = "DYN_KVBM_NIXL_BACKEND_";
289    }
290}
291
292/// LLM (Language Model) inference environment variables
293pub mod llm {
294    /// HTTP body size limit in MB
295    pub const DYN_HTTP_BODY_LIMIT_MB: &str = "DYN_HTTP_BODY_LIMIT_MB";
296
297    pub const DYN_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_SECS: &str =
298        "DYN_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_SECS";
299
300    /// HTTP status code returned when the frontend rejects a request because
301    /// all workers are overloaded. Defaults to 529 ("Site is overloaded"); set
302    /// to 503 for Service Unavailable retry semantics. Any valid HTTP status
303    /// code (100–999) is accepted; an unparseable or out-of-range value falls
304    /// back to 529.
305    pub const DYN_HTTP_OVERLOAD_STATUS_CODE: &str = "DYN_HTTP_OVERLOAD_STATUS_CODE";
306
307    /// Enable LoRA adapter support (set to "true" to enable)
308    pub const DYN_LORA_ENABLED: &str = "DYN_LORA_ENABLED";
309
310    /// LoRA cache directory path
311    pub const DYN_LORA_PATH: &str = "DYN_LORA_PATH";
312
313    /// Enable the experimental Anthropic Messages API endpoint (/v1/messages)
314    pub const DYN_ENABLE_ANTHROPIC_API: &str = "DYN_ENABLE_ANTHROPIC_API";
315
316    /// Master switch for the `nvext` extension protocol on the frontend.
317    /// The protocol is **enabled by default**; this variable disables it.
318    /// Truthy values (`1` / `true` / `yes` / `on`, case-insensitive) cause
319    /// the frontend to drop `request.nvext` at handler entry, ignore the
320    /// routing-override headers (`x-dynamo-worker-instance-id`,
321    /// `x-dynamo-prefill-instance-id`, `x-dynamo-dp-rank`,
322    /// `x-dynamo-prefill-dp-rank`), and silently ignore the response-side
323    /// `extra_fields` opt-in.
324    pub const DYN_DISABLE_FRONTEND_NVEXT: &str = "DYN_DISABLE_FRONTEND_NVEXT";
325
326    /// Ignore unknown OpenAI frontend request fields. Unknown fields are dropped,
327    /// not handled; known pass-through fields remain type-validated.
328    pub const DYN_IGNORE_OPENAI_FE_UNSUPPORTED_FIELDS: &str =
329        "DYN_IGNORE_OPENAI_FE_UNSUPPORTED_FIELDS";
330
331    /// Master switch for the frontend's HTTP admin API surface.
332    /// The admin API is **enabled by default**; this variable disables it.
333    /// Truthy values (`1` / `true` / `yes` / `on`, case-insensitive) prevent
334    /// registration of `GET` / `POST /busy_threshold`. Inference, metrics,
335    /// models, health, and liveness routes are unaffected.
336    pub const DYN_DISABLE_FRONTEND_ADMIN_API: &str = "DYN_DISABLE_FRONTEND_ADMIN_API";
337
338    /// Strip the Claude Code billing preamble (`x-anthropic-billing-header: ...`)
339    /// from the system prompt before forwarding to the target model. The preamble
340    /// varies per session and per release, wasting tokens and breaking prompt caching.
341    pub const DYN_STRIP_ANTHROPIC_PREAMBLE: &str = "DYN_STRIP_ANTHROPIC_PREAMBLE";
342
343    /// Enable streaming tool call dispatch (`event: tool_call_dispatch` SSE events)
344    pub const DYN_ENABLE_STREAMING_TOOL_DISPATCH: &str = "DYN_ENABLE_STREAMING_TOOL_DISPATCH";
345
346    /// Enable streaming reasoning dispatch (`event: reasoning_dispatch` SSE events)
347    pub const DYN_ENABLE_STREAMING_REASONING_DISPATCH: &str =
348        "DYN_ENABLE_STREAMING_REASONING_DISPATCH";
349
350    /// \[EXPERIMENTAL\] Route supported tool-call families (Qwen3-Coder, DeepSeek-V4)
351    /// through the `dynamo-parsers-v2` streaming parser for BOTH the batch and the
352    /// streaming path, bypassing the v1 tool-call jail. Off by default; when set, the
353    /// v2 parser owns incremental tool-call emission and drops values truncated at EOF.
354    pub const DYN_ENABLE_EXPERIMENTAL_PARSERS_V2: &str = "DYN_ENABLE_EXPERIMENTAL_PARSERS_V2";
355
356    /// Backend stream inactivity timeout in seconds.
357    ///
358    /// When set to a positive integer, the frontend will kill the engine context
359    /// and drop the inflight guard if no SSE event is received from the backend
360    /// within this many seconds. Acts as a circuit breaker for zombie workers
361    /// that hold a live TCP connection but never produce output.
362    ///
363    /// Set to `0` or leave unset to disable the timeout (default: disabled).
364    pub const DYN_HTTP_BACKEND_STREAM_TIMEOUT_SECS: &str = "DYN_HTTP_BACKEND_STREAM_TIMEOUT_SECS";
365
366    /// Enable the LoRA allocation controller (set to "true" to enable)
367    pub const DYN_LORA_ALLOCATION_ENABLED: &str = "DYN_LORA_ALLOCATION_ENABLED";
368
369    /// LoRA allocation algorithm ("hrw", "random", or "mcf")
370    pub const DYN_LORA_ALLOCATION_ALGORITHM: &str = "DYN_LORA_ALLOCATION_ALGORITHM";
371
372    /// JSON configuration for the MCF (min-cost flow) placement solver.
373    /// Example: '{"candidate_m":16,"gamma_load":2000,"beta_keep":500}'
374    /// Omitted fields use defaults. Only relevant when algorithm is "mcf".
375    pub const DYN_LORA_MCF_CONFIG: &str = "DYN_LORA_MCF_CONFIG";
376
377    /// LoRA allocation controller recompute interval in seconds
378    pub const DYN_LORA_ALLOCATION_TIMESTEP_SECS: &str = "DYN_LORA_ALLOCATION_TIMESTEP_SECS";
379
380    /// Ticks to wait before scaling down a LoRA's replicas
381    pub const DYN_LORA_ALLOCATION_SCALE_DOWN_COOLDOWN_TICKS: &str =
382        "DYN_LORA_ALLOCATION_SCALE_DOWN_COOLDOWN_TICKS";
383
384    /// Multiplier for the load estimator's rate window relative to the controller timestep.
385    pub const DYN_LORA_ALLOCATION_RATE_WINDOW_MULTIPLIER: &str =
386        "DYN_LORA_ALLOCATION_RATE_WINDOW_MULTIPLIER";
387
388    /// Number of counter buckets per second in the BucketedRateCounter.
389    pub const DYN_LORA_ALLOCATION_BUCKETS_PER_SECOND: &str =
390        "DYN_LORA_ALLOCATION_BUCKETS_PER_SECOND";
391
392    /// Load predictor type: "none" (raw counts) or "ema" (exponential moving average).
393    pub const DYN_LORA_ALLOCATION_PREDICTOR_TYPE: &str = "DYN_LORA_ALLOCATION_PREDICTOR_TYPE";
394
395    /// EMA smoothing factor (alpha) for the EMA predictor. Range [0.0, 1.0].
396    pub const DYN_LORA_ALLOCATION_EMA_ALPHA: &str = "DYN_LORA_ALLOCATION_EMA_ALPHA";
397
398    /// Metrics configuration
399    pub mod metrics {
400        /// Custom metrics prefix (overrides default "dynamo_frontend")
401        pub const DYN_METRICS_PREFIX: &str = "DYN_METRICS_PREFIX";
402
403        /// Histogram bucket configuration (pattern: <PREFIX>_MIN, <PREFIX>_MAX, <PREFIX>_COUNT)
404        /// Example: DYN_HISTOGRAM_TTFT_MIN, DYN_HISTOGRAM_TTFT_MAX, DYN_HISTOGRAM_TTFT_COUNT
405        pub const HISTOGRAM_PREFIX: &str = "DYN_HISTOGRAM_";
406    }
407
408    /// Audit sink configuration
409    pub mod audit {
410        /// Audit sink selection. Comma-separated values: `stderr`, `nats`,
411        /// `jsonl`, `jsonl_gz`. Setting any non-empty value enables audit
412        /// recording.
413        pub const DYN_AUDIT_SINKS: &str = "DYN_AUDIT_SINKS";
414
415        /// Force audit emission even when the request `store` flag is `false`.
416        pub const DYN_AUDIT_FORCE_LOGGING: &str = "DYN_AUDIT_FORCE_LOGGING";
417
418        /// In-process audit bus capacity.
419        pub const DYN_AUDIT_CAPACITY: &str = "DYN_AUDIT_CAPACITY";
420
421        /// NATS subject the JetStream audit sink publishes to.
422        pub const DYN_AUDIT_NATS_SUBJECT: &str = "DYN_AUDIT_NATS_SUBJECT";
423
424        /// Local output path for audit records.
425        ///
426        /// For `jsonl`, this is the literal file path. For `jsonl_gz`, this is
427        /// the segment prefix used to derive `<prefix>.<index>.jsonl.gz` files.
428        pub const DYN_AUDIT_OUTPUT_PATH: &str = "DYN_AUDIT_OUTPUT_PATH";
429
430        /// JSONL audit sink buffer size in bytes.
431        pub const DYN_AUDIT_JSONL_BUFFER_BYTES: &str = "DYN_AUDIT_JSONL_BUFFER_BYTES";
432
433        /// JSONL audit sink periodic flush interval in milliseconds.
434        pub const DYN_AUDIT_JSONL_FLUSH_INTERVAL_MS: &str = "DYN_AUDIT_JSONL_FLUSH_INTERVAL_MS";
435
436        /// Rotating gzip JSONL audit sink roll threshold in uncompressed bytes.
437        pub const DYN_AUDIT_JSONL_GZ_ROLL_BYTES: &str = "DYN_AUDIT_JSONL_GZ_ROLL_BYTES";
438
439        /// Rotating gzip JSONL audit sink roll threshold in record lines.
440        pub const DYN_AUDIT_JSONL_GZ_ROLL_LINES: &str = "DYN_AUDIT_JSONL_GZ_ROLL_LINES";
441    }
442
443    /// Per-request replay trace configuration
444    pub mod request_trace {
445        /// Master switch. Truthy enables per-request replay tracing.
446        pub const DYN_REQUEST_TRACE: &str = "DYN_REQUEST_TRACE";
447
448        /// Request trace sink selection. Comma-separated values: stderr,jsonl,jsonl_gz.
449        pub const DYN_REQUEST_TRACE_SINKS: &str = "DYN_REQUEST_TRACE_SINKS";
450
451        /// Local output path for request trace records.
452        ///
453        /// For `jsonl`, this is the literal file path. For `jsonl_gz`, this is the
454        /// segment prefix used to derive `<prefix>.<index>.jsonl.gz` files.
455        pub const DYN_REQUEST_TRACE_OUTPUT_PATH: &str = "DYN_REQUEST_TRACE_OUTPUT_PATH";
456
457        /// In-process trace bus capacity.
458        pub const DYN_REQUEST_TRACE_CAPACITY: &str = "DYN_REQUEST_TRACE_CAPACITY";
459
460        /// JSONL sink buffer size in bytes.
461        pub const DYN_REQUEST_TRACE_JSONL_BUFFER_BYTES: &str =
462            "DYN_REQUEST_TRACE_JSONL_BUFFER_BYTES";
463
464        /// JSONL sink periodic flush interval in milliseconds.
465        pub const DYN_REQUEST_TRACE_JSONL_FLUSH_INTERVAL_MS: &str =
466            "DYN_REQUEST_TRACE_JSONL_FLUSH_INTERVAL_MS";
467
468        /// Rotating gzip JSONL sink roll threshold in uncompressed bytes.
469        pub const DYN_REQUEST_TRACE_JSONL_GZ_ROLL_BYTES: &str =
470            "DYN_REQUEST_TRACE_JSONL_GZ_ROLL_BYTES";
471
472        /// Rotating gzip JSONL sink roll threshold in record lines.
473        pub const DYN_REQUEST_TRACE_JSONL_GZ_ROLL_LINES: &str =
474            "DYN_REQUEST_TRACE_JSONL_GZ_ROLL_LINES";
475
476        /// Local ZMQ PULL endpoint Dynamo binds for harness tool events.
477        pub const DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_ENDPOINT: &str =
478            "DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_ENDPOINT";
479
480        /// First-frame ZMQ topic filter override for harness tool events.
481        pub const DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_TOPIC: &str =
482            "DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_TOPIC";
483    }
484}
485
486/// Model loading and caching environment variables
487pub mod model {
488    /// Model Express configuration
489    pub mod model_express {
490        /// Model Express server endpoint URL
491        pub const MODEL_EXPRESS_URL: &str = "MODEL_EXPRESS_URL";
492
493        /// Model Express cache path
494        pub const MODEL_EXPRESS_CACHE_PATH: &str = "MODEL_EXPRESS_CACHE_PATH";
495
496        /// Disable shared-storage mode for the Model Express client. When set,
497        /// the client streams model files from the server over gRPC instead of
498        /// relying on a shared filesystem path. Required when the Model Express
499        /// server and worker pods do not share a filesystem (e.g. RWO PVCs,
500        /// cross-namespace deployments). Set to "1" or "true" to enable.
501        pub const MODEL_EXPRESS_NO_SHARED_STORAGE: &str = "MODEL_EXPRESS_NO_SHARED_STORAGE";
502    }
503
504    /// Hugging Face configuration
505    pub mod huggingface {
506        /// Hugging Face authentication token
507        pub const HF_TOKEN: &str = "HF_TOKEN";
508
509        /// Deprecated alias for the Hugging Face authentication token
510        pub const HUGGING_FACE_HUB_TOKEN: &str = "HUGGING_FACE_HUB_TOKEN";
511
512        /// Path to the stored Hugging Face authentication token
513        pub const HF_TOKEN_PATH: &str = "HF_TOKEN_PATH";
514
515        /// Hugging Face Hub cache directory
516        pub const HF_HUB_CACHE: &str = "HF_HUB_CACHE";
517
518        /// Hugging Face home directory
519        pub const HF_HOME: &str = "HF_HOME";
520
521        /// Override the Hugging Face Hub API endpoint
522        pub const HF_ENDPOINT: &str = "HF_ENDPOINT";
523
524        /// Offline mode - skip API calls when model is cached
525        /// Set to "1", "true", "on", or "yes" to enable
526        pub const HF_HUB_OFFLINE: &str = "HF_HUB_OFFLINE";
527    }
528}
529
530/// KV Router configuration environment variables
531pub mod router {
532    /// Scale applied to adjusted prompt-side prefill load after overlap/cache-hit credits.
533    pub const DYN_ROUTER_PREFILL_LOAD_SCALE: &str = "DYN_ROUTER_PREFILL_LOAD_SCALE";
534
535    /// Queue threshold fraction for prefill token capacity.
536    /// When set, requests are queued if all workers exceed this fraction of max_num_batched_tokens.
537    pub const DYN_ROUTER_QUEUE_THRESHOLD: &str = "DYN_ROUTER_QUEUE_THRESHOLD";
538
539    /// Scheduling policy for the router queue ("fcfs" or "wspt").
540    pub const DYN_ROUTER_QUEUE_POLICY: &str = "DYN_ROUTER_QUEUE_POLICY";
541    pub const DYN_ROUTER_POLICY_CONFIG: &str = "DYN_ROUTER_POLICY_CONFIG";
542}
543
544/// Request plane transport environment variables
545pub mod request_plane {
546    /// Request plane payload codec selection: "json" or "msgpack".
547    /// JSON is the compatibility default.
548    pub const DYN_REQUEST_PLANE_CODEC: &str = "DYN_REQUEST_PLANE_CODEC";
549}
550
551/// TCP response stream server (CallHome listener) environment variables
552pub mod tcp_response_stream {
553    /// Port for the TCP response stream server.
554    /// If unset or 0, the OS assigns a free ephemeral port.
555    pub const DYN_TCP_RESPONSE_STREAM_PORT: &str = "DYN_TCP_RESPONSE_STREAM_PORT";
556
557    /// Host/interface for the TCP response stream server.
558    /// If unset, the server auto-detects a routable local IP.
559    pub const DYN_TCP_RESPONSE_STREAM_HOST: &str = "DYN_TCP_RESPONSE_STREAM_HOST";
560}
561
562/// Event Plane transport environment variables
563pub mod event_plane {
564    /// Event transport selection: "zmq" or "nats".
565    ///
566    /// When unset the default depends on the discovery backend:
567    /// - `file` / `mem` backends: defaults to `zmq` (no external services required).
568    /// - `etcd` / `kubernetes` backends: defaults to `nats`.
569    ///
570    /// Set this explicitly to override the context-aware default.
571    pub const DYN_EVENT_PLANE: &str = "DYN_EVENT_PLANE";
572
573    /// Event plane codec selection: "json" or "msgpack".
574    pub const DYN_EVENT_PLANE_CODEC: &str = "DYN_EVENT_PLANE_CODEC";
575
576    /// Bounded capacity of the direct ZMQ event-subscriber's merged event channel.
577    ///
578    /// Many peer publishers (e.g. every other frontend under replica-sync) feed
579    /// this single-consumer channel; an unbounded channel grows RSS without limit
580    /// when the consumer can't keep up. When the channel is full, new events are
581    /// dropped — the event plane is already best-effort/lossy (ZMQ RCVHWM), so a
582    /// dropped event costs routing-estimate freshness, not correctness.
583    /// Default: 100_000 (matches ZMQ_RCVHWM). Applies only to the direct ZMQ
584    /// subscriber path.
585    pub const DYN_ZMQ_EVENT_SUBSCRIBER_CHANNEL_CAPACITY: &str =
586        "DYN_ZMQ_EVENT_SUBSCRIBER_CHANNEL_CAPACITY";
587}
588
589/// ZMQ Broker environment variables
590pub mod zmq_broker {
591    /// Explicit ZMQ broker URL (takes precedence over discovery)
592    /// Format: "xsub=<url1>[;<url2>...] , xpub=<url1>[;<url2>...]"
593    /// Example: "xsub=tcp://broker:5555 , xpub=tcp://broker:5556"
594    pub const DYN_ZMQ_BROKER_URL: &str = "DYN_ZMQ_BROKER_URL";
595
596    /// Enable ZMQ broker discovery mode
597    pub const DYN_ZMQ_BROKER_ENABLED: &str = "DYN_ZMQ_BROKER_ENABLED";
598
599    /// XSUB bind address (broker binary only)
600    pub const ZMQ_BROKER_XSUB_BIND: &str = "ZMQ_BROKER_XSUB_BIND";
601
602    /// XPUB bind address (broker binary only)
603    pub const ZMQ_BROKER_XPUB_BIND: &str = "ZMQ_BROKER_XPUB_BIND";
604
605    /// Namespace for broker discovery registration
606    pub const ZMQ_BROKER_NAMESPACE: &str = "ZMQ_BROKER_NAMESPACE";
607}
608
609/// Discovery environment variables
610pub mod discovery {
611    /// Discovery backend: "kubernetes" or "etcd" (default)
612    pub const DYN_DISCOVERY_BACKEND: &str = "DYN_DISCOVERY_BACKEND";
613
614    /// Kube discovery mode: "pod" (default) or "container" (each container registers independently)
615    pub const DYN_KUBE_DISCOVERY_MODE: &str = "DYN_KUBE_DISCOVERY_MODE";
616}
617
618/// CUDA and GPU environment variables
619pub mod cuda {
620    /// Path to custom CUDA fatbin file.
621    ///
622    /// Note: build.rs files cannot import this constant at build time,
623    /// so they must define local constants with the same value.
624    pub const DYN_FATBIN_PATH: &str = "DYN_FATBIN_PATH";
625}
626
627/// Build-time environment variables
628pub mod build {
629    /// Cargo output directory for build artifacts
630    ///
631    /// Note: This constant cannot be used with the `env!()` macro,
632    /// which requires a string literal at compile time.
633    /// Build scripts (build.rs) also cannot import this constant.
634    pub const OUT_DIR: &str = "OUT_DIR";
635}
636
637/// Mocker (mock scheduler/KV manager) environment variables
638pub mod mocker {
639    /// Enable structured KV cache allocation/eviction trace logs (set to "1" or "true" to enable)
640    pub const DYN_MOCKER_KV_CACHE_TRACE: &str = "DYN_MOCKER_KV_CACHE_TRACE";
641
642    /// Use the original direct() code path in the mocker request dispatch.
643    ///
644    /// This path is race-prone during startup; prefer leaving it unset unless you are
645    /// explicitly trying to reproduce the original behavior.
646    pub const DYN_MOCKER_SYNC_DIRECT: &str = "DYN_MOCKER_SYNC_DIRECT";
647}
648
649/// Testing environment variables
650pub mod testing {
651    /// Enable queued-up request processing in tests
652    pub const DYN_QUEUED_UP_PROCESSING: &str = "DYN_QUEUED_UP_PROCESSING";
653
654    /// Soak test run duration (e.g., "3s", "5m")
655    pub const DYN_SOAK_RUN_DURATION: &str = "DYN_SOAK_RUN_DURATION";
656
657    /// Soak test batch load size
658    pub const DYN_SOAK_BATCH_LOAD: &str = "DYN_SOAK_BATCH_LOAD";
659}
660
661#[cfg(test)]
662mod tests {
663    use super::*;
664
665    #[test]
666    fn test_no_duplicate_env_var_names() {
667        use std::collections::HashSet;
668
669        let mut seen = HashSet::new();
670        let vars = [
671            // Logging
672            logging::DYN_LOG,
673            logging::DYN_LOGGING_CONFIG_PATH,
674            logging::DYN_LOGGING_JSONL,
675            logging::DYN_SDK_DISABLE_ANSI_LOGGING,
676            logging::DYN_LOG_USE_LOCAL_TZ,
677            logging::DYN_LOGGING_SPAN_EVENTS,
678            logging::otlp::OTEL_EXPORT_ENABLED,
679            logging::otlp::OTEL_EXPORTER_OTLP_PROTOCOL,
680            logging::otlp::OTEL_EXPORTER_OTLP_TRACES_PROTOCOL,
681            logging::otlp::OTEL_EXPORTER_OTLP_LOGS_PROTOCOL,
682            logging::otlp::OTEL_EXPORTER_OTLP_ENDPOINT,
683            logging::otlp::OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
684            logging::otlp::OTEL_SERVICE_NAME,
685            logging::otlp::OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
686            logging::otlp::OTEL_TRACES_SAMPLE_RATIO,
687            // Runtime
688            runtime::DYN_RUNTIME_NUM_WORKER_THREADS,
689            runtime::DYN_RUNTIME_MAX_BLOCKING_THREADS,
690            runtime::DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS,
691            runtime::system::DYN_SYSTEM_ENABLED,
692            runtime::system::DYN_SYSTEM_HOST,
693            runtime::system::DYN_SYSTEM_PORT,
694            runtime::system::DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS,
695            runtime::system::DYN_SYSTEM_STARTING_HEALTH_STATUS,
696            runtime::system::DYN_SYSTEM_HEALTH_PATH,
697            runtime::system::DYN_SYSTEM_LIVE_PATH,
698            runtime::canary::DYN_CANARY_WAIT_TIME,
699            // Worker
700            worker::DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT,
701            // NATS
702            nats::NATS_SERVER,
703            nats::DYN_NATS_REQUEST_TIMEOUT_SECS,
704            nats::auth::NATS_AUTH_USERNAME,
705            nats::auth::NATS_AUTH_PASSWORD,
706            nats::auth::NATS_AUTH_TOKEN,
707            nats::auth::NATS_AUTH_NKEY,
708            nats::auth::NATS_AUTH_CREDENTIALS_FILE,
709            nats::stream::DYN_NATS_STREAM_MAX_AGE,
710            // ETCD
711            etcd::ETCD_ENDPOINTS,
712            etcd::ETCD_LEASE_TTL,
713            etcd::auth::ETCD_AUTH_USERNAME,
714            etcd::auth::ETCD_AUTH_PASSWORD,
715            etcd::auth::ETCD_AUTH_CA,
716            etcd::auth::ETCD_AUTH_CLIENT_CERT,
717            etcd::auth::ETCD_AUTH_CLIENT_KEY,
718            // KVBM
719            kvbm::DYN_KVBM_METRICS,
720            kvbm::DYN_KVBM_METRICS_PORT,
721            kvbm::DYN_KVBM_ENABLE_RECORD,
722            kvbm::DYN_KVBM_DISABLE_DISK_OFFLOAD_FILTER,
723            kvbm::cpu_cache::DYN_KVBM_CPU_CACHE_GB,
724            kvbm::cpu_cache::DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS,
725            kvbm::disk_cache::DYN_KVBM_DISK_CACHE_GB,
726            kvbm::disk_cache::DYN_KVBM_DISK_CACHE_OVERRIDE_NUM_BLOCKS,
727            kvbm::leader::DYN_KVBM_LEADER_WORKER_INIT_TIMEOUT_SECS,
728            kvbm::leader::DYN_KVBM_LEADER_ZMQ_HOST,
729            kvbm::leader::DYN_KVBM_LEADER_ZMQ_PUB_PORT,
730            kvbm::leader::DYN_KVBM_LEADER_ZMQ_ACK_PORT,
731            // LLM
732            llm::DYN_HTTP_BODY_LIMIT_MB,
733            llm::DYN_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_SECS,
734            llm::DYN_HTTP_OVERLOAD_STATUS_CODE,
735            llm::DYN_HTTP_BACKEND_STREAM_TIMEOUT_SECS,
736            llm::DYN_LORA_ENABLED,
737            llm::DYN_LORA_PATH,
738            llm::DYN_ENABLE_ANTHROPIC_API,
739            llm::DYN_DISABLE_FRONTEND_NVEXT,
740            llm::DYN_IGNORE_OPENAI_FE_UNSUPPORTED_FIELDS,
741            llm::DYN_DISABLE_FRONTEND_ADMIN_API,
742            llm::DYN_STRIP_ANTHROPIC_PREAMBLE,
743            llm::DYN_ENABLE_STREAMING_TOOL_DISPATCH,
744            llm::DYN_ENABLE_STREAMING_REASONING_DISPATCH,
745            llm::DYN_ENABLE_EXPERIMENTAL_PARSERS_V2,
746            llm::DYN_LORA_ALLOCATION_ENABLED,
747            llm::DYN_LORA_ALLOCATION_ALGORITHM,
748            llm::DYN_LORA_ALLOCATION_TIMESTEP_SECS,
749            llm::DYN_LORA_ALLOCATION_SCALE_DOWN_COOLDOWN_TICKS,
750            llm::DYN_LORA_ALLOCATION_RATE_WINDOW_MULTIPLIER,
751            llm::DYN_LORA_ALLOCATION_BUCKETS_PER_SECOND,
752            llm::DYN_LORA_ALLOCATION_PREDICTOR_TYPE,
753            llm::DYN_LORA_ALLOCATION_EMA_ALPHA,
754            llm::DYN_LORA_MCF_CONFIG,
755            llm::metrics::DYN_METRICS_PREFIX,
756            llm::audit::DYN_AUDIT_SINKS,
757            llm::audit::DYN_AUDIT_FORCE_LOGGING,
758            llm::audit::DYN_AUDIT_CAPACITY,
759            llm::audit::DYN_AUDIT_NATS_SUBJECT,
760            llm::audit::DYN_AUDIT_OUTPUT_PATH,
761            llm::audit::DYN_AUDIT_JSONL_BUFFER_BYTES,
762            llm::audit::DYN_AUDIT_JSONL_FLUSH_INTERVAL_MS,
763            llm::audit::DYN_AUDIT_JSONL_GZ_ROLL_BYTES,
764            llm::audit::DYN_AUDIT_JSONL_GZ_ROLL_LINES,
765            llm::request_trace::DYN_REQUEST_TRACE,
766            llm::request_trace::DYN_REQUEST_TRACE_SINKS,
767            llm::request_trace::DYN_REQUEST_TRACE_OUTPUT_PATH,
768            llm::request_trace::DYN_REQUEST_TRACE_CAPACITY,
769            llm::request_trace::DYN_REQUEST_TRACE_JSONL_BUFFER_BYTES,
770            llm::request_trace::DYN_REQUEST_TRACE_JSONL_FLUSH_INTERVAL_MS,
771            llm::request_trace::DYN_REQUEST_TRACE_JSONL_GZ_ROLL_BYTES,
772            llm::request_trace::DYN_REQUEST_TRACE_JSONL_GZ_ROLL_LINES,
773            llm::request_trace::DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_ENDPOINT,
774            llm::request_trace::DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_TOPIC,
775            // Model
776            model::model_express::MODEL_EXPRESS_URL,
777            model::model_express::MODEL_EXPRESS_CACHE_PATH,
778            model::model_express::MODEL_EXPRESS_NO_SHARED_STORAGE,
779            model::huggingface::HF_TOKEN,
780            model::huggingface::HUGGING_FACE_HUB_TOKEN,
781            model::huggingface::HF_TOKEN_PATH,
782            model::huggingface::HF_HUB_CACHE,
783            model::huggingface::HF_HOME,
784            model::huggingface::HF_ENDPOINT,
785            model::huggingface::HF_HUB_OFFLINE,
786            // Router
787            router::DYN_ROUTER_PREFILL_LOAD_SCALE,
788            router::DYN_ROUTER_QUEUE_THRESHOLD,
789            router::DYN_ROUTER_QUEUE_POLICY,
790            router::DYN_ROUTER_POLICY_CONFIG,
791            request_plane::DYN_REQUEST_PLANE_CODEC,
792            // TCP Response Stream
793            tcp_response_stream::DYN_TCP_RESPONSE_STREAM_PORT,
794            tcp_response_stream::DYN_TCP_RESPONSE_STREAM_HOST,
795            // Event Plane
796            event_plane::DYN_EVENT_PLANE,
797            event_plane::DYN_EVENT_PLANE_CODEC,
798            event_plane::DYN_ZMQ_EVENT_SUBSCRIBER_CHANNEL_CAPACITY,
799            // ZMQ Broker
800            zmq_broker::DYN_ZMQ_BROKER_URL,
801            zmq_broker::DYN_ZMQ_BROKER_ENABLED,
802            zmq_broker::ZMQ_BROKER_XSUB_BIND,
803            zmq_broker::ZMQ_BROKER_XPUB_BIND,
804            zmq_broker::ZMQ_BROKER_NAMESPACE,
805            // Discovery
806            discovery::DYN_DISCOVERY_BACKEND,
807            discovery::DYN_KUBE_DISCOVERY_MODE,
808            // CUDA
809            cuda::DYN_FATBIN_PATH,
810            // Build
811            build::OUT_DIR,
812            // Mocker
813            mocker::DYN_MOCKER_KV_CACHE_TRACE,
814            mocker::DYN_MOCKER_SYNC_DIRECT,
815            // Testing
816            testing::DYN_QUEUED_UP_PROCESSING,
817            testing::DYN_SOAK_RUN_DURATION,
818            testing::DYN_SOAK_BATCH_LOAD,
819        ];
820
821        for var in &vars {
822            if !seen.insert(var) {
823                panic!("Duplicate environment variable name: {}", var);
824            }
825        }
826    }
827
828    #[test]
829    fn test_naming_conventions() {
830        // Dynamo-specific vars should start with DYN_
831        assert!(runtime::DYN_RUNTIME_NUM_WORKER_THREADS.starts_with("DYN_"));
832        assert!(runtime::DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS.starts_with("DYN_"));
833        assert!(runtime::system::DYN_SYSTEM_ENABLED.starts_with("DYN_"));
834        assert!(kvbm::DYN_KVBM_METRICS.starts_with("DYN_"));
835        assert!(worker::DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT.starts_with("DYN_"));
836
837        // NATS vars should start with NATS_
838        assert!(nats::NATS_SERVER.starts_with("NATS_"));
839        assert!(nats::auth::NATS_AUTH_USERNAME.starts_with("NATS_AUTH_"));
840
841        // ETCD vars should start with ETCD_
842        assert!(etcd::ETCD_ENDPOINTS.starts_with("ETCD_"));
843        assert!(etcd::ETCD_LEASE_TTL.starts_with("ETCD_"));
844        assert!(etcd::auth::ETCD_AUTH_USERNAME.starts_with("ETCD_AUTH_"));
845
846        // OpenTelemetry vars should start with OTEL_
847        assert!(logging::otlp::OTEL_EXPORT_ENABLED.starts_with("OTEL_"));
848        assert!(logging::otlp::OTEL_SERVICE_NAME.starts_with("OTEL_"));
849    }
850}