Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
|
@@ -969,7 +969,6 @@ KNOWN_VOICE_IDS = {
|
|
| 969 |
|
| 970 |
class ConversationalAIHandler:
|
| 971 |
def __init__(self):
|
| 972 |
-
# Per documentation, the base URL for all v1 API calls.
|
| 973 |
self.base_url = "https://api.elevenlabs.io/v1"
|
| 974 |
self.api_key = os.getenv("ELEVENLABS_API_KEY")
|
| 975 |
if not self.api_key:
|
|
@@ -981,20 +980,17 @@ class ConversationalAIHandler:
|
|
| 981 |
}
|
| 982 |
|
| 983 |
def get_british_male_voice_id(self):
|
| 984 |
-
"""Gets a known British male voice ID."""
|
| 985 |
logger.info(f"[VOICE] Using known voice ID for Daniel.")
|
| 986 |
-
return KNOWN_VOICE_IDS.get("Daniel", "onwK4e9ZLuTAKqWW03F9")
|
| 987 |
|
| 988 |
def create_or_get_agent(self, project_id, project_data):
|
| 989 |
-
"""Creates or retrieves an agent, strictly following the /v1/agents documentation."""
|
| 990 |
try:
|
| 991 |
logger.info(f"[AGENT] Starting agent creation/retrieval for project: {project_id}")
|
| 992 |
|
| 993 |
-
# First, check for and verify an existing agent in the database.
|
| 994 |
existing_agent_id = db_ref.child(f'projects/{project_id}/agent_id').get()
|
| 995 |
if existing_agent_id:
|
| 996 |
logger.info(f"[AGENT] Found existing agent ID in DB: {existing_agent_id}. Verifying...")
|
| 997 |
-
verify_url = f"{self.base_url}/agents/{existing_agent_id}"
|
| 998 |
try:
|
| 999 |
response = requests.get(verify_url, headers=self.headers, timeout=15)
|
| 1000 |
if response.status_code == 200:
|
|
@@ -1005,7 +1001,7 @@ class ConversationalAIHandler:
|
|
| 1005 |
except Exception as e:
|
| 1006 |
logger.warning(f"[AGENT] Error verifying agent: {e}. Creating a new one.")
|
| 1007 |
|
| 1008 |
-
logger.info(f"[AGENT] Creating new agent as per API documentation.")
|
| 1009 |
voice_id = self.get_british_male_voice_id()
|
| 1010 |
|
| 1011 |
diy_expert_prompt = f"""
|
|
@@ -1019,35 +1015,30 @@ class ConversationalAIHandler:
|
|
| 1019 |
Ask clarifying questions when needed and share relevant tips from your experience.
|
| 1020 |
"""
|
| 1021 |
|
| 1022 |
-
# This payload EXACTLY matches the fields in the /v1/agents/create documentation.
|
| 1023 |
-
# The complex 'conversation_config' is NOT part of this documented endpoint.
|
| 1024 |
agent_payload = {
|
| 1025 |
-
"
|
| 1026 |
-
|
| 1027 |
-
|
| 1028 |
-
|
| 1029 |
-
|
| 1030 |
-
|
|
|
|
| 1031 |
}
|
| 1032 |
|
| 1033 |
-
|
| 1034 |
-
creation_url = f"{self.base_url}/agents"
|
| 1035 |
logger.info(f"[AGENT] Posting to official endpoint: {creation_url}")
|
| 1036 |
-
|
| 1037 |
response = requests.post(creation_url, headers=self.headers, json=agent_payload, timeout=30)
|
| 1038 |
-
|
| 1039 |
-
# A successful creation returns HTTP 200 OK.
|
| 1040 |
if response.status_code == 200:
|
| 1041 |
agent_info = response.json()
|
| 1042 |
agent_id = agent_info.get("agent_id")
|
| 1043 |
logger.info(f"[AGENT] New agent created successfully: {agent_id}")
|
| 1044 |
-
|
| 1045 |
db_ref.child(f'projects/{project_id}').update({'agent_id': agent_id})
|
| 1046 |
return agent_id
|
| 1047 |
else:
|
| 1048 |
-
# If this 404 error persists, the issue is not in the code but in the environment/account.
|
| 1049 |
logger.error(f"[AGENT] Failed to create agent. Status: {response.status_code}, Response: {response.text}")
|
| 1050 |
-
logger.error("[AGENT] ACTION REQUIRED: This
|
| 1051 |
raise Exception(f"Failed to create agent: HTTP {response.status_code} - {response.text}")
|
| 1052 |
|
| 1053 |
except Exception as e:
|
|
@@ -1055,13 +1046,12 @@ class ConversationalAIHandler:
|
|
| 1055 |
raise
|
| 1056 |
|
| 1057 |
def start_conversation(self, agent_id):
|
| 1058 |
-
"""Starts a conversation with the created agent."""
|
| 1059 |
try:
|
| 1060 |
logger.info(f"[CONVERSATION] Starting conversation with agent: {agent_id}")
|
| 1061 |
-
conversation_url = f"{self.base_url}/agents/{agent_id}/conversations"
|
| 1062 |
|
| 1063 |
response = requests.post(conversation_url, headers=self.headers, json={}, timeout=30)
|
| 1064 |
-
|
| 1065 |
if response.status_code == 200:
|
| 1066 |
conversation_info = response.json()
|
| 1067 |
conversation_id = conversation_info.get("conversation_id")
|
|
@@ -1075,9 +1065,7 @@ class ConversationalAIHandler:
|
|
| 1075 |
raise
|
| 1076 |
|
| 1077 |
def send_message(self, agent_id, conversation_id, message):
|
| 1078 |
-
"""Sends a message to an active conversation."""
|
| 1079 |
try:
|
| 1080 |
-
# Note: agent_id is not used in the URL but kept for consistent function signature.
|
| 1081 |
logger.info(f"[MESSAGE] Sending message to conversation: {conversation_id}")
|
| 1082 |
message_url = f"{self.base_url}/conversations/{conversation_id}/messages"
|
| 1083 |
payload = {"text": message}
|
|
@@ -1094,7 +1082,6 @@ class ConversationalAIHandler:
|
|
| 1094 |
logger.error(f"[MESSAGE] An exception occurred in send_message: {e}")
|
| 1095 |
raise
|
| 1096 |
|
| 1097 |
-
|
| 1098 |
def calculate_cost(duration_seconds):
|
| 1099 |
"""Calculate cost based on conversation duration"""
|
| 1100 |
minutes = (duration_seconds + 59) // 60
|
|
|
|
| 969 |
|
| 970 |
class ConversationalAIHandler:
|
| 971 |
def __init__(self):
|
|
|
|
| 972 |
self.base_url = "https://api.elevenlabs.io/v1"
|
| 973 |
self.api_key = os.getenv("ELEVENLABS_API_KEY")
|
| 974 |
if not self.api_key:
|
|
|
|
| 980 |
}
|
| 981 |
|
| 982 |
def get_british_male_voice_id(self):
|
|
|
|
| 983 |
logger.info(f"[VOICE] Using known voice ID for Daniel.")
|
| 984 |
+
return KNOWN_VOICE_IDS.get("Daniel", "onwK4e9ZLuTAKqWW03F9")
|
| 985 |
|
| 986 |
def create_or_get_agent(self, project_id, project_data):
|
|
|
|
| 987 |
try:
|
| 988 |
logger.info(f"[AGENT] Starting agent creation/retrieval for project: {project_id}")
|
| 989 |
|
|
|
|
| 990 |
existing_agent_id = db_ref.child(f'projects/{project_id}/agent_id').get()
|
| 991 |
if existing_agent_id:
|
| 992 |
logger.info(f"[AGENT] Found existing agent ID in DB: {existing_agent_id}. Verifying...")
|
| 993 |
+
verify_url = f"{self.base_url}/convai/agents/{existing_agent_id}"
|
| 994 |
try:
|
| 995 |
response = requests.get(verify_url, headers=self.headers, timeout=15)
|
| 996 |
if response.status_code == 200:
|
|
|
|
| 1001 |
except Exception as e:
|
| 1002 |
logger.warning(f"[AGENT] Error verifying agent: {e}. Creating a new one.")
|
| 1003 |
|
| 1004 |
+
logger.info(f"[AGENT] Creating new agent as per Convai API documentation.")
|
| 1005 |
voice_id = self.get_british_male_voice_id()
|
| 1006 |
|
| 1007 |
diy_expert_prompt = f"""
|
|
|
|
| 1015 |
Ask clarifying questions when needed and share relevant tips from your experience.
|
| 1016 |
"""
|
| 1017 |
|
|
|
|
|
|
|
| 1018 |
agent_payload = {
|
| 1019 |
+
"conversation_config": {
|
| 1020 |
+
"name": f"DIY Expert - {project_data.get('projectTitle', project_id)}",
|
| 1021 |
+
"voice_id": voice_id,
|
| 1022 |
+
"model_id": "eleven_turbo_v2",
|
| 1023 |
+
"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?",
|
| 1024 |
+
"prompt": diy_expert_prompt
|
| 1025 |
+
}
|
| 1026 |
}
|
| 1027 |
|
| 1028 |
+
creation_url = f"{self.base_url}/convai/agents/create"
|
|
|
|
| 1029 |
logger.info(f"[AGENT] Posting to official endpoint: {creation_url}")
|
| 1030 |
+
|
| 1031 |
response = requests.post(creation_url, headers=self.headers, json=agent_payload, timeout=30)
|
| 1032 |
+
|
|
|
|
| 1033 |
if response.status_code == 200:
|
| 1034 |
agent_info = response.json()
|
| 1035 |
agent_id = agent_info.get("agent_id")
|
| 1036 |
logger.info(f"[AGENT] New agent created successfully: {agent_id}")
|
|
|
|
| 1037 |
db_ref.child(f'projects/{project_id}').update({'agent_id': agent_id})
|
| 1038 |
return agent_id
|
| 1039 |
else:
|
|
|
|
| 1040 |
logger.error(f"[AGENT] Failed to create agent. Status: {response.status_code}, Response: {response.text}")
|
| 1041 |
+
logger.error("[AGENT] ACTION REQUIRED: This error may indicate a subscription issue or malformed payload.")
|
| 1042 |
raise Exception(f"Failed to create agent: HTTP {response.status_code} - {response.text}")
|
| 1043 |
|
| 1044 |
except Exception as e:
|
|
|
|
| 1046 |
raise
|
| 1047 |
|
| 1048 |
def start_conversation(self, agent_id):
|
|
|
|
| 1049 |
try:
|
| 1050 |
logger.info(f"[CONVERSATION] Starting conversation with agent: {agent_id}")
|
| 1051 |
+
conversation_url = f"{self.base_url}/convai/agents/{agent_id}/conversations"
|
| 1052 |
|
| 1053 |
response = requests.post(conversation_url, headers=self.headers, json={}, timeout=30)
|
| 1054 |
+
|
| 1055 |
if response.status_code == 200:
|
| 1056 |
conversation_info = response.json()
|
| 1057 |
conversation_id = conversation_info.get("conversation_id")
|
|
|
|
| 1065 |
raise
|
| 1066 |
|
| 1067 |
def send_message(self, agent_id, conversation_id, message):
|
|
|
|
| 1068 |
try:
|
|
|
|
| 1069 |
logger.info(f"[MESSAGE] Sending message to conversation: {conversation_id}")
|
| 1070 |
message_url = f"{self.base_url}/conversations/{conversation_id}/messages"
|
| 1071 |
payload = {"text": message}
|
|
|
|
| 1082 |
logger.error(f"[MESSAGE] An exception occurred in send_message: {e}")
|
| 1083 |
raise
|
| 1084 |
|
|
|
|
| 1085 |
def calculate_cost(duration_seconds):
|
| 1086 |
"""Calculate cost based on conversation duration"""
|
| 1087 |
minutes = (duration_seconds + 59) // 60
|