import streamlit as st import tempfile import os import logging from pathlib import Path from PIL import Image import io import numpy as np import sys import subprocess import json from pygments import highlight from pygments.lexers import PythonLexer from pygments.formatters import HtmlFormatter import base64 import torch import re import shutil import time from datetime import datetime import streamlit.components.v1 as components import uuid import pandas as pd import plotly.express as px import zipfile import traceback # Set up enhanced logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler()] ) logger = logging.getLogger(__name__) # Model configuration mapping MODEL_CONFIGS = { "DeepSeek-V3-0324": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "DeepSeek"}, "DeepSeek-R1": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "DeepSeek"}, "Llama-4-Scout-17B-16E-Instruct": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "Meta"}, "Llama-4-Maverick-17B-128E-Instruct-FP8": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "Meta"}, "gpt-4o-mini": {"max_tokens": 15000, "param_name": "max_tokens", "api_version": None, "category": "OpenAI"}, "gpt-4o": {"max_tokens": 16000, "param_name": "max_tokens", "api_version": None, "category": "OpenAI"}, "gpt-4.1": {"max_tokens": 32768, "param_name": "max_tokens", "api_version": None, "category": "OpenAI"}, "gpt-4.1-mini": {"max_tokens": 32768, "param_name": "max_tokens", "api_version": None, "category": "OpenAI"}, "gpt-4.1-nano": {"max_tokens": 32768, "param_name": "max_tokens", "api_version": None, "category": "OpenAI"}, "o3-mini": {"max_completion_tokens": 100000, "param_name": "max_completion_tokens", "api_version": "2024-12-01-preview", "category": "OpenAI"}, "o1": {"max_completion_tokens": 100000, "param_name": "max_completion_tokens", "api_version": "2024-12-01-preview", "category": "OpenAI"}, "o1-mini": {"max_completion_tokens": 66000, "param_name": "max_completion_tokens", "api_version": "2024-12-01-preview", "category": "OpenAI"}, "o1-preview": {"max_tokens": 33000, "param_name": "max_tokens", "api_version": None, "category": "OpenAI"}, "Phi-4-multimodal-instruct": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "Microsoft"}, "Mistral-large-2407": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "Mistral"}, "Codestral-2501": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "Mistral"}, "default": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "Other"} } # Try to import Streamlit Ace try: from streamlit_ace import st_ace ACE_EDITOR_AVAILABLE = True except ImportError: ACE_EDITOR_AVAILABLE = False logger.warning("streamlit-ace not available, falling back to text area") def prepare_api_params(messages, model_name): config = MODEL_CONFIGS.get(model_name, MODEL_CONFIGS["default"]) params = {"messages": messages, "model": model_name} params[config["param_name"]] = config.get(config["param_name"]) return params, config def get_secret(env_var): val = os.environ.get(env_var) if not val: logger.warning(f"Secret '{env_var}' not found") return val def check_password(): correct = get_secret("password") if not correct: st.error("Admin password not configured") return False if "password_entered" not in st.session_state: st.session_state.password_entered = False if not st.session_state.password_entered: pwd = st.text_input("Enter password to access AI features", type="password") if pwd: if pwd == correct: st.session_state.password_entered = True return True else: st.error("Incorrect password") return False return False return True def ensure_packages(): required = { 'manim': '0.17.3', 'Pillow': '9.0.0', 'numpy': '1.22.0', 'transformers': '4.30.0', 'torch': '2.0.0', 'pygments': '2.15.1', 'streamlit-ace': '0.1.1', 'pydub': '0.25.1', 'plotly': '5.14.0', 'pandas': '2.0.0', 'python-pptx': '0.6.21', 'fpdf': '1.7.2', 'matplotlib': '3.5.0', 'seaborn': '0.11.2', 'scipy': '1.7.3', 'huggingface_hub': '0.16.0' } missing = {} for pkg, ver in required.items(): try: __import__(pkg if pkg != 'Pillow' else 'PIL') except ImportError: missing[pkg] = ver if not missing: return True bar = st.progress(0) txt = st.empty() for i, (pkg, ver) in enumerate(missing.items()): bar.progress(i / len(missing)) txt.text(f"Installing {pkg}...") res = subprocess.run([sys.executable, "-m", "pip", "install", f"{pkg}>={ver}"], capture_output=True, text=True) if res.returncode != 0: st.error(f"Failed to install {pkg}") return False bar.progress(1.0) txt.empty() return True def install_custom_packages(pkgs): if not pkgs.strip(): return True, "No packages specified" parts = [p.strip() for p in pkgs.split(",") if p.strip()] if not parts: return True, "No valid packages" sidebar_txt = st.sidebar.empty() bar = st.sidebar.progress(0) results, success = [], True for i, p in enumerate(parts): bar.progress(i / len(parts)) sidebar_txt.text(f"Installing {p}...") res = subprocess.run([sys.executable, "-m", "pip", "install", p], capture_output=True, text=True) if res.returncode != 0: results.append(f"Failed {p}: {res.stderr}") success = False else: results.append(f"Installed {p}") bar.progress(1.0) sidebar_txt.empty() return success, "\n".join(results) @st.cache_resource(ttl=3600) def init_ai_models_direct(): token = get_secret("github_token_api") if not token: st.error("API token not configured") return None try: from azure.ai.inference import ChatCompletionsClient from azure.ai.inference.models import UserMessage from azure.core.credentials import AzureKeyCredential client = ChatCompletionsClient( endpoint="https://models.inference.ai.azure.com", credential=AzureKeyCredential(token) ) return {"client": client, "model_name": "gpt-4o", "last_loaded": datetime.now().isoformat()} except ImportError as e: st.error("Azure AI SDK not installed") logger.error(str(e)) return None def generate_manim_preview(code): objects = [] if "Circle" in code: objects.append("⭕") if "Square" in code: objects.append("🔲") if "MathTex" in code or "Tex" in code: objects.append("📊") if "Text" in code: objects.append("📝") if "Axes" in code: objects.append("📈") icons = "".join(objects) or "🎬" return f"""
Full rendering required for accurate preview