Vibow commited on
Commit
6c6e36b
Β·
verified Β·
1 Parent(s): ba12a9e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -13
app.py CHANGED
@@ -39,6 +39,7 @@ GROQ_API_KEY_2 = os.getenv("GROQ_API_KEY_2") # Reserved for STT
39
  GROQ_API_KEY_3 = os.getenv("GROQ_API_KEY_3") # Reserved for TTS
40
  GROQ_API_KEY_4 = os.getenv("GROQ_API_KEY_4") # Additional Key (Fallback)
41
  SERPAPI_KEY = os.getenv("SERPAPI_KEY") # Search
 
42
 
43
  # List of API Keys for the Chat function
44
  GROQ_CHAT_KEYS = [
@@ -722,6 +723,104 @@ def chat():
722
  prompt = data.get("prompt", "")
723
  history = data.get("history", [])
724
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
725
  # Flags
726
  user_timezone_str = data.get("user_timezone", "Asia/Jakarta")
727
  current_username = data.get("current_username")
@@ -738,10 +837,10 @@ def chat():
738
  # SUPER GTE FLAG
739
  super_gte_active = data.get("super_gte", False)
740
 
741
- # Rate limit logic
742
 
743
 
744
- # LIMIT CHECK
745
 
746
 
747
  print(f"[CHAT] πŸ’¬ User Prompt (Text Mode): {prompt}")
@@ -771,13 +870,9 @@ def chat():
771
  return Response("Deep research requires a question.", mimetype="text/plain")
772
 
773
  def gen_deep():
774
-
775
-
776
  final_answer = deep_research_mode(deep_query, history, num_sources=15)
777
  yield final_answer
778
 
779
-
780
-
781
  response = Response(gen_deep(), mimetype="text/plain")
782
 
783
  return response
@@ -808,12 +903,9 @@ def chat():
808
  # Note: If agent_active is True, the Agent logic is handled inside stream_chat
809
 
810
  # ======================
811
- # πŸ’¬ 4. STANDARD CHAT (FIXED)
812
  # ======================
813
 
814
- # --- FIX: decrement MUST be OUTSIDE generator ---
815
-
816
-
817
  def generate():
818
  for chunk in stream_chat(
819
  prompt,
@@ -827,9 +919,6 @@ def chat():
827
  ):
828
  yield chunk
829
 
830
- # Ambil sisa limit setelah decrement
831
-
832
-
833
  response = Response(generate(), mimetype="text/plain")
834
 
835
  return response
 
39
  GROQ_API_KEY_3 = os.getenv("GROQ_API_KEY_3") # Reserved for TTS
40
  GROQ_API_KEY_4 = os.getenv("GROQ_API_KEY_4") # Additional Key (Fallback)
41
  SERPAPI_KEY = os.getenv("SERPAPI_KEY") # Search
42
+ COHERE_API_KEY = os.getenv("COHERE_KEY")
43
 
44
  # List of API Keys for the Chat function
45
  GROQ_CHAT_KEYS = [
 
723
  prompt = data.get("prompt", "")
724
  history = data.get("history", [])
725
 
726
+ # ======================
727
+ # πŸ–ΌοΈ VISION MODE (AUTO DETECT - BASE64 ONLY)
728
+ # ======================
729
+ image_base64 = data.get("image_base64")
730
+ if image_base64:
731
+ print("[VISION] πŸ–ΌοΈ Image detected β†’ using c4ai-aya-vision-32b (Cohere)")
732
+
733
+ # Validate base64 quickly
734
+ try:
735
+ # If user sends full data URI like "data:image/png;base64,....", strip prefix for decoding test
736
+ test_b64 = image_base64
737
+ if test_b64.startswith("data:"):
738
+ test_b64 = test_b64.split(",", 1)[1]
739
+ base64.b64decode(test_b64, validate=True)
740
+ except Exception as e:
741
+ print(f"[VISION] ❌ Invalid base64: {e}")
742
+ return jsonify({"error": "Invalid base64 image"}), 400
743
+
744
+ # Build payload for Cohere v2 chat (vision)
745
+ cohere_url = "https://api.cohere.ai/v2/chat"
746
+ payload = {
747
+ "model": "c4ai-aya-vision-32b",
748
+ "messages": [
749
+ {
750
+ "role": "user",
751
+ "content": [
752
+ {
753
+ "type": "input_text",
754
+ "text": prompt if prompt else "Describe this image."
755
+ },
756
+ {
757
+ # Cohere accepts data URI as image url - keep the data URI if present
758
+ "type": "input_image",
759
+ "image": image_base64
760
+ }
761
+ ]
762
+ }
763
+ ],
764
+ # optional tuning
765
+ "temperature": 0.6,
766
+ "max_tokens": 800
767
+ }
768
+
769
+ headers = {
770
+ "Authorization": f"Bearer {COHERE_API_KEY}",
771
+ "Content-Type": "application/json"
772
+ }
773
+
774
+ try:
775
+ res = requests.post(cohere_url, json=payload, headers=headers, timeout=60)
776
+ try:
777
+ res_json = res.json()
778
+ except Exception:
779
+ print("[VISION] ❌ Cohere returned non-json response")
780
+ return jsonify({"error": "Cohere returned non-json response", "status_code": res.status_code, "text": res.text}), 500
781
+
782
+ # Robust extraction of text reply (support several possible shapes)
783
+ ai_reply = None
784
+ # Try common v2 shape: res_json["messages"][0]["content"][0]["text"]
785
+ try:
786
+ ai_reply = res_json.get("messages", [])[0].get("content", [])[0].get("text")
787
+ except Exception:
788
+ ai_reply = None
789
+
790
+ # Fallback: sometimes Cohere returns 'output' or 'text' fields
791
+ if not ai_reply:
792
+ # Try to find any 'text' in nested dicts
793
+ def find_text(obj):
794
+ if isinstance(obj, dict):
795
+ for k, v in obj.items():
796
+ if k == "text" and isinstance(v, str):
797
+ return v
798
+ else:
799
+ found = find_text(v)
800
+ if found:
801
+ return found
802
+ elif isinstance(obj, list):
803
+ for item in obj:
804
+ found = find_text(item)
805
+ if found:
806
+ return found
807
+ return None
808
+ ai_reply = find_text(res_json) or ""
809
+
810
+ return jsonify({
811
+ "mode": "vision",
812
+ "reply": ai_reply,
813
+ "raw": res_json
814
+ })
815
+
816
+ except requests.exceptions.RequestException as e:
817
+ print(f"[VISION] ❌ RequestException: {e}")
818
+ return jsonify({"error": "Failed to call Cohere", "details": str(e)}), 500
819
+
820
+ # =====================================================
821
+ # 🧩 🎚️ (VISION DONE) β€” LANJUTKAN MODE TEXT SEPERTI BIASA
822
+ # =====================================================
823
+
824
  # Flags
825
  user_timezone_str = data.get("user_timezone", "Asia/Jakarta")
826
  current_username = data.get("current_username")
 
837
  # SUPER GTE FLAG
838
  super_gte_active = data.get("super_gte", False)
839
 
840
+ # Rate limit logic (kept placeholder as in your original)
841
 
842
 
843
+ # LIMIT CHECK (kept placeholder)
844
 
845
 
846
  print(f"[CHAT] πŸ’¬ User Prompt (Text Mode): {prompt}")
 
870
  return Response("Deep research requires a question.", mimetype="text/plain")
871
 
872
  def gen_deep():
 
 
873
  final_answer = deep_research_mode(deep_query, history, num_sources=15)
874
  yield final_answer
875
 
 
 
876
  response = Response(gen_deep(), mimetype="text/plain")
877
 
878
  return response
 
903
  # Note: If agent_active is True, the Agent logic is handled inside stream_chat
904
 
905
  # ======================
906
+ # πŸ’¬ 4. STANDARD STREAM CHAT (unchanged)
907
  # ======================
908
 
 
 
 
909
  def generate():
910
  for chunk in stream_chat(
911
  prompt,
 
919
  ):
920
  yield chunk
921
 
 
 
 
922
  response = Response(generate(), mimetype="text/plain")
923
 
924
  return response