Skip to content

Latest commit

 

History

History
414 lines (318 loc) · 14.4 KB

File metadata and controls

414 lines (318 loc) · 14.4 KB

Session Continuity Detector

Detect PC offline gaps across Hermes sessions — Know when your user went to sleep, when they're back from a break, or when it's a brand new day.

Python License Hermes


🎯 Problem Solved

Your PC isn't 24/7. You turn it off at night, on in the morning. Without continuity detection:

Scenario Without This Skill With This Skill
10 PM → 6 AM (8h gap) "Haan Boss, bolo?" "Wapas aaye Boss! 🌙 8h gap tha. Raat ko so gaye the kya?"
2 PM → 4 PM (2h break) "Haan Boss, bolo?" "Welcome back (2h baad). Continue karein?"
First ever session "Haan Boss, bolo?" "Shubh prabhat Boss! 🌅 Pehli baar mil rahe hain?"

📋 The Problem (In Detail)

Real-World Usage Pattern

┌─────────────────────────────────────────────────────────────────┐
│  TYPICAL USER DAY (Not a 24/7 Server)                          │
├─────────────────────────────────────────────────────────────────┤
│  10:30 PM  →  "Gym jaa raha hoon, kal milte hain"              │
│  10:35 PM  →  PC SHUTDOWN                                       │
│  6:30 AM   →  PC BOOT                                           │
│  6:35 AM   →  "Haan bolo" (expects fresh context)              │
└─────────────────────────────────────────────────────────────────┘

What Goes Wrong Without Detection

Issue Impact
False Continuity Agent thinks last message was "5 minutes ago" when it was actually 8+ hours ago
Context Pollution Night conversation context incorrectly applied to morning session
Tone Deaf Responses "Haan Boss, bolo?" at 6 AM after 8h sleep feels robotic
Memory Leakage Personal/evening topics bleed into professional morning context
No Session Boundaries Can't distinguish "continue previous task" vs "start fresh"

Root Cause

  • Hermes runs on user's local PC (not a cloud server)
  • PC powers off/on daily — memory persists but time doesn't
  • Agent has no concept of "wall clock time" between sessions
  • SQLite memory stores timestamps but nothing reads them at session start

✅ The Solution

This skill bridges the gap by:

  1. Reading timestamps from Hermes SQLite memory at session start
  2. Calculating real-world gap (current_time - last_activity_time)
  3. Categorizing intelligently with configurable thresholds:
    • < 4 hoursCONTINUOUS (short break, maintain context)
    • 4-12 hoursBROKEN (overnight, acknowledge gap, fresh greeting)
    • > 12 hoursFRESH (new day, full context reset)
  4. Injecting context into agent prompt automatically
  5. Recording new timestamps for next session

✨ Features

  • 🕐 Automatic gap detection — Compares last message timestamp with current time
  • 🧠 Smart categorization — Continuous / Broken / Fresh with configurable thresholds
  • 💬 Contextual greetings — Hindi/English mixed natural responses
  • 🗄️ Persistent storage — Uses Hermes SQLite memory (survives PC restarts)
  • 🔌 Zero-config plugin — Auto-loads on session start via Hermes hook
  • 🧪 Fully tested — 8 comprehensive test cases covering all edge cases

📦 Installation

Method 1: Hermes Skill Install (Recommended)

# Clone the skill
git clone https://github.com/jojo535/session-continuity-detector.git
cd session-continuity-detector

# Install via Hermes (auto-copies to ~/.hermes/skills/)
hermes skill install .

Method 2: Manual Install

# Copy to your Hermes skills directory
cp -r session-continuity-detector ~/.hermes/skills/core/

# Enable the plugin in config.yaml
echo "
plugins:
  enabled:
    - session-continuity
" >> ~/.hermes/config.yaml

Method 3: As a Standalone Module

pip install -e .

🚀 Quick Start

1. Basic Usage (Python)

from session_continuity import SessionContinuityDetector

detector = SessionContinuityDetector()

# Check continuity at session start
status = detector.check_continuity()

if status.is_fresh:
    print("🌅 Fresh session - new day!")
elif status.is_broken:
    print("🌙 Overnight gap detected")
elif status.is_continuous:
    print("💬 Continuous session")

# Use the suggested greeting
print(status.suggested_greeting)

# Record each user message to keep timestamps fresh
detector.record_message()

2. With Custom Thresholds

detector = SessionContinuityDetector(
    gap_threshold_hours=4.0,      # >4h = likely overnight
    fresh_threshold_hours=12.0,   # >12h = new day
    memory_key_prefix="my_app"    # Custom prefix for multi-app
)

3. CLI Usage

# Check current continuity status
python -m session_continuity --check

# Record activity (call on each user message)
python -m session_continuity --record

# Reset session (for testing)
python -m session_continuity --reset

🔧 Configuration

Add to your ~/.hermes/config.yaml:

plugins:
  enabled:
    - session-continuity
    - a2a
    - spotify

# Optional: Customize thresholds
session_continuity:
  gap_threshold_hours: 4.0
  fresh_threshold_hours: 12.0
  auto_record_on_message: true
  inject_into_prompt: true

Threshold Guide

Threshold Default Meaning
gap_threshold_hours 4.0 Hours after which session = "broken" (overnight)
fresh_threshold_hours 12.0 Hours after which session = "fresh" (new day)

🏗️ Architecture

┌─────────────────────────────────────────────────────────┐
│                    Session Start                         │
└─────────────────────────┬───────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────┐
│              on_session_start Hook                       │
│  (Auto-fired by Hermes plugin system)                   │
└─────────────────────────┬───────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────┐
│          SessionContinuityDetector.check()               │
│  1. Read last_message_ts, last_activity_ts from SQLite  │
│  2. Calculate gap = now - max(last_msg, last_activity)  │
│  3. Categorize: continuous / broken / fresh             │
│  4. Generate contextual greeting                         │
│  5. Record new session_start_ts                          │
└─────────────────────────┬───────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────┐
│              Context Injected to Agent                   │
│  "[SESSION CONTINUITY: BROKEN] Last activity 8h ago.   │
│   Suggested: Wapas aaye Boss! 🌙 8h gap tha..."         │
└─────────────────────────────────────────────────────────┘

Memory Schema (SQLite)

-- Table: hermes_agent_memory
key                              | value    | updated_at
--------------------------------|----------|-----------
session_last_message_ts         | 1787737113 | 1787737113
session_last_activity_ts        | 1787737113 | 1787737113
session_continuity_status       | broken   | 1787737113
session_gap_hours               | 8.00     | 1787737113
session_start_ts                | 1787769513 | 1787769513

📚 API Reference

SessionContinuityDetector

detector = SessionContinuityDetector(
    gap_threshold_hours: float = 4.0,
    fresh_threshold_hours: float = 12.0,
    memory_key_prefix: str = "session"
)

Methods

Method Returns Description
check_continuity() ContinuityStatus Main detection — call at session start
record_activity() None Record generic activity timestamp
record_message() None Record user message (updates both timestamps)
get_last_timestamps() Tuple[int, int] Returns (last_msg_ts, last_activity_ts)
reset_session() None Force fresh session (testing)

ContinuityStatus (dataclass)

@dataclass
class ContinuityStatus:
    is_continuous: bool      # < gap_threshold
    is_broken: bool          # gap_threshold <= gap < fresh_threshold
    is_fresh: bool           # >= fresh_threshold OR first session
    gap_hours: float         # Hours since last activity
    last_message_ts: int     # Unix timestamp
    last_activity_ts: int    # Unix timestamp
    current_ts: int          # Current Unix timestamp
    status_label: str        # "continuous" | "broken" | "fresh"
    suggested_greeting: str  # Ready-to-use greeting string

🧪 Testing

# Run full test suite
python tests/test_session_continuity.py

# Expected output:
# ============================================================
# SESSION CONTINUITY DETECTOR - TEST SUITE
# ============================================================
# 🧪 Test 1: Fresh session (no history)
#    ✅ fresh: Shubh prabhat Boss! 🌅 Pehli baar mil rahe hain?
#
# 🧪 Test 2: Continuous - short gap (30 min)
#    ✅ continuous: Wapas aaye (30 min baad). Kya chal raha hai? (gap: 0.50h)
#
# 🧪 Test 3: Continuous - medium gap (2 hours)
#    ✅ continuous: Welcome back (2.0h baad). Continue karein? (gap: 2.00h)
#
# 🧪 Test 4: Broken - overnight gap (8 hours)
#    ✅ broken: Wapas aaye Boss! 🌙 8.0 hours gap tha. Raat ko so gaye the kya? (gap: 8.00h)
#
# 🧪 Test 5: Fresh - new day gap (16 hours)
#    ✅ fresh: Shubh prabhat Boss! 🌅 16.0 hours pehle baat hui thi. Naya din, naya start? (gap: 16.00h)
#
# 🧪 Test 6: Edge cases at thresholds
#    ✅ 4h exactly: broken
#    ✅ 12h exactly: fresh
#
# 🧪 Test 7: Record message updates timestamps
#    ✅ Timestamps updated: msg=1787737457, activity=1787737457
#
# 🧪 Test 8: Persistence across instances
#    ✅ Persistence works: continuous (gap: 0.0000h)
#
# ============================================================
# ✅ ALL TESTS PASSED!
# ============================================================

📁 Project Structure

session-continuity-detector/
├── scripts/
│   └── session_continuity.py      # Core detector class
├── tests/
│   └── test_session_continuity.py # Test suite (8 tests)
├── docs/
│   └── INTEGRATION.md             # Hermes integration guide
├── examples/
│   ├── basic_usage.py             # Simple example
│   ├── hermes_plugin.py           # Plugin integration
│   └── custom_thresholds.py       # Custom config example
├── SKILL.md                       # Hermes skill manifest
├── README.md                      # This file
├── LICENSE                        # MIT License
├── pyproject.toml                 # Package metadata
└── requirements.txt               # Dependencies (none!)

🔌 Hermes Plugin Integration

The skill includes a ready-to-use Hermes plugin at plugins/session-continuity/:

# plugins/session-continuity/__init__.py
from hermes_cli.plugins import PluginManager
from session_continuity import SessionContinuityDetector

def on_session_start(session_id: str, model: str = "", platform: str = "", **kwargs):
    detector = SessionContinuityDetector()
    status = detector.check_continuity()
    detector.record_message()  # Update timestamp
    
    if status.is_fresh or status.is_broken or (status.is_continuous and status.gap_hours > 0.5):
        return {"context": f"[SESSION CONTINUITY: {status.status_label.upper()}] {status.suggested_greeting}"}
    return {}

def register(plugin_manager: PluginManager):
    plugin_manager.register_hook("on_session_start", on_session_start)
    return True

Auto-loads when added to config.yaml plugins.enabled.


💡 Use Cases

Use Case How It Helps
Daily AI assistant Knows when you wake up vs quick break
Coding sessions Distinguishes "continue where left off" vs "new task"
Learning streaks Tracks actual daily continuity
Multi-device sync Shared memory via Hermes SQLite

🤝 Contributing

  1. Fork the repo
  2. Create feature branch: git checkout -b feature/amazing-feature
  3. Run tests: python tests/test_session_continuity.py
  4. Commit: git commit -m 'Add amazing feature'
  5. Push: git push origin feature/amazing-feature
  6. Open PR

📄 License

MIT License — see LICENSE for details.


🙏 Credits

  • Built for Hermes Agent by Nous Research
  • Uses SQLite for persistent memory
  • Inspired by real-world PC usage patterns (not 24/7 servers!)

📞 Support


Made with ❤️ for Hermes Agent users who actually sleep