Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,3 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import os
|
2 |
import subprocess
|
3 |
import gradio as gr
|
@@ -9,25 +115,99 @@ import google.generativeai as genai
|
|
9 |
# from playwright._impl._driver import get_driver_dir
|
10 |
|
11 |
from helpers import (
|
12 |
-
list_docx_files, get_splits, get_json_splits_only, prompt_order, log_message
|
13 |
)
|
14 |
|
15 |
-
from file_loader import get_vectorstore
|
16 |
# import asyncio
|
17 |
|
|
|
18 |
key = os.getenv("GOOGLE_API_KEY")
|
19 |
# Cấu hình API key cho Google GenAI
|
20 |
genai.configure(api_key=key)
|
21 |
|
22 |
-
vectorstore = get_vectorstore()
|
|
|
23 |
last_vector_docs = None # Lưu kết quả docs từ vectorstore.invoke trong lần gọi get_answer gần nhất
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
-
|
|
|
|
|
|
|
26 |
global last_vector_docs
|
27 |
-
|
|
|
|
|
|
|
|
|
28 |
results = retriever.invoke(query)
|
29 |
# Lưu kết quả để dùng cho log và lọc sau này
|
30 |
-
last_vector_docs = results
|
31 |
if results:
|
32 |
source_knowledge = "\n\n".join([doc.page_content for doc in results])
|
33 |
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.
|
@@ -37,33 +217,44 @@ Dữ liệu:
|
|
37 |
else:
|
38 |
return "Không có thông tin liên quan.\n."
|
39 |
|
40 |
-
def get_answer(query,
|
41 |
-
if
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
44 |
messages = [
|
45 |
-
{"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,
|
46 |
-
{"role": "user", "parts": [{"text": augment_prompt(query=query,
|
47 |
]
|
48 |
-
|
49 |
queries_list.append(query)
|
50 |
-
queries =
|
|
|
|
|
|
|
51 |
messages_with_queries = messages.copy()
|
52 |
messages_with_queries.append(queries)
|
53 |
-
|
54 |
# Cấu hình API key và khởi tạo model Gemini
|
55 |
genai.configure(api_key=key)
|
56 |
model = genai.GenerativeModel("gemini-2.0-flash")
|
57 |
-
|
58 |
-
response = model.generate_content(contents=messages_with_queries, stream=
|
59 |
response_text = ""
|
60 |
-
for chunk in response
|
61 |
-
response_text += chunk.text
|
62 |
-
yield response_text
|
63 |
messages.append({"role": "model", "parts": [{"text": response_text}]})
|
64 |
-
log_message(messages)
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
-
def filter_vector_docs(keyword: str):
|
67 |
global last_vector_docs
|
68 |
if last_vector_docs is None:
|
69 |
return "Chưa có dữ liệu vectorstore được gọi từ get_answer."
|
@@ -78,6 +269,11 @@ def filter_vector_docs(keyword: str):
|
|
78 |
return f"Không có kết quả chứa từ khoá '{keyword}'."
|
79 |
return "\n\n".join(filtered)
|
80 |
|
|
|
|
|
|
|
|
|
|
|
81 |
institutions = ['Tất cả', 'Trường Công Nghệ']
|
82 |
categories = ['Tất cả', 'Đề án', 'Chương trình đào tạo']
|
83 |
|
@@ -85,19 +281,45 @@ print("Launching on space... This may take some time...")
|
|
85 |
|
86 |
with gr.Blocks() as demo:
|
87 |
with gr.Row():
|
88 |
-
# Dropdown category nếu cần
|
89 |
category1 = gr.Dropdown(choices=institutions, label="Trường", value=None)
|
90 |
category2 = gr.Dropdown(choices=categories, label="Bạn quan tâm tới", value=None)
|
91 |
-
|
92 |
-
#
|
|
|
|
|
|
|
|
|
|
|
93 |
shared_query = gr.Textbox(placeholder="Đặt câu hỏi tại đây", container=False, autoscroll=True, scale=7)
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
with gr.Row():
|
99 |
-
filter_prompt = gr.Textbox(label="Nhập từ khoá", placeholder="Nhập từ khoá", interactive=True)
|
100 |
-
filter_button = gr.Button("
|
101 |
filter_output = gr.Textbox(label="Content", interactive=False)
|
102 |
filter_button.click(fn=filter_vector_docs, inputs=filter_prompt, outputs=filter_output)
|
103 |
|
|
|
1 |
+
# import os
|
2 |
+
# import subprocess
|
3 |
+
# import gradio as gr
|
4 |
+
# import json
|
5 |
+
# from tqdm import tqdm
|
6 |
+
# from langchain_community.vectorstores import FAISS
|
7 |
+
# from langchain_google_genai import GoogleGenerativeAIEmbeddings
|
8 |
+
# import google.generativeai as genai
|
9 |
+
# # from playwright._impl._driver import get_driver_dir
|
10 |
+
|
11 |
+
# from helpers import (
|
12 |
+
# list_docx_files, get_splits, get_json_splits_only, prompt_order, log_message
|
13 |
+
# )
|
14 |
+
|
15 |
+
# from file_loader import get_vectorstore
|
16 |
+
# # import asyncio
|
17 |
+
|
18 |
+
# key = os.getenv("GOOGLE_API_KEY")
|
19 |
+
# # Cấu hình API key cho Google GenAI
|
20 |
+
# genai.configure(api_key=key)
|
21 |
+
|
22 |
+
# vectorstore = get_vectorstore()
|
23 |
+
# last_vector_docs = None # Lưu kết quả docs từ vectorstore.invoke trong lần gọi get_answer gần nhất
|
24 |
+
|
25 |
+
# def augment_prompt(query: str, k: int = 10):
|
26 |
+
# global last_vector_docs
|
27 |
+
# retriever = vectorstore.as_retriever(search_kwargs={"k": k})
|
28 |
+
# results = retriever.invoke(query)
|
29 |
+
# # Lưu kết quả để dùng cho log và lọc sau này
|
30 |
+
# last_vector_docs = results
|
31 |
+
# if results:
|
32 |
+
# source_knowledge = "\n\n".join([doc.page_content for doc in results])
|
33 |
+
# 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.
|
34 |
+
# Dữ liệu:
|
35 |
+
# {source_knowledge}
|
36 |
+
# """
|
37 |
+
# else:
|
38 |
+
# return "Không có thông tin liên quan.\n."
|
39 |
+
|
40 |
+
# def get_answer(query, queries_list=None):
|
41 |
+
# if queries_list is None:
|
42 |
+
# queries_list = []
|
43 |
+
|
44 |
+
# messages = [
|
45 |
+
# {"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."}]},
|
46 |
+
# {"role": "user", "parts": [{"text": augment_prompt(query=query, k=100)}]}
|
47 |
+
# ]
|
48 |
+
|
49 |
+
# queries_list.append(query)
|
50 |
+
# queries = {"role": "user", "parts": [{"text": prompt_order(queries_list)}]}
|
51 |
+
# messages_with_queries = messages.copy()
|
52 |
+
# messages_with_queries.append(queries)
|
53 |
+
|
54 |
+
# # Cấu hình API key và khởi tạo model Gemini
|
55 |
+
# genai.configure(api_key=key)
|
56 |
+
# model = genai.GenerativeModel("gemini-2.0-flash")
|
57 |
+
|
58 |
+
# response = model.generate_content(contents=messages_with_queries, stream=True)
|
59 |
+
# response_text = ""
|
60 |
+
# for chunk in response:
|
61 |
+
# response_text += chunk.text
|
62 |
+
# yield response_text
|
63 |
+
# messages.append({"role": "model", "parts": [{"text": response_text}]})
|
64 |
+
# log_message(messages)
|
65 |
+
|
66 |
+
# def filter_vector_docs(keyword: str):
|
67 |
+
# global last_vector_docs
|
68 |
+
# if last_vector_docs is None:
|
69 |
+
# return "Chưa có dữ liệu vectorstore được gọi từ get_answer."
|
70 |
+
# else:
|
71 |
+
# if not keyword.strip():
|
72 |
+
# # Nếu không nhập gì, trả về tất cả
|
73 |
+
# filtered = [doc.page_content for doc in last_vector_docs]
|
74 |
+
# else:
|
75 |
+
# # Lọc các chunk chứa từ khoá (không phân biệt chữ hoa thường)
|
76 |
+
# filtered = [doc.page_content for doc in last_vector_docs if keyword.lower() in doc.page_content.lower()]
|
77 |
+
# if not filtered:
|
78 |
+
# return f"Không có kết quả chứa từ khoá '{keyword}'."
|
79 |
+
# return "\n\n".join(filtered)
|
80 |
+
|
81 |
+
# institutions = ['Tất cả', 'Trường Công Nghệ']
|
82 |
+
# categories = ['Tất cả', 'Đề án', 'Chương trình đào tạo']
|
83 |
+
|
84 |
+
# print("Launching on space... This may take some time...")
|
85 |
+
|
86 |
+
# with gr.Blocks() as demo:
|
87 |
+
# with gr.Row():
|
88 |
+
# # Dropdown category nếu cần
|
89 |
+
# category1 = gr.Dropdown(choices=institutions, label="Trường", value=None)
|
90 |
+
# category2 = gr.Dropdown(choices=categories, label="Bạn quan tâm tới", value=None)
|
91 |
+
|
92 |
+
# # Chat Interface sử dụng ô nhập chung
|
93 |
+
# shared_query = gr.Textbox(placeholder="Đặt câu hỏi tại đây", container=False, autoscroll=True, scale=7)
|
94 |
+
# chat_interface = gr.ChatInterface(get_answer, textbox=shared_query, type="messages")
|
95 |
+
|
96 |
+
# # 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,
|
97 |
+
# # kết quả sẽ hiển thị ở ô bên dưới. Nếu để trống, hiển thị toàn bộ.
|
98 |
+
# with gr.Row():
|
99 |
+
# filter_prompt = gr.Textbox(label="Nhập từ khoá", placeholder="Nhập từ khoá", interactive=True)
|
100 |
+
# filter_button = gr.Button("Đọc trích xuất")
|
101 |
+
# filter_output = gr.Textbox(label="Content", interactive=False)
|
102 |
+
# filter_button.click(fn=filter_vector_docs, inputs=filter_prompt, outputs=filter_output)
|
103 |
+
|
104 |
+
# if __name__ == "__main__":
|
105 |
+
# demo.launch()
|
106 |
+
|
107 |
import os
|
108 |
import subprocess
|
109 |
import gradio as gr
|
|
|
115 |
# from playwright._impl._driver import get_driver_dir
|
116 |
|
117 |
from helpers import (
|
118 |
+
list_docx_files, get_splits, get_json_splits_only, prompt_order, log_message, extract_metadata,
|
119 |
)
|
120 |
|
121 |
+
# from file_loader import get_vectorstore
|
122 |
# import asyncio
|
123 |
|
124 |
+
# key = "AIzaSyDJ4vIKuIBIPNHATLxnoHlagXWbsAz-vRs"
|
125 |
key = os.getenv("GOOGLE_API_KEY")
|
126 |
# Cấu hình API key cho Google GenAI
|
127 |
genai.configure(api_key=key)
|
128 |
|
129 |
+
# vectorstore = get_vectorstore()
|
130 |
+
# vectorstore = get_vectorstore()
|
131 |
last_vector_docs = None # Lưu kết quả docs từ vectorstore.invoke trong lần gọi get_answer gần nhất
|
132 |
+
# see_metadata = None
|
133 |
+
# see_metadata2 = None
|
134 |
+
# see_metadata_fin = None
|
135 |
+
queries_list = []
|
136 |
+
|
137 |
+
metadata = {}
|
138 |
+
|
139 |
+
def augment_prompt(query: str, queries_list=None, k: int = 5):
|
140 |
+
#define metadata, make the button to clear metadata
|
141 |
+
global metadata
|
142 |
+
messages = [
|
143 |
+
{"role": "user", "parts": [{"text": """
|
144 |
+
'Tai lieu ve': ['Đề án', 'Chương trình đào tạo', 'Đề cương']
|
145 |
+
'Nganh': ['Trí tuệ nhân tạo',
|
146 |
+
'Toán kinh tế (TOKT)',
|
147 |
+
'Thống kê kinh tế',
|
148 |
+
'Phân tích dữ liệu trong Kinh tế (DSEB)',
|
149 |
+
'Kỹ thuật phần mềm',
|
150 |
+
'Khoa học máy tính',
|
151 |
+
'Khoa học dữ liệu',
|
152 |
+
'Hệ thống thông tin quản lý',
|
153 |
+
'Hệ thống thông tin',
|
154 |
+
'Định phí bảo hiểm và Quản trị rủi ro (Actuary)',
|
155 |
+
'Công nghệ thông tin',
|
156 |
+
'An toàn thông tin']
|
157 |
+
'Khoa': ['Công nghệ thông tin (FIT)',
|
158 |
+
'Toán Kinh tế (MFE)',
|
159 |
+
'Khoa học dữ liệu và Trí tuệ nhân tạo (FDA)',
|
160 |
+
'Thống kê',
|
161 |
+
'Hệ thống thông tin quản lý (MIS)']
|
162 |
+
|
163 |
+
"""}]},
|
164 |
+
{"role": "user", "parts": [{"text": f'''Câu hỏi là: "{query}"'''}]},
|
165 |
+
{"role": "user", "parts": [{"text": """Bạn là một mô hình NER, nhiệm vụ của bạn là đọc và hiểu câu hỏi, sau đó đưa ra metadata dưới dạng dict, metadata có dạng: {'Tai lieu ve': '<write here>', 'Nganh': <write here>, 'Khoa': <write here>}, nếu không có theo 3 lists bên trên thì trả về dict rỗng {}"""}]},
|
166 |
+
]
|
167 |
+
genai.configure(api_key=key)
|
168 |
+
model = genai.GenerativeModel("gemini-2.0-flash")
|
169 |
+
|
170 |
+
response = model.generate_content(contents=messages)
|
171 |
+
response_text = "\n\n".join([chunk.text for chunk in response])
|
172 |
+
# global see_metadata
|
173 |
+
metadata_child = extract_metadata(response_text)
|
174 |
+
# see_metadata = str(response_text)
|
175 |
+
|
176 |
+
messages2 = [
|
177 |
+
{"role": "user", "parts": [{"text": f'''Metadata cũ: "{str(metadata_child)}"'''}]},
|
178 |
+
{"role": "user", "parts": [{"text": """
|
179 |
+
Bạn là một mô hình NER, bạn sẽ update metadata cũ thỏa mãn các tiêu chí sau:
|
180 |
+
1. Tôi đã đưa metadata ở phía trên, nếu bạn thấy metadata cũ không có hoặc 1 dict rỗng {} thì output của bạn là dict rỗng {}.
|
181 |
+
2. Nếu không có biến 'Nganh' thì output của bạn là dict rỗng {}.
|
182 |
+
3. Nếu thỏa mãn các tiêu chí trên thì output ra giống hệt như cũ, không thay đổi gì cả, output dưới dạng dict {}.
|
183 |
+
]}"""}]},
|
184 |
+
]
|
185 |
+
# genai.configure(api_key=key)
|
186 |
+
model = genai.GenerativeModel("gemini-2.0-flash")
|
187 |
+
response = model.generate_content(contents=messages2)
|
188 |
+
response_text = "\n\n".join([chunk.text for chunk in response])
|
189 |
+
# global see_metadata2
|
190 |
+
metadata_child = extract_metadata(response_text)
|
191 |
+
|
192 |
+
# see_metadata2 = response_text
|
193 |
+
#retrieve
|
194 |
+
if metadata_child == None:
|
195 |
+
metadata_child = {}
|
196 |
+
# metadata = {}
|
197 |
|
198 |
+
#hàm update metadata
|
199 |
+
# global see_metadata_fin
|
200 |
+
metadata = update_metadata(metadata, metadata_child)
|
201 |
+
# see_metadata_fin = metadata
|
202 |
global last_vector_docs
|
203 |
+
if metadata == {}:
|
204 |
+
retriever = vectorstore.as_retriever(search_kwargs={"k": 25, "fetch_k": 50, "filter": {'Tai lieu ve': 'Đề án'}})
|
205 |
+
else:
|
206 |
+
retriever = vectorstore.as_retriever(search_kwargs={"k": k, "fetch_k": 20, "filter": metadata})
|
207 |
+
|
208 |
results = retriever.invoke(query)
|
209 |
# Lưu kết quả để dùng cho log và lọc sau này
|
210 |
+
last_vector_docs = results
|
211 |
if results:
|
212 |
source_knowledge = "\n\n".join([doc.page_content for doc in results])
|
213 |
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.
|
|
|
217 |
else:
|
218 |
return "Không có thông tin liên quan.\n."
|
219 |
|
220 |
+
def get_answer(query, queries_listt = None):
|
221 |
+
# if history is None:
|
222 |
+
# history = [] # tạm thời không lưu lịch sử
|
223 |
+
global queries_list
|
224 |
+
queries_list.append(query)
|
225 |
+
|
226 |
+
queries_listt = queries_list.copy()
|
227 |
+
|
228 |
messages = [
|
229 |
+
{"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, tell user to make a more detailed question."}]},
|
230 |
+
{"role": "user", "parts": [{"text": augment_prompt(query=query, queries_list=queries_listt)}]}
|
231 |
]
|
232 |
+
|
233 |
queries_list.append(query)
|
234 |
+
queries = [
|
235 |
+
{"role": "user", "parts": [{"text": prompt_order(queries_list)}]},
|
236 |
+
{"role": "user", "parts": [{"text": "Lưu ý: Nếu câu hỏi về môn học, hãy hỏi người dùng về ngành dạy bộ môn đó là ngành nào!"}]}
|
237 |
+
]
|
238 |
messages_with_queries = messages.copy()
|
239 |
messages_with_queries.append(queries)
|
240 |
+
|
241 |
# Cấu hình API key và khởi tạo model Gemini
|
242 |
genai.configure(api_key=key)
|
243 |
model = genai.GenerativeModel("gemini-2.0-flash")
|
244 |
+
|
245 |
+
response = model.generate_content(contents=messages_with_queries, stream=False)
|
246 |
response_text = ""
|
247 |
+
response_text = "".join(chunk.text for chunk in response)
|
|
|
|
|
248 |
messages.append({"role": "model", "parts": [{"text": response_text}]})
|
249 |
+
# log_message(messages)
|
250 |
+
return response_text
|
251 |
+
|
252 |
+
def reset_metadata(): #reset metadata button
|
253 |
+
global metadata
|
254 |
+
metadata = {}
|
255 |
+
return "{}"
|
256 |
|
257 |
+
def filter_vector_docs(keyword: str): #check retrived content button
|
258 |
global last_vector_docs
|
259 |
if last_vector_docs is None:
|
260 |
return "Chưa có dữ liệu vectorstore được gọi từ get_answer."
|
|
|
269 |
return f"Không có kết quả chứa từ khoá '{keyword}'."
|
270 |
return "\n\n".join(filtered)
|
271 |
|
272 |
+
def get_metadata():
|
273 |
+
# Hàm này dùng để cập nhật ô metadata sau mỗi prompt
|
274 |
+
global metadata
|
275 |
+
return str(metadata) if metadata is not None else "{}"
|
276 |
+
|
277 |
institutions = ['Tất cả', 'Trường Công Nghệ']
|
278 |
categories = ['Tất cả', 'Đề án', 'Chương trình đào tạo']
|
279 |
|
|
|
281 |
|
282 |
with gr.Blocks() as demo:
|
283 |
with gr.Row():
|
|
|
284 |
category1 = gr.Dropdown(choices=institutions, label="Trường", value=None)
|
285 |
category2 = gr.Dropdown(choices=categories, label="Bạn quan tâm tới", value=None)
|
286 |
+
|
287 |
+
# Create the metadata display box at the top for better visibility
|
288 |
+
with gr.Row():
|
289 |
+
metadata_box = gr.Textbox(label="Metadata", value="{}", interactive=False)
|
290 |
+
reset_meta_button = gr.Button("Reset Metadata", scale=0.5)
|
291 |
+
|
292 |
+
# Use a custom submit function to handle both answer generation and metadata updating
|
293 |
shared_query = gr.Textbox(placeholder="Đặt câu hỏi tại đây", container=False, autoscroll=True, scale=7)
|
294 |
+
|
295 |
+
# Modified chat interface with custom submit function
|
296 |
+
chatbot = gr.Chatbot()
|
297 |
+
|
298 |
+
def submit_query(message, chat_history):
|
299 |
+
response, metadata_str = get_answer(message)
|
300 |
+
chat_history.append((message, response))
|
301 |
+
return "", chat_history, metadata_str
|
302 |
+
|
303 |
+
submit_btn = gr.Button("Gửi")
|
304 |
+
submit_btn.click(
|
305 |
+
fn=submit_query,
|
306 |
+
inputs=[shared_query, chatbot],
|
307 |
+
outputs=[shared_query, chatbot, metadata_box]
|
308 |
+
)
|
309 |
+
|
310 |
+
# Also handle Enter key press in the text box
|
311 |
+
shared_query.submit(
|
312 |
+
fn=submit_query,
|
313 |
+
inputs=[shared_query, chatbot],
|
314 |
+
outputs=[shared_query, chatbot, metadata_box]
|
315 |
+
)
|
316 |
+
|
317 |
+
# Connect reset button to reset function
|
318 |
+
reset_meta_button.click(fn=reset_metadata, inputs=[], outputs=metadata_box)
|
319 |
+
|
320 |
with gr.Row():
|
321 |
+
filter_prompt = gr.Textbox(label="Nhập từ khoá", placeholder="Nhập từ khoá để lọc (để trống để hiển thị tất cả)", interactive=True)
|
322 |
+
filter_button = gr.Button("Tìm trích xuất")
|
323 |
filter_output = gr.Textbox(label="Content", interactive=False)
|
324 |
filter_button.click(fn=filter_vector_docs, inputs=filter_prompt, outputs=filter_output)
|
325 |
|