Files
Cortex-Inara/cortex/session_store.py
Scott Idem 2f675ee4bf Initial commit — Cortex API + Inara identity
Cortex: FastAPI backend serving Inara via Claude/Gemini CLI backends.
Includes SSE streaming chat, session persistence, Google Chat webhook
handler, and Docker support.

Inara: Identity files (persona, soul, protocols, memory, context tiers)
mounted read-only into the container at runtime.

Features in initial cut:
- /chat endpoint with SSE keepalive + LLM fallback
- Session store with rolling history window
- Markdown rendering, copy-to-clipboard, links open in new tab
- Stacked right-column input controls (height selector, enter toggle,
  note mode with public/private) — semi-hidden until textarea grows
- /note endpoint for injecting public context into session history
- Docker Compose config (local dev runs natively; Docker for server)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 03:41:00 -05:00

51 lines
1.4 KiB
Python

import json
from pathlib import Path
from datetime import datetime
from config import settings
def _path(session_id: str) -> Path:
d = settings.sessions_path()
d.mkdir(parents=True, exist_ok=True)
return d / f"{session_id}.json"
def load(session_id: str) -> list[dict]:
path = _path(session_id)
if not path.exists():
return []
return json.loads(path.read_text()).get("messages", [])
def save(session_id: str, messages: list[dict]) -> None:
path = _path(session_id)
existing = json.loads(path.read_text()) if path.exists() else {}
# Enforce rolling window
windowed = messages[-settings.max_history_messages:]
path.write_text(json.dumps({
"session_id": session_id,
"created": existing.get("created", datetime.now().isoformat()),
"updated": datetime.now().isoformat(),
"messages": windowed,
}, indent=2))
def list_all() -> list[dict]:
d = settings.sessions_path()
if not d.exists():
return []
results = []
for f in sorted(d.glob("*.json"), key=lambda p: p.stat().st_mtime, reverse=True):
try:
data = json.loads(f.read_text())
results.append({
"session_id": data["session_id"],
"updated": data.get("updated"),
"message_count": len(data.get("messages", [])),
})
except Exception:
pass
return results