| import os |
| import requests |
| import json |
| import re |
| import io |
| import tempfile |
| import base64 |
| from pathlib import Path |
| from datetime import datetime, timedelta, timezone |
| from bs4 import BeautifulSoup |
| from flask import Flask, request, Response, stream_with_context, send_from_directory |
| from supertonic import TTS |
|
|
| |
| |
| |
| app = Flask(__name__, static_folder='.', static_url_path='') |
|
|
| |
| |
| |
| print("Loading RenderLib...") |
| try: |
| from renderlib import RenderLib |
| renderer = RenderLib() |
| print("RenderLib loaded successfully!") |
| except ImportError as e: |
| print(f"RenderLib not installed yet or error: {e}") |
| renderer = None |
|
|
| |
| |
| |
| print("Loading Supertonic TTS Model...") |
| try: |
| tts = TTS(auto_download=True) |
| print("TTS Model loaded successfully!") |
| except Exception as e: |
| print(f"Error initializing TTS: {e}") |
| tts = None |
|
|
| VOICES = ["M1", "M2", "M3", "M4", "M5", "F1", "F2", "F3", "F4", "F5"] |
| LANGUAGES = { |
| "English": "en", "Korean": "ko", "Japanese": "ja", "Arabic": "ar", |
| "Bulgarian": "bg", "Czech": "cs", "Danish": "da", "German": "de", |
| "Greek": "el", "Spanish": "es", "Estonian": "et", "Finnish": "fi", |
| "French": "fr", "Hindi": "hi" |
| } |
| VOICE_STYLES_CACHE = {} |
|
|
| |
| |
| |
| NVIDIA_API_KEY = os.environ.get("NVIDIA_API_KEY", "") |
| INVOKE_URL = "https://integrate.api.nvidia.com/v1/chat/completions" |
|
|
| |
| MODEL_MAPPING = { |
| "Vedika 4.1 Flash": "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", |
| "Vedika 2.5 Balanced": "meta/llama-3.2-90b-vision-instruct", |
| "Vedika 5.6 Pro": "stepfun-ai/step-3.7-flash" |
| } |
|
|
| |
| |
| |
| def analyze_intent(text): |
| text_lower = text.lower() |
| search_keywords = ['news', 'latest', 'today', 'weather', 'price', 'score', 'update', 'current', 'search', 'who won', 'who is', 'what is', 'stock', 'match', 'न्यूज़', 'आज', 'खबर', 'मौसम', 'बताओ'] |
| location_keywords = ['near me', 'my location', 'where am i', 'weather', 'local', 'nearby', 'around me', 'यहाँ', 'मेरे पास', 'लोकेशन'] |
| |
| needs_search = any(kw in text_lower for kw in search_keywords) |
| needs_location = any(kw in text_lower for kw in location_keywords) |
| |
| return needs_search, needs_location |
|
|
| def get_address_from_coords(lat, lon): |
| try: |
| url = f"https://nominatim.openstreetmap.org/reverse?format=json&lat={lat}&lon={lon}" |
| headers = {'User-Agent': 'Vedika_AI_System_by_Divy_Patel'} |
| response = requests.get(url, headers=headers, timeout=5) |
| data = response.json() |
| return data.get('display_name', f"Lat: {lat}, Lon: {lon}") |
| except Exception: |
| return f"Lat: {lat}, Lon: {lon}" |
|
|
| def web_search_scraper(query, num_results=5, user_address=None): |
| results = [] |
| serpapi_key = os.environ.get("SERPAPI_KEY") |
| if not serpapi_key: return results |
| search_query = query |
| if user_address and any(kw in query.lower() for kw in ["near", "nearby", "distance", "local", "weather"]): |
| search_query = f"{query} near {user_address}" |
| try: |
| params = {"engine": "google", "q": search_query, "api_key": serpapi_key, "num": num_results, "hl": "en", "gl": "in"} |
| response = requests.get("https://serpapi.com/search", params=params, timeout=10) |
| data = response.json() |
| if "organic_results" in data: |
| for item in data["organic_results"]: |
| if item.get("title") and item.get("snippet"): |
| results.append({"title": item["title"], "link": item.get("link", ""), "snippet": item["snippet"]}) |
| except Exception: pass |
| return results |
|
|
| def get_live_web_data(query): |
| url = f"https://news.google.com/rss/search?q={query}&hl=en&gl=IN&ceid=IN:en" |
| headers = {"User-Agent": "Mozilla/5.0"} |
| tech_kw = ["ai", "smartphone", "mobile", "tech", "google", "apple", "india", "world", "market"] |
| results = [] |
| try: |
| response = requests.get(url, headers=headers, timeout=6) |
| if response.status_code == 200: |
| soup = BeautifulSoup(response.text, "html.parser") |
| for item in soup.find_all('item'): |
| title = item.title.text if item.title else "" |
| if any(k in title.lower() for k in tech_kw) and "stock" not in title.lower(): |
| results.append({ |
| "title": title, |
| "snippet": f"Pub: {item.pubdate.text if item.pubdate else ''}", |
| "link": item.link.text if item.link else "#" |
| }) |
| if len(results) >= 5: break |
| except Exception: pass |
| return results |
|
|
| |
| |
| |
| def generate_system_prompt(model_name, current_date, location_instruction, custom_prompt, personalization_data=None): |
| base_identity = f"[CRITICAL IDENTITY OVERRIDE]\nName: {model_name}\nCreator/Engineer: Divy Patel\nCurrent Time: {current_date}.{location_instruction}\n\n" |
| |
| |
| memory_instruction = "" |
| if personalization_data: |
| memory_instruction = f""" |
| --- [INTUITIVE INTELLIGENCE: MEMORY LAYER ACTIVE] --- |
| You have access to an "Intuitive Intelligence" memory layer containing persistent user information: |
| {personalization_data} |
| |
| [MEMORY USAGE INSTRUCTIONS]: |
| 1. Use this memory context to personalize your responses and maintain continuity across conversations. |
| 2. Reference stored facts naturally without explicitly mentioning "memory" or "database". |
| 3. Avoid re-asking questions about information already stored in your memory. |
| 4. Build upon known preferences, experiences, and relationships when responding. |
| |
| [MEMORY AUTO-SAVE PROTOCOL - CRITICAL]: |
| - When you learn NEW important facts about the user (preferences, experiences, relationships, goals, etc.), you MUST save them to memory. |
| - To save memory, include this exact format in your response: __MEMORY_ACTION__{{"action": "update_personalization", "email": "user@example.com", "type": "memory", "content": "New fact to save"}}__END_MEMORY_ACTION__ |
| - ONLY trigger memory saves when the personalization toggle is ON (indicated by memory data being present in your prompt). |
| - Save meaningful, lasting information. Do not save trivial or temporary details. |
| - Multiple memory actions can be included if multiple new facts emerge. |
| --- [END MEMORY LAYER] --- |
| """ |
| |
| if custom_prompt: |
| return base_identity + memory_instruction + custom_prompt |
| |
| if model_name == "Vedika 4.1 Flash": |
| return base_identity + memory_instruction + """You are Vedika 4.1 Flash, a fast Omni-modal AI created by Divy Patel. |
| [CRITICAL INSTRUCTION: Format your deep reasoning inside <think> and </think> tags before providing the final answer.] |
| CRITICAL RULES YOU MUST FOLLOW EXACTLY: |
| 1. NO LONG INTRODUCTIONS. Answer directly. |
| 2. If asked for code, provide ONLY the exact working code and a 1-2 line explanation. |
| 3. DO NOT get confused by complex tasks. Break them down into simple, basic steps. |
| 4. Always respect the user. Divy Patel is your creator. |
| 5. Formatting: Use standard Markdown. No fluff.""" |
|
|
| elif model_name == "Vedika 2.5 Balanced": |
| return base_identity + memory_instruction + """You are Vedika 2.5 Balanced, an advanced Vision AI created by Divy Patel. |
| Your goal is to balance deep analytical accuracy with practical, fast solutions. |
| - You specialize in analyzing images and providing well-reasoned, logical breakdowns of visual data. |
| - Write clean, efficient code with necessary comments. |
| - Maintain a helpful, professional tone.""" |
|
|
| elif model_name == "Vedika 5.6 Pro": |
| return base_identity + memory_instruction + """You are Vedika 5.6 Pro, an elite, enterprise-grade AI architect engineered by Divy Patel. |
| [CRITICAL INSTRUCTION: Format your complex architectural reasoning inside <think> and </think> tags before answering.] |
| Your mandate is to deliver highly optimized, production-ready solutions and profound technical insights. |
| - Architecture: Provide scalable, secure, and robust system designs. |
| - Complexity: Handle massive codebases and deep abstractions effortlessly. |
| - Formatting: Meticulously use LaTeX for mathematical/algorithmic complexity (Big O) and structured Markdown tables for comparisons. |
| - Tone: Professional, authoritative, and objective.""" |
|
|
| return base_identity + memory_instruction + "You are Vedika, an AI engineered by Divy Patel. Be helpful and concise." |
|
|
| |
| |
| |
| @app.route('/') |
| def home(): |
| return send_from_directory('.', 'index.html') |
|
|
| @app.route('/api/render', methods=['POST']) |
| def render_content(): |
| if renderer is None: |
| return Response(json.dumps({"error": "RenderLib not available."}), status=500, mimetype='application/json') |
| data = request.get_json() or {} |
| try: |
| result = renderer.render(data.get("subject", "math"), data.get("method", "to_latex"), *(data.get("args", [data.get("expression")] if data.get("expression") else [])), **data.get("kwargs", {})) |
| return Response(json.dumps({"result": result}), mimetype='application/json') |
| except Exception as e: |
| return Response(json.dumps({"error": str(e)}), status=500, mimetype='application/json') |
|
|
| @app.route('/api/chat', methods=['POST']) |
| def chat(): |
| if not NVIDIA_API_KEY: |
| return Response(json.dumps({"error": "NVIDIA_API_KEY missing."}), mimetype='application/json', status=500) |
| |
| data = request.get_json() or {} |
| user_message = data.get("message", "") |
| attachments = data.get("attachments", []) |
| history = data.get("history", []) |
| location = data.get("location") |
| |
| requested_model_name = data.get("model", "Vedika 4.1 Flash") |
| api_model_id = MODEL_MAPPING.get(requested_model_name, MODEL_MAPPING["Vedika 4.1 Flash"]) |
| |
| ist_time = datetime.now(timezone.utc) + timedelta(hours=5, minutes=30) |
| current_date = ist_time.strftime("%A, %d %B %Y, %I:%M %p IST") |
| |
| |
| needs_search, needs_location = analyze_intent(user_message) |
| |
| user_address = None |
| location_instruction = "" |
| if (needs_location or needs_search) and location and location.get('lat'): |
| user_address = get_address_from_coords(location['lat'], location['lng']) |
| location_instruction = f"\n[USER REAL-TIME LOCATION: {user_address}]" |
| |
| system_prompt = generate_system_prompt( |
| model_name=requested_model_name, |
| current_date=current_date, |
| location_instruction=location_instruction, |
| custom_prompt=data.get("system_prompt", None), |
| personalization_data=data.get("personalization_data", None) |
| ) |
|
|
| |
| if needs_search: |
| search_context = "" |
| scraped_data = web_search_scraper(user_message, user_address=user_address) |
| news_data = get_live_web_data(user_message) |
| if scraped_data: |
| search_context += "\n\n--- [LIVE AUTONOMOUS SEARCH] ---\n" + "".join([f"{i+1}. {r['title']}: {r['snippet']}\n" for i, r in enumerate(scraped_data)]) |
| if news_data: |
| search_context += "\n--- [LIVE AUTONOMOUS NEWS] ---\n" + "".join([f"{i+1}. {r['title']}: {r['snippet']}\n" for i, r in enumerate(news_data)]) |
| if search_context: |
| user_message = f"{user_message}\n{search_context}\n[COMMAND: Base your final answer strictly on the real-time facts provided above. Do not mention that you performed a search, just give the answer naturally.]" |
|
|
| messages = [{"role": "system", "content": system_prompt}] |
| |
| for msg in history: |
| if msg == history[-1] and msg.get("role") == "user": continue |
| role = msg.get("role", "user") |
| content = msg.get("content", "") |
| if isinstance(content, list): content = " ".join([i["text"] for i in content if i.get("type") == "text"]) |
| if "Gemma" in content or "DeepMind" in content: continue |
| if content: messages.append({"role": role if role in ["system", "user", "assistant"] else "user", "content": str(content)}) |
|
|
| |
| if attachments: |
| content_payload = [{"type": "text", "text": user_message}] |
| for att in attachments: |
| b64 = att.get("data") |
| att_type = att.get("type") |
| |
| if att_type == "image": |
| content_payload.append({"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{b64}"}}) |
| elif att_type == "video": |
| |
| if requested_model_name == "Vedika 4.1 Flash": |
| content_payload.append({"type": "video_url", "video_url": {"url": f"data:video/mp4;base64,{b64}"}}) |
| messages.append({"role": "user", "content": content_payload}) |
| else: |
| messages.append({"role": "user", "content": user_message}) |
|
|
| |
| payload = { |
| "model": api_model_id, |
| "messages": messages, |
| "stream": True, |
| "top_p": 0.95 |
| } |
| |
| if requested_model_name == "Vedika 4.1 Flash": |
| payload["max_tokens"] = 65536 |
| payload["reasoning_budget"] = 16384 |
| payload["temperature"] = 0.6 |
| payload["chat_template_kwargs"] = {"enable_thinking": True} |
| |
| elif requested_model_name == "Vedika 2.5 Balanced": |
| payload["max_tokens"] = 2977 |
| payload["temperature"] = 1.0 |
| payload["frequency_penalty"] = 0 |
| payload["presence_penalty"] = 0 |
| payload["top_p"] = 1 |
| |
| elif requested_model_name == "Vedika 5.6 Pro": |
| payload["max_tokens"] = 16384 |
| payload["seed"] = 42 |
| payload["temperature"] = 1.0 |
|
|
| try: |
| response = requests.post(INVOKE_URL, headers={"Authorization": f"Bearer {NVIDIA_API_KEY}", "Accept": "text/event-stream"}, json=payload, stream=True, timeout=60) |
| if response.status_code != 200: |
| return Response(f"data: {json.dumps({'error': f'API Error {response.status_code}'})}\n\n", mimetype='text/event-stream') |
|
|
| def generate(): |
| for line in response.iter_lines(): |
| if line: |
| decoded = line.decode("utf-8") |
| if decoded.startswith("data: ") and "[DONE]" not in decoded: |
| try: |
| data_json = json.loads(decoded[6:]) |
| if "choices" in data_json and len(data_json["choices"]) > 0: |
| delta = data_json["choices"][0].get("delta", {}) |
| if "content" in delta and delta["content"]: |
| delta["content"] = delta["content"].replace("<|channel|>thought <|channel|>", "<think>\n").replace("<|channel|>answer <|channel|>", "\n</think>\n") |
| yield "data: " + json.dumps(data_json) + "\n\n" |
| except Exception: |
| yield decoded + "\n\n" |
| else: |
| yield decoded + "\n\n" |
| return Response(stream_with_context(generate()), mimetype='text/event-stream') |
| except Exception as e: |
| return Response(f"data: {json.dumps({'error': str(e)})}\n\n", mimetype='text/event-stream') |
|
|
| @app.route('/api/tts', methods=['POST']) |
| def generate_tts(): |
| if tts is None: return Response(json.dumps({"error": "TTS offline"}), status=500, mimetype='application/json') |
| data = request.get_json() or {} |
| text, voice, lang = data.get("text", ""), data.get("voice", "M2"), data.get("language_name", "English") |
| if not text.strip(): return Response(json.dumps({"error": "Empty text"}), status=400, mimetype='application/json') |
| try: |
| if voice not in VOICE_STYLES_CACHE: VOICE_STYLES_CACHE[voice] = tts.get_voice_style(voice_name=voice) |
| wav, _ = tts.synthesize(text, voice_style=VOICE_STYLES_CACHE[voice], lang=LANGUAGES.get(lang, "en")) |
| with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as tmp: |
| tmp_path = tmp.name |
| tts.save_audio(wav, tmp_path) |
| with open(tmp_path, 'rb') as f: audio_data = f.read() |
| os.unlink(tmp_path) |
| return Response(audio_data, mimetype="audio/wav") |
| except Exception as e: |
| return Response(json.dumps({"error": str(e)}), status=500, mimetype='application/json') |
|
|
| if __name__ == '__main__': |
| app.run(host='0.0.0.0', port=7860) |
|
|