cyberandy commited on
Commit
d4d916e
·
verified ·
1 Parent(s): 1bf336f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +106 -76
app.py CHANGED
@@ -11,31 +11,42 @@ from autogen_agentchat.teams import SelectorGroupChat
11
  from autogen_ext.models.openai import OpenAIChatCompletionClient
12
  from autogen_ext.agents.web_surfer import MultimodalWebSurfer
13
 
14
- # Enable nested event loops for Jupyter compatibility
15
  nest_asyncio.apply()
16
 
17
  class AIShoppingAnalyzer:
18
  def __init__(self, api_key: str):
19
  self.api_key = api_key
20
- # Set the API key in environment
21
  os.environ["OPENAI_API_KEY"] = api_key
22
  self.model_client = OpenAIChatCompletionClient(model="gpt-4o")
23
  self.termination = MaxMessageTermination(max_messages=20) | TextMentionTermination("TERMINATE")
24
 
25
  def create_websurfer(self) -> MultimodalWebSurfer:
26
  """Initialize the web surfer agent for e-commerce research"""
 
 
 
 
 
 
 
 
 
 
 
27
  return MultimodalWebSurfer(
28
  name="websurfer_agent",
29
- description="""E-commerce research specialist that:
30
- 1. Searches multiple retailers for product options
31
- 2. Compares prices and reviews
32
- 3. Checks product specifications and availability
33
- 4. Analyzes website structure and findability
34
- 5. Detects and analyzes structured data (Schema.org, JSON-LD, Microdata)
35
- 6. Evaluates product markup and rich snippets
36
- 7. Checks for proper semantic HTML and data organization""",
37
  model_client=self.model_client,
38
- headless=True
 
 
 
 
 
 
 
 
39
  )
40
 
41
  def create_assistant(self) -> AssistantAgent:
@@ -73,7 +84,7 @@ class AIShoppingAnalyzer:
73
  "[Summary]\n\n"
74
  "🔧 TECHNICAL INSIGHTS\n"
75
  "-------------------\n"
76
- "[Technical Details]\n"
77
  )
78
 
79
  return AssistantAgent(
@@ -83,16 +94,6 @@ class AIShoppingAnalyzer:
83
  model_client=self.model_client
84
  )
85
 
86
- When working with the websurfer_agent:
87
- - Guide their research effectively
88
- - Verify the information they find
89
- - Analyze how easy it was to find products
90
- - Evaluate product page quality
91
- - Say 'keep going' if more research is needed
92
- - Say 'TERMINATE' only when you have a complete analysis""",
93
- model_client=self.model_client
94
- )
95
-
96
  def create_team(self, websurfer_agent: MultimodalWebSurfer, assistant_agent: AssistantAgent) -> SelectorGroupChat:
97
  """Set up the team of agents"""
98
  user_proxy = UserProxyAgent(
@@ -100,17 +101,17 @@ class AIShoppingAnalyzer:
100
  description="An e-commerce site owner looking for AI shopping analysis"
101
  )
102
 
 
 
 
 
 
 
 
 
103
  return SelectorGroupChat(
104
  participants=[websurfer_agent, assistant_agent, user_proxy],
105
- selector_prompt="""You are coordinating an e-commerce analysis system. The following roles are available:
106
- {roles}
107
-
108
- Given the conversation history {history}, select the next role from {participants}.
109
- - The websurfer_agent searches products and analyzes website structure
110
- - The assistant_agent evaluates findings and makes recommendations
111
- - The user_proxy provides input when needed
112
-
113
- Return only the role name.""",
114
  model_client=self.model_client,
115
  termination_condition=self.termination
116
  )
@@ -122,24 +123,21 @@ class AIShoppingAnalyzer:
122
  """Run the analysis with proper cleanup"""
123
  websurfer = None
124
  try:
125
- # Set up the analysis query
126
- query = f"""Analyze the e-commerce experience for {website_url} focusing on:
127
- 1. Product findability in the {product_category} category
128
- 2. Product information quality
129
- 3. Navigation and search functionality
130
- 4. Price visibility and comparison features"""
 
131
 
132
  if specific_product:
133
  query += f"\n5. Detailed analysis of this specific product: {specific_product}"
134
 
135
- # Initialize agents with automatic browser management
136
  websurfer = self.create_websurfer()
137
  assistant = self.create_assistant()
138
-
139
- # Create team
140
  team = self.create_team(websurfer, assistant)
141
 
142
- # Modified execution to handle EOF errors
143
  try:
144
  result = []
145
  async for message in team.run_stream(task=query):
@@ -159,9 +157,8 @@ class AIShoppingAnalyzer:
159
  await websurfer.close()
160
  except Exception as e:
161
  print(f"Cleanup error: {str(e)}")
162
- # Continue even if cleanup fails
163
 
164
- def create_gradio_interface() -> gr.Interface:
165
  """Create the Gradio interface for the AI Shopping Analyzer"""
166
 
167
  css = """
@@ -198,7 +195,6 @@ def create_gradio_interface() -> gr.Interface:
198
  background-color: #e5e7eb;
199
  }
200
 
201
- /* Custom styling for form elements */
202
  .gr-form {
203
  background: transparent !important;
204
  border: none !important;
@@ -233,17 +229,13 @@ def create_gradio_interface() -> gr.Interface:
233
  background-color: #3a3ab8 !important;
234
  }
235
  """
236
-
237
- def validate_api_key(api_key: str) -> bool:
238
- """Validate the OpenAI API key format"""
239
- return api_key.startswith("sk-") and len(api_key) > 20
240
 
241
  async def run_analysis(api_key: str,
242
  website_url: str,
243
  product_category: str,
244
  specific_product: str) -> str:
245
  """Handle the analysis submission"""
246
- if not validate_api_key(api_key):
247
  return "Please enter a valid OpenAI API key (should start with 'sk-')"
248
 
249
  if not website_url:
@@ -263,34 +255,72 @@ def create_gradio_interface() -> gr.Interface:
263
  except Exception as e:
264
  return f"Error during analysis: {str(e)}"
265
 
266
- # Create the interface
267
- return gr.Interface(
268
- fn=run_analysis,
269
- inputs=[
270
- gr.Textbox(label="OpenAI API Key", placeholder="sk-...", type="password"),
271
- gr.Textbox(label="Website URL", placeholder="https://your-store.com"),
272
- gr.Textbox(label="Product Category", placeholder="e.g., Electronics, Clothing, etc."),
273
- gr.Textbox(label="Specific Product (Optional)", placeholder="e.g., Blue Widget Model X")
274
- ],
275
- outputs=gr.Textbox(label="Analysis Results", lines=20),
276
- title="AI Shopping Agent Analyzer",
277
- description="""Analyze how your e-commerce site performs when the shopper is an AI agent.
278
- This tool helps you understand your site's effectiveness for AI-powered shopping assistants.""",
279
- theme="default",
280
- allow_flagging="never"
281
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
  if __name__ == "__main__":
284
- # Install Playwright browsers and dependencies
285
- import subprocess
286
  try:
287
- subprocess.run(["playwright", "install"], check=True)
288
- subprocess.run(["playwright", "install-deps"], check=True)
289
- except subprocess.CalledProcessError as e:
290
- print(f"Error installing Playwright dependencies: {e}")
 
 
 
291
  except Exception as e:
292
- print(f"Unexpected error during setup: {e}")
293
-
294
- # Create and launch the interface
295
- iface = create_gradio_interface()
296
- iface.launch()
 
11
  from autogen_ext.models.openai import OpenAIChatCompletionClient
12
  from autogen_ext.agents.web_surfer import MultimodalWebSurfer
13
 
14
+ # Enable nested event loops
15
  nest_asyncio.apply()
16
 
17
  class AIShoppingAnalyzer:
18
  def __init__(self, api_key: str):
19
  self.api_key = api_key
 
20
  os.environ["OPENAI_API_KEY"] = api_key
21
  self.model_client = OpenAIChatCompletionClient(model="gpt-4o")
22
  self.termination = MaxMessageTermination(max_messages=20) | TextMentionTermination("TERMINATE")
23
 
24
  def create_websurfer(self) -> MultimodalWebSurfer:
25
  """Initialize the web surfer agent for e-commerce research"""
26
+ description = (
27
+ "E-commerce research specialist that:\n"
28
+ "1. Searches multiple retailers for product options\n"
29
+ "2. Compares prices and reviews\n"
30
+ "3. Checks product specifications and availability\n"
31
+ "4. Analyzes website structure and findability\n"
32
+ "5. Detects and analyzes structured data (Schema.org, JSON-LD, Microdata)\n"
33
+ "6. Evaluates product markup and rich snippets\n"
34
+ "7. Checks for proper semantic HTML and data organization"
35
+ )
36
+
37
  return MultimodalWebSurfer(
38
  name="websurfer_agent",
39
+ description=description,
 
 
 
 
 
 
 
40
  model_client=self.model_client,
41
+ headless=True,
42
+ browser_type="chromium",
43
+ playwright_browser_launch_kwargs={
44
+ "args": [
45
+ "--disable-dev-shm-usage",
46
+ "--no-sandbox",
47
+ "--disable-setuid-sandbox"
48
+ ]
49
+ }
50
  )
51
 
52
  def create_assistant(self) -> AssistantAgent:
 
84
  "[Summary]\n\n"
85
  "🔧 TECHNICAL INSIGHTS\n"
86
  "-------------------\n"
87
+ "[Technical Details]"
88
  )
89
 
90
  return AssistantAgent(
 
94
  model_client=self.model_client
95
  )
96
 
 
 
 
 
 
 
 
 
 
 
97
  def create_team(self, websurfer_agent: MultimodalWebSurfer, assistant_agent: AssistantAgent) -> SelectorGroupChat:
98
  """Set up the team of agents"""
99
  user_proxy = UserProxyAgent(
 
101
  description="An e-commerce site owner looking for AI shopping analysis"
102
  )
103
 
104
+ selector_prompt = (
105
+ "You are coordinating an e-commerce analysis system. Select the next role from these participants:\n"
106
+ "- The websurfer_agent searches products and analyzes website structure\n"
107
+ "- The assistant_agent evaluates findings and makes recommendations\n"
108
+ "- The user_proxy provides input when needed\n\n"
109
+ "Return only the role name."
110
+ )
111
+
112
  return SelectorGroupChat(
113
  participants=[websurfer_agent, assistant_agent, user_proxy],
114
+ selector_prompt=selector_prompt,
 
 
 
 
 
 
 
 
115
  model_client=self.model_client,
116
  termination_condition=self.termination
117
  )
 
123
  """Run the analysis with proper cleanup"""
124
  websurfer = None
125
  try:
126
+ query = (
127
+ f"Analyze the e-commerce experience for {website_url} focusing on:\n"
128
+ f"1. Product findability in the {product_category} category\n"
129
+ "2. Product information quality\n"
130
+ "3. Navigation and search functionality\n"
131
+ "4. Price visibility and comparison features"
132
+ )
133
 
134
  if specific_product:
135
  query += f"\n5. Detailed analysis of this specific product: {specific_product}"
136
 
 
137
  websurfer = self.create_websurfer()
138
  assistant = self.create_assistant()
 
 
139
  team = self.create_team(websurfer, assistant)
140
 
 
141
  try:
142
  result = []
143
  async for message in team.run_stream(task=query):
 
157
  await websurfer.close()
158
  except Exception as e:
159
  print(f"Cleanup error: {str(e)}")
 
160
 
161
+ def create_gradio_interface() -> gr.Blocks:
162
  """Create the Gradio interface for the AI Shopping Analyzer"""
163
 
164
  css = """
 
195
  background-color: #e5e7eb;
196
  }
197
 
 
198
  .gr-form {
199
  background: transparent !important;
200
  border: none !important;
 
229
  background-color: #3a3ab8 !important;
230
  }
231
  """
 
 
 
 
232
 
233
  async def run_analysis(api_key: str,
234
  website_url: str,
235
  product_category: str,
236
  specific_product: str) -> str:
237
  """Handle the analysis submission"""
238
+ if not api_key.startswith("sk-"):
239
  return "Please enter a valid OpenAI API key (should start with 'sk-')"
240
 
241
  if not website_url:
 
255
  except Exception as e:
256
  return f"Error during analysis: {str(e)}"
257
 
258
+ with gr.Blocks(css=css) as demo:
259
+ gr.HTML("""
260
+ <div class="dashboard-container p-6">
261
+ <h1 class="text-2xl font-bold mb-2">AI Shopping Agent Analyzer</h1>
262
+ <p class="text-gray-600 mb-6">Analyze how your e-commerce site performs with AI shoppers</p>
263
+ </div>
264
+ """)
265
+
266
+ with gr.Group():
267
+ api_key = gr.Textbox(
268
+ label="OpenAI API Key",
269
+ placeholder="sk-...",
270
+ type="password",
271
+ container=True
272
+ )
273
+
274
+ website_url = gr.Textbox(
275
+ label="Website URL",
276
+ placeholder="https://your-store.com",
277
+ container=True
278
+ )
279
+
280
+ product_category = gr.Textbox(
281
+ label="Product Category",
282
+ placeholder="e.g., Electronics, Clothing, etc.",
283
+ container=True
284
+ )
285
+
286
+ specific_product = gr.Textbox(
287
+ label="Specific Product (Optional)",
288
+ placeholder="e.g., Blue Widget Model X",
289
+ container=True
290
+ )
291
+
292
+ analyze_button = gr.Button(
293
+ "Analyze Site",
294
+ variant="primary"
295
+ )
296
+
297
+ analysis_output = gr.Textbox(
298
+ label="Analysis Results",
299
+ lines=20,
300
+ container=True
301
+ )
302
+
303
+ analyze_button.click(
304
+ fn=run_analysis,
305
+ inputs=[api_key, website_url, product_category, specific_product],
306
+ outputs=analysis_output
307
+ )
308
+
309
+ return demo
310
 
311
  if __name__ == "__main__":
312
+ print("Setting up Playwright...")
 
313
  try:
314
+ import subprocess
315
+ subprocess.run(
316
+ ["playwright", "install", "chromium"],
317
+ check=True,
318
+ capture_output=True,
319
+ text=True
320
+ )
321
  except Exception as e:
322
+ print(f"Warning: Playwright setup encountered an issue: {str(e)}")
323
+
324
+ print("Starting Gradio interface...")
325
+ demo = create_gradio_interface()
326
+ demo.launch()