yogies commited on
Commit
57ec1a6
·
verified ·
1 Parent(s): d072ec5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +187 -62
app.py CHANGED
@@ -4,11 +4,8 @@ import os
4
  import time
5
  import gradio as gr
6
  import importlib.util
7
-
8
  from huggingface_hub import hf_hub_download
9
- from gradio.components.chatbot import Chatbot as grChatbot # Import for type hints
10
- from gradio.components.textbox import Textbox as grTextbox
11
- from gradio.events import EventListener
12
 
13
  # ----------------------------------------------------------------------
14
  # Helper to read secrets from the HF Space environment
@@ -22,17 +19,21 @@ def _secret(key: str, fallback: str = None) -> str:
22
  # ----------------------------------------------------------------------
23
  # 1. Configuration & Constants
24
  # ----------------------------------------------------------------------
 
25
  REPO_ID = _secret("REPO_ID")
 
26
  FILES_TO_DOWNLOAD = ["index.faiss", "index.pkl", "agent_logic.py"]
 
27
  LOCAL_DOWNLOAD_DIR = "downloaded_assets"
28
  EMBEDDING_MODEL_NAME = "google/embeddinggemma-300m"
29
 
30
  # ----------------------------------------------------------------------
31
  # 2. Bootstrap Phase: Download assets and initialize the engine
 
32
  # ----------------------------------------------------------------------
33
  print("--- [UI App] Starting bootstrap process ---")
34
  os.makedirs(LOCAL_DOWNLOAD_DIR, exist_ok=True)
35
- hf_token = _secret("HF_TOKEN")
36
 
37
  for filename in FILES_TO_DOWNLOAD:
38
  print(f"--- [UI App] Downloading '{filename}'... ---")
@@ -44,12 +45,15 @@ for filename in FILES_TO_DOWNLOAD:
44
  except Exception as e:
45
  raise RuntimeError(f"Failed to download '{filename}'. Check repo/file names and HF_TOKEN. Error: {e}")
46
 
 
47
  logic_script_path = os.path.join(LOCAL_DOWNLOAD_DIR, "agent_logic.py")
48
  spec = importlib.util.spec_from_file_location("agent_logic", logic_script_path)
49
  agent_logic_module = importlib.util.module_from_spec(spec)
50
  spec.loader.exec_module(agent_logic_module)
51
  print("--- [UI App] Agent logic module imported successfully. ---")
52
 
 
 
53
  engine = agent_logic_module.RAG_Engine(
54
  local_download_dir=LOCAL_DOWNLOAD_DIR,
55
  embedding_model_name=EMBEDDING_MODEL_NAME
@@ -57,84 +61,205 @@ engine = agent_logic_module.RAG_Engine(
57
  print("--- [UI App] Bootstrap complete. Gradio UI is starting. ---")
58
 
59
  # ----------------------------------------------------------------------
60
- # 3. Core Gradio Chat Logic
61
  # ----------------------------------------------------------------------
62
- def add_message_and_respond(message: str, history: list):
63
- history.append([message, None])
64
- yield history
65
-
66
- history_for_engine = []
67
- for user_msg, bot_msg in history[:-1]:
68
- history_for_engine.append({"role": "user", "content": user_msg})
69
- if bot_msg:
70
- history_for_engine.append({"role": "assistant", "content": bot_msg})
71
-
72
- final_response = engine.get_response(message, history_for_engine)
73
 
74
- history[-1][1] = ""
 
75
  for char in final_response:
76
- history[-1][1] += char
77
  time.sleep(0.01)
78
- yield history
79
 
80
  # ----------------------------------------------------------------------
81
- # 4. UI Layout and Launch (Beautified with gr.Blocks)
82
  # ----------------------------------------------------------------------
 
 
 
 
 
 
 
83
 
84
- css = """
85
- #chatbot { min-height: 600px; }
86
- .footer { text-align: center; color: #777; font-size: 0.8em; padding: 10px 0; }
87
- """
 
88
 
89
- # The theme must be passed to gr.Blocks now
90
- with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
91
- gr.Markdown("<h1>🤖 PRECISE RAG Agent</h1>")
92
- gr.Markdown("Tanya Jawab Cerdas Mengenai Dokumentasi Sistem PRECISE")
93
-
94
- chatbot = grChatbot(
95
- elem_id="chatbot",
96
- label="Conversation",
97
- likeable=True, # This is a valid and nice feature
98
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
- with gr.Row():
101
- msg = grTextbox(
102
- label="Your Question",
103
- placeholder="Ketik pertanyaan Anda di sini dan tekan Enter...",
104
- scale=4,
105
- )
106
- submit_btn = gr.Button("Send", variant="primary", scale=1)
107
 
108
- gr.Examples(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  examples=[
110
- "Apa rumus untuk menghitung PVR?",
111
- "Apa tujuan pengadaan PRECISE?",
112
- "Jelaskan segmentasi *slow-moving*",
113
  ],
114
- inputs=msg,
115
  )
116
 
117
- gr.Markdown("<hr><p class='footer'>Powered by OpenRouter and LangChain. All rights reserved.</p>")
118
-
119
- # --- Event Handlers ---
120
-
121
- # Create a submit action that can be triggered by button click or textbox submit
122
- submit_event = msg.submit(add_message_and_respond, [msg, chatbot], chatbot)
123
- submit_event.then(lambda: "", None, msg) # Clears textbox after submit
124
-
125
- btn_event = submit_btn.click(add_message_and_respond, [msg, chatbot], chatbot)
126
- btn_event.then(lambda: "", None, msg) # Clears textbox after click
 
 
 
 
 
 
 
 
 
 
127
 
128
- # ----------------------------------------------------------------------
129
- # 5. Launch the App
130
- # ----------------------------------------------------------------------
131
  if __name__ == "__main__":
132
  allowed_user = _secret("CHAT_USER")
133
  allowed_pass = _secret("CHAT_PASS")
134
- # Tell Gradio to load the MathJax library for LaTeX rendering
135
  demo.launch(
136
  auth=(allowed_user, allowed_pass),
137
  server_name="0.0.0.0",
138
  ssr_mode=False,
139
- server_port=7860,
140
  )
 
4
  import time
5
  import gradio as gr
6
  import importlib.util
7
+ import markdown
8
  from huggingface_hub import hf_hub_download
 
 
 
9
 
10
  # ----------------------------------------------------------------------
11
  # Helper to read secrets from the HF Space environment
 
19
  # ----------------------------------------------------------------------
20
  # 1. Configuration & Constants
21
  # ----------------------------------------------------------------------
22
+ # The private repo containing the vector DB and the logic script
23
  REPO_ID = _secret("REPO_ID")
24
+ # Files to download from the repo
25
  FILES_TO_DOWNLOAD = ["index.faiss", "index.pkl", "agent_logic.py"]
26
+ # A local directory to store all downloaded assets
27
  LOCAL_DOWNLOAD_DIR = "downloaded_assets"
28
  EMBEDDING_MODEL_NAME = "google/embeddinggemma-300m"
29
 
30
  # ----------------------------------------------------------------------
31
  # 2. Bootstrap Phase: Download assets and initialize the engine
32
+ # (This code runs only once when the Space starts up)
33
  # ----------------------------------------------------------------------
34
  print("--- [UI App] Starting bootstrap process ---")
35
  os.makedirs(LOCAL_DOWNLOAD_DIR, exist_ok=True)
36
+ hf_token = _secret("HF_TOKEN") # A read-access token is required for private repos
37
 
38
  for filename in FILES_TO_DOWNLOAD:
39
  print(f"--- [UI App] Downloading '{filename}'... ---")
 
45
  except Exception as e:
46
  raise RuntimeError(f"Failed to download '{filename}'. Check repo/file names and HF_TOKEN. Error: {e}")
47
 
48
+ # Dynamically import the RAG_Engine class from the downloaded script
49
  logic_script_path = os.path.join(LOCAL_DOWNLOAD_DIR, "agent_logic.py")
50
  spec = importlib.util.spec_from_file_location("agent_logic", logic_script_path)
51
  agent_logic_module = importlib.util.module_from_spec(spec)
52
  spec.loader.exec_module(agent_logic_module)
53
  print("--- [UI App] Agent logic module imported successfully. ---")
54
 
55
+ # Instantiate the engine. This single line triggers all the complex setup
56
+ # defined in the private_logic.py file.
57
  engine = agent_logic_module.RAG_Engine(
58
  local_download_dir=LOCAL_DOWNLOAD_DIR,
59
  embedding_model_name=EMBEDDING_MODEL_NAME
 
61
  print("--- [UI App] Bootstrap complete. Gradio UI is starting. ---")
62
 
63
  # ----------------------------------------------------------------------
64
+ # 3. Core Gradio Chat Logic (Now a simple wrapper)
65
  # ----------------------------------------------------------------------
66
+ def respond(message: str, history: list[dict[str, str]]):
67
+ """
68
+ This function is called by Gradio for each user message.
69
+ It passes the inputs to the RAG engine and streams the output.
70
+ """
71
+ final_response = engine.get_response(message, history)
 
 
 
 
 
72
 
73
+ # Stream the response back to the UI for a "typing" effect
74
+ response = ""
75
  for char in final_response:
76
+ response += char
77
  time.sleep(0.01)
78
+ yield response
79
 
80
  # ----------------------------------------------------------------------
81
+ # 4. Custom CSS for better styling
82
  # ----------------------------------------------------------------------
83
+ custom_css = """
84
+ /* Main container styling */
85
+ .contain {
86
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
87
+ min-height: 100vh;
88
+ padding: 20px;
89
+ }
90
 
91
+ /* Header styling */
92
+ .header {
93
+ text-align: center;
94
+ margin-bottom: 30px;
95
+ }
96
 
97
+ .header h1 {
98
+ color: #2c3e50;
99
+ font-weight: 700;
100
+ margin-bottom: 10px;
101
+ font-size: 2.5rem;
102
+ }
103
+
104
+ .header p {
105
+ color: #7f8c8d;
106
+ font-size: 1.2rem;
107
+ }
108
+
109
+ /* Chat container styling */
110
+ .gr-chat-message {
111
+ padding: 16px 20px;
112
+ border-radius: 18px;
113
+ margin: 10px 0;
114
+ line-height: 1.5;
115
+ }
116
+
117
+ .gr-chat-message-user {
118
+ background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
119
+ color: white;
120
+ margin-left: 20%;
121
+ }
122
+
123
+ .gr-chat-message-bot {
124
+ background: linear-gradient(135deg, #ecf0f1 0%, #ffffff 100%);
125
+ color: #2c3e50;
126
+ margin-right: 20%;
127
+ border: 1px solid #e0e0e0;
128
+ }
129
+
130
+ /* Chat input styling */
131
+ .gr-text-input textarea {
132
+ border-radius: 12px;
133
+ padding: 15px;
134
+ font-size: 16px;
135
+ border: 2px solid #bdc3c7;
136
+ }
137
+
138
+ .gr-text-input textarea:focus {
139
+ border-color: #3498db;
140
+ box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);
141
+ }
142
+
143
+ /* Button styling */
144
+ .gr-button {
145
+ background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
146
+ color: white;
147
+ border: none;
148
+ border-radius: 12px;
149
+ padding: 12px 24px;
150
+ font-weight: 600;
151
+ transition: all 0.3s ease;
152
+ }
153
+
154
+ .gr-button:hover {
155
+ transform: translateY(-2px);
156
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
157
+ }
158
+
159
+ /* Example styling */
160
+ .gr-examples {
161
+ border-radius: 12px;
162
+ background: white;
163
+ padding: 15px;
164
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
165
+ }
166
+
167
+ .gr-examples button {
168
+ background: #f8f9fa;
169
+ border: 1px solid #e9ecef;
170
+ border-radius: 8px;
171
+ padding: 10px 15px;
172
+ margin: 5px;
173
+ transition: all 0.2s ease;
174
+ }
175
+
176
+ .gr-examples button:hover {
177
+ background: #e9ecef;
178
+ transform: translateY(-1px);
179
+ }
180
+
181
+ /* Formula styling */
182
+ .formula {
183
+ background-color: #f8f9fa;
184
+ border-left: 4px solid #3498db;
185
+ padding: 15px;
186
+ margin: 15px 0;
187
+ border-radius: 0 8px 8px 0;
188
+ overflow-x: auto;
189
+ }
190
+
191
+ .formula p {
192
+ margin: 0;
193
+ font-family: monospace;
194
+ color: #2c3e50;
195
+ }
196
+
197
+ /* Responsive adjustments */
198
+ @media (max-width: 768px) {
199
+ .gr-chat-message-user, .gr-chat-message-bot {
200
+ margin-left: 10%;
201
+ margin-right: 10%;
202
+ }
203
 
204
+ .header h1 {
205
+ font-size: 2rem;
206
+ }
207
+ }
208
+ """
 
 
209
 
210
+ # ----------------------------------------------------------------------
211
+ # 5. UI Layout and Launch
212
+ # ----------------------------------------------------------------------
213
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
214
+ # Header section
215
+ with gr.Row():
216
+ with gr.Column(scale=1):
217
+ gr.HTML("""
218
+ <div class="header">
219
+ <h1>🤖 PRECISE RAG Agent</h1>
220
+ <p>Silakan bertanya tentang PRECISE dan sistem promosinya</p>
221
+ </div>
222
+ """)
223
+
224
+ # Chat interface
225
+ chatbot = gr.ChatInterface(
226
+ respond,
227
+ type="messages",
228
  examples=[
229
+ ["Apa rumus untuk menghitung PVR?"],
230
+ ["Apa tujuan pengadaan PRECISE?"],
231
+ ["Jelaskan tentang promo 'beli 4 gratis 2'"],
232
  ],
233
+ cache_examples=False,
234
  )
235
 
236
+ # Additional information section
237
+ with gr.Accordion("📊 Informasi Formula PVR", open=False):
238
+ gr.Markdown("""
239
+ **PVR untuk promo "beli 4 gratis 2" dihitung dengan rumus:**
240
+
241
+ ```math
242
+ \\text{PVR} = \\frac{\\text{added\\_value}}{\\text{purchase\\_value}}
243
+ = \\frac{\\text{target\\_value} \\times \\text{avg\\_price\\_AVP}}
244
+ {\\text{target\\_value} \\times \\text{avg\\_price\\_AVP}
245
+ + \\text{condition\\_value} \\times \\text{avg\\_price\\_REP}}
246
+ ```
247
+
248
+ Keterangan:
249
+ - **added_value**: Nilai tambah dari promo
250
+ - **purchase_value**: Nilai pembelian keseluruhan
251
+ - **target_value**: Jumlah produk target dalam promo
252
+ - **avg_price_AVP**: Harga rata-rata produk AVP
253
+ - **condition_value**: Jumlah produk kondisi dalam promo
254
+ - **avg_price_REP**: Harga rata-rata produk REP
255
+ """)
256
 
 
 
 
257
  if __name__ == "__main__":
258
  allowed_user = _secret("CHAT_USER")
259
  allowed_pass = _secret("CHAT_PASS")
 
260
  demo.launch(
261
  auth=(allowed_user, allowed_pass),
262
  server_name="0.0.0.0",
263
  ssr_mode=False,
264
+ server_port=7860
265
  )