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

# Session Model Restore

> Resumed sessions run on their recorded model, not the current default

Resuming a session runs it on the model it was recorded with — a later change to your default model does not silently rewrite an ongoing conversation.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Session Model Restore"
        Rec[🔑 Recorded model] --> Res[⏩ Resume]
        Res --> Restore[✅ Restored model]
        Restore --> Turn[▶️ Next turn]
    end

    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef process fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff

    class Rec input
    class Res process
    class Restore,Turn output
```

## Quick Start

<Steps>
  <Step title="Start a session on a model">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai run "What is the capital of France?" --model anthropic/claude-3-5-sonnet-latest
    ```
  </Step>

  <Step title="Change your default — resume still uses the original">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai config set default_model gpt-4o
    praisonai run "What about Germany?" --continue
    # → Restored session model: anthropic/claude-3-5-sonnet-latest
    ```
  </Step>

  <Step title="Override on resume when you want a different model">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai run "Try again with a smaller model" --continue --model gpt-4o-mini
    # The recorded model is now gpt-4o-mini for subsequent turns.
    ```
  </Step>
</Steps>

***

## How It Works

The wrapper reads the recorded model from the session store before the credential gate, so a resumed cloud session is never shadowed by a reachable local endpoint.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant CLI
    participant Store as Session Store
    participant Resolver as Model Resolver

    User->>CLI: run --continue
    CLI->>Store: find_session_model(session_id)
    alt recorded model found
        Store-->>CLI: recorded model
        CLI-->>User: Restored session model: <model>
    else none recorded
        CLI->>Resolver: resolve_default_model()
        Resolver-->>CLI: current default
    end
```

The store resolves the recorded model from the session-level `metadata["model"]` first, then from the most recent turn that recorded its own `model`. When neither exists it returns `None`, so the caller falls back to normal default resolution.

***

## Precedence

The model that wins on resume is the first non-empty entry in this order.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q{--model passed?} -->|Yes| M[Use --model<br/>update recorded]
    Q -->|No| C{Config has agent.model?}
    C -->|Yes| CM[Use config model]
    C -->|No| R{Session has recorded model?}
    R -->|Yes| RM[Restore recorded model]
    R -->|No| D[Default resolution]

    classDef pick fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef ans fill:#10B981,stroke:#7C90A0,color:#fff
    classDef fall fill:#6366F1,stroke:#7C90A0,color:#fff

    class Q,C,R pick
    class M,CM,RM ans
    class D fall
```

| Step | Source | Wins when |
| - | - | - |
| 1 | Explicit `--model` flag | Always, when passed |
| 2 | Config `agent.model` | No `--model` and config sets a model |
| 3 | Recorded session model | Resuming and steps 1–2 are unset |
| 4 | Keyless local-first fallback | All above unset and no cloud key present |
| 5 | Default resolution | Nothing else resolved a model |

***

## Legacy Session Files

Older PraisonAI versions stored `model` / `llm` as top-level fields rather than under `metadata`. On load, the store folds those legacy fields back into metadata so historical sessions recover their recorded model without any migration.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.session.store import SessionData

restored = SessionData.from_dict(
    {"session_id": "legacy", "messages": [], "model": "gpt-4o"}
)
restored.metadata["model"]  # → "gpt-4o"
```

Existing `metadata` values always win over the mirrored top-level value.

<Note>
  **`from_dict` skips non-object turns.** Any entry in `messages` or `archived_messages` that is not a JSON object (`null`, a string, a number) is silently dropped, so a single malformed turn cannot crash reconstruction (gateway routing, portable import, `get_working_history`). The on-disk transcript is left untouched. When dropped active turns precede the compaction anchor, `last_compaction.message_index` is shifted down so the retained tail still slices correctly. See PraisonAI PR [#5676](https://github.com/MervinPraison/PraisonAI/pull/5676) / issue [#5672](https://github.com/MervinPraison/PraisonAI/issues/5672).

  ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  from praisonaiagents.session.store import SessionData

  # Input with a null turn
  data = {
      "session_id": "s1",
      "messages": [None, {"role": "user", "content": "hi"}],
  }
  restored = SessionData.from_dict(data)
  [m.content for m in restored.messages]  # → ["hi"]  (null is dropped)
  ```
</Note>

***

## Best Practices

<AccordionGroup>
  <Accordion title="Let resume pick the model — don't re-pass --model">
    Resuming without `--model` keeps the conversation on its original model. Only pass `--model` when you deliberately want to switch mid-thread.
  </Accordion>

  <Accordion title="Switch models intentionally with --model">
    Passing `--model` on resume both overrides the recorded model and records the new one for subsequent turns, so the switch persists.

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai run "continue" --continue --model gpt-4o-mini
    ```
  </Accordion>

  <Accordion title="Resume cloud sessions on machines with local endpoints">
    The recorded-model lookup runs before the keyless local-first gate, so a resumed cloud session is not switched to a local model just because Ollama or LM Studio is reachable.
  </Accordion>

  <Accordion title="Trust legacy sessions to restore correctly">
    Sessions created by older versions recover their recorded model automatically — no export/re-import step is needed.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Session Resume" icon="play" href="/docs/cli/session-resume">
    Continue previous conversations
  </Card>

  <Card title="Keyless Local-First Run" icon="server" href="/docs/features/keyless-local-first-run">
    Auto-detect local endpoints when no cloud key is set
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.