Spaces:
Sleeping
Sleeping
| from fastmcp import FastMCP | |
| import chromadb | |
| from chromadb.utils import embedding_functions | |
| from datetime import datetime | |
| import os | |
| import shutil | |
| from huggingface_hub import HfApi, snapshot_download | |
| # --- КОНФИГУРАЦИЯ --- | |
| # Локальная временная папка (внутри контейнера) | |
| LOCAL_DB_PATH = "/app/chroma_db_cache" | |
| # Твой личный сейф для памяти | |
| REPO_ID = "LevinAleksey/neuron-brain-storage" | |
| # Токен берется из Secrets спейса (убедись, что добавил HF_TOKEN) | |
| HF_TOKEN = os.environ.get("HF_TOKEN") | |
| # --- ЛОГИКА СИНХРОНИЗАЦИИ (ОБЛАКО <-> СЕРВЕР) --- | |
| api = HfApi(token=HF_TOKEN) | |
| def pull_memory(): | |
| """Скачиваем память из Dataset при старте сервера""" | |
| print(f"📥 PULL: Подключаюсь к хранилищу {REPO_ID}...") | |
| try: | |
| # Проверка: если репозиторий пустой, не пытаемся качать | |
| if not api.repo_info(repo_id=REPO_ID, repo_type="dataset").sha: | |
| print("⚠️ Репозиторий памяти пуст. Начинаем с чистого листа.") | |
| return | |
| # Чистим локальный кэш перед загрузкой во избежание конфликтов | |
| if os.path.exists(LOCAL_DB_PATH): | |
| shutil.rmtree(LOCAL_DB_PATH) | |
| # Скачиваем файлы базы данных | |
| snapshot_download( | |
| repo_id=REPO_ID, | |
| repo_type="dataset", | |
| local_dir=LOCAL_DB_PATH, | |
| token=HF_TOKEN, | |
| allow_patterns=["chroma*"] # Качаем только файлы базы | |
| ) | |
| print("✅ PULL: Память успешно восстановлена!") | |
| except Exception as e: | |
| print(f"ℹ️ Инфо (первый запуск или ошибка): {e}") | |
| def push_memory(reason="Auto-save"): | |
| """Отправляем обновления памяти обратно в Dataset""" | |
| print(f"☁️ PUSH: Синхронизация с облаком ({reason})...") | |
| try: | |
| api.upload_folder( | |
| folder_path=LOCAL_DB_PATH, | |
| repo_id=REPO_ID, | |
| repo_type="dataset", | |
| path_in_repo=".", | |
| commit_message=f"Memory Sync: {reason}", | |
| token=HF_TOKEN | |
| ) | |
| print("✅ PUSH: Знания надежно сохранены в Dataset!") | |
| except Exception as e: | |
| print(f"❌ Ошибка сохранения в облако: {e}") | |
| # 1. СТАРТ: Восстанавливаем память | |
| pull_memory() | |
| # 2. ИНИЦИАЛИЗАЦИЯ: Подключаем ChromaDB | |
| chroma_client = chromadb.PersistentClient(path=LOCAL_DB_PATH) | |
| emb_fn = embedding_functions.SentenceTransformerEmbeddingFunction( | |
| model_name="all-MiniLM-L6-v2" | |
| ) | |
| collection = chroma_client.get_or_create_collection( | |
| name="architect_memory", | |
| embedding_function=emb_fn | |
| ) | |
| # 3. СЕРВЕР MCP | |
| mcp = FastMCP("Neuron_Architect_Brain") | |
| # --- ИНСТРУМЕНТЫ (TOOLS) --- | |
| def learn_update(project: str, summary: str, details: str = ""): | |
| """ | |
| [ВАЖНО] Используй этот инструмент, чтобы ЗАПОМНИТЬ архитектурные изменения. | |
| project: имя проекта (School, Clinic, etc.) | |
| summary: суть изменений | |
| details: технические детали или код | |
| """ | |
| timestamp = datetime.now().isoformat() | |
| text_chunk = f"UPDATE: {timestamp}\nPROJECT: {project}\nSUMMARY: {summary}\nDETAILS: {details}" | |
| # 1. Сохраняем локально | |
| collection.add( | |
| documents=[text_chunk], | |
| metadatas=[{"project": project, "type": "update", "timestamp": timestamp}], | |
| ids=[f"{project}_{datetime.now().timestamp()}"] | |
| ) | |
| # 2. Сохраняем в облако (Dataset) | |
| push_memory(f"Update for {project}") | |
| return f"✅ Запомнил и синхронизировал с репозиторием {REPO_ID}" | |
| def recall_context(query: str, project: str = None): | |
| """ | |
| Используй этот инструмент, чтобы ВСПОМНИТЬ прошлые решения. | |
| """ | |
| where_filter = {"project": project} if project else None | |
| results = collection.query( | |
| query_texts=[query], | |
| n_results=3, | |
| where=where_filter | |
| ) | |
| if not results['documents'] or not results['documents'][0]: | |
| return "В памяти ничего не найдено по этому запросу." | |
| return "\n---\n".join(results['documents'][0]) | |
| if __name__ == "__main__": | |
| mcp.run(transport="sse") |