hermes - ✅(Solved) Fix [Bug]: Auto-reset in gateway discards context — parent session ID never stored [3 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#12857Fetched 2026-04-20 12:16:40
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
0
Timeline (top)
cross-referenced ×3referenced ×3commented ×1labeled ×1

Error Message

Additional Logs / Traceback (optional)

Root Cause

Root Cause Analysis (optional)

Fix Action

Fixed

PR fix notes

PR #12869: fix(gateway): persist parent session ID on auto-reset and restore transcript

Description (problem / solution / changelog)

Fixes #12857

Problem: When gateway auto-reset triggers (idle timeout or daily reset), two bugs prevent session continuity:

  1. Parent session ID never persisteddb_end_session_id is computed but never stored in SessionEntry or passed to state.db.create_session(), so the parent link is lost.
  2. Transcript not restored on auto-reset — Even with a parent ID, nothing reads the old transcript back. build_session_context() only injects metadata. Users must manually /resume.

Fix:

Bug 1 (gateway/session.py): Added parent_session_id field to SessionEntry, set it to the old session ID on auto-reset, and pass it to create_session().

Bug 2 (gateway/run.py): After loading the new (empty) session, check for auto-reset + parent ID. If present, load the parent transcript (filtering out session_meta entries), matching the CLI /resume behavior.

Tests: 7 new tests covering parent ID storage, DB persistence, transcript carry-over, and edge cases (no parent, existing history).

Changed files

  • gateway/run.py (modified, +23/-0)
  • gateway/session.py (modified, +7/-0)
  • tests/gateway/test_session_reset_parent_id.py (added, +220/-0)

PR #12890: fix: persist parent session ID and restore transcript on auto-reset

Description (problem / solution / changelog)

Problem

Gateway auto-reset did not persist the parent session ID into SessionEntry, making it impossible to trace historical session relationships after a reset. Additionally, the old session transcript was not automatically restored, causing conversation context loss.

Solution

  • Add parent_session_id field to SessionEntry so the link to the previous session survives across resets.
  • Restore the prior session transcript automatically after auto-reset completes.

Both changes are localized to gateway/run.py and gateway/session.py, keeping the blast radius minimal.

Verification

  • Reviewed the affected code paths in gateway/run.py and gateway/session.py.
  • Confirmed the changes only touch the auto-reset flow and do not affect other session operations.

Closes #12857.

Changed files

  • gateway/run.py (modified, +2908/-788)
  • gateway/session.py (modified, +294/-103)

PR #12897: fix(gateway): persist parent session ID and restore transcript on auto-reset

Description (problem / solution / changelog)

Fixes #12857

Two bugs in gateway auto-reset:

Bug 1: get_or_create_session() computes db_end_session_id but never stores it in SessionEntry or passes it to state.db.create_session(). Fixed by adding parent_session_id field to SessionEntry and forwarding it to DB creation.

Bug 2: After auto-reset, the old transcript is not restored into the new session context (unlike CLI /resume). Fixed by loading the parent session's transcript when the new session has none and was created via auto-reset.

Tests: 8 new tests covering parent ID persistence, DB forwarding, serialization roundtrip, and transcript restore logic.

Changed files

  • gateway/run.py (modified, +21/-3)
  • gateway/session.py (modified, +8/-0)
  • tests/gateway/test_session_reset_parent_id.py (added, +219/-0)

Code Example

- session_reset.mode: both, idle_minutes: 1440, at_hour: 4
- db_end_session_id is a local var in gateway/session.py:get_or_create_session() — never stored in SessionEntry or passed to state.db.create_session()
- SessionEntry dataclass has no parent_session_id field
- gateway/run.py never calls get_messages_as_conversation() on auto-reset

---
RAW_BUFFERClick to expand / collapse

Bug Description

When session_reset triggers in the gateway (idle timeout or daily reset), the session transcript is saved to SQLite but the new session starts with zero conversation history in context. Two bugs are at play:

Bug 1 — Parent session ID never persisted: In gateway/session.py:get_or_create_session(), db_end_session_id is computed as a local variable but never stored — not in the SessionEntry dataclass and not passed to state.db.create_session(). The parent link is completely lost, making it impossible to programmatically find the parent session.

Bug 2 — Transcript not restored on auto-reset: In gateway/run.py, even if the parent session ID were available, nothing reads the old transcript back. build_session_context() only injects metadata. The user must manually run /resume to recover work.

CLI /resume (cli.py:4375) does this correctly — the gateway auto-reset path does not.

Steps to Reproduce

  1. Start a gateway session (e.g. Telegram), accumulate meaningful conversation context with several tool calls
  2. Wait for idle timeout (24h with default idle_minutes: 1440) — or wait for the at_hour: 4 daily reset
  3. Send a new message after the reset fires
  4. Observe: new session has empty context despite intact transcript on disk
  5. Run /resume — full history is recoverable

Expected Behavior

On auto-reset, the gateway should automatically restore the parent session's transcript into the new session's context, so users pick up where they left off without manual interventio

Actual Behavior

◐ Session automatically reset (inactive for 24h). Conversation history cleared. Use /resume to browse and restore a previous session.

New session starts with zero conversation history. User must manually /resume to recover the prior session.

Affected Component

Gateway (Telegram/Discord/Slack/WhatsApp), Agent Core (conversation loop, context compression, memory)

Messaging Platform (if gateway-related)

Telegram

Debug Report

- session_reset.mode: both, idle_minutes: 1440, at_hour: 4
- db_end_session_id is a local var in gateway/session.py:get_or_create_session() — never stored in SessionEntry or passed to state.db.create_session()
- SessionEntry dataclass has no parent_session_id field
- gateway/run.py never calls get_messages_as_conversation() on auto-reset

Operating System

Linux(WSL)

Python Version

3.x

Hermes Version

v0.10.0 (2026.4.16)

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

No response

Proposed Fix (optional)

No response

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

extent analysis

TL;DR

To fix the issue, modify the get_or_create_session function in gateway/session.py to store the db_end_session_id and pass it to state.db.create_session, and update gateway/run.py to read the old transcript back when a new session starts after auto-reset.

Guidance

  • Modify the SessionEntry dataclass to include a parent_session_id field to store the parent session ID.
  • Update the get_or_create_session function to store the db_end_session_id in the SessionEntry object and pass it to state.db.create_session.
  • In gateway/run.py, add a call to get_messages_as_conversation to read the old transcript back when a new session starts after auto-reset, and inject the conversation history into the new session's context.
  • Verify the fix by reproducing the issue and checking that the new session has the correct conversation history after auto-reset.
  • Consider adding error handling to ensure that the parent session ID is correctly retrieved and stored.

Example

# Modified SessionEntry dataclass
class SessionEntry:
    # ... existing fields ...
    parent_session_id: int = None

# Modified get_or_create_session function
def get_or_create_session():
    # ... existing code ...
    db_end_session_id = compute_db_end_session_id()
    session_entry = SessionEntry(parent_session_id=db_end_session_id)
    state.db.create_session(session_entry)
    # ... existing code ...

# Modified gateway/run.py
def build_session_context():
    # ... existing code ...
    if parent_session_id:
        conversation_history = get_messages_as_conversation(parent_session_id)
        # inject conversation history into new session's context
    # ... existing code ...

Notes

The proposed fix assumes that the get_messages_as_conversation function is correctly implemented and returns the conversation history for a given session ID. Additionally, the fix may require modifications to other parts of the codebase to handle cases where the parent session ID is not available or is invalid.

Recommendation

Apply the workaround by modifying the get_or_create_session function and gateway/run.py as described above, as this will allow the gateway to correctly restore the conversation history after auto-reset.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING