Spaces:
Sleeping
Sleeping
Download memory_cloud.py from maryjscout/error: direct link, hf CLI and curl.
- Browser
- Download file 6.01 kB
-
https://huggingface.co/spaces/maryjscout/error/resolve/main/memory_cloud.py
- Command line
-
hf download hf://spaces/maryjscout/error/memory_cloud.py
-
curl -L -o memory_cloud.py https://huggingface.co/spaces/maryjscout/error/resolve/main/memory_cloud.py
6.01 kB
| """ | |
| memory_cloud.py — conversation long-term memory for Jarvis. | |
| Backend: Firebase Firestore (cloud only). No local fallback — if Firestore | |
| is unavailable, remember() reports failure and recall() returns nothing. | |
| """ | |
| import os | |
| import time | |
| _firestore = None | |
| _firestore_failed = False | |
| def _credentials_path(): | |
| p = os.environ.get("FIREBASE_CREDENTIALS_PATH", "").strip() | |
| if p: | |
| return p | |
| here = os.path.dirname(os.path.abspath(__file__)) | |
| return os.path.join(here, "firebase_service_account.json") | |
| def _init_firestore(): | |
| """Lazily init Firestore once. Returns client or None.""" | |
| global _firestore, _firestore_failed | |
| if _firestore is not None: | |
| return _firestore | |
| if _firestore_failed: | |
| return None | |
| try: | |
| import firebase_admin | |
| from firebase_admin import credentials, firestore | |
| import json as _json | |
| js = (os.environ.get("FIREBASE_CREDENTIALS_JSON") or "").strip() | |
| if js: | |
| info = _json.loads(js) | |
| app = firebase_admin.get_app() if firebase_admin._apps else firebase_admin.initialize_app( | |
| credentials.Certificate(info) | |
| ) | |
| else: | |
| path = _credentials_path() | |
| if not os.path.exists(path): | |
| print("[warn] No firebase_service_account.json - memory disabled (no local fallback).") | |
| _firestore_failed = True | |
| return None | |
| app = firebase_admin.get_app() if firebase_admin._apps else firebase_admin.initialize_app( | |
| credentials.Certificate(path) | |
| ) | |
| _firestore = firestore.client(app) | |
| print("[ok] Firebase Firestore connected for memory.") | |
| return _firestore | |
| except Exception as exc: | |
| print(f"[warn] Firestore unavailable ({exc}) - memory disabled.") | |
| _firestore_failed = True | |
| return None | |
| def remember(content: str) -> bool: | |
| """Save a fact/interaction to Firestore. False if Firestore unavailable.""" | |
| if not content: | |
| return False | |
| db = _init_firestore() | |
| if db is None: | |
| return False | |
| try: | |
| db.collection("jarvis_memory").add({"content": content, "ts": time.time()}) | |
| return True | |
| except Exception as exc: | |
| print(f"[warn] Firestore write failed ({exc}).") | |
| return False | |
| CHAT_DOC = "shared" | |
| CHAT_CAP = 12 | |
| def set_pref(key: str, value: str) -> bool: | |
| """Cross-channel preference (one doc, never raises).""" | |
| try: | |
| db = _init_firestore() | |
| if db is None: | |
| return False | |
| import time as _t | |
| ref = db.collection("jarvis_prefs").document("user") | |
| doc = ref.get() | |
| prefs = ((doc.to_dict() or {}).get("prefs") or {}) if doc.exists else {} | |
| prefs[key] = (value or "")[:300] | |
| ref.set({"prefs": prefs, "updated": _t.time()}) | |
| return True | |
| except Exception as exc: | |
| print(f"[warn] pref save failed ({exc}).") | |
| return False | |
| def get_prefs() -> dict: | |
| try: | |
| db = _init_firestore() | |
| if db is None: | |
| return {} | |
| doc = db.collection("jarvis_prefs").document("user").get() | |
| if doc.exists: | |
| return (doc.to_dict() or {}).get("prefs") or {} | |
| except Exception as exc: | |
| print(f"[warn] pref load failed ({exc}).") | |
| return {} | |
| def chat_load(limit: int = 8) -> list: | |
| """Shared BAT<->Telegram conversation (list of {r,t,ts,src}). Never raises.""" | |
| try: | |
| db = _init_firestore() | |
| if db is None: | |
| return [] | |
| doc = db.collection("jarvis_chat").document(CHAT_DOC).get() | |
| if doc.exists: | |
| msgs = (doc.to_dict() or {}).get("msgs") or [] | |
| msgs = sorted(msgs, key=lambda m: m.get("ts", 0)) | |
| return msgs[-limit:] | |
| except Exception as exc: | |
| print(f"[warn] chat load failed ({exc}).") | |
| return [] | |
| def chat_save(role: str, text: str, src: str = "?") -> bool: | |
| """Append one exchange line to the shared conversation. Never raises.""" | |
| try: | |
| db = _init_firestore() | |
| if db is None or not text: | |
| return False | |
| ref = db.collection("jarvis_chat").document(CHAT_DOC) | |
| doc = ref.get() | |
| msgs = ((doc.to_dict() or {}).get("msgs") or []) if doc.exists else [] | |
| msgs.append({"r": role, "t": text[:500], "ts": time.time(), "src": src}) | |
| msgs = sorted(msgs, key=lambda m: m.get("ts", 0))[-CHAT_CAP:] | |
| ref.set({"msgs": msgs, "updated": time.time()}) | |
| return True | |
| except Exception as exc: | |
| print(f"[warn] chat save failed ({exc}).") | |
| return False | |
| def stats() -> dict: | |
| """Count memory entries: history (jarvis_memory docs), contacts, chat turns. | |
| Never raises — returns zeros when offline.""" | |
| out = {"history": 0, "contacts": 0, "turns": 0} | |
| try: | |
| db = _init_firestore() | |
| if db is None: | |
| return out | |
| try: | |
| out["history"] = len(db.collection("jarvis_memory").get()) | |
| except Exception: | |
| pass | |
| try: | |
| out["contacts"] = len(db.collection("jarvis_contacts").get()) | |
| except Exception: | |
| pass | |
| try: | |
| doc = db.collection("jarvis_chat").document(CHAT_DOC).get() | |
| if doc.exists: | |
| out["turns"] = len((doc.to_dict() or {}).get("msgs") or []) | |
| except Exception: | |
| pass | |
| except Exception: | |
| pass | |
| return out | |
| def recall(limit: int = 10) -> str: | |
| """Return the most recent remembered items as a spoken-friendly string.""" | |
| db = _init_firestore() | |
| if db is None: | |
| return "" | |
| try: | |
| snaps = ( | |
| db.collection("jarvis_memory") | |
| .order_by("ts", direction="DESCENDING") | |
| .limit(limit) | |
| .get() | |
| ) | |
| parts = [s.to_dict().get("content", "") for s in snaps] | |
| return "; ".join(p for p in parts if p) | |
| except Exception as exc: | |
| print(f"[warn] Firestore read failed ({exc}).") | |
| return "" |