File size: 2,578 Bytes
e370f3a
d1406e8
51ce63b
d1406e8
 
270b445
efbfb8b
bb68426
3868931
270b445
51ce63b
 
270b445
 
efbfb8b
3868931
e370f3a
b3766ed
51ce63b
3868931
39f5430
270b445
 
3868931
 
 
e370f3a
3868931
a4b560c
bb68426
3868931
e370f3a
 
 
3868931
e370f3a
 
 
 
 
0527279
 
 
 
3868931
0527279
 
 
e07b81a
e370f3a
 
 
 
efa5f27
51ce63b
bb68426
a4b560c
51ce63b
 
 
a4b560c
270b445
e370f3a
51ce63b
e370f3a
 
3868931
e370f3a
e07b81a
 
 
 
 
 
e370f3a
e07b81a
e370f3a
3868931
e370f3a
3868931
e370f3a
3868931
e370f3a
 
 
 
3868931
 
e370f3a
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import gradio as gr
import requests
import os
import faiss
import numpy as np
import json
from sentence_transformers import SentenceTransformer

# βœ… Load context
with open("texts.json", "r", encoding="utf-8") as f:
    texts = json.load(f)

index = faiss.read_index("faiss_index.bin")
embed_model = SentenceTransformer("all-MiniLM-L6-v2")

# βœ… API Setup
API_KEY = os.environ.get("OPENROUTER_API_KEY")
MODEL = "meta-llama/llama-3.3-8b-instruct:free"

# βœ… Context search
def get_context(query, top_k=5, min_score=0.05):
    query_vec = embed_model.encode([query])
    D, I = index.search(np.array(query_vec), top_k)

    # If top score is too low, reject
    if D[0][0] < min_score:
        return None

    return "\n".join([texts[i] for i in I[0]])

# βœ… Chat function
def chat_fn(message, history):
    context = get_context(message)
    if context is None:
        return history[:-1] + [(message, "❌ Sorry! I cannot answer that.")]

    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json"
    }

    messages = [
        {
            "role": "system",
            "content": f"You are a helpful assistant. Use ONLY this context to answer:\n{context}\nIf not found in context, reply: 'Sorry! I cannot answer that.'"
        }
    ]

    for user, assistant in history[:-1]:
        messages.append({"role": "user", "content": user})
        messages.append({"role": "assistant", "content": assistant})

    messages.append({"role": "user", "content": message})

    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 history[:-1] + [(message, reply)]

# βœ… UI
with gr.Blocks(css="""
  .footer {display: none !important;}
  #chat-window {height: 500px !important; overflow-y: auto;}
""") as demo:
    chatbot = gr.Chatbot(elem_id="chat-window")
    state = gr.State([])

    with gr.Row():
        msg = gr.Textbox(placeholder="Type your message and press enter...", scale=9)

    # Typing sim
    def user_send(message, history):
        return "", history + [(message, "⏳ ...")]

    def complete_chat(message, history):
        return chat_fn(message, history)

    msg.submit(user_send, [msg, state], [msg, chatbot]).then(
        complete_chat, [msg, state], [chatbot]
    )

demo.launch()