File size: 6,606 Bytes
2426d62
53a5038
41b8230
 
 
 
 
5cf3079
41b8230
 
33a3ad3
a6c549e
46486f5
41b8230
4164239
 
 
 
 
 
 
 
 
 
 
41b8230
 
05bf013
41b8230
 
 
125b60f
3d03f6e
 
 
41b8230
 
 
 
4164239
 
41b8230
 
 
 
 
 
 
 
4164239
41b8230
 
 
 
 
 
43c1570
 
41b8230
 
 
 
 
 
 
 
 
 
 
 
53a5038
 
ba9e337
824b61b
 
 
 
4164239
 
ba9e337
33a3ad3
 
 
 
 
 
74cbdcf
 
33a3ad3
97d3ce4
9911861
33a3ad3
ba9e337
9911861
74cbdcf
9911861
74cbdcf
ba9e337
 
 
 
 
 
 
 
 
ebc3d73
9911861
 
ebc3d73
 
 
 
8996b37
74cbdcf
a6c549e
 
 
 
74cbdcf
a6c549e
 
74cbdcf
 
 
ba9e337
74cbdcf
46486f5
fe10fad
 
 
 
 
 
 
 
 
 
 
 
33a3ad3
74cbdcf
33a3ad3
 
 
 
 
 
 
 
74cbdcf
 
 
 
 
 
33a3ad3
4164239
 
 
 
 
74cbdcf
 
 
4164239
74cbdcf
 
 
 
 
 
 
 
 
4164239
74cbdcf
4164239
74cbdcf
4164239
 
 
 
 
 
 
 
 
 
 
74cbdcf
4164239
 
74cbdcf
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import subprocess
import gradio as gr
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.llms import HuggingFacePipeline
from langchain.chains import RetrievalQA
from transformers import AutoConfig, AutoTokenizer, pipeline, AutoModelForCausalLM
from langchain_community.document_loaders import DirectoryLoader
import torch
import re
import requests
from urllib.parse import urlencode, urlparse, parse_qs
import spaces

# Step 1: Run the setup script
script_path = './setup.sh'  # Adjust the path if needed

# Run the script
exit_code = subprocess.call(['bash', script_path])

if exit_code == 0:
    print("Script executed successfully.")
else:
    print(f"Script failed with exit code {exit_code}.")

# Initialize embeddings and ChromaDB
model_name = "sentence-transformers/all-mpnet-base-v2"
device = "cuda" if torch.cuda.is_available() else "cpu"
model_kwargs = {"device": device}
embeddings = HuggingFaceEmbeddings(model_name=model_name, model_kwargs=model_kwargs)

loader = DirectoryLoader('./example', glob="**/*.pdf", recursive=True, use_multithreading=True)
docs = loader.load()
vectordb = Chroma.from_documents(documents=docs, embedding=embeddings, persist_directory="companies_db")
books_db = Chroma(persist_directory="./companies_db", embedding_function=embeddings)
books_db_client = books_db.as_retriever()

# Initialize the model and tokenizer
model_name = "stabilityai/stablelm-zephyr-3b"
model_config = AutoConfig.from_pretrained(model_name, max_new_tokens=1024)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    trust_remote_code=True,
    config=model_config,
    device_map=device,
)

tokenizer = AutoTokenizer.from_pretrained(model_name)

query_pipeline = pipeline(
    "text-generation",
    model=model,
    tokenizer=tokenizer,
    return_full_text=True,
    torch_dtype=torch.float16,
    device_map=device,
    do_sample=True,
    temperature=0.7,
    top_p=0.9,
    top_k=50,
    max_new_tokens=256
)

llm = HuggingFacePipeline(pipeline=query_pipeline)

books_db_client_retriever = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=books_db_client,
    verbose=True
)

# OAuth Configuration
TENANT_ID = '2b093ced-2571-463f-bc3e-b4f8bcb427ee'
CLIENT_ID = '2a7c884c-942d-49e2-9e5d-7a29d8a0d3e5'
CLIENT_SECRET = 'EOF8Q~kKHCRgx8tnlLM-H8e93ifetxI6x7sU6bGW'
REDIRECT_URI = 'https://sanjeevbora-chatbot.hf.space/'
AUTH_URL = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/authorize"
TOKEN_URL = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token"

params = {
    'client_id': CLIENT_ID,
    'response_type': 'code',
    'redirect_uri': REDIRECT_URI,
    'response_mode': 'query',
    'scope': 'User.Read',
    'state': '12345',
    'prompt': 'login'  # This ensures the login prompt appears even if already logged in
}

# Construct the login URL
login_url = f"{AUTH_URL}?{urlencode(params)}"

def show_login_button():
    return f'<a href="{login_url}" class="GFG">Click here to login with Microsoft</a>'

# Function to exchange auth code for token
def exchange_code_for_token(auth_code):
    data = {
        'grant_type': 'authorization_code',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'code': auth_code,
        'redirect_uri': REDIRECT_URI
    }
    response = requests.post(TOKEN_URL, data=data)
    
    if response.status_code == 200:
        token_data = response.json()
        access_token = token_data.get('access_token')
        return access_token
    else:
        return None

# Function to handle redirect URL and extract the auth code
def handle_redirect(url):
    parsed_url = urlparse(url)
    query_params = parse_qs(parsed_url.query)
    auth_code = query_params.get('code')
    
    if auth_code:
        token = exchange_code_for_token(auth_code[0])
        if token:
            return "Logged in", True  # Successfully logged in
    return "Login failed", False

# Function to retrieve answer using the RAG system
@spaces.GPU(duration=60)
def test_rag(query):
    books_retriever = books_db_client_retriever.run(query)
    
    # Extract the relevant answer using regex
    corrected_text_match = re.search(r"Helpful Answer:(.*)", books_retriever, re.DOTALL)
    
    if corrected_text_match:
        corrected_text_books = corrected_text_match.group(1).strip()
    else:
        corrected_text_books = "No helpful answer found."
    
    return corrected_text_books

# Define the Gradio interface
def chat(query, history=None):
    if history is None:
        history = []
    if query:
        answer = test_rag(query)
        history.append((query, answer))
    return history, ""  # Clear input after submission

# Function to clear input text
def clear_input():
    return "",  # Return empty string to clear input field


# Gradio Interface
with gr.Blocks() as interface:
    with gr.Tab("Login"):
        gr.Markdown("## Login Page")
        login_link = gr.HTML(show_login_button())
        
        # Hidden textbox for redirect URL
        redirect_url_input = gr.Textbox(label="Redirect URL", visible=True)  # URL from the Microsoft redirect

        status_label = gr.Label(value="Not logged in")  # Label to show login status
        
        def on_redirect(redirect_url):
            # Extract and exchange token
            status, logged_in = handle_redirect(redirect_url)
            if logged_in:
                return gr.update(visible=False), status, gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)
            else:
                return gr.update(visible=True), status, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
        
        # Handle redirect and switch to chatbot page upon login
        redirect_url_input.change(
            on_redirect,
            inputs=[redirect_url_input],
            outputs=[redirect_url_input, status_label, gr.Textbox.update(visible=True), gr.Button.update(visible=True), gr.Chatbot.update(visible=True)],
            show_progress=True
        )
        
    with gr.Tab("Chatbot"):
        gr.Markdown("## Chatbot Page")
        
        # Components for chat (initially hidden)
        input_box = gr.Textbox(label="Enter your question", placeholder="Type your question here...", visible=False)
        submit_btn = gr.Button("Submit", visible=False)
        chat_history = gr.Chatbot(label="Chat History", visible=False)

        # Chat submission
        submit_btn.click(chat, inputs=[input_box, chat_history], outputs=[chat_history, input_box])

interface.launch()