> ## Documentation Index
> Fetch the complete documentation index at: https://dsrs.herumbshandilya.com/llms.txt
> Use this file to discover all available pages before exploring further.

# State

> Save and restore optimized module state with ModuleState and PredictState

After an optimizer tunes a module, the improved instructions and demos live only in memory. `ModuleState` snapshots the mutable state of every `Predict` leaf in a module into a serializable value, so an optimized program can be saved to disk and reloaded in production without re-running optimization.

```rust theme={null}
// After optimization:
ModuleState::from_module(&mut module)?.save("optimized.json")?;

// In production:
let mut module = MyPipeline::new();
ModuleState::load("optimized.json")?.apply(&mut module)?;
```

## `ModuleState`

A `ModuleState` holds one `PredictState` per predictor, keyed by the dotted path the optimizer walker discovers (`predictors: BTreeMap<String, PredictState>`). The `BTreeMap` keeps JSON output stable across runs. Paths follow the module structure: struct fields join with dots (`inner.predictor`), list elements append an index (`steps[0]`), and map entries append an escaped key (`stages['draft']`).

| Method        | Signature                                                  | Behavior                                                                                                                                                                |
| ------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `from_module` | `fn from_module<M: Facet>(module: &mut M) -> Result<Self>` | Snapshots every `Predict` leaf. Takes `&mut` because leaf discovery uses the exclusive Facet walker; the module is not modified.                                        |
| `apply`       | `fn apply<M: Facet>(&self, module: &mut M) -> Result<()>`  | Applies the state in place. Every path in the state must resolve to a `Predict` leaf; unknown paths are an error. Predictors not named in the state are left untouched. |
| `to_json`     | `fn to_json(&self) -> Result<String>`                      | Serializes to pretty-printed JSON.                                                                                                                                      |
| `from_json`   | `fn from_json(json: &str) -> Result<Self>`                 | Deserializes JSON produced by `to_json`.                                                                                                                                |
| `save`        | `fn save(&self, path: impl AsRef<Path>) -> Result<()>`     | Writes `to_json` output to a file.                                                                                                                                      |
| `load`        | `fn load(path: impl AsRef<Path>) -> Result<Self>`          | Reads a file written by `save`.                                                                                                                                         |

## `PredictState` and the JSON shape

`PredictState` is the serializable snapshot of a single predictor's mutable state.

| Field                  | Type             | Meaning                                                                                                                                                                                              |
| ---------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `demos`                | `Vec<JsonMap>`   | Demo rows as flat JSON objects: field name to value, with input and output fields merged into one object. Rows are split back into the predictor's typed `Demo<S>` via the signature schema on load. |
| `instruction_override` | `Option<String>` | The instruction override, if any. `null` means the signature default applies.                                                                                                                        |

A saved file therefore looks like:

```json theme={null}
{
  "predictors": {
    "answerer": {
      "demos": [
        { "question": "2+2?", "answer": "4" }
      ],
      "instruction_override": "Answer concisely."
    }
  }
}
```

## The mutation seam

Internally, both state loading and optimizers reach predictors through one type-erased trait, `DynPredictor` (crate-private). Its `apply_update` method is the single mutation seam: every write to a predictor's optimizable state flows through it, including optimizer candidate set and restore, `ModuleState::apply`, and the `fx::Params` overlay. An update is partial: `None` fields are left untouched, `instruction: Some(None)` clears the override back to the signature default, and `Some(demos)` replaces the demo set. `load_state` (used by `apply`) delegates to `apply_update` with both fields set. This is also the single place where prompt caches are invalidated: a candidate is data applied through the seam, never ad hoc field mutation.

## Compatibility behavior

There is no version field in the format. Compatibility is field level and structural:

| Situation                                             | Result                                                                                        |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Missing `demos` or `instruction_override` in JSON     | Defaults apply (`serde(default)` on both fields).                                             |
| State names a path absent from the module             | `apply` returns an error listing the unknown predictors.                                      |
| Demo rows do not fit the predictor's signature schema | `apply` returns `failed to load state for `name\`\`.                                          |
| Module has predictors the state does not name         | Left untouched, no error.                                                                     |
| `Predict` leaf inside `Rc` or `Arc`                   | Traversal error; `Box`, `Option`, `Vec`, arrays, slices, and string-keyed maps are supported. |

## See also

* [Predict](/docs/components/predict)
* [Optimizers](/docs/components/optimizers)
* [Functional lane (fx)](/docs/components/fx)
* [Modules](/docs/components/modules)
* [Example: save and load state](https://github.com/krypticmouse/DSRs/blob/main/crates/dspy-rs/examples/13-save-load-state.rs)
