not-lain commited on
Commit
bb5628b
Β·
1 Parent(s): 1322445

format with ruff

Browse files
Files changed (1) hide show
  1. app.py +118 -83
app.py CHANGED
@@ -2,12 +2,12 @@
2
  import gradio as gr
3
  from crewai import Agent, Task, Crew, LLM
4
  from crewai_tools import ScrapeWebsiteTool
5
- import os
6
  import queue
7
  import threading
8
  import asyncio
9
  from typing import List, Dict, Generator
10
 
 
11
  # Message Queue System to manage flow of message
12
  class SupportMessageQueue:
13
  def __init__(self):
@@ -24,6 +24,7 @@ class SupportMessageQueue:
24
  messages.append(self.message_queue.get())
25
  return messages
26
 
 
27
  # main class
28
  class SupportCrew:
29
  def __init__(self, api_key: str = None):
@@ -53,9 +54,9 @@ class SupportCrew:
53
  "You need to make sure that you provide the best support! "
54
  "Make sure to provide full complete answers, and make no assumptions."
55
  ),
56
- llm = self.llm,
57
  allow_delegation=False,
58
- verbose=True
59
  )
60
 
61
  self.qa_agent = Agent(
@@ -67,8 +68,8 @@ class SupportCrew:
67
  "You need to make sure that the support representative is providing full "
68
  "complete answers, and make no assumptions."
69
  ),
70
- llm = self.llm,
71
- verbose=True
72
  )
73
 
74
  # task creation with description and expected output format and tools
@@ -87,7 +88,7 @@ class SupportCrew:
87
  "leaving no questions unanswered, and maintain a helpful and friendly tone throughout."
88
  ),
89
  tools=[self.scrape_tool],
90
- agent=self.support_agent
91
  )
92
 
93
  quality_assurance_review = Task(
@@ -106,25 +107,31 @@ class SupportCrew:
106
  "relevant feedback and improvements.\n"
107
  "Don't be too formal, maintain a professional and friendly tone throughout."
108
  ),
109
- agent=self.qa_agent
110
  )
111
 
112
  return [inquiry_resolution, quality_assurance_review]
113
 
114
  # main processing function
115
- async def process_support(self, inquiry: str, website_url: str) -> Generator[List[Dict], None, None]:
 
 
116
  def add_agent_messages(agent_name: str, tasks: str, emoji: str = "πŸ€–"):
117
- self.message_queue.add_message({
118
- "role": "assistant",
119
- "content": agent_name,
120
- "metadata": {"title": f"{emoji} {agent_name}"}
121
- })
122
-
123
- self.message_queue.add_message({
124
- "role": "assistant",
125
- "content": tasks,
126
- "metadata": {"title": f"πŸ“‹ Task for {agent_name}"}
127
- })
 
 
 
 
128
 
129
  # Manages transition between agents
130
  def setup_next_agent(current_agent: str) -> None:
@@ -132,64 +139,69 @@ class SupportCrew:
132
  self.current_agent = "Support Quality Assurance Specialist"
133
  add_agent_messages(
134
  "Support Quality Assurance Specialist",
135
- "Review and improve the support representative's response"
136
  )
137
 
138
  def task_callback(task_output) -> None:
139
  print(f"Task callback received: {task_output}")
140
-
141
  raw_output = task_output.raw
142
  if "## Final Answer:" in raw_output:
143
  content = raw_output.split("## Final Answer:")[1].strip()
144
  else:
145
  content = raw_output.strip()
146
-
147
  if self.current_agent == "Support Quality Assurance Specialist":
148
- self.message_queue.add_message({
149
- "role": "assistant",
150
- "content": "Final response is ready!",
151
- "metadata": {"title": "βœ… Final Response"}
152
- })
153
-
 
 
154
  formatted_content = content
155
  formatted_content = formatted_content.replace("\n#", "\n\n#")
156
  formatted_content = formatted_content.replace("\n-", "\n\n-")
157
  formatted_content = formatted_content.replace("\n*", "\n\n*")
158
  formatted_content = formatted_content.replace("\n1.", "\n\n1.")
159
  formatted_content = formatted_content.replace("\n\n\n", "\n\n")
160
-
161
- self.message_queue.add_message({
162
- "role": "assistant",
163
- "content": formatted_content
164
- })
165
  else:
166
- self.message_queue.add_message({
167
- "role": "assistant",
168
- "content": content,
169
- "metadata": {"title": f"✨ Output from {self.current_agent}"}
170
- })
 
 
171
  setup_next_agent(self.current_agent)
172
 
173
  try:
174
  self.initialize_agents(website_url)
175
  self.current_agent = "Senior Support Representative"
176
 
177
- yield [{
178
- "role": "assistant",
179
- "content": "Starting to process your inquiry...",
180
- "metadata": {"title": "πŸš€ Process Started"}
181
- }]
 
 
182
 
183
  add_agent_messages(
184
  "Senior Support Representative",
185
- "Analyze customer inquiry and provide comprehensive support"
186
  )
187
 
188
  crew = Crew(
189
  agents=[self.support_agent, self.qa_agent],
190
  tasks=self.create_tasks(inquiry),
191
  verbose=True,
192
- task_callback=task_callback
193
  )
194
 
195
  def run_crew():
@@ -197,11 +209,13 @@ class SupportCrew:
197
  crew.kickoff()
198
  except Exception as e:
199
  print(f"Error in crew execution: {str(e)}")
200
- self.message_queue.add_message({
201
- "role": "assistant",
202
- "content": f"An error occurred: {str(e)}",
203
- "metadata": {"title": "❌ Error"}
204
- })
 
 
205
 
206
  thread = threading.Thread(target=run_crew)
207
  thread.start()
@@ -215,23 +229,28 @@ class SupportCrew:
215
 
216
  except Exception as e:
217
  print(f"Error in process_support: {str(e)}")
218
- yield [{
219
- "role": "assistant",
220
- "content": f"An error occurred: {str(e)}",
221
- "metadata": {"title": "❌ Error"}
222
- }]
 
 
 
223
 
224
  def create_demo():
225
  support_crew = None
226
 
227
  with gr.Blocks(theme=gr.themes.Ocean()) as demo:
228
  gr.Markdown("# 🎯 AI Customer Support Crew")
229
- gr.Markdown("This is a friendly, high-performing multi-agent application built with Gradio and CrewAI. Enter a webpage URL and your questions from that webpage.")
 
 
230
  HF_api_key = gr.Textbox(
231
- label='HuggingFace API Key',
232
- type='password',
233
- placeholder='Type your OpenAI API Key and press Enter to access the app...',
234
- interactive=True
235
  )
236
 
237
  chatbot = gr.Chatbot(
@@ -240,8 +259,11 @@ def create_demo():
240
  type="messages",
241
  show_label=True,
242
  visible=False,
243
- avatar_images=(None, "https://avatars.githubusercontent.com/u/170677839?v=4"),
244
- render_markdown=True
 
 
 
245
  )
246
 
247
  with gr.Row(equal_height=True):
@@ -249,13 +271,13 @@ def create_demo():
249
  label="Your Inquiry",
250
  placeholder="Enter your question...",
251
  scale=4,
252
- visible=False
253
  )
254
  website_url = gr.Textbox(
255
  label="Documentation URL",
256
  placeholder="Enter documentation URL to search...",
257
  scale=4,
258
- visible=False
259
  )
260
  btn = gr.Button("Get Support", variant="primary", scale=1, visible=False)
261
 
@@ -263,11 +285,13 @@ def create_demo():
263
  nonlocal support_crew
264
  if not api_key:
265
  history = history or []
266
- history.append({
267
- "role": "assistant",
268
- "content": "Please provide an OpenAI API key.",
269
- "metadata": {"title": "❌ Error"}
270
- })
 
 
271
  yield history
272
  return
273
 
@@ -275,22 +299,28 @@ def create_demo():
275
  support_crew = SupportCrew(api_key=api_key)
276
 
277
  history = history or []
278
- history.append({
279
- "role": "user",
280
- "content": f"Question: {inquiry_text}\nDocumentation: {website_url_text}"
281
- })
 
 
282
  yield history
283
 
284
  try:
285
- async for messages in support_crew.process_support(inquiry_text, website_url_text):
 
 
286
  history.extend(messages)
287
  yield history
288
  except Exception as e:
289
- history.append({
290
- "role": "assistant",
291
- "content": f"An error occurred: {str(e)}",
292
- "metadata": {"title": "❌ Error"}
293
- })
 
 
294
  yield history
295
 
296
  def show_interface():
@@ -299,16 +329,21 @@ def create_demo():
299
  chatbot: gr.Chatbot(visible=True),
300
  inquiry: gr.Textbox(visible=True),
301
  website_url: gr.Textbox(visible=True),
302
- btn: gr.Button(visible=True)
303
  }
304
 
305
- HF_api_key.submit(show_interface, None, [HF_api_key, chatbot, inquiry, website_url, btn])
 
 
306
  btn.click(process_input, [inquiry, website_url, chatbot, HF_api_key], [chatbot])
307
- inquiry.submit(process_input, [inquiry, website_url, chatbot, HF_api_key], [chatbot])
 
 
308
 
309
  return demo
310
 
 
311
  if __name__ == "__main__":
312
  demo = create_demo()
313
  demo.queue()
314
- demo.launch(debug=True)
 
2
  import gradio as gr
3
  from crewai import Agent, Task, Crew, LLM
4
  from crewai_tools import ScrapeWebsiteTool
 
5
  import queue
6
  import threading
7
  import asyncio
8
  from typing import List, Dict, Generator
9
 
10
+
11
  # Message Queue System to manage flow of message
12
  class SupportMessageQueue:
13
  def __init__(self):
 
24
  messages.append(self.message_queue.get())
25
  return messages
26
 
27
+
28
  # main class
29
  class SupportCrew:
30
  def __init__(self, api_key: str = None):
 
54
  "You need to make sure that you provide the best support! "
55
  "Make sure to provide full complete answers, and make no assumptions."
56
  ),
57
+ llm=self.llm,
58
  allow_delegation=False,
59
+ verbose=True,
60
  )
61
 
62
  self.qa_agent = Agent(
 
68
  "You need to make sure that the support representative is providing full "
69
  "complete answers, and make no assumptions."
70
  ),
71
+ llm=self.llm,
72
+ verbose=True,
73
  )
74
 
75
  # task creation with description and expected output format and tools
 
88
  "leaving no questions unanswered, and maintain a helpful and friendly tone throughout."
89
  ),
90
  tools=[self.scrape_tool],
91
+ agent=self.support_agent,
92
  )
93
 
94
  quality_assurance_review = Task(
 
107
  "relevant feedback and improvements.\n"
108
  "Don't be too formal, maintain a professional and friendly tone throughout."
109
  ),
110
+ agent=self.qa_agent,
111
  )
112
 
113
  return [inquiry_resolution, quality_assurance_review]
114
 
115
  # main processing function
116
+ async def process_support(
117
+ self, inquiry: str, website_url: str
118
+ ) -> Generator[List[Dict], None, None]:
119
  def add_agent_messages(agent_name: str, tasks: str, emoji: str = "πŸ€–"):
120
+ self.message_queue.add_message(
121
+ {
122
+ "role": "assistant",
123
+ "content": agent_name,
124
+ "metadata": {"title": f"{emoji} {agent_name}"},
125
+ }
126
+ )
127
+
128
+ self.message_queue.add_message(
129
+ {
130
+ "role": "assistant",
131
+ "content": tasks,
132
+ "metadata": {"title": f"πŸ“‹ Task for {agent_name}"},
133
+ }
134
+ )
135
 
136
  # Manages transition between agents
137
  def setup_next_agent(current_agent: str) -> None:
 
139
  self.current_agent = "Support Quality Assurance Specialist"
140
  add_agent_messages(
141
  "Support Quality Assurance Specialist",
142
+ "Review and improve the support representative's response",
143
  )
144
 
145
  def task_callback(task_output) -> None:
146
  print(f"Task callback received: {task_output}")
147
+
148
  raw_output = task_output.raw
149
  if "## Final Answer:" in raw_output:
150
  content = raw_output.split("## Final Answer:")[1].strip()
151
  else:
152
  content = raw_output.strip()
153
+
154
  if self.current_agent == "Support Quality Assurance Specialist":
155
+ self.message_queue.add_message(
156
+ {
157
+ "role": "assistant",
158
+ "content": "Final response is ready!",
159
+ "metadata": {"title": "βœ… Final Response"},
160
+ }
161
+ )
162
+
163
  formatted_content = content
164
  formatted_content = formatted_content.replace("\n#", "\n\n#")
165
  formatted_content = formatted_content.replace("\n-", "\n\n-")
166
  formatted_content = formatted_content.replace("\n*", "\n\n*")
167
  formatted_content = formatted_content.replace("\n1.", "\n\n1.")
168
  formatted_content = formatted_content.replace("\n\n\n", "\n\n")
169
+
170
+ self.message_queue.add_message(
171
+ {"role": "assistant", "content": formatted_content}
172
+ )
 
173
  else:
174
+ self.message_queue.add_message(
175
+ {
176
+ "role": "assistant",
177
+ "content": content,
178
+ "metadata": {"title": f"✨ Output from {self.current_agent}"},
179
+ }
180
+ )
181
  setup_next_agent(self.current_agent)
182
 
183
  try:
184
  self.initialize_agents(website_url)
185
  self.current_agent = "Senior Support Representative"
186
 
187
+ yield [
188
+ {
189
+ "role": "assistant",
190
+ "content": "Starting to process your inquiry...",
191
+ "metadata": {"title": "πŸš€ Process Started"},
192
+ }
193
+ ]
194
 
195
  add_agent_messages(
196
  "Senior Support Representative",
197
+ "Analyze customer inquiry and provide comprehensive support",
198
  )
199
 
200
  crew = Crew(
201
  agents=[self.support_agent, self.qa_agent],
202
  tasks=self.create_tasks(inquiry),
203
  verbose=True,
204
+ task_callback=task_callback,
205
  )
206
 
207
  def run_crew():
 
209
  crew.kickoff()
210
  except Exception as e:
211
  print(f"Error in crew execution: {str(e)}")
212
+ self.message_queue.add_message(
213
+ {
214
+ "role": "assistant",
215
+ "content": f"An error occurred: {str(e)}",
216
+ "metadata": {"title": "❌ Error"},
217
+ }
218
+ )
219
 
220
  thread = threading.Thread(target=run_crew)
221
  thread.start()
 
229
 
230
  except Exception as e:
231
  print(f"Error in process_support: {str(e)}")
232
+ yield [
233
+ {
234
+ "role": "assistant",
235
+ "content": f"An error occurred: {str(e)}",
236
+ "metadata": {"title": "❌ Error"},
237
+ }
238
+ ]
239
+
240
 
241
  def create_demo():
242
  support_crew = None
243
 
244
  with gr.Blocks(theme=gr.themes.Ocean()) as demo:
245
  gr.Markdown("# 🎯 AI Customer Support Crew")
246
+ gr.Markdown(
247
+ "This is a friendly, high-performing multi-agent application built with Gradio and CrewAI. Enter a webpage URL and your questions from that webpage."
248
+ )
249
  HF_api_key = gr.Textbox(
250
+ label="HuggingFace API Key",
251
+ type="password",
252
+ placeholder="Type your OpenAI API Key and press Enter to access the app...",
253
+ interactive=True,
254
  )
255
 
256
  chatbot = gr.Chatbot(
 
259
  type="messages",
260
  show_label=True,
261
  visible=False,
262
+ avatar_images=(
263
+ None,
264
+ "https://avatars.githubusercontent.com/u/170677839?v=4",
265
+ ),
266
+ render_markdown=True,
267
  )
268
 
269
  with gr.Row(equal_height=True):
 
271
  label="Your Inquiry",
272
  placeholder="Enter your question...",
273
  scale=4,
274
+ visible=False,
275
  )
276
  website_url = gr.Textbox(
277
  label="Documentation URL",
278
  placeholder="Enter documentation URL to search...",
279
  scale=4,
280
+ visible=False,
281
  )
282
  btn = gr.Button("Get Support", variant="primary", scale=1, visible=False)
283
 
 
285
  nonlocal support_crew
286
  if not api_key:
287
  history = history or []
288
+ history.append(
289
+ {
290
+ "role": "assistant",
291
+ "content": "Please provide an OpenAI API key.",
292
+ "metadata": {"title": "❌ Error"},
293
+ }
294
+ )
295
  yield history
296
  return
297
 
 
299
  support_crew = SupportCrew(api_key=api_key)
300
 
301
  history = history or []
302
+ history.append(
303
+ {
304
+ "role": "user",
305
+ "content": f"Question: {inquiry_text}\nDocumentation: {website_url_text}",
306
+ }
307
+ )
308
  yield history
309
 
310
  try:
311
+ async for messages in support_crew.process_support(
312
+ inquiry_text, website_url_text
313
+ ):
314
  history.extend(messages)
315
  yield history
316
  except Exception as e:
317
+ history.append(
318
+ {
319
+ "role": "assistant",
320
+ "content": f"An error occurred: {str(e)}",
321
+ "metadata": {"title": "❌ Error"},
322
+ }
323
+ )
324
  yield history
325
 
326
  def show_interface():
 
329
  chatbot: gr.Chatbot(visible=True),
330
  inquiry: gr.Textbox(visible=True),
331
  website_url: gr.Textbox(visible=True),
332
+ btn: gr.Button(visible=True),
333
  }
334
 
335
+ HF_api_key.submit(
336
+ show_interface, None, [HF_api_key, chatbot, inquiry, website_url, btn]
337
+ )
338
  btn.click(process_input, [inquiry, website_url, chatbot, HF_api_key], [chatbot])
339
+ inquiry.submit(
340
+ process_input, [inquiry, website_url, chatbot, HF_api_key], [chatbot]
341
+ )
342
 
343
  return demo
344
 
345
+
346
  if __name__ == "__main__":
347
  demo = create_demo()
348
  demo.queue()
349
+ demo.launch(debug=True)