CORVO-AI commited on
Commit
5cda5d3
·
verified ·
1 Parent(s): b22de8d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -115
app.py CHANGED
@@ -177,13 +177,27 @@ def delete_workspace(workspace_id):
177
 
178
 
179
  # -------------------------------------------------------------------
180
- # Main function that calls the Botpress API endpoint
181
  # -------------------------------------------------------------------
182
- def chat_with_assistant(user_input, chat_history, bot_id, workspace_id, temperature=0.9, top_p=0.95, max_tokens=None):
183
  """
184
- Sends the user input and chat history to the Botpress API endpoint,
185
- returns the assistant's response and (possibly updated) bot/workspace IDs.
 
 
 
 
 
 
 
 
 
 
186
  """
 
 
 
 
187
  # Prepare the headers
188
  headers = {
189
  "User-Agent": "Mozilla/5.0",
@@ -192,49 +206,24 @@ def chat_with_assistant(user_input, chat_history, bot_id, workspace_id, temperat
192
  "Cookie": AUTH_COOKIE
193
  }
194
 
195
- # Process chat history into the format expected by the API
196
- messages = []
197
- system_prompt = ""
198
- for msg in chat_history:
199
- if msg["role"] == "system":
200
- system_prompt = msg["content"]
201
- else:
202
- messages.append({
203
- "role": msg["role"],
204
- "content": msg["content"],
205
- "type": "text"
206
- })
207
-
208
- # Add the latest user input if not already in chat history
209
- if user_input and (not messages or messages[-1]["role"] != "user" or messages[-1]["content"] != user_input):
210
- messages.append({
211
- "role": "user",
212
- "content": user_input,
213
- "type": "text"
214
- })
215
 
216
  # Prepare the payload for the API
217
  payload = {
218
- "type": "openai:generateContent",
219
  "input": {
220
- "model": {
221
- "id": "gpt-4.1-2025-04-14"
222
- },
223
- "systemPrompt": system_prompt,
224
- "messages": messages,
225
- "temperature": temperature,
226
-
227
- "debug": False,
228
  }
229
  }
230
 
231
- # Add maxTokens to the payload if provided
232
- if max_tokens is not None:
233
- payload["input"]["maxTokens"] = max_tokens
234
-
235
  botpress_url = "https://api.botpress.cloud/v1/chat/actions"
236
  max_retries = 3
237
- timeout = 120 # Increased timeout for long messages
238
 
239
  # Flag to track if we need to create new IDs due to quota exceeded
240
  quota_exceeded = False
@@ -242,15 +231,14 @@ def chat_with_assistant(user_input, chat_history, bot_id, workspace_id, temperat
242
  # Attempt to send the request
243
  for attempt in range(max_retries):
244
  try:
245
- print(f"Attempt {attempt+1}: Sending request to Botpress API with bot_id={bot_id}, workspace_id={workspace_id}")
246
  response = requests.post(botpress_url, json=payload, headers=headers, timeout=timeout)
247
 
248
  # If successful (200)
249
  if response.status_code == 200:
250
  data = response.json()
251
- assistant_content = data.get('output', {}).get('choices', [{}])[0].get('content', '')
252
- print(f"Successfully received response from Botpress API")
253
- return assistant_content, bot_id, workspace_id
254
 
255
  # Check for quota exceeded error specifically
256
  elif response.status_code == 403:
@@ -268,7 +256,7 @@ def chat_with_assistant(user_input, chat_history, bot_id, workspace_id, temperat
268
  time.sleep(2)
269
  continue
270
  else:
271
- return f"Unable to get a response from the assistant (Error 403).", bot_id, workspace_id
272
 
273
  # Handle network errors or timeouts (just retry)
274
  elif response.status_code in [404, 408, 502, 503, 504]:
@@ -283,7 +271,7 @@ def chat_with_assistant(user_input, chat_history, bot_id, workspace_id, temperat
283
  time.sleep(2)
284
  continue
285
  else:
286
- return f"Unable to get a response from the assistant (Error {response.status_code}).", bot_id, workspace_id
287
 
288
  except requests.exceptions.Timeout:
289
  print(f"Request timed out. Retrying...")
@@ -291,7 +279,7 @@ def chat_with_assistant(user_input, chat_history, bot_id, workspace_id, temperat
291
  time.sleep(2)
292
  continue
293
  else:
294
- return "The assistant is taking too long to respond. Please try again with a shorter message.", bot_id, workspace_id
295
 
296
  except Exception as e:
297
  print(f"Error during request: {str(e)}")
@@ -299,7 +287,7 @@ def chat_with_assistant(user_input, chat_history, bot_id, workspace_id, temperat
299
  time.sleep(2)
300
  continue
301
  else:
302
- return f"Unable to get a response from the assistant: {str(e)}", bot_id, workspace_id
303
 
304
  # If quota exceeded, we need to create new resources
305
  if quota_exceeded:
@@ -328,12 +316,12 @@ def chat_with_assistant(user_input, chat_history, bot_id, workspace_id, temperat
328
  # Create new workspace
329
  new_workspace_id = create_workspace()
330
  if not new_workspace_id:
331
- return "Failed to create a new workspace after quota exceeded. Please try again later.", bot_id, workspace_id
332
 
333
  # Create new bot in the new workspace
334
  new_bot_id = create_bot(new_workspace_id)
335
  if not new_bot_id:
336
- return "Failed to create a new bot after quota exceeded. Please try again later.", new_workspace_id, workspace_id
337
 
338
  # Update headers with new bot ID
339
  headers["x-bot-id"] = new_bot_id
@@ -345,85 +333,58 @@ def chat_with_assistant(user_input, chat_history, bot_id, workspace_id, temperat
345
 
346
  if retry_response.status_code == 200:
347
  data = retry_response.json()
348
- assistant_content = data.get('output', {}).get('choices', [{}])[0].get('content', '')
349
- print(f"Successfully received response with new IDs")
350
- return assistant_content, new_bot_id, new_workspace_id
351
  else:
352
  print(f"Failed with new IDs: {retry_response.status_code}, {retry_response.text}")
353
- return f"Unable to get a response from the assistant with new credentials.", new_bot_id, new_workspace_id
354
 
355
  except Exception as e:
356
  print(f"Error with new IDs: {str(e)}")
357
- return f"Unable to get a response from the assistant with new credentials: {str(e)}", new_bot_id, new_workspace_id
358
 
359
  # Should not reach here due to the handling in the loop
360
- return "Unable to get a response from the assistant.", bot_id, workspace_id
361
 
362
 
363
  # -------------------------------------------------------------------
364
- # Flask Endpoint
365
  # -------------------------------------------------------------------
366
- @app.route("/chat", methods=["POST"])
367
- def chat_endpoint():
368
  """
 
369
  Expects JSON with:
370
  {
371
- "user_input": "string",
372
- "chat_history": [
373
- {"role": "system", "content": "..."},
374
- {"role": "user", "content": "..."},
375
- ...
376
- ],
377
- "temperature": 0.9, // Optional, defaults to 0.9
378
- "top_p": 0.95, // Optional, defaults to 0.95
379
- "max_tokens": 1000 // Optional, defaults to null (no limit)
380
- }
381
- Returns JSON with:
382
- {
383
- "assistant_response": "string"
384
  }
 
385
  """
386
  global GLOBAL_WORKSPACE_ID, GLOBAL_BOT_ID
387
 
388
  # Parse JSON from request
389
  data = request.get_json(force=True)
390
- user_input = data.get("user_input", "")
391
- chat_history = data.get("chat_history", [])
 
 
392
 
393
- # Get temperature, top_p, and max_tokens from request, or use defaults
394
- temperature = data.get("temperature", 0.9)
395
- top_p = data.get("top_p", 0.95)
396
- max_tokens = data.get("max_tokens", None)
397
 
398
- # Validate temperature and top_p values
399
  try:
400
- temperature = float(temperature)
401
- if not 0 <= temperature <= 2:
402
- temperature = 0.9
403
- print(f"Invalid temperature value. Using default: {temperature}")
404
  except (ValueError, TypeError):
405
- temperature = 0.9
406
- print(f"Invalid temperature format. Using default: {temperature}")
407
-
408
- try:
409
- top_p = float(top_p)
410
- if not 0 <= top_p <= 1:
411
- top_p = 0.95
412
- print(f"Invalid top_p value. Using default: {top_p}")
413
- except (ValueError, TypeError):
414
- top_p = 0.95
415
- print(f"Invalid top_p format. Using default: {top_p}")
416
-
417
- # Validate max_tokens if provided
418
- if max_tokens is not None:
419
- try:
420
- max_tokens = int(max_tokens)
421
- if max_tokens <= 0:
422
- print("Invalid max_tokens value (must be positive). Not using max_tokens.")
423
- max_tokens = None
424
- except (ValueError, TypeError):
425
- print("Invalid max_tokens format. Not using max_tokens.")
426
- max_tokens = None
427
 
428
  # If we don't yet have a workspace or bot, create them
429
  if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
@@ -434,20 +395,19 @@ def chat_endpoint():
434
 
435
  # If creation failed
436
  if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
437
- return jsonify({"assistant_response": "I'm currently unavailable. Please try again later."}), 500
438
 
439
- # Call our function that interacts with Botpress API
440
- print(f"Sending chat request with existing bot_id={GLOBAL_BOT_ID}, workspace_id={GLOBAL_WORKSPACE_ID}")
441
- print(f"Using temperature={temperature}, top_p={top_p}, max_tokens={max_tokens}")
442
 
443
- assistant_response, updated_bot_id, updated_workspace_id = chat_with_assistant(
444
- user_input,
445
- chat_history,
 
 
446
  GLOBAL_BOT_ID,
447
- GLOBAL_WORKSPACE_ID,
448
- temperature,
449
- top_p,
450
- max_tokens
451
  )
452
 
453
  # Update global IDs if they changed
@@ -456,7 +416,8 @@ def chat_endpoint():
456
  GLOBAL_BOT_ID = updated_bot_id
457
  GLOBAL_WORKSPACE_ID = updated_workspace_id
458
 
459
- return jsonify({"assistant_response": assistant_response})
 
460
 
461
 
462
  # -------------------------------------------------------------------
 
177
 
178
 
179
  # -------------------------------------------------------------------
180
+ # Web Search Function
181
  # -------------------------------------------------------------------
182
+ def web_search(query, count=3, include_sites=None, exclude_sites=None, bot_id=None, workspace_id=None):
183
  """
184
+ Performs a web search using the Botpress API
185
+
186
+ Args:
187
+ query (str): The search query
188
+ count (int): Number of search results to return
189
+ include_sites (list): List of sites to include in the search
190
+ exclude_sites (list): List of sites to exclude from the search
191
+ bot_id (str): The bot ID to use for the request
192
+ workspace_id (str): The workspace ID to use for the request
193
+
194
+ Returns:
195
+ tuple: (search_results, bot_id, workspace_id)
196
  """
197
+ if not bot_id or not workspace_id:
198
+ print("Cannot perform search: Missing bot ID or workspace ID")
199
+ return {"error": "Missing bot ID or workspace ID"}, bot_id, workspace_id
200
+
201
  # Prepare the headers
202
  headers = {
203
  "User-Agent": "Mozilla/5.0",
 
206
  "Cookie": AUTH_COOKIE
207
  }
208
 
209
+ # Prepare include/exclude sites
210
+ include_sites = include_sites or []
211
+ exclude_sites = exclude_sites or []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
  # Prepare the payload for the API
214
  payload = {
215
+ "type": "browser:webSearch",
216
  "input": {
217
+ "query": query,
218
+ "includeSites": include_sites,
219
+ "excludeSites": exclude_sites,
220
+ "count": count
 
 
 
 
221
  }
222
  }
223
 
 
 
 
 
224
  botpress_url = "https://api.botpress.cloud/v1/chat/actions"
225
  max_retries = 3
226
+ timeout = 60
227
 
228
  # Flag to track if we need to create new IDs due to quota exceeded
229
  quota_exceeded = False
 
231
  # Attempt to send the request
232
  for attempt in range(max_retries):
233
  try:
234
+ print(f"Attempt {attempt+1}: Sending search request to Botpress API with bot_id={bot_id}, workspace_id={workspace_id}")
235
  response = requests.post(botpress_url, json=payload, headers=headers, timeout=timeout)
236
 
237
  # If successful (200)
238
  if response.status_code == 200:
239
  data = response.json()
240
+ print(f"Successfully received search results from Botpress API")
241
+ return data, bot_id, workspace_id
 
242
 
243
  # Check for quota exceeded error specifically
244
  elif response.status_code == 403:
 
256
  time.sleep(2)
257
  continue
258
  else:
259
+ return {"error": f"Unable to get search results (Error 403)."}, bot_id, workspace_id
260
 
261
  # Handle network errors or timeouts (just retry)
262
  elif response.status_code in [404, 408, 502, 503, 504]:
 
271
  time.sleep(2)
272
  continue
273
  else:
274
+ return {"error": f"Unable to get search results (Error {response.status_code})."}, bot_id, workspace_id
275
 
276
  except requests.exceptions.Timeout:
277
  print(f"Request timed out. Retrying...")
 
279
  time.sleep(2)
280
  continue
281
  else:
282
+ return {"error": "The search request timed out. Please try again."}, bot_id, workspace_id
283
 
284
  except Exception as e:
285
  print(f"Error during request: {str(e)}")
 
287
  time.sleep(2)
288
  continue
289
  else:
290
+ return {"error": f"Unable to get search results: {str(e)}"}, bot_id, workspace_id
291
 
292
  # If quota exceeded, we need to create new resources
293
  if quota_exceeded:
 
316
  # Create new workspace
317
  new_workspace_id = create_workspace()
318
  if not new_workspace_id:
319
+ return {"error": "Failed to create a new workspace after quota exceeded. Please try again later."}, bot_id, workspace_id
320
 
321
  # Create new bot in the new workspace
322
  new_bot_id = create_bot(new_workspace_id)
323
  if not new_bot_id:
324
+ return {"error": "Failed to create a new bot after quota exceeded. Please try again later."}, new_workspace_id, workspace_id
325
 
326
  # Update headers with new bot ID
327
  headers["x-bot-id"] = new_bot_id
 
333
 
334
  if retry_response.status_code == 200:
335
  data = retry_response.json()
336
+ print(f"Successfully received search results with new IDs")
337
+ return data, new_bot_id, new_workspace_id
 
338
  else:
339
  print(f"Failed with new IDs: {retry_response.status_code}, {retry_response.text}")
340
+ return {"error": f"Unable to get search results with new credentials."}, new_bot_id, new_workspace_id
341
 
342
  except Exception as e:
343
  print(f"Error with new IDs: {str(e)}")
344
+ return {"error": f"Unable to get search results with new credentials: {str(e)}"}, new_bot_id, new_workspace_id
345
 
346
  # Should not reach here due to the handling in the loop
347
+ return {"error": "Unable to get search results."}, bot_id, workspace_id
348
 
349
 
350
  # -------------------------------------------------------------------
351
+ # Flask Endpoints
352
  # -------------------------------------------------------------------
353
+ @app.route("/search", methods=["POST"])
354
+ def search_endpoint():
355
  """
356
+ Endpoint for web search.
357
  Expects JSON with:
358
  {
359
+ "query": "search query",
360
+ "count": 3, // Optional, defaults to 3
361
+ "include_sites": [], // Optional, defaults to empty list
362
+ "exclude_sites": [] // Optional, defaults to empty list
 
 
 
 
 
 
 
 
 
363
  }
364
+ Returns the raw search results JSON from the Botpress API
365
  """
366
  global GLOBAL_WORKSPACE_ID, GLOBAL_BOT_ID
367
 
368
  # Parse JSON from request
369
  data = request.get_json(force=True)
370
+ query = data.get("query", "")
371
+ count = data.get("count", 3)
372
+ include_sites = data.get("include_sites", [])
373
+ exclude_sites = data.get("exclude_sites", [])
374
 
375
+ # Validate query
376
+ if not query:
377
+ return jsonify({"error": "Query parameter is required"}), 400
 
378
 
379
+ # Validate count
380
  try:
381
+ count = int(count)
382
+ if count <= 0:
383
+ count = 3
384
+ print(f"Invalid count value. Using default: {count}")
385
  except (ValueError, TypeError):
386
+ count = 3
387
+ print(f"Invalid count format. Using default: {count}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
 
389
  # If we don't yet have a workspace or bot, create them
390
  if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
 
395
 
396
  # If creation failed
397
  if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
398
+ return jsonify({"error": "Failed to initialize search capability. Please try again later."}), 500
399
 
400
+ # Call our search function
401
+ print(f"Sending search request with query='{query}', count={count}")
402
+ print(f"Using existing bot_id={GLOBAL_BOT_ID}, workspace_id={GLOBAL_WORKSPACE_ID}")
403
 
404
+ search_results, updated_bot_id, updated_workspace_id = web_search(
405
+ query,
406
+ count,
407
+ include_sites,
408
+ exclude_sites,
409
  GLOBAL_BOT_ID,
410
+ GLOBAL_WORKSPACE_ID
 
 
 
411
  )
412
 
413
  # Update global IDs if they changed
 
416
  GLOBAL_BOT_ID = updated_bot_id
417
  GLOBAL_WORKSPACE_ID = updated_workspace_id
418
 
419
+ # Return the raw API response
420
+ return jsonify(search_results)
421
 
422
 
423
  # -------------------------------------------------------------------