This page documents the memory and session management systems in Hermes Agent, which provide persistent conversation context, agent memory storage, and session management capabilities. The implementations span several layers including file-based memories (MEMORY.md, USER.md), SQLite-backed session persistence with full-text search, and session search for long-term retrieval.
The memory system maintains persistent knowledge for the agent and user across sessions. This is stored in two Markdown files in the memories directory scoped to each profile tools/memory_tool.py5-14
| File | Purpose | Max Size | Tool Actions |
|---|---|---|---|
MEMORY.md | Agent personal notes, facts, and quirks | 2200 chars | add, replace, remove |
USER.md | User preferences and profiles | 1375 chars | add, replace, remove |
Entries are separated using the § (section sign) character and can span multiple lines tools/memory_tool.py59 Before being committed to disk, content is scanned by _scan_memory_content for prompt injection, role hijacking, and exfiltration patterns using the "strict" scope tools/memory_tool.py78-82
MemoryStore Class and Frozen Snapshot PatternMemoryStore manages in-memory representations of these files while applying a frozen snapshot pattern to preserve prompt prefix caching between conversation turns tools/memory_tool.py113-124:
load_from_disk(), the contents of MEMORY.md and USER.md are read and captured into _system_prompt_snapshot tools/memory_tool.py132-149memory tool update the files on disk immediately using atomic_replace and file locks tools/memory_tool.py36-47 but do not modify the current session's system prompt snapshot.§ delimiter format, the tool detects "drift" via _drift_error and refuses to overwrite, saving a backup to prevent data loss tools/memory_tool.py83-111The agent performs background memory and skill reviews via spawn_background_review agent/background_review.py1-17 After a turn, a daemon thread forks the AIAgent and replays the conversation to evaluate if new memories or skills should be created agent/background_review.py3-9 This process uses a restricted toolset limited to memory and skill_manage agent/background_review.py12-13
Title: Memory Persistence Flow
Sources: tools/memory_tool.py55-142 tools/memory_tool.py78-82 tools/memory_tool.py83-111 agent/background_review.py1-17
Sessions track conversational context and metadata. A session is identified by a unique ID and associated with a SessionSource describing its origin gateway/session.py148-180
SessionSource and Context InjectionEach session tracks its origin via the SessionSource dataclass gateway/session.py148-180:
platform: Origin (e.g., LOCAL, TELEGRAM, DISCORD) gateway/session.py158chat_id: Unique identifier for the chat room or DM gateway/session.py159user_id: The sender's platform-specific ID gateway/session.py162scope_id: Platform-neutral scope discriminator (Discord guild / Slack workspace) gateway/session.py175This information is used to build a session context, which is then injected into the system prompt via build_session_context_prompt so the agent understands its environment gateway/session.py8-9
SessionDBThe SessionDB class in hermes_state.py provides SQLite-backed storage with WAL (Write-Ahead Logging) mode enabled for concurrent access hermes_state.py10-15 If WAL mode fails (e.g., on NFS/SMB/WSL1), it falls back to DELETE mode hermes_state.py166-169
The schema includes several key tables hermes_state.py10-15:
sessions: Stores metadata including model, system_prompt, token_count, and title.messages: Stores individual turns with role, content, and tool_calls.messages_fts: A virtual FTS5 table for fast text search across all session messages hermes_state.py11For CJK (Chinese, Japanese, Korean) language support, the system utilizes a native FTS5 tokenizer extension located in native/fts5_cjk/. This allows the messages_fts table to perform accurate full-text search on CJK characters which do not use whitespace delimiters hermes_state.py11-15
Title: SessionDB Table Schema and Relations
Sources: hermes_state.py10-25 gateway/session.py148-180 hermes_state.py137-164 tests/test_hermes_state.py83-96 tests/test_hermes_state.py132-139
The session_search_tool provides long-term conversation recall using three distinct modes inferred from arguments tools/session_search_tool.py5-30 It operates directly on the SessionDB without LLM calls tools/session_search_tool.py23
query. Uses FTS5 to find matches, dedupes by lineage via _resolve_to_parent, and returns hits with a ±5 message window tools/session_search_tool.py8-11 tools/session_search_tool.py102-134session_id and around_message_id. Returns a specific window of messages centered on an anchor ID tools/session_search_tool.py13-16The tool applies specific logic to ensure relevant results:
cron sources are demoted below interactive sessions to prevent "recall blindness" where repetitive cron vocabulary starves user interactive sessions tools/session_search_tool.py42-50subagent or tool (third-party integrations) are hidden from search by default tools/session_search_tool.py36-40The search tool uses _resolve_to_parent to walk parent_session_id chains to the lineage root tools/session_search_tool.py102-134 It identifies if a lineage has undergone a compression hop, which helps distinguish between compression-split lineages and delegation lineages tools/session_search_tool.py108-111
Sources: tools/session_search_tool.py1-30 tools/session_search_tool.py42-50 tools/session_search_tool.py102-134
Hermes uses parent_session_id chains for context management:
cwd and git_repo_root from the parent to ensure it remains in the correct project sidebar hermes_state.py12 tests/test_hermes_state.py142-154/branch) create child sessions marked with _branched_from in model_config hermes_state.py135-143The SessionStore in the gateway manages the lifecycle of remote sessions gateway/session.py1-9
_AUTO_CONTINUE_FRESHNESS_SECS_DEFAULT) determines if a session interrupted by a restart should be auto-resumed gateway/session.py31-37resume_pending=True. The next user message auto-resumes from the existing transcript, injecting a build_resume_recovery_note to inform the agent of the interruption tests/gateway/test_restart_resume_pending.py1-12 tests/gateway/test_restart_resume_pending.py154-158The hermes backup command creates a zip archive of the ~/.hermes/ directory hermes_cli/backup.py4-9
.db-wal, .db-shm, and .db-journal are skipped to avoid torn restores hermes_cli/backup.py71-83 Large regeneratable directories like .venv, node_modules, and .cache are also excluded to keep backup sizes manageable hermes_cli/backup.py49-69hermes import command specifically skips volatile runtime files like gateway_state.json and gateway.pid to ensure a clean boot on the target environment hermes_cli/backup.py116-122Sources: hermes_state.py10-15 hermes_state.py135-143 hermes_cli/backup.py49-83 gateway/session.py31-37 tests/gateway/test_restart_resume_pending.py1-26 tests/test_hermes_state.py142-154
Refresh this wiki
This wiki was recently refreshed. Please wait 4 days to refresh again.