Spaces:
Runtime error
Runtime error
Update utils.py
Browse files
utils.py
CHANGED
@@ -1,41 +1,3 @@
|
|
1 |
-
import os
|
2 |
-
import json
|
3 |
-
import faiss
|
4 |
-
import numpy as np
|
5 |
-
from uuid import uuid4
|
6 |
-
from datetime import datetime
|
7 |
-
from sentence_transformers import SentenceTransformer
|
8 |
-
from transformers import AutoTokenizer, AutoModelForCausalLM
|
9 |
-
|
10 |
-
# === Config ===
|
11 |
-
EMBED_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
|
12 |
-
SUMMARIZER_MODEL = "gpt2"
|
13 |
-
MEMORY_INDEX_PATH = "memory.index"
|
14 |
-
MEMORY_TEXTS_PATH = "memory_texts.json"
|
15 |
-
CHAT_LOG_PATH = "chatlog.jsonl"
|
16 |
-
FEEDBACK_PATH = "feedback.jsonl"
|
17 |
-
SUMMARY_TRIGGER = int(os.getenv("SUMMARY_TRIGGER", 100))
|
18 |
-
CHUNK_SIZE = int(os.getenv("SUMMARY_CHUNK", 10))
|
19 |
-
|
20 |
-
# === Load models ===
|
21 |
-
embedder = SentenceTransformer(EMBED_MODEL)
|
22 |
-
summary_tokenizer = AutoTokenizer.from_pretrained(SUMMARIZER_MODEL)
|
23 |
-
summary_model = AutoModelForCausalLM.from_pretrained(SUMMARIZER_MODEL).eval()
|
24 |
-
|
25 |
-
embedding_dim = embedder.get_sentence_embedding_dimension()
|
26 |
-
|
27 |
-
# === Memory state ===
|
28 |
-
try:
|
29 |
-
if os.path.exists(MEMORY_INDEX_PATH) and os.path.exists(MEMORY_TEXTS_PATH):
|
30 |
-
memory_index = faiss.read_index(MEMORY_INDEX_PATH)
|
31 |
-
with open(MEMORY_TEXTS_PATH, "r") as f:
|
32 |
-
memory_texts = json.load(f)
|
33 |
-
else:
|
34 |
-
raise FileNotFoundError
|
35 |
-
except:
|
36 |
-
memory_index = faiss.IndexFlatL2(embedding_dim)
|
37 |
-
memory_texts = []
|
38 |
-
|
39 |
|
40 |
def get_type(schema):
|
41 |
if not isinstance(schema, dict):
|
@@ -60,91 +22,4 @@ def _json_schema_to_python_type(schema, defs):
|
|
60 |
if not isinstance(schema, dict):
|
61 |
return str(type(schema).__name__)
|
62 |
# The rest of the function is assumed to already exist in the original file
|
63 |
-
return "Handled" # Placeholder for safety
|
64 |
-
|
65 |
-
def embed(texts):
|
66 |
-
"""Embed a list of texts into vectors"""
|
67 |
-
return embedder.encode(texts)
|
68 |
-
|
69 |
-
def add_to_memory(text):
|
70 |
-
"""Add a memory item"""
|
71 |
-
vec = embed([text])
|
72 |
-
memory_index.add(np.array(vec))
|
73 |
-
memory_texts.append({
|
74 |
-
"id": str(uuid4()),
|
75 |
-
"text": text,
|
76 |
-
"timestamp": datetime.now().isoformat()
|
77 |
-
})
|
78 |
-
save_memory()
|
79 |
-
if len(memory_texts) > SUMMARY_TRIGGER:
|
80 |
-
summarize_old_memories()
|
81 |
-
|
82 |
-
def retrieve_memories(query, k=3):
|
83 |
-
"""Retrieve top relevant memories"""
|
84 |
-
if memory_index.ntotal == 0:
|
85 |
-
return []
|
86 |
-
vec = embed([query])
|
87 |
-
D, I = memory_index.search(np.array(vec), k)
|
88 |
-
return [memory_texts[i]["text"] for i in I[0] if i < len(memory_texts)]
|
89 |
-
|
90 |
-
def save_memory():
|
91 |
-
"""Save FAISS and text memory to disk"""
|
92 |
-
faiss.write_index(memory_index, MEMORY_INDEX_PATH)
|
93 |
-
with open(MEMORY_TEXTS_PATH, "w") as f:
|
94 |
-
json.dump(memory_texts, f)
|
95 |
-
print(f"[INFO] Memory saved: {len(memory_texts)} items")
|
96 |
-
|
97 |
-
def reset_memory():
|
98 |
-
"""Reset memory entirely"""
|
99 |
-
memory_index.reset()
|
100 |
-
memory_texts.clear()
|
101 |
-
for path in [MEMORY_INDEX_PATH, MEMORY_TEXTS_PATH]:
|
102 |
-
if os.path.exists(path):
|
103 |
-
os.remove(path)
|
104 |
-
|
105 |
-
def summarize_old_memories():
|
106 |
-
"""Replace older entries with a summary to save space"""
|
107 |
-
old = "\n".join(m["text"] for m in memory_texts[:CHUNK_SIZE])
|
108 |
-
inputs = summary_tokenizer(f"Summarize: {old}", return_tensors="pt")
|
109 |
-
output = summary_model.generate(**inputs, max_new_tokens=100)
|
110 |
-
summary = summary_tokenizer.decode(output[0][inputs['input_ids'].shape[-1]:], skip_special_tokens=True)
|
111 |
-
|
112 |
-
memory_texts[:CHUNK_SIZE] = [{
|
113 |
-
"id": str(uuid4()),
|
114 |
-
"text": summary,
|
115 |
-
"timestamp": datetime.now().isoformat()
|
116 |
-
}]
|
117 |
-
memory_index.reset()
|
118 |
-
for mem in memory_texts:
|
119 |
-
vec = embed([mem["text"]])
|
120 |
-
memory_index.add(np.array(vec))
|
121 |
-
save_memory()
|
122 |
-
|
123 |
-
def log_event(file, entry):
|
124 |
-
"""Append an event to a JSONL log"""
|
125 |
-
with open(file, "a") as f:
|
126 |
-
f.write(json.dumps(entry) + "\n")
|
127 |
-
|
128 |
-
def log_chat(user_msg, ai_reply, persona):
|
129 |
-
log_event(CHAT_LOG_PATH, {
|
130 |
-
"timestamp": datetime.now().isoformat(),
|
131 |
-
"persona": persona,
|
132 |
-
"user": user_msg,
|
133 |
-
"assistant": ai_reply
|
134 |
-
})
|
135 |
-
|
136 |
-
def log_feedback(feedback, suggestions):
|
137 |
-
log_event(FEEDBACK_PATH, {
|
138 |
-
"timestamp": datetime.now().isoformat(),
|
139 |
-
"feedback": feedback,
|
140 |
-
"suggestions": suggestions
|
141 |
-
})
|
142 |
-
|
143 |
-
def generate_suggestions(feedback_text):
|
144 |
-
"""Generate suggestions for AI improvement"""
|
145 |
-
prompt = f"Based on this feedback: '{feedback_text}' suggest improvements:"
|
146 |
-
inputs = summary_tokenizer(prompt, return_tensors="pt")
|
147 |
-
outputs = summary_model.generate(**inputs, max_new_tokens=100)
|
148 |
-
suggestions = summary_tokenizer.decode(outputs[0][inputs['input_ids'].shape[-1]:], skip_special_tokens=True)
|
149 |
-
log_feedback(feedback_text, suggestions)
|
150 |
-
return suggestions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
2 |
def get_type(schema):
|
3 |
if not isinstance(schema, dict):
|
|
|
22 |
if not isinstance(schema, dict):
|
23 |
return str(type(schema).__name__)
|
24 |
# The rest of the function is assumed to already exist in the original file
|
25 |
+
return "Handled" # Placeholder for safety
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|