How the Session Management System Maintains State in nGPT Chat Conversations
The nGPT session management system persists interactive chat state using JSON-based file storage, a centralized session index, and a Rich-powered terminal UI to enable seamless conversation continuity across CLI invocations.
The nazdridoy/ngpt repository implements a robust session management system that ensures no conversational context is lost between commands. By combining persistent file storage with lightweight metadata indexing, the system allows users to pause, resume, and manage multiple chat sessions without relying on in-memory state alone.
Core Components of the Session Management System
The architecture centers on two primary classes that separate data persistence from user interface concerns.
SessionManager Class
Located in ngpt/cli/handlers/session_handler.py, the SessionManager class handles all disk operations and index maintenance. It constructs unique session identifiers, manages the history/ directory via _get_history_dir(), and ensures data integrity through validate_session_index().
The save_session() method generates a new session file (session_<id>.json) when called without an existing ID, or overwrites the existing file during subsequent turns. It automatically derives a friendly session name from the first user prompt and updates session-index.json with lightweight metadata including timestamps and file size.
For retrieval, load_session() reads the JSON file and returns the complete message list, while get_session_index() provides quick access to metadata without loading full conversation histories.
SessionUI Class
The SessionUI class in ngpt/ui/session_ui.py leverages the Rich library to render interactive terminal interfaces. It transforms raw session metadata into sortable tables via print_session_list(), displaying size indicators (green/yellow/red dots) and temporal information.
For detailed inspection, show_session_preview() renders collapsible panels containing user/assistant message pairs extracted from the session files, allowing users to review conversation context before resuming.
How Session State Persistence Works in the Chat Loop
The session management system integrates seamlessly into the interactive chat workflow defined in ngpt/cli/modes/interactive.py.
-
Initial Session Creation: When a user sends the first message in a fresh chat, the
interactive_chat_session()function callsauto_save_session()after receiving the AI response. If nosession_idexists,SessionManager.save_session()creates a new unique identifier, writes the conversation tosession_<id>.json, and registers the metadata insession-index.json. -
Continuous Persistence: Every subsequent exchange passes the existing
session_idtoauto_save_session(). The manager overwrites the same JSON file, ensuring the full dialogue history remains synchronized with disk storage throughout the conversation. -
Session Retrieval via Commands: When the user enters the reserved command
/sessions, the system triggershandle_session_management(). This function loads the session index, validates it against actual files usingvalidate_session_index(), and displays the UI list viaSessionUI.print_session_list(). -
State Restoration: Upon selecting "load" for a specific session, the handler calls
SessionManager.load_session()to retrieve the complete message list. The interactive mode replaces its in-memoryconversationlist with the loaded data, restoring the exact state used for previous API calls. The system prompt and any additional pre-prompts are automatically reapplied, preserving the original context. -
Metadata Visibility: The
SessionUIcomponent readssession-index.jsonto present users with sortable metadata including creation times, modification timestamps, and visual size indicators, facilitating quick identification of target conversations without parsing raw JSON files.
Practical Code Examples
Automatic Saving After Each AI Turn
The following pattern from ngpt/cli/modes/interactive.py demonstrates how the chat loop persists state automatically:
# After the assistant response is received
current_session_id, current_session_filepath, current_session_name = auto_save_session(
conversation=conversation,
session_id=current_session_id,
session_filepath=current_session_filepath,
session_name=current_session_name,
first_user_prompt=first_user_prompt,
logger=logger,
)
The auto_save_session() function delegates to SessionManager.save_session(), which handles both new session creation and subsequent overwrites.
Loading a Saved Session via the /sessions Command
When users invoke session management through the CLI:
# When the user runs "/sessions"
result = handle_session_management(logger=logger)
# Result contains (session_id, session_filepath, session_name, loaded_conversation)
if result is not None:
session_id, session_filepath, session_name, loaded_conversation = result
conversation = loaded_conversation # Replace current history
current_session_id = session_id
current_session_filepath = session_filepath
current_session_name = session_name
The handle_session_management() function internally invokes SessionManager.load_session() and returns the complete conversation list for state restoration.
Manual SessionManager Usage in Scripts
For programmatic access to the session management system:
from ngpt.cli.handlers.session_handler import SessionManager
sm = SessionManager()
# Create a brand-new conversation list
conv = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello, who are you?"},
]
# Persist it – a new session file is written and indexed
session_id, path, name = sm.save_session(conv, first_user_prompt=conv[1]["content"])
print(f"Saved as {name} ({session_id}) → {path}")
# Later, retrieve the same conversation
loaded = sm.load_session(session_id)
print("Restored messages:", loaded)
Rendering the Session List with Rich UI
To display sessions using the terminal interface:
from ngpt.cli.handlers.session_handler import SessionManager
from ngpt.ui.session_ui import SessionUI
sm = SessionManager()
ui = SessionUI(sm)
index = sm.get_session_index()
sorted_sessions = ui.format_sessions_for_display(index["sessions"])
ui.print_session_list(sorted_sessions, sorted_sessions, current_session_idx=0)
This produces a Rich table with indices, IDs, size indicators, creation dates, and last-modified timestamps.
Key Files in the Session Management Architecture
| File | Purpose |
|---|---|
ngpt/cli/handlers/session_handler.py |
Core SessionManager class – creates, loads, saves, indexes, and validates session files. |
ngpt/ui/session_ui.py |
Rich-based UI for listing sessions, showing previews, and printing help. |
ngpt/cli/modes/interactive.py |
Interactive chat loop; integrates session management via /sessions and auto_save_session. |
ngpt/ui/interactive_ui.py |
Handles the welcome screen, help, and other UI elements used by the chat mode. |
ngpt/core/config.py |
Provides get_config_dir() which determines where the history/ folder resides. |
These files collectively implement the session management subsystem that preserves conversational state across CLI invocations, enabling seamless continuation of interactive chat sessions.
Summary
- The session management system in
nazdridoy/ngptuses JSON file persistence and a metadata index to maintain chat state across CLI restarts. SessionManagerinngpt/cli/handlers/session_handler.pyhandles all disk operations, includingsave_session(),load_session(), andvalidate_session_index().SessionUIinngpt/ui/session_ui.pyprovides Rich-based terminal visualization for browsing and previewing saved conversations.- The interactive chat loop in
ngpt/cli/modes/interactive.pyautomatically persists conversations viaauto_save_session()and restores them throughhandle_session_management()when users invoke the/sessionscommand. - Session files follow the naming convention
session_<id>.json, with metadata aggregated insession-index.jsonfor fast lookup without loading full conversation histories.
Frequently Asked Questions
How does nGPT store session data on disk?
nGPT stores session data as JSON files in a history/ directory within the configuration folder. Each conversation receives a unique ID and is saved as session_<id>.json containing the complete message list. A separate session-index.json file maintains lightweight metadata—including session names, timestamps, and file sizes—enabling rapid listing without parsing full conversation files.
What happens when I load a session in the middle of a chat?
When you invoke the /sessions command and select a session to load, the handle_session_management() function calls SessionManager.load_session() to read the JSON file. The interactive chat loop then replaces its in-memory conversation list with the loaded messages and updates the current session_id, session_filepath, and session_name variables. This restoration includes the original system prompt and context, allowing you to continue the conversation exactly where it left off.
How does the session management system handle data integrity?
The SessionManager class includes a validate_session_index() method that reconciles the session-index.json metadata with actual files on disk. This validation detects orphaned index entries (referencing deleted files) and unindexed session files (existing JSON files missing from the index), repairing the metadata automatically. Additionally, each save operation atomically overwrites the session file, ensuring the stored conversation history always reflects the most recent state.
Can I use the session management system programmatically outside the interactive chat mode?
Yes, the SessionManager class is designed for independent use. You can import it from ngpt.cli.handlers.session_handler and instantiate it to create, save, and load sessions manually. The class provides direct access to save_session() for persisting conversation lists, load_session() for retrieval by ID, and get_session_index() for browsing metadata without loading full conversations. This enables custom scripts and alternative interfaces to leverage the same persistent storage mechanism used by the interactive CLI.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →