Cascade Bot commited on
Commit
b4bc78c
·
1 Parent(s): 72416ea

fix: update chat interface

Browse files

- Fixed event handlers to return tuples instead of lists
- Added chat state initialization
- Fixed process_message to handle history correctly
- Simplified response handling

Files changed (1) hide show
  1. app.py +109 -290
app.py CHANGED
@@ -39,53 +39,35 @@ from api.venture_api import VentureAPI
39
  logging.basicConfig(level=logging.INFO)
40
  logger = logging.getLogger(__name__)
41
 
42
- # Configure network settings
43
- TIMEOUT = int(os.getenv('REQUESTS_TIMEOUT', '30'))
44
- MAX_RETRIES = 5
45
- RETRY_BACKOFF = 1
46
-
47
  def setup_requests_session():
48
- """Configure requests session with retries."""
49
  session = requests.Session()
50
- retry_strategy = Retry(
51
- total=MAX_RETRIES,
52
- backoff_factor=RETRY_BACKOFF,
53
- status_forcelist=[408, 429, 500, 502, 503, 504],
54
- allowed_methods=["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"]
55
  )
56
- adapter = HTTPAdapter(max_retries=retry_strategy)
57
- session.mount("https://", adapter)
58
- session.mount("http://", adapter)
59
  return session
60
 
61
- def check_network(max_attempts=3):
62
- """Check network connectivity with retries."""
63
- session = setup_requests_session()
 
 
 
 
 
64
 
65
- for attempt in range(max_attempts):
66
- try:
67
- # Try multiple DNS servers
68
- for dns in ['8.8.8.8', '8.8.4.4', '1.1.1.1']:
69
- try:
70
- socket.gethostbyname('huggingface.co')
71
- break
72
- except socket.gaierror:
73
- continue
74
-
75
- # Test connection to Hugging Face
76
- response = session.get('https://huggingface.co/api/health',
77
- timeout=TIMEOUT)
78
- if response.status_code == 200:
79
- return True
80
-
81
- except (requests.RequestException, socket.gaierror) as e:
82
- logger.warning(f"Network check attempt {attempt + 1} failed: {e}")
83
- if attempt < max_attempts - 1:
84
- time.sleep(RETRY_BACKOFF * (attempt + 1))
85
- continue
86
-
87
- logger.error("Network connectivity check failed after all attempts")
88
- return False
89
 
90
  class ChatInterface:
91
  """Chat interface for interacting with the agentic system."""
@@ -109,6 +91,10 @@ class ChatInterface:
109
  }
110
  }
111
 
 
 
 
 
112
  # Initialize components
113
  self.orchestrator = AgentOrchestrator(config)
114
  self.team_manager = TeamManager(self.orchestrator)
@@ -267,7 +253,7 @@ class ChatInterface:
267
  try:
268
  # Convert history to the format expected by process_message
269
  history_list = [[x, y] for x, y in history] if history else []
270
- response, history_list = await self.process_message(message, history_list)
271
 
272
  # Update history
273
  if history is None:
@@ -292,39 +278,39 @@ class ChatInterface:
292
  history = history[:-1] # Remove last exchange
293
  return await respond(last_user_msg, history)
294
 
 
295
  msg.submit(
296
  respond,
297
  [msg, chatbot],
298
- [msg, chatbot],
299
- api_name="chat"
300
  ).then(
301
- lambda: gr.update(interactive=True),
302
  None,
303
- [msg, submit],
304
- queue=False
305
  )
306
 
307
  submit.click(
308
  respond,
309
  [msg, chatbot],
310
- [msg, chatbot],
311
- api_name="submit"
312
  ).then(
313
- lambda: gr.update(interactive=True),
314
  None,
315
- [msg, submit],
316
- queue=False
317
  )
318
 
319
  retry.click(
320
  retry_last,
321
  [chatbot],
322
- [chatbot],
323
- api_name="retry"
324
  )
325
 
326
  # Event handlers for better UX
327
- msg.change(lambda x: gr.update(interactive=bool(x.strip())), [msg], [submit])
 
 
 
 
328
 
329
  # Add example inputs
330
  gr.Examples(
@@ -343,54 +329,35 @@ class ChatInterface:
343
  async def process_message(
344
  self,
345
  message: str,
346
- history: List[List[str]]
347
- ) -> Tuple[str, List[List[str]]]:
348
- """Process incoming chat message."""
349
  try:
 
 
 
 
350
  # Update chat history
351
  self.chat_history = history
352
-
353
- # Process message
354
- response = await self._handle_message(message)
355
-
356
- # Update history
357
- if response:
358
- history.append([message, response])
359
 
360
- return response, history
361
-
362
- except Exception as e:
363
- logger.error(f"Error processing message: {str(e)}")
364
- error_msg = "I apologize, but I encountered an error. Please try again."
365
- history.append([message, error_msg])
366
- return error_msg, history
367
-
368
- async def _handle_message(self, message: str) -> str:
369
- """Handle message processing with error recovery."""
370
- try:
371
- # Analyze intent
372
  intent = await self._analyze_intent(message)
373
- intent_type = self._get_intent_type(intent)
374
 
375
- # Route to appropriate handler
376
- if intent_type == "query":
377
- return await self._handle_query(message)
378
- elif intent_type == "objective":
379
- return await self._handle_objective(message)
380
- elif intent_type == "status":
381
- return await self._handle_status_request(message)
382
  else:
383
- return await self._handle_general_chat(message)
384
-
 
 
385
  except Exception as e:
386
- logger.error(f"Error in message handling: {str(e)}")
387
- return "I apologize, but I encountered an error processing your message. Please try again."
388
-
389
- def _get_intent_type(self, intent) -> str:
390
- """Safely extract intent type from various result formats."""
391
- if isinstance(intent, dict):
392
- return intent.get("type", "general")
393
- return "general"
394
 
395
  async def _analyze_intent(self, message: str) -> Dict[str, Any]:
396
  """Analyze user message intent with error handling."""
@@ -404,77 +371,35 @@ class ChatInterface:
404
  }
405
  )
406
 
407
- return {
408
- "type": analysis.get("intent_type", "general"),
409
- "confidence": analysis.get("confidence", 0.5),
410
- "entities": analysis.get("entities", []),
411
- "action_required": analysis.get("action_required", False)
412
- }
413
- except Exception as e:
414
- logger.error(f"Error analyzing intent: {str(e)}")
415
- return {"type": "general", "confidence": 0.5}
416
-
417
- async def _handle_query(self, message: str) -> str:
418
- """Handle information queries."""
419
- try:
420
- # Get relevant teams for the query
421
- recommended_teams = await self.team_manager.get_team_recommendations(message)
422
-
423
- # Get responses from relevant teams
424
- responses = []
425
- for team_type in recommended_teams:
426
- response = await self._get_team_response(team_type, message)
427
- if response:
428
- responses.append(response)
429
-
430
- if not responses:
431
- return "I apologize, but I couldn't find a relevant answer to your query."
432
-
433
- # Combine and format responses
434
- return self._format_team_responses(responses)
435
 
436
  except Exception as e:
437
- logger.error(f"Error handling query: {str(e)}")
438
- return "I apologize, but I encountered an error processing your query. Please try again."
439
-
440
- async def _handle_objective(self, message: str) -> str:
441
- """Handle new objective creation."""
442
- try:
443
- # Create new objective
444
- objective_id = await self.team_manager.create_objective(message)
445
- if not objective_id:
446
- return "I apologize, but I couldn't create the objective. Please try again."
447
-
448
- # Format and return response
449
- return self._format_objective_creation(objective_id)
450
-
451
- except Exception as e:
452
- logger.error(f"Error creating objective: {str(e)}")
453
- return "I apologize, but I encountered an error creating the objective. Please try again."
454
 
455
- async def _handle_status_request(self, message: str) -> str:
456
- """Handle status check requests."""
457
  try:
458
- # Get system status
459
- system_status = await self.agentic_system.get_system_status()
 
 
 
 
 
 
 
460
 
461
- # Get team status
462
- team_status = {}
463
- for team_id, team in self.team_manager.teams.items():
464
- team_status[team.name] = await self.team_manager.monitor_objective_progress(team_id)
465
 
466
- # Get objective status
467
- objective_status = {}
468
- for obj_id, obj in self.active_objectives.items():
469
- objective_status[obj_id] = await self.team_manager.monitor_objective_progress(obj_id)
470
-
471
- return self._format_status_response(system_status, team_status, objective_status)
472
 
473
  except Exception as e:
474
- logger.error(f"Error getting status: {str(e)}")
475
- return "I apologize, but I encountered an error getting the status. Please try again."
476
 
477
- async def _handle_general_chat(self, message: str) -> str:
478
  """Handle general chat interactions with error recovery."""
479
  try:
480
  # Use reasoning engine for response generation
@@ -482,149 +407,43 @@ class ChatInterface:
482
  query=message,
483
  context={
484
  "chat_history": self.chat_history,
485
- "system_state": await self.agentic_system.get_system_status()
486
  }
487
  )
488
 
489
- if not response or not response.get("response"):
490
- return "I apologize, but I couldn't generate a meaningful response. Please try again."
491
-
492
- return response["response"]
493
-
494
- except Exception as e:
495
- logger.error(f"Error in general chat: {str(e)}")
496
- return "I apologize, but I encountered an error processing your message. Please try again."
497
-
498
- async def _get_team_response(self, team_type: TeamType, query: str) -> Dict[str, Any]:
499
- """Get response from a specific team."""
500
- try:
501
- team = self.team_manager.teams.get(team_type.value)
502
- if not team:
503
- return None
504
-
505
- # Get response from team's agents
506
- responses = []
507
- for agent in team.agents:
508
- response = await agent.process_query(query)
509
- if response:
510
- responses.append(response)
511
-
512
- if not responses:
513
- return None
514
-
515
- # Return best response
516
- return self._combine_agent_responses(responses)
517
 
518
  except Exception as e:
519
- logger.error(f"Error getting team response: {str(e)}")
520
- return None
521
 
522
- def _combine_agent_responses(self, responses: List[Dict[str, Any]]) -> Dict[str, Any]:
523
- """Combine multiple agent responses into a coherent response."""
524
  try:
525
- # Sort by confidence
526
- valid_responses = [
527
- r for r in responses
528
- if r.get("success", False) and r.get("response")
529
- ]
530
-
531
- if not valid_responses:
532
- return None
533
-
534
- sorted_responses = sorted(
535
- valid_responses,
536
- key=lambda x: x.get("confidence", 0),
537
- reverse=True
538
- )
539
-
540
- # Take the highest confidence response
541
- return sorted_responses[0]
542
-
543
- except Exception as e:
544
- logger.error(f"Error combining responses: {str(e)}")
545
- return None
546
-
547
- def _format_team_responses(self, responses: List[Dict[str, Any]]) -> str:
548
- """Format team responses into a readable message."""
549
- try:
550
- if not responses:
551
- return "No team responses available."
552
-
553
- formatted = []
554
- for resp in responses:
555
- if resp and resp.get("response"):
556
- team_name = resp.get("team_name", "Unknown Team")
557
- confidence = resp.get("confidence", 0)
558
- formatted.append(
559
- f"\n{team_name} (Confidence: {confidence:.2%}):\n{resp['response']}"
560
- )
561
-
562
- if not formatted:
563
- return "No valid team responses available."
564
-
565
- return "\n".join(formatted)
566
-
567
- except Exception as e:
568
- logger.error(f"Error formatting responses: {str(e)}")
569
- return "Error formatting team responses."
570
-
571
- def _format_objective_creation(self, objective_id: str) -> str:
572
- """Format objective creation response."""
573
- try:
574
- obj = self.active_objectives.get(objective_id)
575
- if not obj:
576
- return "Objective created but details not available."
577
 
578
- return "\n".join([
579
- "New Objective Created:",
580
- f"Description: {obj['description']}",
581
- f"Status: {obj['status']}",
582
- f"Assigned Teams: {', '.join(t.value for t in obj['teams'])}"
583
- ])
584
 
585
- except Exception as e:
586
- logger.error(f"Error formatting objective: {str(e)}")
587
- return "Error formatting objective details."
588
-
589
- def _format_status_response(
590
- self,
591
- system_status: Dict[str, Any],
592
- team_status: Dict[str, Any],
593
- objective_status: Dict[str, Any]
594
- ) -> str:
595
- """Format status response."""
596
- try:
597
- # Format system status
598
- status = [
599
- "System Status:",
600
- f"- State: {system_status['state']}",
601
- f"- Active Agents: {system_status['agent_count']}",
602
- f"- Active Tasks: {system_status['active_tasks']}",
603
- "\nTeam Status:"
604
- ]
605
 
606
- # Add team status
607
- for team_name, team_info in team_status.items():
608
- status.extend([
609
- f"\n{team_name}:",
610
- f"- Active Agents: {team_info['active_agents']}",
611
- f"- Completion Rate: {team_info['completion_rate']:.2%}",
612
- f"- Collaboration Score: {team_info['collaboration_score']:.2f}"
613
- ])
614
 
615
- # Add objective status
616
- if objective_status:
617
- status.append("\nActive Objectives:")
618
- for obj_id, obj_info in objective_status.items():
619
- obj = self.active_objectives[obj_id]
620
- status.extend([
621
- f"\n{obj['description']}:",
622
- f"- Status: {obj['status']}",
623
- f"- Teams: {', '.join(t.value for t in obj['teams'])}",
624
- f"- Progress: {sum(t['completion_rate'] for t in obj_info.values())/len(obj_info):.2%}"
625
- ])
626
 
627
- return "\n".join(status)
628
 
629
  except Exception as e:
630
  logger.error(f"Error formatting status: {str(e)}")
@@ -637,8 +456,8 @@ def create_chat_interface() -> gr.Blocks:
637
 
638
  # Initialize FastAPI
639
  app = FastAPI(
640
- title="Advanced Agentic System",
641
- description="Venture Strategy Optimizer with OpenAI-compatible API",
642
  version="1.0.0"
643
  )
644
 
 
39
  logging.basicConfig(level=logging.INFO)
40
  logger = logging.getLogger(__name__)
41
 
 
 
 
 
 
42
  def setup_requests_session():
43
+ """Set up requests session with retries."""
44
  session = requests.Session()
45
+ retries = Retry(
46
+ total=5,
47
+ backoff_factor=0.1,
48
+ status_forcelist=[500, 502, 503, 504]
 
49
  )
50
+ session.mount('http://', HTTPAdapter(max_retries=retries))
51
+ session.mount('https://', HTTPAdapter(max_retries=retries))
 
52
  return session
53
 
54
+ def check_network():
55
+ """Check network connectivity."""
56
+ try:
57
+ # Try DNS resolution first
58
+ socket.gethostbyname('huggingface.co')
59
+ return True
60
+ except socket.gaierror:
61
+ logger.warning("DNS resolution failed")
62
 
63
+ try:
64
+ # Try HTTP request as backup
65
+ session = setup_requests_session()
66
+ response = session.get('https://huggingface.co', timeout=5)
67
+ return response.status_code == 200
68
+ except (requests.RequestException, socket.gaierror) as e:
69
+ logger.warning(f"Network connectivity check failed: {e}")
70
+ return False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  class ChatInterface:
73
  """Chat interface for interacting with the agentic system."""
 
91
  }
92
  }
93
 
94
+ # Initialize chat state
95
+ self.chat_history = []
96
+ self.active_objectives = {}
97
+
98
  # Initialize components
99
  self.orchestrator = AgentOrchestrator(config)
100
  self.team_manager = TeamManager(self.orchestrator)
 
253
  try:
254
  # Convert history to the format expected by process_message
255
  history_list = [[x, y] for x, y in history] if history else []
256
+ response = await self.process_message(message, history_list)
257
 
258
  # Update history
259
  if history is None:
 
278
  history = history[:-1] # Remove last exchange
279
  return await respond(last_user_msg, history)
280
 
281
+ # Submit handlers
282
  msg.submit(
283
  respond,
284
  [msg, chatbot],
285
+ [msg, chatbot]
 
286
  ).then(
287
+ lambda: (gr.update(value="", interactive=True), gr.update(interactive=True)),
288
  None,
289
+ [msg, submit]
 
290
  )
291
 
292
  submit.click(
293
  respond,
294
  [msg, chatbot],
295
+ [msg, chatbot]
 
296
  ).then(
297
+ lambda: (gr.update(value="", interactive=True), gr.update(interactive=True)),
298
  None,
299
+ [msg, submit]
 
300
  )
301
 
302
  retry.click(
303
  retry_last,
304
  [chatbot],
305
+ [chatbot]
 
306
  )
307
 
308
  # Event handlers for better UX
309
+ msg.change(
310
+ lambda x: (gr.update(interactive=bool(x.strip())), gr.update(interactive=bool(x.strip()))),
311
+ [msg],
312
+ [msg, submit]
313
+ )
314
 
315
  # Add example inputs
316
  gr.Examples(
 
329
  async def process_message(
330
  self,
331
  message: str,
332
+ history: List[List[str]] = None
333
+ ) -> str:
334
+ """Process a user message."""
335
  try:
336
+ # Initialize history if None
337
+ if history is None:
338
+ history = []
339
+
340
  # Update chat history
341
  self.chat_history = history
 
 
 
 
 
 
 
342
 
343
+ # Analyze message intent
 
 
 
 
 
 
 
 
 
 
 
344
  intent = await self._analyze_intent(message)
 
345
 
346
+ # Process based on intent
347
+ if intent.get('type') == 'objective':
348
+ response = await self._handle_objective(message, intent)
349
+ elif intent.get('type') == 'status':
350
+ response = await self._get_status()
351
+ elif intent.get('type') == 'chat':
352
+ response = await self._handle_chat(message)
353
  else:
354
+ response = await self._handle_chat(message) # Default to chat handler
355
+
356
+ return response
357
+
358
  except Exception as e:
359
+ logger.error(f"Error processing message: {str(e)}")
360
+ return "I encountered an error processing your message. Please try again."
 
 
 
 
 
 
361
 
362
  async def _analyze_intent(self, message: str) -> Dict[str, Any]:
363
  """Analyze user message intent with error handling."""
 
371
  }
372
  )
373
 
374
+ return analysis
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
 
376
  except Exception as e:
377
+ logger.error(f"Error analyzing intent: {str(e)}")
378
+ return {"type": "unknown", "error": str(e)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
 
380
+ async def _handle_objective(self, message: str, intent: Dict[str, Any]) -> str:
381
+ """Handle objective creation and management."""
382
  try:
383
+ # Extract objective details
384
+ objective = intent.get('objective', {})
385
+
386
+ # Create objective
387
+ objective_id = await self.team_manager.create_cross_team_objective(
388
+ objective=objective.get('description', message),
389
+ required_teams=objective.get('teams', []),
390
+ priority=objective.get('priority', 'MEDIUM')
391
+ )
392
 
393
+ # Monitor progress
394
+ status = await self.team_manager.monitor_objective_progress(objective_id)
 
 
395
 
396
+ return f"Created objective {objective_id}. Current status: {status}"
 
 
 
 
 
397
 
398
  except Exception as e:
399
+ logger.error(f"Error handling objective: {str(e)}")
400
+ return "Failed to create objective. Please try again."
401
 
402
+ async def _handle_chat(self, message: str) -> str:
403
  """Handle general chat interactions with error recovery."""
404
  try:
405
  # Use reasoning engine for response generation
 
407
  query=message,
408
  context={
409
  "chat_history": self.chat_history,
410
+ "active_objectives": self.active_objectives
411
  }
412
  )
413
 
414
+ return response.get('response', "I'm not sure how to respond to that.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
 
416
  except Exception as e:
417
+ logger.error(f"Error in chat response: {str(e)}")
418
+ return "I encountered an error generating a response. Please try again."
419
 
420
+ async def _get_status(self) -> str:
421
+ """Get system status information."""
422
  try:
423
+ # Get team status
424
+ team_status = await self.team_manager.get_team_status()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
 
426
+ # Get objective status
427
+ objective_status = await self.team_manager.get_objective_status()
 
 
 
 
428
 
429
+ # Format status information
430
+ status = "Current System Status:\n\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
 
432
+ # Add team information
433
+ status += "Teams:\n"
434
+ for team, info in team_status.items():
435
+ status += f"- {team}: {info['status']}\n"
436
+ status += f" Active Projects: {info['active_projects']}\n"
437
+ status += f" Success Rate: {info['success_rate']}%\n\n"
 
 
438
 
439
+ # Add objective information
440
+ status += "\nActive Objectives:\n"
441
+ for obj, info in objective_status.items():
442
+ status += f"- {obj}: {info['status']}\n"
443
+ status += f" Progress: {info['progress']}%\n"
444
+ status += f" Teams: {', '.join(info['teams'])}\n\n"
 
 
 
 
 
445
 
446
+ return status
447
 
448
  except Exception as e:
449
  logger.error(f"Error formatting status: {str(e)}")
 
456
 
457
  # Initialize FastAPI
458
  app = FastAPI(
459
+ title="Advanced Agentic System API",
460
+ description="API for interacting with the autonomous agent teams",
461
  version="1.0.0"
462
  )
463