Spaces:
Sleeping
Sleeping
| import base64 | |
| from flask import Flask, render_template, request, jsonify, Response, stream_with_context | |
| from huggingface_hub import login | |
| from vismem.core import SectorMemory | |
| from ai_engine import LocalModelHandler, get_embedding | |
| import json | |
| import os | |
| from werkzeug.utils import secure_filename | |
| app = Flask(__name__) | |
| if os.getenv("HF_TOKEN"): login(token=os.getenv("HF_TOKEN")) | |
| repo_id = os.getenv("LOCAL_MODEL_PATH", "google/gemma-3-1b-it") | |
| local_bot = LocalModelHandler(repo_id=repo_id) | |
| mem_history = SectorMemory("history") | |
| # Future: mem_docs = SectorMemory("documents") | |
| def index(): | |
| return render_template('index.html') | |
| # --- NEW: RAG INGESTION ENDPOINTS --- | |
| def ingest_upload(): | |
| if 'files[]' not in request.files: | |
| return jsonify({"error": "No file part"}), 400 | |
| files = request.files.getlist('files[]') | |
| processed_files = [] | |
| for file in files: | |
| if file.filename == '': continue | |
| filename = secure_filename(file.filename) | |
| # TODO: Implement your novel document parsing logic here | |
| # content = parse_pdf_or_txt(file) | |
| # vec = get_embedding(content) | |
| # mem_docs.write_entry(content, vec) | |
| processed_files.append(filename) | |
| print(f"[RAG] Received file: {filename}") | |
| return jsonify({ | |
| "success": True, | |
| "message": f"Queued {len(processed_files)} documents for vectorization.", | |
| "files": processed_files | |
| }) | |
| def ingest_url(): | |
| data = request.json | |
| target_url = data.get('url') | |
| if not target_url: return jsonify({"error": "No URL provided"}), 400 | |
| # TODO: Implement URL scraping and PDF extraction logic here | |
| print(f"[RAG] Processing URL: {target_url}") | |
| return jsonify({ | |
| "success": True, | |
| "message": f"URL {target_url} added to processing queue." | |
| }) | |
| # ------------------------------------ | |
| def visualize(mem_type): | |
| target = mem_history | |
| # 1. Generate Image | |
| img_bytes = target.to_image_bytes() | |
| b64 = base64.b64encode(img_bytes).decode('utf-8') | |
| # 2. Get Stats | |
| active_count = target.count | |
| text_usage = target.cursor_green | |
| return jsonify({ | |
| "image": f"data:image/png;base64,{b64}", | |
| "stats": f"{active_count} Active Entries", | |
| "usage": f"{text_usage} Bytes Text" | |
| }) | |
| def inspect(mem_type): | |
| content = mem_history.dump_heap_content() | |
| return jsonify({"content": content}) | |
| def chat(): | |
| user_msg = request.json.get('message') | |
| if not user_msg: return jsonify({"error": "Empty"}), 400 | |
| def generate(): | |
| # 1. VECTORIZE USER INPUT | |
| q_vec = get_embedding(user_msg) | |
| # B. Relevant Past History | |
| hist_hits = mem_history.search(q_vec, top_k=2) | |
| long_term_txt = "\n".join([f"[Memory]: {h['text']}" for h in hist_hits if h['score'] > 0.4]) | |
| # C. Recent Conversation | |
| recent_msgs = mem_history.get_recent_entries(n=4) | |
| recent_txt = "\n".join(recent_msgs) | |
| # 3. BUILD PROMPT | |
| system_prompt = f"""You are a helpful AI Assistant with an evolving rule system and knowledge base. | |
| ### RELEVANT MEMORIES (Context from past): | |
| {long_term_txt} | |
| ### CURRENT CONVERSATION: | |
| {recent_txt} | |
| """ | |
| messages = [ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": user_msg} | |
| ] | |
| # 4. STREAM GENERATION | |
| full_response = "" | |
| for chunk in local_bot.chat_stream(messages): | |
| full_response += chunk | |
| yield chunk | |
| # 5. BACKGROUND: WRITE & REFLECT | |
| log_entry = f"User: {user_msg}\nAI: {full_response}" | |
| mem_history.write_entry(log_entry, q_vec) | |
| return Response(stream_with_context(generate()), mimetype='text/plain') | |
| def wipe(): | |
| mem_history.wipe() | |
| return jsonify({"success":True}) | |
| if __name__ == '__main__': | |
| app.run(debug=True, host="0.0.0.0", port=7860) |