rairo commited on
Commit
e5c8e12
·
verified ·
1 Parent(s): 8f77489

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +54 -52
main.py CHANGED
@@ -976,9 +976,8 @@ import logging
976
 
977
  class ConversationalAIHandler:
978
  def __init__(self):
979
- # CORRECTED: The base_url should be the root of the v1 API.
980
- # Specific paths like '/agents' or '/conversations' will be appended later.
981
- self.base_url = "https://api.elevenlabs.io/v1"
982
  self.api_key = os.getenv("ELEVENLABS_API_KEY")
983
  self.headers = {
984
  "xi-api-key": self.api_key,
@@ -987,7 +986,6 @@ class ConversationalAIHandler:
987
 
988
  def get_british_male_voice_id(self):
989
  """Get British male voice ID"""
990
- # This method's logic is sound and remains unchanged.
991
  try:
992
  logger.info(f"[VOICE] Using known voice ID for Daniel: {KNOWN_VOICE_IDS['Daniel']}")
993
  return KNOWN_VOICE_IDS["Daniel"]
@@ -1000,55 +998,59 @@ class ConversationalAIHandler:
1000
  try:
1001
  logger.info(f"[AGENT] Starting agent creation/retrieval for project: {project_id}")
1002
 
1003
- # Step 1: Check for and verify an existing agent.
 
1004
  existing_agent_id = db_ref.child(f'projects/{project_id}/agent_id').get()
1005
  if existing_agent_id:
1006
- logger.info(f"[AGENT] Found existing agent ID: {existing_agent_id}. Verifying...")
1007
- # CORRECTED: Use the correct verification endpoint.
1008
- verify_url = f"{self.base_url}/agents/{existing_agent_id}"
1009
- try:
1010
- response = requests.get(verify_url, headers=self.headers, timeout=15)
1011
- if response.status_code == 200:
1012
- logger.info(f"[AGENT] Existing agent {existing_agent_id} verified and active.")
1013
- return existing_agent_id
1014
- else:
1015
- logger.warning(f"[AGENT] Verification failed for agent {existing_agent_id} (Status: {response.status_code}). Creating a new one.")
1016
- except Exception as e:
1017
- logger.warning(f"[AGENT] Error verifying existing agent: {str(e)}. Creating a new one.")
1018
-
1019
- # Step 2: If no valid agent exists, create a new one.
1020
- logger.info(f"[AGENT] Creating new agent.")
1021
  voice_id = self.get_british_male_voice_id()
1022
 
1023
  diy_expert_prompt = f"""
1024
  You are an experienced DIY expert with years of hands-on experience in Home Appliance Repair, Automotive Maintenance, Gardening & Urban Farming,
1025
- Upcycling & Sustainable Crafts, or DIY Project Creation. You speak in a friendly, knowledgeable British manner and provide
1026
  practical, actionable advice. You're working on this specific project:
1027
  Project: {project_data.get('projectTitle', 'DIY Project')}
1028
  Description: {project_data.get('projectDescription', '')}
1029
  Initial Plan: {project_data.get('initialPlan', '')}
1030
- Provide helpful, step-by-step guidance while being encouraging and safety-conscious.
1031
  Ask clarifying questions when needed and share relevant tips from your experience.
1032
  """
1033
 
1034
- # CORRECTED: The payload for agent creation is a flatter structure.
1035
- # The complex 'conversation_config' is not used for the standard /agents endpoint.
1036
- agent_payload = {
1037
- "name": f"DIY Expert - {project_data.get('projectTitle', project_id)}",
1038
- "prompt": diy_expert_prompt,
1039
- "voice_id": voice_id,
1040
- "initial_message": "Hello! I'm your Sozo DIY expert assistant. I'm here to help you with your project. What would you like to work on today?",
1041
- "webhook_url": f"{os.getenv('BASE_URL', 'https://rairo-neofix-api.hf.space')}/api/webhook/agent/{project_id}",
1042
- "model": "eleven_turbo_v2" # A default model is recommended
 
 
 
 
 
 
 
 
 
 
 
 
 
1043
  }
1044
 
1045
- # CORRECTED: Use the single, correct endpoint for agent creation.
1046
  creation_url = f"{self.base_url}/agents"
1047
- logger.info(f"[AGENT] Posting to agent creation endpoint: {creation_url}")
1048
 
1049
- response = requests.post(creation_url, headers=self.headers, json=agent_payload, timeout=30)
1050
 
1051
- if response.status_code == 200: # A successful creation returns status 200
 
1052
  agent_info = response.json()
1053
  agent_id = agent_info.get("agent_id")
1054
  logger.info(f"[AGENT] New agent created successfully: {agent_id}")
@@ -1060,7 +1062,6 @@ class ConversationalAIHandler:
1060
  logger.info(f"[AGENT] Agent ID stored in database.")
1061
  return agent_id
1062
  else:
1063
- # This will now give a much more informative error if the payload is wrong.
1064
  logger.error(f"[AGENT] Failed to create agent. Status: {response.status_code}, Response: {response.text}")
1065
  raise Exception(f"Failed to create agent: HTTP {response.status_code} - {response.text}")
1066
 
@@ -1070,12 +1071,13 @@ class ConversationalAIHandler:
1070
 
1071
  def start_conversation(self, agent_id):
1072
  """Start a conversation with the agent"""
1073
- logger.info(f"[CONVERSATION] Starting conversation with agent: {agent_id}")
1074
- # CORRECTED: Use the single, correct endpoint for starting a conversation with an agent.
1075
- conversation_url = f"{self.base_url}/agents/{agent_id}/conversations"
1076
  try:
 
 
 
1077
  response = requests.post(conversation_url, headers=self.headers, json={}, timeout=30)
1078
- if response.status_code == 200: # Successful start returns 200
 
1079
  conversation_info = response.json()
1080
  conversation_id = conversation_info.get("conversation_id")
1081
  logger.info(f"[CONVERSATION] Conversation started successfully: {conversation_id}")
@@ -1083,31 +1085,31 @@ class ConversationalAIHandler:
1083
  else:
1084
  logger.error(f"[CONVERSATION] Failed to start conversation. Status: {response.status_code}, Response: {response.text}")
1085
  raise Exception(f"Failed to start conversation: {response.text}")
 
1086
  except Exception as e:
1087
  logger.error(f"[CONVERSATION] An exception occurred in start_conversation: {e}")
1088
  raise
1089
 
1090
  def send_message(self, agent_id, conversation_id, message):
1091
  """Send a message to the conversation"""
1092
- # The 'agent_id' is not required for this endpoint, but we'll keep the signature for compatibility with your calling code.
1093
- logger.info(f"[MESSAGE] Sending message to conversation: {conversation_id}")
1094
- # CORRECTED: Use the single, correct endpoint for sending a message.
1095
- message_url = f"{self.base_url}/conversations/{conversation_id}/messages"
1096
-
1097
- # CORRECTED: The payload for sending a message is simpler.
1098
- message_payload = {
1099
- "text": message
1100
- }
1101
-
1102
  try:
1103
- response = requests.post(message_url, headers=self.headers, json=message_payload, timeout=30)
 
 
 
 
 
 
 
 
 
1104
  if response.status_code == 200:
1105
  logger.info(f"[MESSAGE] Message sent successfully to {conversation_id}.")
1106
- # The response is streaming audio, but we can return the successful JSON confirmation.
1107
  return response.json()
1108
  else:
1109
  logger.error(f"[MESSAGE] Failed to send message. Status: {response.status_code}, Response: {response.text}")
1110
  raise Exception(f"Failed to send message: {response.text}")
 
1111
  except Exception as e:
1112
  logger.error(f"[MESSAGE] An exception occurred in send_message: {e}")
1113
  raise
 
976
 
977
  class ConversationalAIHandler:
978
  def __init__(self):
979
+ # The base URL for the specific Conversational AI API
980
+ self.base_url = "https://api.elevenlabs.io/v1/conversational-ai"
 
981
  self.api_key = os.getenv("ELEVENLABS_API_KEY")
982
  self.headers = {
983
  "xi-api-key": self.api_key,
 
986
 
987
  def get_british_male_voice_id(self):
988
  """Get British male voice ID"""
 
989
  try:
990
  logger.info(f"[VOICE] Using known voice ID for Daniel: {KNOWN_VOICE_IDS['Daniel']}")
991
  return KNOWN_VOICE_IDS["Daniel"]
 
998
  try:
999
  logger.info(f"[AGENT] Starting agent creation/retrieval for project: {project_id}")
1000
 
1001
+ # Verification of conversational agents requires listing all agents, which is inefficient.
1002
+ # We will rely on the database ID and create a new one if it fails to be used later.
1003
  existing_agent_id = db_ref.child(f'projects/{project_id}/agent_id').get()
1004
  if existing_agent_id:
1005
+ logger.info(f"[AGENT] Found existing agent ID in DB: {existing_agent_id}. Assuming it is active.")
1006
+ return existing_agent_id
1007
+
1008
+ logger.info(f"[AGENT] No existing agent ID found in DB. Creating a new agent.")
 
 
 
 
 
 
 
 
 
 
 
1009
  voice_id = self.get_british_male_voice_id()
1010
 
1011
  diy_expert_prompt = f"""
1012
  You are an experienced DIY expert with years of hands-on experience in Home Appliance Repair, Automotive Maintenance, Gardening & Urban Farming,
1013
+ Upcycling & Sustainable Crafts, or DIY Project Creation. You speak in a friendly, knowledgeable British manner and provide
1014
  practical, actionable advice. You're working on this specific project:
1015
  Project: {project_data.get('projectTitle', 'DIY Project')}
1016
  Description: {project_data.get('projectDescription', '')}
1017
  Initial Plan: {project_data.get('initialPlan', '')}
1018
+ Provide helpful, step-by-step guidance while being encouraging and safety-conscious.
1019
  Ask clarifying questions when needed and share relevant tips from your experience.
1020
  """
1021
 
1022
+ # This is the correct, detailed payload required by the conversational-ai endpoint.
1023
+ agent_data = {
1024
+ "name": f"DIY Expert - {project_data.get('projectTitle', project_data.get('title', 'Project'))}",
1025
+ "conversation_config": {
1026
+ "agent": {
1027
+ "prompt": {"prompt": diy_expert_prompt},
1028
+ "first_message": "Hello! I'm your Sozo DIY expert assistant. I'm here to help you with your project. What would you like to work on today?",
1029
+ "language": "en"
1030
+ },
1031
+ "asr": {
1032
+ "provider": "deepgram",
1033
+ "user_input_audio_format": "pcm_16000"
1034
+ },
1035
+ "tts": {"voice_id": voice_id},
1036
+ "llm": {
1037
+ "provider": "openai",
1038
+ "model": "gpt-4"
1039
+ }
1040
+ },
1041
+ "platform_settings": {
1042
+ "webhook_url": f"{os.getenv('BASE_URL', 'https://rairo-neofix-api.hf.space')}/api/webhook/agent/{project_id}"
1043
+ }
1044
  }
1045
 
1046
+ # This is the correct endpoint that was causing the 404 Not Found error.
1047
  creation_url = f"{self.base_url}/agents"
1048
+ logger.info(f"[AGENT] Posting to the correct endpoint: {creation_url}")
1049
 
1050
+ response = requests.post(creation_url, headers=self.headers, json=agent_data, timeout=30)
1051
 
1052
+ # A successful creation with this endpoint returns 201 Created.
1053
+ if response.status_code == 201:
1054
  agent_info = response.json()
1055
  agent_id = agent_info.get("agent_id")
1056
  logger.info(f"[AGENT] New agent created successfully: {agent_id}")
 
1062
  logger.info(f"[AGENT] Agent ID stored in database.")
1063
  return agent_id
1064
  else:
 
1065
  logger.error(f"[AGENT] Failed to create agent. Status: {response.status_code}, Response: {response.text}")
1066
  raise Exception(f"Failed to create agent: HTTP {response.status_code} - {response.text}")
1067
 
 
1071
 
1072
  def start_conversation(self, agent_id):
1073
  """Start a conversation with the agent"""
 
 
 
1074
  try:
1075
+ logger.info(f"[CONVERSATION] Starting conversation with agent: {agent_id}")
1076
+ conversation_url = f"{self.base_url}/agents/{agent_id}/conversations"
1077
+
1078
  response = requests.post(conversation_url, headers=self.headers, json={}, timeout=30)
1079
+
1080
+ if response.status_code == 201:
1081
  conversation_info = response.json()
1082
  conversation_id = conversation_info.get("conversation_id")
1083
  logger.info(f"[CONVERSATION] Conversation started successfully: {conversation_id}")
 
1085
  else:
1086
  logger.error(f"[CONVERSATION] Failed to start conversation. Status: {response.status_code}, Response: {response.text}")
1087
  raise Exception(f"Failed to start conversation: {response.text}")
1088
+
1089
  except Exception as e:
1090
  logger.error(f"[CONVERSATION] An exception occurred in start_conversation: {e}")
1091
  raise
1092
 
1093
  def send_message(self, agent_id, conversation_id, message):
1094
  """Send a message to the conversation"""
 
 
 
 
 
 
 
 
 
 
1095
  try:
1096
+ logger.info(f"[MESSAGE] Sending message to conversation: {conversation_id}")
1097
+ message_url = f"{self.base_url}/agents/{agent_id}/conversations/{conversation_id}/messages"
1098
+
1099
+ payload = {
1100
+ "message": message,
1101
+ "message_type": "text"
1102
+ }
1103
+
1104
+ response = requests.post(message_url, headers=self.headers, json=payload, timeout=30)
1105
+
1106
  if response.status_code == 200:
1107
  logger.info(f"[MESSAGE] Message sent successfully to {conversation_id}.")
 
1108
  return response.json()
1109
  else:
1110
  logger.error(f"[MESSAGE] Failed to send message. Status: {response.status_code}, Response: {response.text}")
1111
  raise Exception(f"Failed to send message: {response.text}")
1112
+
1113
  except Exception as e:
1114
  logger.error(f"[MESSAGE] An exception occurred in send_message: {e}")
1115
  raise