utils module bundles three small pieces of shared infrastructure: the LM response cache, tracing setup, and the stable hasher used everywhere identity hashes are persisted. Cache and telemetry items are re-exported at the crate root; hash items live under dspy_rs::utils::hash.
ResponseCache
A hybrid memory plus disk LM response cache built on foyer: 256MB in memory and 1GB on disk in a per-process temp directory. It also maintains a sliding window of the 100 most recent entries for LM::inspect_history. The cache is created automatically by LM; you do not construct it directly. Caching is per LM instance, and entries are not shared across instances.
CacheEntry and CacheKey
CacheEntry is a cached prompt-response pair: prompt (the formatted prompt sent to the LM), usage (token usage recorded for the original uncached call), and raw_output (the raw assistant text, so LM::call can replay a cached completion through the normal parse path).
CacheKey is a u64. Keys are produced by LM, never built by hand: the LM streams the model name, the temperature bits, max_tokens, and the Debug representation of the full message history through StableHasher, with no intermediate JSON tree or string materialized. Demos and instructions live inside the messages, so they are covered automatically. Hashed keys keep foyer lookups and disk serialization O(1) in prompt size.
Telemetry
init_tracing() installs process-global, pretty tracing output for DSRs.
The module also exports
truncate(value: &str, max_chars: usize) -> &str, a character-boundary-safe prefix truncation helper. Optimizers such as GEPA and SIMBA use it to bound raw span output when building reflection prompts.
Stable hashing
std::hash::DefaultHasher is not guaranteed stable across Rust releases. Replay fixtures, on-disk trace files, and cache keys must survive toolchain upgrades, so everything that hashes for identity uses FNV-1a 64-bit with a fixed algorithm.
This guarantee is load-bearing in three places: trace
request_hash values (recorded traces replay against live code in later builds), LM cache keys (cache_key_for uses the same hasher as the trace format), and optimizer candidate hashes (the engine hashes canonical JSON with StableHasher).
