File size: 4,542 Bytes
587c522
ba964ad
dfabed7
d802f7b
e0f269f
d802f7b
e0f269f
07b2dc9
c104d72
e0f269f
 
245e246
e0f269f
d802f7b
c56e053
62319f5
2bd39e5
130357b
587c522
 
c56e053
62319f5
5c846ae
c56e053
5c846ae
 
c56e053
 
5c846ae
 
c56e053
 
5ffcb10
 
c56e053
 
 
5c846ae
c56e053
 
 
 
5ffcb10
c56e053
5c846ae
50189e2
5c846ae
 
c56e053
 
 
 
5c846ae
 
c56e053
 
5c846ae
c56e053
 
 
 
 
 
 
 
5c846ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5ffcb10
 
 
 
587c522
 
 
5c846ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
587c522
68d8ac5
5c846ae
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
import os
import subprocess
import gradio as gr
import json
from tqdm import tqdm
from langchain_community.vectorstores import FAISS
from langchain_google_genai import GoogleGenerativeAIEmbeddings
import google.generativeai as genai
# from playwright._impl._driver import get_driver_dir

from helpers import (
    list_docx_files, get_splits, get_json_splits_only, prompt_order, log_message
)

from file_loader import get_vectorstore
# import asyncio

key = os.getenv("GOOGLE_API_KEY")
# Cấu hình API key cho Google GenAI
genai.configure(api_key=key)

vectorstore = get_vectorstore()
last_vector_docs = None  # Lưu kết quả docs từ vectorstore.invoke trong lần gọi get_answer gần nhất

def augment_prompt(query: str, k: int = 10):
    global last_vector_docs
    retriever = vectorstore.as_retriever(search_kwargs={"k": k})
    results = retriever.invoke(query)
    # Lưu kết quả để dùng cho log và lọc sau này
    last_vector_docs = results  
    if results:
        source_knowledge = "\n\n".join([doc.page_content for doc in results])
        return f"""Dữ liệu dưới đây liên quan đến Trường Công Nghệ (NCT) thuộc Đại học Kinh tế Quốc dân (NEU), dựa vào đó trả lời câu hỏi.
Dữ liệu:
{source_knowledge}
"""
    else:
        return "Không có thông tin liên quan.\n."

def get_answer(query, queries_list=None):
    if queries_list is None:
        queries_list = []
    
    messages = [
        {"role": "user", "parts": [{"text": "IMPORTANT: You are a super helpful, polite, Vietnamese-speaking assistant to give information of an university. If you cannot see the answer in contexts, try to search it up online by yourself OR tell user to make a more detailed question."}]},
        {"role": "user", "parts": [{"text": augment_prompt(query=query, k=100)}]}
    ]
    
    queries_list.append(query)
    queries = {"role": "user", "parts": [{"text": prompt_order(queries_list)}]}
    messages_with_queries = messages.copy()
    messages_with_queries.append(queries)
    
    # Cấu hình API key và khởi tạo model Gemini
    genai.configure(api_key=key)
    model = genai.GenerativeModel("gemini-2.0-flash")
    
    response = model.generate_content(contents=messages_with_queries, stream=True)
    response_text = ""
    for chunk in response:
        response_text += chunk.text
        yield response_text
    messages.append({"role": "model", "parts": [{"text": response_text}]})
    log_message(messages)

def filter_vector_docs(keyword: str):
    global last_vector_docs
    if last_vector_docs is None:
        return "Chưa có dữ liệu vectorstore được gọi từ get_answer."
    else:
        if not keyword.strip():
            # Nếu không nhập gì, trả về tất cả
            filtered = [doc.page_content for doc in last_vector_docs]
        else:
            # Lọc các chunk chứa từ khoá (không phân biệt chữ hoa thường)
            filtered = [doc.page_content for doc in last_vector_docs if keyword.lower() in doc.page_content.lower()]
        if not filtered:
            return f"Không có kết quả chứa từ khoá '{keyword}'."
        return "\n\n".join(filtered)

institutions = ['Tất cả', 'Trường Công Nghệ']
categories = ['Tất cả', 'Đề án', 'Chương trình đào tạo']

print("Launching on space... This may take some time...")

with gr.Blocks() as demo:
    with gr.Row():
        # Dropdown category nếu cần
        category1 = gr.Dropdown(choices=institutions, label="Trường", value=None)
        category2 = gr.Dropdown(choices=categories, label="Bạn quan tâm tới", value=None)
    
    # Chat Interface sử dụng ô nhập chung
    shared_query = gr.Textbox(placeholder="Đặt câu hỏi tại đây", container=False, autoscroll=True, scale=7)
    chat_interface = gr.ChatInterface(get_answer, textbox=shared_query, type="messages")
    
    # Phần lọc các chunk: ô prompt nhập từ khoá và nút "Tìm trích xuất" nằm cùng hàng,
    # kết quả sẽ hiển thị ở ô bên dưới. Nếu để trống, hiển thị toàn bộ.
    with gr.Row():
        filter_prompt = gr.Textbox(label="Nhập từ khoá", placeholder="Nhập từ khoá", interactive=True)
        filter_button = gr.Button("Đọc trích xuất")
    filter_output = gr.Textbox(label="Content", interactive=False)
    filter_button.click(fn=filter_vector_docs, inputs=filter_prompt, outputs=filter_output)

if __name__ == "__main__":
    demo.launch()