| | import logging |
| | from typing import Dict, Any, Optional |
| | import asyncio |
| |
|
| | logger = logging.getLogger(__name__) |
| |
|
| | class VoiceTool: |
| | """ |
| | Enhanced MCP Tool for voice-based Q&A using ElevenLabs conversational AI |
| | |
| | Improvements: |
| | - Better error handling and user feedback |
| | - Support for conversation context |
| | - Streaming responses support |
| | - Session management |
| | """ |
| | |
| | def __init__(self, elevenlabs_service): |
| | """ |
| | Initialize Voice Tool |
| | |
| | Args: |
| | elevenlabs_service: ElevenLabs service instance |
| | """ |
| | self.elevenlabs_service = elevenlabs_service |
| | |
| | async def voice_qa( |
| | self, |
| | question: str, |
| | session_id: Optional[str] = None |
| | ) -> Dict[str, Any]: |
| | """ |
| | Ask a question using voice assistant (text-based for web UI) |
| | |
| | Args: |
| | question: User's question |
| | session_id: Optional session ID for conversation context |
| | |
| | Returns: |
| | Dictionary with answer and metadata |
| | """ |
| | try: |
| | |
| | if not self.elevenlabs_service or not self.elevenlabs_service.is_available(): |
| | return { |
| | "success": False, |
| | "error": "Voice assistant not configured. Please set ELEVENLABS_API_KEY in your .env file.", |
| | "help": "Get your API key from: https://elevenlabs.io/app/settings/api-keys" |
| | } |
| | |
| | if not question or not question.strip(): |
| | return { |
| | "success": False, |
| | "error": "Please enter a question" |
| | } |
| | |
| | logger.info(f"Voice QA (session: {session_id}): {question}") |
| | |
| | |
| | result = await self.elevenlabs_service.send_text_message( |
| | message=question, |
| | session_id=session_id or "default" |
| | ) |
| | |
| | if result.get("success"): |
| | return { |
| | "success": True, |
| | "question": question, |
| | "answer": result["answer"], |
| | "session_id": session_id, |
| | "mode": "text" |
| | } |
| | else: |
| | return { |
| | "success": False, |
| | "error": result.get("error", "Unknown error"), |
| | "question": question |
| | } |
| | |
| | except Exception as e: |
| | logger.error(f"Voice QA failed: {str(e)}", exc_info=True) |
| | return { |
| | "success": False, |
| | "error": f"An error occurred: {str(e)}", |
| | "question": question |
| | } |
| | |
| | async def start_session(self, session_id: str) -> Dict[str, Any]: |
| | """ |
| | Start a new voice assistant session |
| | |
| | Args: |
| | session_id: Unique session identifier |
| | |
| | Returns: |
| | Session start status |
| | """ |
| | try: |
| | result = await self.elevenlabs_service.start_conversation(session_id) |
| | return result |
| | except Exception as e: |
| | logger.error(f"Failed to start session: {str(e)}") |
| | return { |
| | "success": False, |
| | "error": str(e) |
| | } |
| | |
| | async def end_session(self, session_id: str) -> Dict[str, Any]: |
| | """ |
| | End a voice assistant session |
| | |
| | Args: |
| | session_id: Session identifier |
| | |
| | Returns: |
| | Session end status |
| | """ |
| | try: |
| | success = await self.elevenlabs_service.end_conversation(session_id) |
| | return { |
| | "success": success, |
| | "message": "Session ended" if success else "Session not found" |
| | } |
| | except Exception as e: |
| | logger.error(f"Failed to end session: {str(e)}") |
| | return { |
| | "success": False, |
| | "error": str(e) |
| | } |
| | |
| | def get_conversation_history(self, session_id: str) -> Dict[str, Any]: |
| | """ |
| | Get conversation history for a session |
| | |
| | Args: |
| | session_id: Session identifier |
| | |
| | Returns: |
| | Dictionary with conversation history |
| | """ |
| | try: |
| | history = self.elevenlabs_service.get_conversation_history(session_id) |
| | return { |
| | "success": True, |
| | "history": history, |
| | "message_count": len(history) |
| | } |
| | except Exception as e: |
| | logger.error(f"Failed to get history: {str(e)}") |
| | return { |
| | "success": False, |
| | "error": str(e), |
| | "history": [] |
| | } |
| | |
| | async def test_connection(self) -> Dict[str, Any]: |
| | """ |
| | Test voice assistant connection |
| | |
| | Returns: |
| | Connection test results |
| | """ |
| | try: |
| | if not self.elevenlabs_service: |
| | return { |
| | "success": False, |
| | "message": "Service not initialized" |
| | } |
| | |
| | result = await self.elevenlabs_service.test_connection() |
| | return { |
| | "success": result["status"] == "success", |
| | **result |
| | } |
| | except Exception as e: |
| | logger.error(f"Connection test failed: {str(e)}") |
| | return { |
| | "success": False, |
| | "message": str(e) |
| | } |