- Python buffers stdout when running as systemd service (no TTY)
- This prevented journalctl from showing real-time turn captures
- Added Environment='PYTHONUNBUFFERED=1' to disable buffering
- Now shows '✅ Turn N (role) → Qdrant' in real-time via journalctl -f
Fixes issue where watcher captured turns but only logged on restart.
3.6 KiB
3.6 KiB
Changelog - openclaw-true-recall-base
All notable changes to this project will be documented in this file.
[v1.4] - 2026-03-13
Fixed
Real-Time Logging Not Visible in journalctl
Error: Watcher was capturing turns to Qdrant but journalctl -u mem-qdrant-watcher -f showed no output between restarts.
Root Cause:
- Python buffers stdout when not connected to a TTY (systemd service)
print()statements in the watcher were buffered, not flushed- Logs only appeared on service restart when buffer was flushed
Impact: Impossible to monitor real-time capture status, difficult to debug
Fix:
- Added
Environment="PYTHONUNBUFFERED=1"to systemd service file - This disables Python's stdout buffering, forcing immediate flush
Changed Files:
watcher/mem-qdrant-watcher.service- Added PYTHONUNBUFFERED environment variable
Validation:
journalctl -u mem-qdrant-watcher -f
# Now shows: ✅ Turn 170 (assistant) → Qdrant (in real-time)
[v1.3] - 2026-03-10
Fixed
Critical: Crash Loop on Deleted Session Files
Error: FileNotFoundError: [Errno 2] No such file or directory: '/root/.openclaw/agents/main/sessions/daccff90-f889-44fa-ba8b-c8d7397e5241.jsonl'
Root Cause:
- OpenClaw deletes session
.jsonlfiles when/newor/resetis called - The watcher opened the file before checking existence
- Between file detection and opening, the file was deleted
- This caused unhandled
FileNotFoundError→ crash → systemd restart
Impact: 2,551 restarts in 24 hours
Original Code (v1.2):
# Track file handle for re-opening
f = open(session_file, 'r') # CRASH HERE if file deleted
f.seek(last_position)
try:
while running:
if not session_file.exists(): # Check happens AFTER crash
...
Fix (v1.3):
# Check file exists before opening (handles deleted sessions)
if not session_file.exists():
print(f"Session file gone: {session_file.name}, looking for new session...", file=sys.stderr)
return None
# Track file handle for re-opening
try:
f = open(session_file, 'r')
f.seek(last_position)
except FileNotFoundError:
print(f"Session file removed during open: {session_file.name}", file=sys.stderr)
return None
Embedding Token Overflow
Error: Ollama API error 400: {"StatusCode":400,"Status":"400 Bad Request","error":"prompt too long; exceeded max context length by 4 tokens"}
Root Cause:
- The embedding model
snowflake-arctic-embed2has a 4,096 token limit (~16K chars) - Long messages were sent to embedding without truncation
- The watcher's
get_embedding()call passed fullturn['content']
Impact: Failed embedding generation, memory loss for long messages
Fix:
- Added
chunk_text()function to split long content into 6,000 char overlapping chunks - Each chunk gets its own Qdrant point with
chunk_indexandtotal_chunksmetadata - Overlap (200 chars) ensures search continuity
- No data loss - all content stored
Changed
store_to_qdrant()now handles multiple chunks per turn- Each chunk stored with metadata:
chunk_index,total_chunks,full_content_length
[v1.2] - 2026-02-26
Fixed
- Session rotation bug - added inactivity detection (30s threshold)
- Improved file scoring to properly detect new sessions on
/newor/reset
[v1.1] - 2026-02-25
Added
- 1-second mtime polling for session rotation
[v1.0] - 2026-02-24
Added
- Initial release
- Real-time monitoring of OpenClaw sessions
- Automatic embedding via local Ollama (snowflake-arctic-embed2)
- Storage to Qdrant
memories_trcollection