migrate_hermes: schema-tolerant sessions (у Риты нет last_activity_at), REPO_ROOT fix (импорт стора из scripts/), живые чаты раньше крона в истории
This commit is contained in:
parent
61858a408b
commit
d7ee7d1fcb
1 changed files with 34 additions and 7 deletions
|
|
@ -41,6 +41,9 @@ import sys
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
# корень репо Simbiot (файл лежит в scripts/): импорт стора + OUT-пакет
|
||||||
|
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
MAX_HISTORY_SESSIONS = 40 # сколько последних сессий с диалогом переносим
|
MAX_HISTORY_SESSIONS = 40 # сколько последних сессий с диалогом переносим
|
||||||
MAX_HISTORY_MSGS_PER_SESSION = 40
|
MAX_HISTORY_MSGS_PER_SESSION = 40
|
||||||
MAX_TOTAL_HISTORY_MSGS = 150
|
MAX_TOTAL_HISTORY_MSGS = 150
|
||||||
|
|
@ -135,23 +138,47 @@ def extract_history(hermes_dir: str, out_dir: str) -> dict:
|
||||||
return res
|
return res
|
||||||
db = sqlite3.connect(f"file:{state}?mode=ro", uri=True)
|
db = sqlite3.connect(f"file:{state}?mode=ro", uri=True)
|
||||||
db.row_factory = sqlite3.Row
|
db.row_factory = sqlite3.Row
|
||||||
sessions = db.execute("""
|
# схемы Гермеса различаются по версиям (t-261001124130: у Риты нет
|
||||||
|
# last_activity_at) — толерантный ORDER BY
|
||||||
|
scols = {r[1] for r in db.execute("PRAGMA table_info(sessions)")}
|
||||||
|
if "last_activity_at" in scols:
|
||||||
|
order_expr = "COALESCE(s.last_activity_at, s.started_at)"
|
||||||
|
last_expr = "s.last_activity_at"
|
||||||
|
else:
|
||||||
|
order_expr = "s.started_at"
|
||||||
|
last_expr = "s.started_at"
|
||||||
|
# два прохода (t-261001124130): сначала ЖИВЫЕ чаты (telegram/matrix/cli/
|
||||||
|
# subagent) — крон-сессии (watchdog-пинги, отчёты) шумом съедали весь кап;
|
||||||
|
# крон берём только в остаток лимита
|
||||||
|
sessions = db.execute(f"""
|
||||||
SELECT s.id, s.source, s.chat_type, s.display_name, s.title,
|
SELECT s.id, s.source, s.chat_type, s.display_name, s.title,
|
||||||
s.started_at, s.last_activity_at, COUNT(m.id) n
|
s.started_at, {last_expr} AS last_at, COUNT(m.id) n
|
||||||
FROM sessions s JOIN messages m ON m.session_id = s.id
|
FROM sessions s JOIN messages m ON m.session_id = s.id
|
||||||
WHERE m.active = 1 AND m.role IN ('user', 'assistant')
|
WHERE m.active = 1 AND m.role IN ('user', 'assistant')
|
||||||
|
AND COALESCE(s.source, 'cron') != 'cron'
|
||||||
GROUP BY s.id
|
GROUP BY s.id
|
||||||
HAVING n >= 2
|
HAVING n >= 2
|
||||||
ORDER BY COALESCE(s.last_activity_at, s.started_at) DESC
|
ORDER BY {order_expr} DESC
|
||||||
LIMIT ?""", (MAX_HISTORY_SESSIONS,)).fetchall()
|
LIMIT ?""", (MAX_HISTORY_SESSIONS,)).fetchall()
|
||||||
res["sessions_total"] = len(sessions)
|
cron_sessions = db.execute(f"""
|
||||||
|
SELECT s.id, s.source, s.chat_type, s.display_name, s.title,
|
||||||
|
s.started_at, {last_expr} AS last_at, COUNT(m.id) n
|
||||||
|
FROM sessions s JOIN messages m ON m.session_id = s.id
|
||||||
|
WHERE m.active = 1 AND m.role IN ('user', 'assistant')
|
||||||
|
AND COALESCE(s.source, 'cron') = 'cron'
|
||||||
|
GROUP BY s.id
|
||||||
|
HAVING n >= 2
|
||||||
|
ORDER BY {order_expr} DESC
|
||||||
|
LIMIT ?""", (MAX_HISTORY_SESSIONS,)).fetchall()
|
||||||
|
all_sessions = list(sessions) + list(cron_sessions) # живые первыми
|
||||||
|
res["sessions_total"] = len(all_sessions)
|
||||||
hdir = os.path.join(out_dir, "history")
|
hdir = os.path.join(out_dir, "history")
|
||||||
os.makedirs(hdir, exist_ok=True)
|
os.makedirs(hdir, exist_ok=True)
|
||||||
idx_lines = ["# История диалогов Гермеса → Simbiot",
|
idx_lines = ["# История диалогов Гермеса → Simbiot",
|
||||||
"", "сессии с реальным диалогом (active=1, ≥2 сообщения),",
|
"", "сессии с реальным диалогом (active=1, ≥2 сообщения),",
|
||||||
f"капы: {MAX_HISTORY_MSGS_PER_SESSION}/сессия, {MAX_TOTAL_HISTORY_MSGS} всего", ""]
|
f"капы: {MAX_HISTORY_MSGS_PER_SESSION}/сессия, {MAX_TOTAL_HISTORY_MSGS} всего", ""]
|
||||||
total = 0
|
total = 0
|
||||||
for s in sessions:
|
for s in all_sessions:
|
||||||
if total >= MAX_TOTAL_HISTORY_MSGS:
|
if total >= MAX_TOTAL_HISTORY_MSGS:
|
||||||
idx_lines.append(f"- (усечено: достигнут глобальный кап {MAX_TOTAL_HISTORY_MSGS} сообщений)")
|
idx_lines.append(f"- (усечено: достигнут глобальный кап {MAX_TOTAL_HISTORY_MSGS} сообщений)")
|
||||||
break
|
break
|
||||||
|
|
@ -183,7 +210,7 @@ def extract_history(hermes_dir: str, out_dir: str) -> dict:
|
||||||
total += len(msgs)
|
total += len(msgs)
|
||||||
idx_lines.append(f"- [{title}]({os.path.basename(path)}) — "
|
idx_lines.append(f"- [{title}]({os.path.basename(path)}) — "
|
||||||
f"{s['source'] or '?'}, {len(msgs)} сообщ., "
|
f"{s['source'] or '?'}, {len(msgs)} сообщ., "
|
||||||
f"последнее {datetime.fromtimestamp(s['last_activity_at'] or s['started_at'] or 0, tz=timezone.utc).strftime('%Y-%m-%d')}")
|
f"последнее {datetime.fromtimestamp(s['last_at'] or s['started_at'] or 0, tz=timezone.utc).strftime('%Y-%m-%d')}")
|
||||||
db.close()
|
db.close()
|
||||||
with open(os.path.join(out_dir, "history-index.md"), "w", encoding="utf-8") as f:
|
with open(os.path.join(out_dir, "history-index.md"), "w", encoding="utf-8") as f:
|
||||||
f.write("\n".join(idx_lines) + "\n")
|
f.write("\n".join(idx_lines) + "\n")
|
||||||
|
|
@ -341,7 +368,7 @@ def main():
|
||||||
ap.add_argument("--rag-script", default="/root/rag/rag.py")
|
ap.add_argument("--rag-script", default="/root/rag/rag.py")
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
|
|
||||||
simbiot_repo = os.path.dirname(os.path.abspath(__file__))
|
simbiot_repo = REPO_ROOT
|
||||||
out_dir = args.out or os.path.join(simbiot_repo, "hermes-migration")
|
out_dir = args.out or os.path.join(simbiot_repo, "hermes-migration")
|
||||||
if args.apply:
|
if args.apply:
|
||||||
os.makedirs(out_dir, exist_ok=True)
|
os.makedirs(out_dir, exist_ok=True)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue