kaburia commited on
Commit
ca14c49
·
1 Parent(s): 04b440e

thinking mode

Browse files
Files changed (1) hide show
  1. app.py +269 -100
app.py CHANGED
@@ -1,3 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # import gradio as gr
2
  # from openai import OpenAI
3
 
@@ -9,19 +98,35 @@
9
 
10
  # # Parameters
11
  # DEFAULT_RETRIEVAL_RUNS = 3 # adjustable in UI
 
 
 
 
 
 
 
12
 
13
  # def policy_chat(message, history, retrieval_runs=DEFAULT_RETRIEVAL_RUNS):
14
  # """
15
- # Chatbot with streaming + multiple retrieval runs.
16
  # """
17
- # # Show "processing" placeholder
 
 
 
18
  # history = history + [[message, "Processing..."]]
19
  # yield history, history
20
 
21
  # aggregated_responses = []
22
 
23
  # for run in range(retrieval_runs):
 
 
 
 
 
24
  # try:
 
25
  # stream = client.chat.completions.create(
26
  # model="n/a", # agent handles routing
27
  # messages=[
@@ -37,142 +142,206 @@
37
  # response_text = ""
38
  # for chunk in stream:
39
  # delta = chunk.choices[0].delta
40
- # if delta and delta.content: # delta.content is a string or None
41
  # response_text += delta.content
42
- # # Stream update to Gradio UI
43
- # history[-1][1] = response_text
44
- # yield history, history
45
 
46
  # aggregated_responses.append(response_text or "⚠️ Empty response")
47
 
48
  # except Exception as e:
49
  # aggregated_responses.append(f"⚠️ Error during run {run+1}: {str(e)}")
50
 
51
- # # 🔹 Choose the “best” response (longest for now)
 
52
  # best_response = max(aggregated_responses, key=len, default="⚠️ No response")
 
 
53
  # history[-1][1] = best_response
54
  # yield history, history
55
 
56
 
57
  # with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="gray")) as demo:
58
- # gr.Markdown("# 🤖 Policy-Agent Chatbot\nAsk me about policies. I’ll query the knowledge base multiple times to retrieve the best answer for you!")
59
-
60
- # popup_widget_html = '''<style>
61
- # .policy-agent-popup-container { position:fixed; bottom:16px; right:16px; z-index:9999; }
62
- # </style>
63
- # <div class="policy-agent-popup-container">
64
- # <script async
65
- # src="https://q77iuwf7ncfemoonbzon2iyd.agents.do-ai.run/static/chatbot/widget.js"
66
- # data-agent-id="fcad9141-8590-11f0-b074-4e013e2ddde4"
67
- # data-chatbot-id="oTQKgtWMkQLbLVw7CIHkbxw25Pu9jekn"
68
- # data-name="policy-agent Chatbot"
69
- # data-primary-color="#031B4E"
70
- # data-secondary-color="#E5E8ED"
71
- # data-button-background-color="#0061EB"
72
- # data-starting-message="Hello! I am your policy analysis bot made to help you comb through the policies."
73
- # data-logo="/static/chatbot/icons/default-agent.svg">
74
- # </script>
75
- # </div>'''
76
- # gr.HTML(popup_widget_html)
77
 
78
  # chatbot = gr.Chatbot(height=500)
79
  # msg = gr.Textbox(placeholder="Type your question...")
80
  # retrieval_slider = gr.Slider(1, 10, value=DEFAULT_RETRIEVAL_RUNS, step=1, label="Number of retrieval runs")
81
- # clear = gr.Button("Clear Chat")
 
 
82
 
83
  # msg.submit(policy_chat, [msg, chatbot, retrieval_slider], [chatbot, chatbot])
84
  # msg.submit(lambda: "", None, msg) # clear textbox
85
  # clear.click(lambda: None, None, chatbot, queue=False)
 
86
 
87
  # if __name__ == "__main__":
88
  # demo.launch(debug=True)
89
 
90
  import gradio as gr
91
- from openai import OpenAI
 
 
 
92
 
93
- # 🔹 Configure your agent
94
- agent_endpoint = "https://q77iuwf7ncfemoonbzon2iyd.agents.do-ai.run/api/v1/"
95
- agent_access_key = "CzIwmTIDFNWRRIHvxVNzKWztq8rn5S5w"
96
 
97
- client = OpenAI(base_url=agent_endpoint, api_key=agent_access_key)
 
98
 
99
- # Parameters
100
- DEFAULT_RETRIEVAL_RUNS = 3 # adjustable in UI
101
- stop_flag = {"stop": False} # global flag for stopping runs
102
 
103
- def stop_runs():
104
- """Set stop flag to True to interrupt current processing."""
105
- stop_flag["stop"] = True
106
- return "⛔ Retrieval stopped by user."
107
-
108
-
109
- def policy_chat(message, history, retrieval_runs=DEFAULT_RETRIEVAL_RUNS):
110
  """
111
- Runs multiple retrievals, stores responses, and returns the best one.
 
112
  """
113
- # Reset stop flag
114
  stop_flag["stop"] = False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
- # Show "processing" placeholder in UI
117
- history = history + [[message, "Processing..."]]
118
- yield history, history
119
-
120
- aggregated_responses = []
121
-
122
- for run in range(retrieval_runs):
123
- if stop_flag["stop"]:
124
- history[-1][1] = "⛔ Stopped before completion."
125
- yield history, history
126
- return
127
-
128
- try:
129
- # Stream response but collect full text silently
130
- stream = client.chat.completions.create(
131
- model="n/a", # agent handles routing
132
- messages=[
133
- {"role": "system", "content": "The data must be returned verbatim. Please be quite detailed and include all information. You are new to the analysis of policy documents, hence you need to be objective in retrieving information, and it is not expected that you will analyse and interpret the information."},
134
- *[{"role": "user", "content": u} if i % 2 == 0 else {"role": "assistant", "content": b}
135
- for i, (u, b) in enumerate(history[:-1])], # exclude placeholder
136
- {"role": "user", "content": message},
137
- ],
138
- extra_body={"include_retrieval_info": True},
139
- stream=True,
140
- )
141
-
142
- response_text = ""
143
- for chunk in stream:
144
- delta = chunk.choices[0].delta
145
- if delta and delta.content:
146
- response_text += delta.content
147
-
148
- aggregated_responses.append(response_text or "⚠️ Empty response")
149
-
150
- except Exception as e:
151
- aggregated_responses.append(f"⚠️ Error during run {run+1}: {str(e)}")
152
-
153
- # --- Selection logic ---
154
- # For now, pick the "best" as the longest response
155
- best_response = max(aggregated_responses, key=len, default="⚠️ No response")
156
-
157
- # Replace "Processing..." with final answer
158
- history[-1][1] = best_response
159
- yield history, history
160
-
161
 
162
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="gray")) as demo:
163
- gr.Markdown("# 🤖 Policy-Agent Chatbot\nAsk me about policies. Ill query the knowledge base multiple times!")
164
 
165
- chatbot = gr.Chatbot(height=500)
166
- msg = gr.Textbox(placeholder="Type your question...")
167
- retrieval_slider = gr.Slider(1, 10, value=DEFAULT_RETRIEVAL_RUNS, step=1, label="Number of retrieval runs")
168
  with gr.Row():
169
- clear = gr.Button("Clear Chat")
170
- stop = gr.Button(" Stop")
 
 
 
 
 
 
 
 
171
 
172
- msg.submit(policy_chat, [msg, chatbot, retrieval_slider], [chatbot, chatbot])
173
- msg.submit(lambda: "", None, msg) # clear textbox
174
- clear.click(lambda: None, None, chatbot, queue=False)
175
- stop.click(stop_runs, None, chatbot, queue=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
  if __name__ == "__main__":
178
- demo.launch(debug=True)
 
 
 
 
1
+ # # import gradio as gr
2
+ # # from openai import OpenAI
3
+
4
+ # # # 🔹 Configure your agent
5
+ # # agent_endpoint = "https://q77iuwf7ncfemoonbzon2iyd.agents.do-ai.run/api/v1/"
6
+ # # agent_access_key = "CzIwmTIDFNWRRIHvxVNzKWztq8rn5S5w"
7
+
8
+ # # client = OpenAI(base_url=agent_endpoint, api_key=agent_access_key)
9
+
10
+ # # # Parameters
11
+ # # DEFAULT_RETRIEVAL_RUNS = 3 # adjustable in UI
12
+
13
+ # # def policy_chat(message, history, retrieval_runs=DEFAULT_RETRIEVAL_RUNS):
14
+ # # """
15
+ # # Chatbot with streaming + multiple retrieval runs.
16
+ # # """
17
+ # # # Show "processing" placeholder
18
+ # # history = history + [[message, "Processing..."]]
19
+ # # yield history, history
20
+
21
+ # # aggregated_responses = []
22
+
23
+ # # for run in range(retrieval_runs):
24
+ # # try:
25
+ # # stream = client.chat.completions.create(
26
+ # # model="n/a", # agent handles routing
27
+ # # messages=[
28
+ # # {"role": "system", "content": "The data must be returned verbatim. Please be quite detailed and include all information. You are new to the analysis of policy documents, hence you need to be objective in retrieving information, and it is not expected that you will analyse and interpret the information."},
29
+ # # *[{"role": "user", "content": u} if i % 2 == 0 else {"role": "assistant", "content": b}
30
+ # # for i, (u, b) in enumerate(history[:-1])], # exclude placeholder
31
+ # # {"role": "user", "content": message},
32
+ # # ],
33
+ # # extra_body={"include_retrieval_info": True},
34
+ # # stream=True,
35
+ # # )
36
+
37
+ # # response_text = ""
38
+ # # for chunk in stream:
39
+ # # delta = chunk.choices[0].delta
40
+ # # if delta and delta.content: # delta.content is a string or None
41
+ # # response_text += delta.content
42
+ # # # Stream update to Gradio UI
43
+ # # history[-1][1] = response_text
44
+ # # yield history, history
45
+
46
+ # # aggregated_responses.append(response_text or "⚠️ Empty response")
47
+
48
+ # # except Exception as e:
49
+ # # aggregated_responses.append(f"⚠️ Error during run {run+1}: {str(e)}")
50
+
51
+ # # # 🔹 Choose the “best” response (longest for now)
52
+ # # best_response = max(aggregated_responses, key=len, default="⚠️ No response")
53
+ # # history[-1][1] = best_response
54
+ # # yield history, history
55
+
56
+
57
+ # # with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="gray")) as demo:
58
+ # # gr.Markdown("# 🤖 Policy-Agent Chatbot\nAsk me about policies. I’ll query the knowledge base multiple times to retrieve the best answer for you!")
59
+
60
+ # # popup_widget_html = '''<style>
61
+ # # .policy-agent-popup-container { position:fixed; bottom:16px; right:16px; z-index:9999; }
62
+ # # </style>
63
+ # # <div class="policy-agent-popup-container">
64
+ # # <script async
65
+ # # src="https://q77iuwf7ncfemoonbzon2iyd.agents.do-ai.run/static/chatbot/widget.js"
66
+ # # data-agent-id="fcad9141-8590-11f0-b074-4e013e2ddde4"
67
+ # # data-chatbot-id="oTQKgtWMkQLbLVw7CIHkbxw25Pu9jekn"
68
+ # # data-name="policy-agent Chatbot"
69
+ # # data-primary-color="#031B4E"
70
+ # # data-secondary-color="#E5E8ED"
71
+ # # data-button-background-color="#0061EB"
72
+ # # data-starting-message="Hello! I am your policy analysis bot made to help you comb through the policies."
73
+ # # data-logo="/static/chatbot/icons/default-agent.svg">
74
+ # # </script>
75
+ # # </div>'''
76
+ # # gr.HTML(popup_widget_html)
77
+
78
+ # # chatbot = gr.Chatbot(height=500)
79
+ # # msg = gr.Textbox(placeholder="Type your question...")
80
+ # # retrieval_slider = gr.Slider(1, 10, value=DEFAULT_RETRIEVAL_RUNS, step=1, label="Number of retrieval runs")
81
+ # # clear = gr.Button("Clear Chat")
82
+
83
+ # # msg.submit(policy_chat, [msg, chatbot, retrieval_slider], [chatbot, chatbot])
84
+ # # msg.submit(lambda: "", None, msg) # clear textbox
85
+ # # clear.click(lambda: None, None, chatbot, queue=False)
86
+
87
+ # # if __name__ == "__main__":
88
+ # # demo.launch(debug=True)
89
+
90
  # import gradio as gr
91
  # from openai import OpenAI
92
 
 
98
 
99
  # # Parameters
100
  # DEFAULT_RETRIEVAL_RUNS = 3 # adjustable in UI
101
+ # stop_flag = {"stop": False} # global flag for stopping runs
102
+
103
+ # def stop_runs():
104
+ # """Set stop flag to True to interrupt current processing."""
105
+ # stop_flag["stop"] = True
106
+ # return "⛔ Retrieval stopped by user."
107
+
108
 
109
  # def policy_chat(message, history, retrieval_runs=DEFAULT_RETRIEVAL_RUNS):
110
  # """
111
+ # Runs multiple retrievals, stores responses, and returns the best one.
112
  # """
113
+ # # Reset stop flag
114
+ # stop_flag["stop"] = False
115
+
116
+ # # Show "processing" placeholder in UI
117
  # history = history + [[message, "Processing..."]]
118
  # yield history, history
119
 
120
  # aggregated_responses = []
121
 
122
  # for run in range(retrieval_runs):
123
+ # if stop_flag["stop"]:
124
+ # history[-1][1] = "⛔ Stopped before completion."
125
+ # yield history, history
126
+ # return
127
+
128
  # try:
129
+ # # Stream response but collect full text silently
130
  # stream = client.chat.completions.create(
131
  # model="n/a", # agent handles routing
132
  # messages=[
 
142
  # response_text = ""
143
  # for chunk in stream:
144
  # delta = chunk.choices[0].delta
145
+ # if delta and delta.content:
146
  # response_text += delta.content
 
 
 
147
 
148
  # aggregated_responses.append(response_text or "⚠️ Empty response")
149
 
150
  # except Exception as e:
151
  # aggregated_responses.append(f"⚠️ Error during run {run+1}: {str(e)}")
152
 
153
+ # # --- Selection logic ---
154
+ # # For now, pick the "best" as the longest response
155
  # best_response = max(aggregated_responses, key=len, default="⚠️ No response")
156
+
157
+ # # Replace "Processing..." with final answer
158
  # history[-1][1] = best_response
159
  # yield history, history
160
 
161
 
162
  # with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="gray")) as demo:
163
+ # gr.Markdown("# 🤖 Policy-Agent Chatbot\nAsk me about policies. I’ll query the knowledge base multiple times!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
  # chatbot = gr.Chatbot(height=500)
166
  # msg = gr.Textbox(placeholder="Type your question...")
167
  # retrieval_slider = gr.Slider(1, 10, value=DEFAULT_RETRIEVAL_RUNS, step=1, label="Number of retrieval runs")
168
+ # with gr.Row():
169
+ # clear = gr.Button("Clear Chat")
170
+ # stop = gr.Button("⛔ Stop")
171
 
172
  # msg.submit(policy_chat, [msg, chatbot, retrieval_slider], [chatbot, chatbot])
173
  # msg.submit(lambda: "", None, msg) # clear textbox
174
  # clear.click(lambda: None, None, chatbot, queue=False)
175
+ # stop.click(stop_runs, None, chatbot, queue=False)
176
 
177
  # if __name__ == "__main__":
178
  # demo.launch(debug=True)
179
 
180
  import gradio as gr
181
+ import openai
182
+ import os
183
+ from datetime import datetime
184
+ import json
185
 
186
+ # --- Global Variables and Initial Setup ---
187
+ stop_flag = {"stop": False}
 
188
 
189
+ # Placeholder for reasoning data
190
+ REASONING_CONTEXT = ""
191
 
192
+ # --- Core Functions ---
 
 
193
 
194
+ def policy_chat(message, history):
 
 
 
 
 
 
195
  """
196
+ Main chat function that handles user messages, streams responses,
197
+ and provides reasoning.
198
  """
199
+ global stop_flag, REASONING_CONTEXT
200
  stop_flag["stop"] = False
201
+
202
+ # 1. Indicate thinking and reset UI elements
203
+ yield {
204
+ thinking_indicator: gr.update(visible=True),
205
+ reasoning_accordion: gr.update(visible=False, value=""),
206
+ chatbot: history,
207
+ stop_btn: gr.update(visible=True),
208
+ send_btn: gr.update(interactive=False),
209
+ }
210
+
211
+ # --- This is where you would add your retrieval logic ---
212
+ # For demonstration, we'll create mock reasoning context.
213
+ # In a real app, you would retrieve this from your RAG pipeline.
214
+ REASONING_CONTEXT = (
215
+ "### Retrieved Context\n\n"
216
+ "1. **Document:** `policy_document_A.pdf` (Page 17)\n"
217
+ " * **Content:** 'The primary objective for renewable energy is to increase its share in the national grid by 20% by the year 2030.'\n"
218
+ "2. **Document:** `strategy_paper_B.pdf` (Page 5)\n"
219
+ " * **Content:** 'Energy efficiency measures will be enforced through new building codes and industrial standards.'\n"
220
+ )
221
+ # --- End of retrieval logic section ---
222
+
223
+ # 2. Show the reasoning and hide the thinking indicator
224
+ yield {
225
+ reasoning_accordion: gr.update(visible=True, value=REASONING_CONTEXT),
226
+ thinking_indicator: gr.update(visible=False)
227
+ }
228
+
229
+ history.append([message, ""])
230
+
231
+ # 3. Stream the final answer
232
+ try:
233
+ # In a real app, you would pass the retrieved context into your prompt
234
+ response = openai.ChatCompletion.create(
235
+ model="gpt-3.5-turbo",
236
+ messages=[{"role": "user", "content": f"Based on the context, answer this question: {message}"}],
237
+ stream=True,
238
+ # api_base="your_api_base", # Add your endpoint if needed
239
+ # api_key="your_api_key" # Add your key if needed
240
+ )
241
+
242
+ for chunk in response:
243
+ if stop_flag["stop"]:
244
+ break
245
+ if hasattr(chunk.choices[0].delta, 'content'):
246
+ content = chunk.choices[0].delta.content
247
+ if content:
248
+ history[-1][1] += content
249
+ yield {chatbot: history}
250
+
251
+ except Exception as e:
252
+ history[-1][1] = f"An error occurred: {str(e)}"
253
+ finally:
254
+ # 4. Clean up UI after streaming is finished or stopped
255
+ stop_flag["stop"] = False
256
+ yield {
257
+ stop_btn: gr.update(visible=False),
258
+ send_btn: gr.update(interactive=True),
259
+ thinking_indicator: gr.update(visible=False)
260
+ }
261
+
262
+ def stop_streaming():
263
+ """Sets the global flag to stop the streaming."""
264
+ global stop_flag
265
+ stop_flag["stop"] = True
266
 
267
+ def export_chat(history):
268
+ """Exports the chat history to a formatted text file."""
269
+ if not history:
270
+ return None
271
+
272
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
273
+ filename = f"chat_history_{timestamp}.txt"
274
+
275
+ formatted_chat = ""
276
+ for user_msg, bot_msg in history:
277
+ formatted_chat += f"You: {user_msg}\n"
278
+ formatted_chat += f"Bot: {bot_msg}\n\n"
279
+
280
+ # Add reasoning context to the export if it exists
281
+ if REASONING_CONTEXT:
282
+ formatted_chat += "\n" + "="*20 + "\n"
283
+ formatted_chat += "Last Reasoning Context:\n"
284
+ formatted_chat += "="*20 + "\n\n"
285
+ formatted_chat += REASONING_CONTEXT
286
+
287
+ # Create a temporary file that Gradio can serve
288
+ with open(filename, "w", encoding="utf-8") as f:
289
+ f.write(formatted_chat)
290
+
291
+ return filename
292
+
293
+ # --- Gradio UI Layout ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
 
295
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="gray")) as demo:
296
+ gr.Markdown("# 🤖 Policy-Agent Chatbot\nAsk me about policies. I'll stream responses and show my reasoning.")
297
 
 
 
 
298
  with gr.Row():
299
+ with gr.Column(scale=3):
300
+ chatbot = gr.Chatbot(height=600, label="Chat Window", show_copy_button=True)
301
+
302
+ thinking_indicator = gr.Markdown("🤔 Thinking...", visible=False)
303
+
304
+ reasoning_accordion = gr.Markdown(
305
+ "",
306
+ visible=False,
307
+ label="Visualise Reasoning (Retrieved Context)"
308
+ )
309
 
310
+ with gr.Column(scale=1):
311
+ export_btn = gr.Button("Export Chat")
312
+ export_file = gr.File(label="Download Chat History", interactive=False)
313
+
314
+ with gr.Row():
315
+ msg = gr.Textbox(
316
+ placeholder="Type your question and press Enter or click Send...",
317
+ scale=4,
318
+ show_label=False
319
+ )
320
+ send_btn = gr.Button("Send", scale=1)
321
+
322
+ with gr.Row():
323
+ stop_btn = gr.Button("⛔ Stop Streaming", visible=False)
324
+ clear_btn = gr.Button("Clear Chat")
325
+
326
+ # --- Event Handlers ---
327
+
328
+ # Combine all UI updates into a single list of outputs for chat submission
329
+ chat_outputs = [chatbot, thinking_indicator, reasoning_accordion, stop_btn, send_btn]
330
+
331
+ msg.submit(policy_chat, [msg, chatbot], chat_outputs)
332
+ send_btn.click(policy_chat, [msg, chatbot], chat_outputs)
333
+
334
+ # Clear message box after send
335
+ msg.submit(lambda: "", None, msg, queue=False)
336
+ send_btn.click(lambda: "", None, msg, queue=False)
337
+
338
+ # Button actions
339
+ stop_btn.click(stop_streaming, None, None, queue=False)
340
+ clear_btn.click(lambda: ([], "", None), None, [chatbot, reasoning_accordion, export_file], queue=False)
341
+ export_btn.click(export_chat, chatbot, export_file)
342
 
343
  if __name__ == "__main__":
344
+ # NOTE: You may need to configure your OpenAI key via environment variables
345
+ # For example: os.environ["OPENAI_API_KEY"] = "your_key_here"
346
+ # openai.api_base = "your_api_base_here_if_needed"
347
+ demo.launch(debug=True)