136 lines
4.7 KiB
Python
136 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import os
|
|
|
|
def extract_assistant_turns(session_file):
|
|
"""Extract user-assistant pairs from a session file."""
|
|
conversation_pairs = []
|
|
|
|
try:
|
|
with open(session_file, 'r') as f:
|
|
lines = f.readlines()
|
|
|
|
messages = []
|
|
for line in lines:
|
|
try:
|
|
data = json.loads(line.strip())
|
|
if data.get('type') == 'message' and 'message' in data:
|
|
messages.append(data['message'])
|
|
except json.JSONDecodeError:
|
|
continue
|
|
|
|
# Group messages into user-assistant pairs
|
|
i = 0
|
|
while i < len(messages):
|
|
if messages[i].get('role') == 'user':
|
|
user_msg = messages[i]
|
|
# Look for the next assistant message
|
|
j = i + 1
|
|
while j < len(messages) and messages[j].get('role') != 'assistant':
|
|
j += 1
|
|
|
|
if j < len(messages) and messages[j].get('role') == 'assistant':
|
|
assistant_msg = messages[j]
|
|
|
|
# Extract text content from both messages
|
|
user_text = ""
|
|
assistant_text = ""
|
|
|
|
# Extract user message text
|
|
if 'content' in user_msg:
|
|
for content in user_msg['content']:
|
|
if content.get('type') == 'text':
|
|
user_text += content.get('text', '')
|
|
|
|
# Extract assistant message text (skip thinking blocks)
|
|
if 'content' in assistant_msg:
|
|
for content in assistant_msg['content']:
|
|
if content.get('type') == 'text':
|
|
assistant_text += content.get('text', '')
|
|
|
|
if user_text.strip() and assistant_text.strip():
|
|
conversation_pairs.append({
|
|
'user': user_text.strip(),
|
|
'assistant': assistant_text.strip()
|
|
})
|
|
|
|
i = j + 1
|
|
else:
|
|
i += 1
|
|
else:
|
|
i += 1
|
|
|
|
except Exception as e:
|
|
print(f"Error processing {session_file}: {e}")
|
|
return []
|
|
|
|
# Return last 10 pairs
|
|
return conversation_pairs[-10:]
|
|
|
|
def send_to_memory_hook(pairs):
|
|
"""Send conversation pairs to the auto-memory hook."""
|
|
script_path = "/home/wdjones/.openclaw/workspace/tools/auto-memory-hook.py"
|
|
|
|
for pair in pairs:
|
|
try:
|
|
payload = {
|
|
"user": pair['user'],
|
|
"assistant": pair['assistant'],
|
|
"agent_id": "case",
|
|
"session": "main"
|
|
}
|
|
|
|
json_payload = json.dumps(payload)
|
|
|
|
# Send to the memory hook script
|
|
result = subprocess.run(
|
|
['python3', script_path],
|
|
input=json_payload,
|
|
text=True,
|
|
capture_output=True
|
|
)
|
|
|
|
if result.returncode != 0:
|
|
print(f"Error from auto-memory-hook.py: {result.stderr}")
|
|
else:
|
|
print(f"Processed pair: {len(pair['user'])} user chars, {len(pair['assistant'])} assistant chars")
|
|
|
|
except Exception as e:
|
|
print(f"Error sending to memory hook: {e}")
|
|
|
|
def main():
|
|
# Find the most recent session file (excluding current session)
|
|
sessions_dir = "/home/wdjones/.openclaw/agents/main/sessions/"
|
|
|
|
# Get session files sorted by modification time
|
|
session_files = []
|
|
for filename in os.listdir(sessions_dir):
|
|
if filename.endswith('.jsonl') and not filename.endswith('.lock'):
|
|
filepath = os.path.join(sessions_dir, filename)
|
|
mtime = os.path.getmtime(filepath)
|
|
session_files.append((mtime, filepath))
|
|
|
|
session_files.sort(key=lambda x: x[0], reverse=True)
|
|
|
|
if len(session_files) < 2:
|
|
print("Need at least 2 session files to avoid current session")
|
|
return
|
|
|
|
# Use second most recent (avoiding current session)
|
|
session_file = session_files[1][1]
|
|
print(f"Processing session file: {session_file}")
|
|
|
|
# Extract assistant turns
|
|
pairs = extract_assistant_turns(session_file)
|
|
print(f"Extracted {len(pairs)} conversation pairs")
|
|
|
|
if pairs:
|
|
send_to_memory_hook(pairs)
|
|
print("Sent pairs to auto-memory-hook.py")
|
|
else:
|
|
print("No conversation pairs found")
|
|
|
|
if __name__ == "__main__":
|
|
main() |