import gradio as gr import faiss import json import numpy as np import os from sentence_transformers import SentenceTransformer import requests # Load embedding model embed_model = SentenceTransformer("all-MiniLM-L6-v2") # Load FAISS index and texts index = faiss.read_index("faiss_index.bin") with open("texts.json", "r") as f: texts = json.load(f) # OpenRouter API Key (Set as secret in Hugging Face Space settings) API_KEY = os.environ.get("OPENROUTER_API_KEY") MODEL = "deepseek/deepseek-chat-v3-0324:free" # Perform semantic search using FAISS def search_context(query, k=5): query_embedding = embed_model.encode([query]) distances, indices = index.search(np.array(query_embedding), k) relevant_chunks = [texts[i] for i in indices[0] if i < len(texts)] return "\n".join(relevant_chunks) def chat_fn(message, history): # Search knowledge base context = search_context(message) if not context.strip(): return "❌ Sorry, I can only answer questions related to the content of logiqcurve.com." # Construct prompt messages = [ {"role": "system", "content": "You are an assistant that only answers based on the provided CONTEXT. Do not answer from general knowledge. If the answer is not in the CONTEXT, reply with 'Sorry, I can only answer questions related to the content of logiqcurve.com.'"}, {"role": "user", "content": f"CONTEXT:\n{context}\n\nQUESTION:\n{message}"}, ] headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } payload = { "model": MODEL, "messages": messages } try: response = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload) response.raise_for_status() reply = response.json()["choices"][0]["message"]["content"] except Exception as e: reply = f"❌ Error: {e}" return reply # Gradio Chat Interface (for Hugging Face Space) chatbot = gr.ChatInterface( fn=chat_fn, title="LogiqCurve ChatBot", description="Ask anything about logiqcurve.com. This bot only answers based on its content.", theme="soft" ) chatbot.launch()