555e282cc4
pi-agent-plugin checks / lint (push) Has been cancelled
pi-agent-plugin checks / test (20) (push) Has been cancelled
pi-agent-plugin checks / test (22) (push) Has been cancelled
pi-agent-plugin checks / build (push) Has been cancelled
TypeScript SDK CI / check_changes (push) Has been cancelled
TypeScript SDK CI / changelog_check (push) Has been cancelled
ci / changelog_check (push) Has been cancelled
ci / check_changes (push) Has been cancelled
ci / build_mem0 (3.10) (push) Has been cancelled
ci / build_mem0 (3.11) (push) Has been cancelled
ci / build_mem0 (3.12) (push) Has been cancelled
CLI Node CI / lint (push) Has been cancelled
CLI Node CI / test (20) (push) Has been cancelled
CLI Node CI / test (22) (push) Has been cancelled
CLI Node CI / build (push) Has been cancelled
CLI Python CI / lint (push) Has been cancelled
CLI Python CI / test (3.10) (push) Has been cancelled
CLI Python CI / test (3.11) (push) Has been cancelled
CLI Python CI / test (3.12) (push) Has been cancelled
CLI Python CI / build (push) Has been cancelled
openclaw checks / lint (push) Has been cancelled
openclaw checks / test (20) (push) Has been cancelled
openclaw checks / test (22) (push) Has been cancelled
openclaw checks / build (push) Has been cancelled
opencode-plugin checks / build (push) Has been cancelled
TypeScript SDK CI / build_ts_sdk (20) (push) Has been cancelled
TypeScript SDK CI / build_ts_sdk (22) (push) Has been cancelled
TypeScript SDK CI / integration_ts_sdk (20) (push) Has been cancelled
TypeScript SDK CI / integration_ts_sdk (22) (push) Has been cancelled
139 lines
3.7 KiB
Python
139 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Session stats tracker for mem0 plugin.
|
|
|
|
Tracks memory adds/searches per session.
|
|
Uses /tmp/mem0_session_stats_$USER.json (single file per user, reset on init).
|
|
|
|
Usage:
|
|
python session_stats.py init # reset for new session
|
|
python session_stats.py add <category> # record a memory write
|
|
python session_stats.py search # record a search
|
|
python session_stats.py report # print summary, clean up temp file
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
from datetime import datetime
|
|
|
|
STATS_FILE = f"/tmp/mem0_session_stats_{os.environ.get('USER', 'default')}.json"
|
|
|
|
|
|
def _load() -> dict:
|
|
if os.path.isfile(STATS_FILE):
|
|
try:
|
|
with open(STATS_FILE) as f:
|
|
return json.load(f)
|
|
except (json.JSONDecodeError, OSError):
|
|
pass
|
|
return {
|
|
"adds": 0,
|
|
"searches": 0,
|
|
"categories": [],
|
|
"category_counts": {},
|
|
"started": datetime.now().isoformat(),
|
|
}
|
|
|
|
|
|
def _save(stats: dict) -> None:
|
|
with open(STATS_FILE, "w") as f:
|
|
json.dump(stats, f)
|
|
|
|
|
|
MAX_RECENT_IDS = 50
|
|
|
|
|
|
def init() -> None:
|
|
_save({
|
|
"adds": 0,
|
|
"searches": 0,
|
|
"categories": [],
|
|
"category_counts": {},
|
|
"recent_ids": [],
|
|
"started": datetime.now().isoformat(),
|
|
})
|
|
|
|
|
|
def record_add(category: str = "", memory_id: str = "") -> None:
|
|
stats = _load()
|
|
stats["adds"] = stats.get("adds", 0) + 1
|
|
if category:
|
|
if category not in stats.get("categories", []):
|
|
stats.setdefault("categories", []).append(category)
|
|
counts = stats.setdefault("category_counts", {})
|
|
counts[category] = counts.get(category, 0) + 1
|
|
if memory_id:
|
|
recent = stats.setdefault("recent_ids", [])
|
|
recent.append({"id": memory_id, "category": category, "ts": datetime.now().isoformat()})
|
|
if len(recent) > MAX_RECENT_IDS:
|
|
stats["recent_ids"] = recent[-MAX_RECENT_IDS:]
|
|
_save(stats)
|
|
|
|
|
|
def record_search() -> None:
|
|
stats = _load()
|
|
stats["searches"] = stats.get("searches", 0) + 1
|
|
_save(stats)
|
|
|
|
|
|
def peek() -> str:
|
|
"""Return current stats as JSON without clearing the file."""
|
|
stats = _load()
|
|
return json.dumps(stats)
|
|
|
|
|
|
def report() -> str:
|
|
stats = _load()
|
|
adds = stats.get("adds", 0)
|
|
searches = stats.get("searches", 0)
|
|
categories = stats.get("categories", [])
|
|
|
|
if adds == 0 and searches == 0:
|
|
return ""
|
|
|
|
parts = []
|
|
category_counts = stats.get("category_counts", {})
|
|
if category_counts:
|
|
breakdown = ", ".join(f"{c} {n}" for c, n in sorted(category_counts.items(), key=lambda x: -x[1]))
|
|
parts.append(f"Session: wrote {adds} memories ({breakdown}), retrieved {searches}")
|
|
else:
|
|
parts.append(f"Session: wrote {adds} memories, retrieved {searches}")
|
|
if categories:
|
|
parts.append(f"Categories touched: {', '.join(categories)}")
|
|
|
|
return ". ".join(parts) + "."
|
|
|
|
|
|
def main() -> int:
|
|
if len(sys.argv) < 2:
|
|
print("Usage: session_stats.py [init|add|search|report]", file=sys.stderr)
|
|
return 1
|
|
|
|
cmd = sys.argv[1]
|
|
if cmd == "init":
|
|
init()
|
|
elif cmd == "add":
|
|
category = sys.argv[2] if len(sys.argv) > 2 else ""
|
|
memory_id = sys.argv[3] if len(sys.argv) > 3 else ""
|
|
record_add(category, memory_id)
|
|
elif cmd == "search":
|
|
record_search()
|
|
elif cmd == "peek":
|
|
print(peek())
|
|
elif cmd == "report":
|
|
result = report()
|
|
if result:
|
|
print(result)
|
|
else:
|
|
print("Session: no memory operations.")
|
|
else:
|
|
print(f"Unknown command: {cmd}", file=sys.stderr)
|
|
return 1
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|