import streamlit as st from openai import OpenAI import requests import os import json from streamlit_cookies_manager import EncryptedCookieManager # --- ИНИЦИАЛИЗАЦИЯ ПАМЯТИ --- cookies = EncryptedCookieManager(password="HiperDouble_Full_Control_2026") if not cookies.ready(): st.stop() # --- GOOGLE AUTH --- CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID") CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET") host = st.context.headers.get("Host", "") REDIRECT_URI = f"https://{host}/" if host else "" def get_google_auth_url(): params = {"client_id": CLIENT_ID, "redirect_uri": REDIRECT_URI, "response_type": "code", "scope": "openid email profile", "access_type": "offline", "prompt": "select_account"} return f"https://accounts.google.com/o/oauth2/v2/auth?{'&'.join([f'{k}={v}' for k, v in params.items()])}" if "user_email" not in st.session_state: st.session_state.user_email = cookies.get("saved_email") st.session_state.user_name = cookies.get("saved_name", "Пользователь") if "code" in st.query_params and not st.session_state.user_email: try: res = requests.post("https://oauth2.googleapis.com/token", data={ "code": st.query_params["code"], "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "redirect_uri": REDIRECT_URI, "grant_type": "authorization_code" }).json() token = res.get("access_token") if token: info = requests.get("https://www.googleapis.com/oauth2/v3/userinfo", headers={"Authorization": f"Bearer {token}"}).json() st.session_state.user_email, st.session_state.user_name = info.get("email"), info.get("name") cookies["saved_email"], cookies["saved_name"] = info.get("email"), info.get("name") cookies.save(); st.rerun() except: pass def logout(): cookies["saved_email"], cookies["saved_name"] = "", "" cookies.save() st.session_state.user_email = None st.rerun() # --- ДИЗАЙН И СТИЛИ (CSS) --- st.set_page_config(page_title="HiperDouble AI", page_icon="🧬", layout="wide") st.markdown(""" """, unsafe_allow_html=True) # --- ВХОД --- if not st.session_state.user_email: st.markdown('

HiperDouble AI

', unsafe_allow_html=True) st.markdown(f'
Войти через Google
', unsafe_allow_html=True) st.stop() # --- ЛОГИКА БД --- u_id = st.session_state.user_email.replace('@','_').replace('.','_') DB_FILE = f"chats_db_{u_id}.json" def load_chats(): if os.path.exists(DB_FILE): try: with open(DB_FILE, "r", encoding="utf-8") as f: return json.load(f) or {"Чат 1": []} except: return {"Чат 1": []} return {"Чат 1": []} def save_chats(chats): with open(DB_FILE, "w", encoding="utf-8") as f: json.dump(chats, f, ensure_ascii=False, indent=4) MODELS_CONFIG = { "🌌 HiperAi v2.1 (Grew up)": {"engine": "groq", "key_name": "GROQ_API_KEY3", "model": "llama-3.3-70b-versatile", "identity": "HiperAI v2.1 Grew up."}, "🧠 HiperAI v2.3 (CORTEX)": {"engine": "groq", "key_name": "GROQ_API_KEY", "model": "llama-3.3-70b-versatile", "identity": "HiperAI v2.3 Cortex."}, "🔥 HiperAI v2.1 (ADULT)": {"engine": "groq", "key_name": "GROQ_API_KEY2", "model": "llama-3.1-8b-instant", "identity": "HiperAI v2.1 Adult."}, "🌐 HiperAI v2.2 (NETWORK)": {"engine": "groq", "key_name": "GROQ_API_KEY", "model": "llama-3.1-8b-instant", "identity": "HiperAI v2.2 Network."}, "👶 HiperAI v2.1 (BABY)": {"engine": "titan", "model": "titan-89m", "identity": "HiperAI v2.1 Baby."}, "🚀 HiperAI v2.0 (Test 1)": {"engine": "groq", "key_name": "GROQ_API_KEY", "model": "llama-3.3-70b-versatile", "identity": "HiperAI v2.0 Test."}, "✨ HiperAI v1.1.3 (Stable)": {"engine": "openai", "model": "gpt-4o-mini", "identity": "HiperAI v1.1.3."}, } if "chats" not in st.session_state: st.session_state.chats = load_chats() if "current_chat" not in st.session_state: st.session_state.current_chat = list(st.session_state.chats.keys())[0] if "rename_mode" not in st.session_state: st.session_state.rename_mode = None # --- SIDEBAR (ПОЛНЫЙ ФУНКЦИОНАЛ) --- with st.sidebar: st.markdown(f"👤 **{st.session_state.user_name}**") if st.button("🚪 Выйти", use_container_width=True): logout() st.markdown("---") sel_mod = st.selectbox("🤖 Модель:", list(MODELS_CONFIG.keys())) cfg = MODELS_CONFIG[sel_mod] if st.button("➕ Новый чат", use_container_width=True): new_n = f"Чат {len(st.session_state.chats)+1}" st.session_state.chats[new_n] = [] st.session_state.current_chat = new_n save_chats(st.session_state.chats); st.rerun() if st.button("🗑️ Очистить текущий", use_container_width=True): st.session_state.chats[st.session_state.current_chat] = [] save_chats(st.session_state.chats); st.rerun() st.markdown("---") st.write("📂 Ваши чаты:") for c_name in list(st.session_state.chats.keys()): col_main, col_edit, col_del = st.columns([0.6, 0.2, 0.2]) # Кнопка выбора чата if col_main.button(f"💬 {c_name[:12]}", key=f"sel_{c_name}", use_container_width=True): st.session_state.current_chat = c_name st.rerun() # Кнопка переименования if col_edit.button("✏️", key=f"ed_{c_name}"): st.session_state.rename_mode = c_name # Кнопка удаления if col_del.button("❌", key=f"del_{c_name}"): if len(st.session_state.chats) > 1: del st.session_state.chats[c_name] st.session_state.current_chat = list(st.session_state.chats.keys())[0] save_chats(st.session_state.chats); st.rerun() # Поле для переименования, если выбран этот чат if st.session_state.rename_mode == c_name: new_title = st.text_input("Новое имя:", c_name, key=f"input_{c_name}") if st.button("OK", key=f"ok_{c_name}"): st.session_state.chats[new_title] = st.session_state.chats.pop(c_name) st.session_state.current_chat = new_title st.session_state.rename_mode = None save_chats(st.session_state.chats); st.rerun() # --- ЧАТ --- st.markdown('

HiperDouble AI

', unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) if st.session_state.current_chat in st.session_state.chats: for m in reversed(st.session_state.chats[st.session_state.current_chat]): role, style = ("Вы", "user-bubble") if m['role'] == 'user' else ("HiperAi", "") st.markdown(f"
{role}:
{m['content']}
", unsafe_allow_html=True) # Невидимый блок (180px) st.markdown("
", unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) # ВВОД u_input = st.chat_input("Напишите HiperAI...") if u_input: st.session_state.chats[st.session_state.current_chat].append({"role": "user", "content": u_input}) try: api_key = st.secrets.get(cfg["key_name"]) or os.environ.get(cfg["key_name"], "").strip() if cfg["engine"] == "titan": res_text = "HiperAI Titan активен." elif cfg["engine"] == "openai": client = OpenAI(api_key=st.secrets.get("OPENAI_API_KEY") or os.environ.get("OPENAI_API_KEY")) r = client.chat.completions.create(model=cfg["model"], messages=[{"role":"system","content":cfg['identity']},{"role":"user","content":u_input}]) res_text = r.choices[0].message.content else: resp = requests.post("https://api.groq.com/openai/v1/chat/completions", json={"model": cfg["model"], "messages": [{"role": "system", "content": cfg['identity']}] + st.session_state.chats[st.session_state.current_chat][-6:]}, headers={"Authorization": f"Bearer {api_key}"}, timeout=25).json() res_text = resp['choices'][0]['message']['content'] except: res_text = "⚠️ Ошибка модели." st.session_state.chats[st.session_state.current_chat].append({"role": "assistant", "content": res_text}) save_chats(st.session_state.chats); st.rerun()