# How Conversation History Works in Open Interpreter: Save and Restore Chat Sessions

> Discover how Open Interpreter saves and restores chat sessions. Learn to manage conversation history with automatic JSON persistence and convenient CLI flags or Python APIs.

- Repository: [Open Interpreter/open-interpreter](https://github.com/openinterpreter/open-interpreter)
- Tags: internals
- Published: 2026-03-05

---

**Open Interpreter automatically persists every chat turn to a JSON file in your local config directory and provides CLI flags and Python APIs to restore previous sessions.**

Open Interpreter maintains a complete **conversation history** for every interactive session, enabling you to resume long-running coding tasks without losing context. According to the Open Interpreter source code, the system uses a combination of automatic JSON serialization, platform-specific storage paths, and a conversation navigator to manage chat persistence.

## Where Conversation History Is Stored

The storage location is determined by `get_storage_path()` in [`interpreter/terminal_interface/utils/local_storage_path.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/utils/local_storage_path.py). This helper uses **platformdirs** to resolve the OS-specific config directory (typically `~/.config/open-interpreter` on Linux, `~/Library/Application Support/open-interpreter` on macOS, or `%LOCALAPPDATA%\open-interpreter` on Windows) and appends a `conversations` subdirectory.

```python

# interpreter/terminal_interface/utils/local_storage_path.py

def get_storage_path(subdirectory=None):
    if subdirectory is None:
        return config_dir
    else:
        return os.path.join(config_dir, subdirectory)

```

When the `Interpreter` class initializes in [`interpreter/core/core.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/core/core.py), it sets `conversation_history_path=get_storage_path("conversations")` by default.

## Automatic Saving of Chat Sessions

By default, `conversation_history=True` in the `Interpreter` constructor. After every turn in `_streaming_chat()` (lines 61‑90 of [`interpreter/core/core.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/core/core.py)), the system serializes the entire `self.messages` list to JSON.

The filename generation logic creates human-readable names:

1. Extracts the first 25 words of the first user message
2. Sanitizes the string to remove filesystem-unsafe characters
3. Appends a timestamp (`datetime.now().strftime("%B_%d_%Y_%H-%M-%S")`)

```python

# interpreter/core/core.py – excerpt from _streaming_chat

if self.conversation_history:
    if not self.conversation_filename:
        first_few_words = ...  # sanitized first message

        date = datetime.now().strftime("%B_%d_%Y_%H-%M-%S")
        self.conversation_filename = f"{first_few_words}__{date}.json"
    if not os.path.exists(self.conversation_history_path):
        os.makedirs(self.conversation_history_path)
    with open(os.path.join(self.conversation_history_path,
                           self.conversation_filename), "w") as f:
        json.dump(self.messages, f)

```

## Restoring Previous Chat Sessions

Open Interpreter provides two methods to restore **conversation history**: the `--conversations` CLI flag and programmatic loading.

### Using the CLI Conversation Navigator

Running `interpreter --conversations` triggers the conversation navigator flow in [`interpreter/terminal_interface/start_terminal_interface.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/start_terminal_interface.py). This invokes `conversation_navigator()` from [`interpreter/terminal_interface/conversation_navigator.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/conversation_navigator.py), which:

1. Calls `get_conversations()` from [`interpreter/terminal_interface/utils/get_conversations.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/utils/get_conversations.py) to list all JSON files in the storage directory
2. Displays a numbered list in the terminal
3. Loads the selected file using `json.load()` and assigns the list to `interpreter.messages`
4. Sets `interpreter.conversation_filename` to the selected file so subsequent turns append to the same history

```bash

# Launch the conversation navigator

interpreter --conversations

# Terminal output:

# 1) hello_world__April_01_2024_12-30-45.json

# 2) data_analysis__April_02_2024_09-15-12.json

# Select a conversation to resume: 2

```

### Programmatic Restoration

You can manually load a saved JSON file into a new `Interpreter` instance via the `messages` parameter:

```python
import json
from interpreter import Interpreter

# Load a previously exported JSON file

with open("/home/user/data_analysis__April_02_2024_09-15-12.json") as f:
    previous_messages = json.load(f)

# Restore the conversation history

interpreter = Interpreter(messages=previous_messages)

# Continue the session

interpreter.chat("Continue where we left off.")

```

## Exporting Conversations to Markdown or Jupyter

In addition to automatic JSON persistence, Open Interpreter provides **magic commands** for human-readable exports. These are implemented in [`interpreter/terminal_interface/magic_commands.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/magic_commands.py).

- **`%markdown [path]`**: Exports the current conversation to Markdown. If no path is provided, it saves to the Downloads folder using the current conversation filename (with `.md` extension).
- **`%jupyter`**: Exports the conversation as a Jupyter notebook (`.ipynb`).

```python

# Inside an Open Interpreter session

%markdown                    # Saves to ~/Downloads/<conversation_name>.md

%markdown /tmp/report.md     # Explicit custom path

%jupyter                     # Creates .ipynb in Downloads

```

The implementation (lines 301‑311 of [`magic_commands.py`](https://github.com/openinterpreter/open-interpreter/blob/main/magic_commands.py)) uses `get_downloads_path()` to determine the default export location:

```python

# interpreter/terminal_interface/magic_commands.py

export_path = get_downloads_path() + f"/{self.conversation_filename[:-4]}.md"

```

## Programmatic Control of Conversation History

You can disable automatic persistence or configure custom storage locations when instantiating the `Interpreter` class.

### Disable History

```python
from interpreter import Interpreter

# No JSON files will be written

interpreter = Interpreter(conversation_history=False)

```

### Custom Storage Path

```python
import os
from interpreter import Interpreter

custom_path = os.path.expanduser("~/custom_chat_backups")
interpreter = Interpreter(conversation_history_path=custom_path)

```

### Manual Save to Custom Location

Even with automatic history enabled, you can manually export the current state:

```python
import json
import os
from interpreter import Interpreter

interpreter = Interpreter()
interpreter.chat("Analyze the CSV file.")

# Manual export

backup_path = os.path.expanduser("~/backups/manual_backup.json")
os.makedirs(os.path.dirname(backup_path), exist_ok=True)
with open(backup_path, "w") as f:
    json.dump(interpreter.messages, f, indent=2)

```

## Summary

- **Automatic Persistence**: Open Interpreter saves every turn to a JSON file in `~/.config/open-interpreter/conversations` (or OS-specific equivalent) when `conversation_history=True` (default).
- **Filename Generation**: Files are named using the first 25 words of the first user message plus a timestamp, implemented in [`interpreter/core/core.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/core/core.py).
- **Restoration**: Use the `--conversations` CLI flag to launch an interactive navigator, or programmatically load JSON into the `messages` parameter of a new `Interpreter` instance.
- **Export Options**: Magic commands `%markdown` and `%jupyter` in [`interpreter/terminal_interface/magic_commands.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/magic_commands.py) export to human-readable formats.
- **Key Files**: [`local_storage_path.py`](https://github.com/openinterpreter/open-interpreter/blob/main/local_storage_path.py) (storage resolution), [`core.py`](https://github.com/openinterpreter/open-interpreter/blob/main/core.py) (saving logic), [`conversation_navigator.py`](https://github.com/openinterpreter/open-interpreter/blob/main/conversation_navigator.py) (loading UI), [`magic_commands.py`](https://github.com/openinterpreter/open-interpreter/blob/main/magic_commands.py) (exports).

## Frequently Asked Questions

### Where does Open Interpreter store conversation history files?

Open Interpreter stores conversation history as JSON files in the `conversations` subdirectory of your platform-specific config directory, typically `~/.config/open-interpreter/conversations` on Linux, `~/Library/Application Support/open-interpreter/conversations` on macOS, or `%LOCALAPPDATA%\open-interpreter\conversations` on Windows. This path is determined by the `get_storage_path()` function in [`interpreter/terminal_interface/utils/local_storage_path.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/utils/local_storage_path.py).

### How do I resume a previous chat session?

You can resume a previous session by running `interpreter --conversations` in your terminal, which launches an interactive navigator listing all saved JSON files. Select the desired conversation by number to restore the full message history. Alternatively, you can programmatically load a saved JSON file using `Interpreter(messages=previous_messages)` where `previous_messages` is a list loaded via `json.load()`.

### Can I disable automatic conversation history?

Yes. When instantiating the `Interpreter` class, set `conversation_history=False` to prevent the system from writing JSON files after each turn. For example: `interpreter = Interpreter(conversation_history=False)`. This disables the automatic persistence logic found in [`interpreter/core/core.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/core/core.py) while still allowing manual exports via magic commands.

### How do I export a conversation to Markdown or Jupyter notebook?

Within an active Open Interpreter session, use the magic command `%markdown` to export the current conversation to a Markdown file in your Downloads folder, or specify a custom path with `%markdown /path/to/file.md`. To export as a Jupyter notebook, use `%jupyter`. These commands are implemented in [`interpreter/terminal_interface/magic_commands.py`](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/magic_commands.py) and convert the internal message list to human-readable formats.