verifimind-peas / validation_logger.py
YSenseAI's picture
fix: v1.5.5 - Fix newline escaping and datetime deprecation warnings
e878e22 verified
Raw
History Blame Contribute Delete
4.8 kB
"""
Validation Records Logger - Stores validation results for transparency
"""
import json
import os
from datetime import datetime, timezone
from pathlib import Path
RECORDS_FILE = "validation_records.jsonl"
def save_validation_record(validation_data: dict) -> bool:
"""
Save a validation record to the public records file
Stores:
- validation_id
- timestamp
- concept (first 200 chars, anonymized)
- agent_mode
- overall_score
- recommendation
- veto_triggered (if applicable)
"""
try:
# Defensive check
if not isinstance(validation_data, dict):
print(f"Warning: validation_data is not a dict: {type(validation_data)}")
return False
# Extract summary data
record = {
"validation_id": validation_data.get("validation_id", "unknown"),
"timestamp": validation_data.get("timestamp", datetime.now(timezone.utc).isoformat()),
"concept_preview": validation_data.get("concept", "")[:200] + "..." if len(validation_data.get("concept", "")) > 200 else validation_data.get("concept", ""),
"agent_mode": validation_data.get("agent_mode", "unknown"),
}
# Add scores based on mode
if isinstance(validation_data, dict) and "synthesis" in validation_data:
# Full Trinity
synthesis = validation_data["synthesis"]
record.update({
"overall_score": synthesis.get("overall_score", "N/A"),
"recommendation": synthesis.get("recommendation", "N/A"),
"veto_triggered": synthesis.get("veto_triggered", False),
"confidence": synthesis.get("confidence", "N/A"),
})
else:
# Single agent
record.update({
"score": validation_data.get(
next((k for k in validation_data.keys() if 'score' in k.lower()), "score"),
"N/A"
),
"recommendation": validation_data.get("recommendation", "N/A"),
"confidence": validation_data.get("confidence", "N/A"),
})
# Append to file
with open(RECORDS_FILE, "a", encoding="utf-8") as f:
f.write(json.dumps(record) + "\n")
return True
except Exception as e:
print(f"Error saving validation record: {e}")
return False
def load_recent_validations(limit: int = 20) -> list:
"""Load recent validation records"""
try:
if not os.path.exists(RECORDS_FILE):
return []
records = []
with open(RECORDS_FILE, "r", encoding="utf-8") as f:
lines = f.readlines()
# Get last N lines
for line in lines[-limit:]:
try:
records.append(json.loads(line.strip()))
except:
continue
# Reverse to show most recent first
return list(reversed(records))
except Exception as e:
print(f"Error loading validation records: {e}")
return []
def get_statistics() -> dict:
"""Get validation statistics"""
try:
if not os.path.exists(RECORDS_FILE):
return {
"total_validations": 0,
"proceed_count": 0,
"revise_count": 0,
"reject_count": 0,
"veto_count": 0,
"avg_score": 0
}
proceed = revise = reject = veto = 0
scores = []
total = 0
with open(RECORDS_FILE, "r", encoding="utf-8") as f:
for line in f:
try:
record = json.loads(line.strip())
total += 1
rec = record.get("recommendation", "")
if rec == "PROCEED":
proceed += 1
elif rec == "REVISE":
revise += 1
elif rec == "REJECT":
reject += 1
if record.get("veto_triggered"):
veto += 1
if "overall_score" in record:
try:
scores.append(float(record["overall_score"]))
except:
pass
except:
continue
return {
"total_validations": total,
"proceed_count": proceed,
"revise_count": revise,
"reject_count": reject,
"veto_count": veto,
"avg_score": round(sum(scores) / len(scores), 1) if scores else 0
}
except Exception as e:
print(f"Error getting statistics: {e}")
return {"total_validations": 0}