Malaji71 commited on
Commit
8c643f8
verified
1 Parent(s): 585c7bd

Create logger.py

Browse files
Files changed (1) hide show
  1. logger.py +168 -0
logger.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import csv
2
+ import os
3
+ from datetime import datetime
4
+ from typing import Dict, List, Optional
5
+
6
+ # Configuraci贸n
7
+ CSV_FILE = "quoota_interactions_log.csv"
8
+ CSV_ENCODING = "utf-8-sig" # UTF-8 con BOM para Excel
9
+
10
+ # Columnas del CSV (en orden exacto)
11
+ CSV_COLUMNS = [
12
+ "timestamp",
13
+ "user_input",
14
+ "stars",
15
+ "coach_notes",
16
+ "conflict_type",
17
+ "confidence",
18
+ "num_sources",
19
+ "unique_tags",
20
+ "sources_raw",
21
+ "logical_works_used",
22
+ "categories_used",
23
+ "faiss_weights_applied",
24
+ "temperature_used",
25
+ "top_p_used",
26
+ "academic_response",
27
+ "practical_response"
28
+ ]
29
+
30
+ def _ensure_csv_exists():
31
+ """Crea el CSV con headers si no existe"""
32
+ if not os.path.exists(CSV_FILE):
33
+ with open(CSV_FILE, 'w', newline='', encoding=CSV_ENCODING) as f:
34
+ writer = csv.DictWriter(f, fieldnames=CSV_COLUMNS)
35
+ writer.writeheader()
36
+
37
+ def _format_list(items: List[str]) -> str:
38
+ """Convierte lista a string separado por | para CSV"""
39
+ return "|".join(items) if items else ""
40
+
41
+ def _format_dict(d: Dict) -> str:
42
+ """Convierte dict a string key:value separado por | para CSV"""
43
+ if not d:
44
+ return ""
45
+ return "|".join([f"{k}:{v}" for k, v in d.items()])
46
+
47
+ def save_interaction(
48
+ user_input: str,
49
+ academic_response: str,
50
+ practical_response: str,
51
+ metadata: Dict,
52
+ temperature_acad: float,
53
+ top_p_acad: float,
54
+ ) -> str:
55
+ """
56
+ Guarda una interacci贸n completa en el CSV.
57
+
58
+ Args:
59
+ user_input: Caso de conflicto introducido
60
+ academic_response: An谩lisis acad茅mico completo (RAG24)
61
+ practical_response: Gu铆a pr谩ctica completa (RAG7)
62
+ metadata: Dict con conflict_type, confidence, num_sources, etc.
63
+ temperature_acad: Temperatura usada en an谩lisis acad茅mico
64
+ top_p_acad: Top-p usado en an谩lisis acad茅mico
65
+
66
+ Returns:
67
+ timestamp: ID 煤nico de la interacci贸n (para actualizar despu茅s)
68
+ """
69
+ _ensure_csv_exists()
70
+
71
+ timestamp = datetime.now().isoformat()
72
+
73
+ # Preparar fila
74
+ row = {
75
+ "timestamp": timestamp,
76
+ "user_input": user_input,
77
+ "stars": "", # Vac铆o inicialmente, se llena con update_rating()
78
+ "coach_notes": "", # Vac铆o inicialmente
79
+ "conflict_type": metadata.get("conflict_type", "unknown"),
80
+ "confidence": metadata.get("confidence", 0),
81
+ "num_sources": metadata.get("num_sources", 0),
82
+ "unique_tags": _format_list(metadata.get("unique_tags", [])),
83
+ "sources_raw": _format_list(metadata.get("sources_raw", [])),
84
+ "logical_works_used": "", # TODO: implementar en agent.py
85
+ "categories_used": _format_list(list(metadata.get("faiss_weights_applied", {}).keys())),
86
+ "faiss_weights_applied": _format_dict(metadata.get("faiss_weights_applied", {})),
87
+ "temperature_used": temperature_acad,
88
+ "top_p_used": top_p_acad,
89
+ "academic_response": academic_response,
90
+ "practical_response": practical_response
91
+ }
92
+
93
+ # Append al CSV
94
+ with open(CSV_FILE, 'a', newline='', encoding=CSV_ENCODING) as f:
95
+ writer = csv.DictWriter(f, fieldnames=CSV_COLUMNS)
96
+ writer.writerow(row)
97
+
98
+ return timestamp
99
+
100
+ def update_rating(
101
+ timestamp: str,
102
+ stars: int,
103
+ coach_notes: str
104
+ ):
105
+ """
106
+ Actualiza stars y coach_notes de una interacci贸n existente.
107
+
108
+ Args:
109
+ timestamp: ID de la interacci贸n (ISO format)
110
+ stars: Puntuaci贸n 1-5
111
+ coach_notes: Comentarios del coach
112
+ """
113
+ if not os.path.exists(CSV_FILE):
114
+ raise FileNotFoundError(f"CSV no existe: {CSV_FILE}")
115
+
116
+ # Leer todas las filas
117
+ rows = []
118
+ with open(CSV_FILE, 'r', newline='', encoding=CSV_ENCODING) as f:
119
+ reader = csv.DictReader(f)
120
+ rows = list(reader)
121
+
122
+ # Buscar y actualizar la fila correspondiente
123
+ found = False
124
+ for row in rows:
125
+ if row["timestamp"] == timestamp:
126
+ row["stars"] = str(stars)
127
+ row["coach_notes"] = coach_notes
128
+ found = True
129
+ break
130
+
131
+ if not found:
132
+ raise ValueError(f"No se encontr贸 interacci贸n con timestamp: {timestamp}")
133
+
134
+ # Reescribir CSV completo
135
+ with open(CSV_FILE, 'w', newline='', encoding=CSV_ENCODING) as f:
136
+ writer = csv.DictWriter(f, fieldnames=CSV_COLUMNS)
137
+ writer.writeheader()
138
+ writer.writerows(rows)
139
+
140
+ def get_stats() -> Dict:
141
+ """
142
+ Retorna estad铆sticas del CSV para debugging.
143
+
144
+ Returns:
145
+ Dict con: total_interactions, avg_stars, conflict_types, etc.
146
+ """
147
+ if not os.path.exists(CSV_FILE):
148
+ return {"total_interactions": 0}
149
+
150
+ with open(CSV_FILE, 'r', newline='', encoding=CSV_ENCODING) as f:
151
+ reader = csv.DictReader(f)
152
+ rows = list(reader)
153
+
154
+ total = len(rows)
155
+ stars_list = [int(r["stars"]) for r in rows if r["stars"].isdigit()]
156
+ avg_stars = sum(stars_list) / len(stars_list) if stars_list else 0
157
+
158
+ conflict_types = {}
159
+ for row in rows:
160
+ ct = row["conflict_type"]
161
+ conflict_types[ct] = conflict_types.get(ct, 0) + 1
162
+
163
+ return {
164
+ "total_interactions": total,
165
+ "avg_stars": round(avg_stars, 2),
166
+ "conflict_types": conflict_types,
167
+ "rated_interactions": len(stars_list)
168
+ }