feat(openclaw): strip tracking agent prompt bloat and add 15m deterministic sliding-window compaction
- Disable bootstrap context injection (contextInjection: never) and skill catalog injection (skills: []) on mila_tracker and nutrition_tracker, dropping baseline prompt by 95% (<350 tokens) - Disable reasoning loops on tracking agents (thinkingDefault: off) for instantaneous sub-second execution - Add compact_tracking_sessions.py with deterministic 8-line sliding window (--max-lines 8) requiring 0 LLM tokens - Register automated 15-minute cron job (tracking-session-sliding-window) in OpenClaw gateway - Streamline setup-compaction-cron.sh to sync python scripts directly and manage both 15m and nightly maintenance
This commit is contained in:
@@ -23,6 +23,15 @@ THRESHOLD_EVENT_COUNT = 30
|
||||
CRON_MAX_AGE_HOURS = 48
|
||||
RPC_TIMEOUT_MS = 180000
|
||||
|
||||
# Tracking Channels: Deterministic sliding-window (mila_tracker, nutrition_tracker).
|
||||
# Strict sliding window of ~5-8 events (2-3 turns max), 0 LLM tokens, instant truncation.
|
||||
TRACKING_TARGETS = [
|
||||
("mila_tracker", "agent:mila_tracker:telegram:group:-1004326921510:topic:2796"),
|
||||
("nutrition_tracker", "agent:nutrition_tracker:telegram:group:-1004326921510:topic:2797"),
|
||||
]
|
||||
MAX_TRACKING_EVENTS = 8
|
||||
MAX_TRACKING_LINES = 8
|
||||
|
||||
# Tier A: High-frequency interaction topics (koch, hebamme, shopping).
|
||||
# Deep-compaction keeps a compact summary + latest 2 turns without completely wiping conversational memory.
|
||||
TIER_A_TARGETS = [
|
||||
@@ -117,6 +126,41 @@ def prune_stale_cron_sessions():
|
||||
|
||||
print(f"Cron pruning complete: {total_pruned} sessions pruned, {total_tokens_reclaimed} tokens reclaimed.")
|
||||
|
||||
def compact_tracking_sessions():
|
||||
print("=== Tracking Channels Sliding-Window Maintenance (mila_tracker, nutrition_tracker) ===")
|
||||
for agent, key in TRACKING_TARGETS:
|
||||
db_path = f"/home/node/.openclaw/agents/{agent}/agent/openclaw-agent.sqlite"
|
||||
if not os.path.exists(db_path):
|
||||
continue
|
||||
try:
|
||||
con = sqlite3.connect(db_path, timeout=5.0)
|
||||
row = con.execute("SELECT current_session_id FROM session_nodes WHERE session_key=?", (key,)).fetchone()
|
||||
if not row or not row[0]:
|
||||
con.close()
|
||||
print(f" [{agent}] No active session node found for {key}.")
|
||||
continue
|
||||
sid = row[0]
|
||||
cnt = con.execute("SELECT count(*) FROM transcript_events WHERE session_id=?", (sid,)).fetchone()[0]
|
||||
con.close()
|
||||
|
||||
if cnt > MAX_TRACKING_EVENTS:
|
||||
print(f" [{agent}] Session {key} has {cnt} events (> {MAX_TRACKING_EVENTS}). Truncating to last {MAX_TRACKING_LINES} lines...")
|
||||
cmd = [
|
||||
"openclaw", "sessions", "compact", key,
|
||||
"--agent", agent,
|
||||
"--max-lines", str(MAX_TRACKING_LINES),
|
||||
"--timeout", "30000"
|
||||
]
|
||||
r = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if r.returncode == 0:
|
||||
print(f" ✓ Truncated successfully: {r.stdout.strip()}")
|
||||
else:
|
||||
print(f" ✗ Truncation failed: {r.stderr.strip()}")
|
||||
else:
|
||||
print(f" [{agent}] Session {key} has {cnt} events (<= {MAX_TRACKING_EVENTS}). Clean.")
|
||||
except Exception as e:
|
||||
print(f" ✗ [{agent}] Error during tracking compaction: {e}")
|
||||
|
||||
def compact_tier_a_sessions():
|
||||
print("=== Tier A: Deep-Compaction (koch, hebamme, shopping) ===")
|
||||
for agent, key in TIER_A_TARGETS:
|
||||
@@ -180,7 +224,7 @@ def get_session_metrics(agent, key, sid=None):
|
||||
return 0, 0
|
||||
|
||||
def compact_active_sessions():
|
||||
tier_a_keys = set(t[1] for t in TIER_A_TARGETS)
|
||||
excluded_keys = set(t[1] for t in TIER_A_TARGETS) | set(t[1] for t in TRACKING_TARGETS)
|
||||
print(f"=== Tier B: Running 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:
|
||||
@@ -197,8 +241,8 @@ def compact_active_sessions():
|
||||
tokens = s.get("totalTokens") or 0
|
||||
sid = s.get("sessionId")
|
||||
|
||||
# Skip Tier A agents as they are handled via hard-reset
|
||||
if key in tier_a_keys:
|
||||
# Skip Tier A and Tracking agents as they have dedicated routines
|
||||
if key in excluded_keys:
|
||||
continue
|
||||
|
||||
# Target main sessions and all telegram sessions (topics and direct)
|
||||
@@ -280,6 +324,7 @@ def main():
|
||||
except Exception:
|
||||
pass
|
||||
prune_stale_cron_sessions()
|
||||
compact_tracking_sessions()
|
||||
compact_tier_a_sessions()
|
||||
compact_active_sessions()
|
||||
checkpoint_wal_journals()
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Lightweight sliding-window compaction for OpenClaw tracking channels:
|
||||
- mila_tracker (topic 2796)
|
||||
- nutrition_tracker (topic 2797)
|
||||
|
||||
Maintains a strict sliding window of ~5-8 transcript events (max 2-3 turns).
|
||||
Uses native gateway truncation (--max-lines 8) requiring 0 LLM tokens and 0 external API calls.
|
||||
"""
|
||||
import os
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
MAX_TRACKING_EVENTS = 8
|
||||
MAX_TRACKING_LINES = 8
|
||||
TIMEOUT_MS = 30000
|
||||
|
||||
TRACKING_TARGETS = [
|
||||
("mila_tracker", "agent:mila_tracker:telegram:group:-1004326921510:topic:2796"),
|
||||
("nutrition_tracker", "agent:nutrition_tracker:telegram:group:-1004326921510:topic:2797"),
|
||||
]
|
||||
|
||||
def check_and_compact_tracking():
|
||||
compacted_count = 0
|
||||
skipped_count = 0
|
||||
|
||||
for agent, key in TRACKING_TARGETS:
|
||||
db_path = f"/home/node/.openclaw/agents/{agent}/agent/openclaw-agent.sqlite"
|
||||
if not os.path.exists(db_path):
|
||||
continue
|
||||
try:
|
||||
con = sqlite3.connect(db_path, timeout=5.0)
|
||||
row = con.execute("SELECT current_session_id FROM session_nodes WHERE session_key=?", (key,)).fetchone()
|
||||
if not row or not row[0]:
|
||||
con.close()
|
||||
continue
|
||||
sid = row[0]
|
||||
cnt = con.execute("SELECT count(*) FROM transcript_events WHERE session_id=?", (sid,)).fetchone()[0]
|
||||
con.close()
|
||||
|
||||
if cnt > MAX_TRACKING_EVENTS:
|
||||
print(f"[{agent}] Session {key} has {cnt} events (threshold {MAX_TRACKING_EVENTS}). Truncating to last {MAX_TRACKING_LINES} lines...")
|
||||
cmd = [
|
||||
"openclaw", "sessions", "compact", key,
|
||||
"--agent", agent,
|
||||
"--max-lines", str(MAX_TRACKING_LINES),
|
||||
"--timeout", str(TIMEOUT_MS)
|
||||
]
|
||||
res = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if res.returncode == 0:
|
||||
print(f" ✓ [{agent}] Truncated successfully: {res.stdout.strip()}")
|
||||
compacted_count += 1
|
||||
else:
|
||||
print(f" ✗ [{agent}] Truncation failed: {res.stderr.strip()}", file=sys.stderr)
|
||||
else:
|
||||
skipped_count += 1
|
||||
except Exception as e:
|
||||
print(f"[{agent}] Error checking session: {e}", file=sys.stderr)
|
||||
|
||||
if compacted_count > 0:
|
||||
print(f"Tracking maintenance: {compacted_count} sessions truncated, {skipped_count} within window.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
check_and_compact_tracking()
|
||||
Reference in New Issue
Block a user