fix(openclaw): harden session compaction cron against stale token metadata and enable user compaction notices
This commit is contained in:
@@ -36,9 +36,11 @@ import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
THRESHOLD_TOKENS = 25000
|
||||
THRESHOLD_TOKENS = 20000
|
||||
THRESHOLD_TRANSCRIPT_BYTES = 300000
|
||||
THRESHOLD_EVENT_COUNT = 40
|
||||
CRON_MAX_AGE_HOURS = 48
|
||||
RPC_TIMEOUT_MS = 120000
|
||||
RPC_TIMEOUT_MS = 180000
|
||||
|
||||
def prewarm_page_cache():
|
||||
print("=== Pre-warming SQLite databases into OS page cache ===")
|
||||
@@ -126,8 +128,30 @@ def prune_stale_cron_sessions():
|
||||
|
||||
print(f"Cron pruning complete: {total_pruned} sessions pruned, {total_tokens_reclaimed} tokens reclaimed.")
|
||||
|
||||
def get_session_metrics(agent, key, sid=None):
|
||||
db_path = f"/home/node/.openclaw/agents/{agent}/agent/openclaw-agent.sqlite"
|
||||
if not os.path.exists(db_path):
|
||||
return 0, 0
|
||||
try:
|
||||
con = sqlite3.connect(db_path, timeout=5.0)
|
||||
cur = con.cursor()
|
||||
if not sid:
|
||||
row = cur.execute("SELECT current_session_id FROM session_nodes WHERE session_key=?", (key,)).fetchone()
|
||||
sid = row[0] if row else None
|
||||
if not sid:
|
||||
con.close()
|
||||
return 0, 0
|
||||
ev_cnt, ev_bytes = cur.execute(
|
||||
"SELECT count(*), coalesce(sum(length(event_json)), 0) FROM transcript_events WHERE session_id=?",
|
||||
(sid,)
|
||||
).fetchone()
|
||||
con.close()
|
||||
return ev_cnt, ev_bytes
|
||||
except Exception:
|
||||
return 0, 0
|
||||
|
||||
def compact_active_sessions():
|
||||
print(f"=== Running OpenClaw Multi-Agent Compaction (threshold: {THRESHOLD_TOKENS} tokens, LLM summarization) ===")
|
||||
print(f"=== Running OpenClaw Multi-Agent Compaction (threshold: {THRESHOLD_TOKENS} tokens / {THRESHOLD_TRANSCRIPT_BYTES//1024}KB, LLM summarization) ===")
|
||||
res = subprocess.run(["openclaw", "sessions", "--all-agents", "--json"], capture_output=True, text=True)
|
||||
if res.returncode != 0:
|
||||
print(f"Failed to list sessions: {res.stderr}")
|
||||
@@ -141,6 +165,7 @@ def compact_active_sessions():
|
||||
key = s.get("key", "")
|
||||
agent = s.get("agentId") or "main"
|
||||
tokens = s.get("totalTokens") or 0
|
||||
sid = s.get("sessionId")
|
||||
|
||||
# Target main sessions and all telegram sessions (topics and direct)
|
||||
is_target = (
|
||||
@@ -149,8 +174,15 @@ def compact_active_sessions():
|
||||
(key.startswith("agent:") and key.endswith(":main"))
|
||||
)
|
||||
if is_target and not key.endswith(":heartbeat"):
|
||||
if tokens >= THRESHOLD_TOKENS:
|
||||
print(f"Compacting {agent} ({tokens} tokens) -> {key}...")
|
||||
ev_cnt, ev_bytes = get_session_metrics(agent, key, sid)
|
||||
needs_compaction = (
|
||||
tokens >= THRESHOLD_TOKENS or
|
||||
ev_bytes >= THRESHOLD_TRANSCRIPT_BYTES or
|
||||
(tokens == 0 and ev_cnt >= THRESHOLD_EVENT_COUNT)
|
||||
)
|
||||
if needs_compaction:
|
||||
stat_str = f"{tokens} tokens" if tokens else f"{ev_bytes//1024}KB / {ev_cnt} events"
|
||||
print(f"Compacting {agent} ({stat_str}) -> {key}...")
|
||||
c_res = subprocess.run(
|
||||
["openclaw", "sessions", "compact", key, "--agent", agent, "--timeout", str(RPC_TIMEOUT_MS)],
|
||||
capture_output=True, text=True
|
||||
@@ -158,10 +190,13 @@ def compact_active_sessions():
|
||||
if c_res.returncode == 0:
|
||||
print(f" ✓ {c_res.stdout.strip()}")
|
||||
compacted += 1
|
||||
elif "Already compacted" in c_res.stderr or "Already compacted" in c_res.stdout:
|
||||
print(f" ✓ Already compacted.")
|
||||
skipped += 1
|
||||
else:
|
||||
print(f" ✗ {c_res.stderr.strip()}; retrying with --max-lines 200 fallback...")
|
||||
print(f" ✗ {c_res.stderr.strip()}; retrying with --max-lines 80 fallback...")
|
||||
fb_res = subprocess.run(
|
||||
["openclaw", "sessions", "compact", key, "--agent", agent, "--max-lines", "200", "--timeout", str(RPC_TIMEOUT_MS)],
|
||||
["openclaw", "sessions", "compact", key, "--agent", agent, "--max-lines", "80", "--timeout", str(RPC_TIMEOUT_MS)],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
if fb_res.returncode == 0:
|
||||
|
||||
Reference in New Issue
Block a user