Initial commit: pi_mcps monorepo with BigMind MCP server
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
"""Auto-close stale sessions older than 24 hours."""
|
||||
import logging
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from bigmind.db import db
|
||||
|
||||
logger = logging.getLogger("BigMindAutoClose")
|
||||
|
||||
STALE_THRESHOLD_HOURS = 24
|
||||
|
||||
|
||||
def auto_close_stale_sessions(user_id: str) -> int:
|
||||
"""
|
||||
Close any open sessions for this user that are older than 24 hours.
|
||||
Returns the number of sessions auto-closed.
|
||||
"""
|
||||
cutoff = (
|
||||
datetime.now(timezone.utc) - timedelta(hours=STALE_THRESHOLD_HOURS)
|
||||
).isoformat()
|
||||
|
||||
with db() as conn:
|
||||
stale = conn.execute(
|
||||
"""SELECT id, started_at FROM sessions
|
||||
WHERE user_id=? AND ended_at IS NULL AND started_at < ?""",
|
||||
(user_id, cutoff),
|
||||
).fetchall()
|
||||
|
||||
for session in stale:
|
||||
conn.execute(
|
||||
"""UPDATE sessions
|
||||
SET ended_at=CURRENT_TIMESTAMP,
|
||||
one_liner='[auto-closed — session exceeded 24h]',
|
||||
outcome='Session automatically closed after exceeding 24h without a proper close call.'
|
||||
WHERE id=?""",
|
||||
(session["id"],),
|
||||
)
|
||||
logger.info(
|
||||
"Auto-closed stale session %s (started %s)",
|
||||
session["id"],
|
||||
session["started_at"],
|
||||
)
|
||||
|
||||
return len(stale)
|
||||
|
||||
|
||||
def close_orphaned_sessions(user_id: str, keep_session_id: str) -> list[str]:
|
||||
"""
|
||||
Close all open sessions for this user EXCEPT the specified keep_session_id.
|
||||
Returns the list of session IDs that were closed.
|
||||
|
||||
Use this to clean up orphaned sessions from crashed IDEs, dead VS Code
|
||||
windows, or any parallel session that was never properly closed.
|
||||
"""
|
||||
with db() as conn:
|
||||
orphans = conn.execute(
|
||||
"""SELECT id, started_at FROM sessions
|
||||
WHERE user_id=? AND ended_at IS NULL AND id != ?""",
|
||||
(user_id, keep_session_id),
|
||||
).fetchall()
|
||||
|
||||
closed_ids = []
|
||||
for session in orphans:
|
||||
conn.execute(
|
||||
"""UPDATE sessions
|
||||
SET ended_at=CURRENT_TIMESTAMP,
|
||||
one_liner='[orphaned — closed by memory_close_stale_sessions]',
|
||||
outcome='Session was open but never properly closed (IDE crash or forgotten). Cleaned up manually.'
|
||||
WHERE id=?""",
|
||||
(session["id"],),
|
||||
)
|
||||
closed_ids.append(session["id"])
|
||||
logger.info(
|
||||
"Closed orphaned session %s (started %s)",
|
||||
session["id"],
|
||||
session["started_at"],
|
||||
)
|
||||
|
||||
return closed_ids
|
||||
|
||||
|
||||
def restart_server_in_place() -> None:
|
||||
"""
|
||||
Replace the current process image with a fresh copy via os.execv.
|
||||
|
||||
Called from a background thread so the MCP response is delivered first.
|
||||
Inherits stdin/stdout file descriptors so the IDE stdio connection survives.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
time.sleep(0.5)
|
||||
logger.info("🔄 os.execv — replacing process image with fresh copy")
|
||||
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||
|
||||
Reference in New Issue
Block a user