Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
|
@@ -1883,18 +1883,18 @@ def get_price_trends():
|
|
| 1883 |
def ai_chat():
|
| 1884 |
auth_header = request.headers.get("Authorization", "");
|
| 1885 |
uid = None
|
| 1886 |
-
response_obj_gemini = None
|
| 1887 |
-
intent = "unknown"
|
| 1888 |
try:
|
| 1889 |
if not FIREBASE_INITIALIZED or not gemini_client:
|
| 1890 |
return jsonify({'error': 'Server or AI service not ready.'}), 503
|
| 1891 |
-
|
| 1892 |
uid = verify_token(auth_header)
|
| 1893 |
-
|
| 1894 |
data = request.get_json()
|
| 1895 |
if not data:
|
| 1896 |
return jsonify({"error": "Invalid request data."}), 400
|
| 1897 |
-
|
| 1898 |
user_message = data.get("message", "").strip()
|
| 1899 |
if not user_message:
|
| 1900 |
return jsonify({"error": "Message cannot be empty."}), 400
|
|
@@ -1905,24 +1905,22 @@ def ai_chat():
|
|
| 1905 |
- "price_trend_query": User is asking about historical price trends, market analysis, or future price predictions. (e.g., "how are maize prices trending?", "what was the price of sorghum last month?")
|
| 1906 |
- "general_agri_info": User is asking for general agricultural advice, farming techniques, business tips, or information not tied to current platform data or specific historical trends. (e.g., "how to grow tomatoes?", "best fertilizer for sandy soils", "exporting crops in SADC")
|
| 1907 |
- "other": If the query doesn't fit well or is a simple greeting/chit-chat.
|
| 1908 |
-
|
| 1909 |
User Query: "{user_message}"
|
| 1910 |
-
|
| 1911 |
Return ONLY the category string (e.g., "platform_data_query").
|
| 1912 |
"""
|
| 1913 |
-
|
| 1914 |
response_obj_gemini = gemini_client.generate_content( # Corrected: use generate_content directly
|
| 1915 |
model='gemini-2.0-flash',
|
| 1916 |
contents=[{'parts': [{'text': classify_prompt}]}] # Pass contents as a list
|
| 1917 |
)
|
| 1918 |
-
|
| 1919 |
intent = response_obj_gemini.text.strip().replace('"', '') if response_obj_gemini.text else "general_agri_info"
|
| 1920 |
-
|
| 1921 |
valid_intents = ["platform_data_query", "price_trend_query", "general_agri_info", "other"]
|
| 1922 |
if intent not in valid_intents:
|
| 1923 |
logger.warning(f"AI Chat: Unexpected intent: '{intent}' for query '{user_message}'. Defaulting to general_agri_info.")
|
| 1924 |
intent = "general_agri_info"
|
| 1925 |
-
|
| 1926 |
context_for_gemini = ""
|
| 1927 |
platform_data_summary = ""
|
| 1928 |
trend_analysis_summary = ""
|
|
@@ -1931,7 +1929,7 @@ def ai_chat():
|
|
| 1931 |
platform_data_summary, _ = _fetch_platform_data_for_chat(user_message)
|
| 1932 |
if platform_data_summary:
|
| 1933 |
context_for_gemini += f"Current Platform Data Context (summarized for you):\n{platform_data_summary}\n\n"
|
| 1934 |
-
|
| 1935 |
elif intent == "price_trend_query":
|
| 1936 |
crop_match = re.search(r"(?:trend for|prices of|price of|trend of)\s+([\w\s]+?)(?:\s+in\s+([\w\s]+?))?(?:\s|$)", user_message.lower())
|
| 1937 |
trend_crop, trend_location = (None, None)
|
|
@@ -1939,37 +1937,34 @@ def ai_chat():
|
|
| 1939 |
trend_crop = crop_match.group(1).strip()
|
| 1940 |
if crop_match.group(2):
|
| 1941 |
trend_location = crop_match.group(2).strip()
|
| 1942 |
-
|
| 1943 |
trend_analysis_summary, _ = _get_price_trend_analysis_for_chat(crop_type=trend_crop, location=trend_location)
|
| 1944 |
if trend_analysis_summary:
|
| 1945 |
context_for_gemini += f"Price Trend Analysis Context (generated for you):\n{trend_analysis_summary}\n\n"
|
| 1946 |
|
| 1947 |
main_prompt = f"""
|
| 1948 |
-
|
| 1949 |
-
|
| 1950 |
-
|
| 1951 |
-
|
| 1952 |
-
|
| 1953 |
-
|
| 1954 |
-
|
| 1955 |
-
|
| 1956 |
-
|
| 1957 |
-
|
| 1958 |
-
|
| 1959 |
-
|
| 1960 |
-
|
| 1961 |
-
|
| 1962 |
-
|
| 1963 |
-
Answer:
|
| 1964 |
-
"""
|
| 1965 |
-
|
| 1966 |
response_obj_gemini = gemini_client.generate_content( # Corrected
|
| 1967 |
model='gemini-2.0-flash',
|
| 1968 |
contents=[{'parts': [{'text': main_prompt}]}]
|
| 1969 |
)
|
| 1970 |
-
|
| 1971 |
ai_response_text = response_obj_gemini.text.strip() if response_obj_gemini.text else "I'm having trouble generating a response right now. Please try again."
|
| 1972 |
-
|
| 1973 |
try:
|
| 1974 |
db.reference(f'ai_chat_history/{uid}/{str(uuid.uuid4())}', app=db_app).set({
|
| 1975 |
'user_message': user_message,
|
|
@@ -1979,14 +1974,14 @@ def ai_chat():
|
|
| 1979 |
})
|
| 1980 |
except Exception as chat_history_error:
|
| 1981 |
logger.error(f"Failed to store chat history for UID {uid}: {chat_history_error}")
|
| 1982 |
-
|
| 1983 |
return jsonify({"response": ai_response_text, "intent": intent})
|
| 1984 |
|
| 1985 |
-
except AttributeError as ae:
|
| 1986 |
logger.error(f"Gemini Response Attribute Error in ai_chat (UID: {uid}): {ae}. Response object: {response_obj_gemini}")
|
| 1987 |
ai_response_text = "I'm having a little trouble understanding that. Could you try rephrasing?"
|
| 1988 |
return jsonify({"response": ai_response_text, "intent": intent, "error_detail": "AI_RESPONSE_FORMAT_ISSUE"}), 200
|
| 1989 |
-
except Exception as e:
|
| 1990 |
return handle_route_errors(e, uid_context=uid)
|
| 1991 |
|
| 1992 |
@app.route('/api/user/ai-chat-history', methods=['GET'])
|
|
|
|
| 1883 |
def ai_chat():
|
| 1884 |
auth_header = request.headers.get("Authorization", "");
|
| 1885 |
uid = None
|
| 1886 |
+
response_obj_gemini = None
|
| 1887 |
+
intent = "unknown"
|
| 1888 |
try:
|
| 1889 |
if not FIREBASE_INITIALIZED or not gemini_client:
|
| 1890 |
return jsonify({'error': 'Server or AI service not ready.'}), 503
|
| 1891 |
+
|
| 1892 |
uid = verify_token(auth_header)
|
| 1893 |
+
|
| 1894 |
data = request.get_json()
|
| 1895 |
if not data:
|
| 1896 |
return jsonify({"error": "Invalid request data."}), 400
|
| 1897 |
+
|
| 1898 |
user_message = data.get("message", "").strip()
|
| 1899 |
if not user_message:
|
| 1900 |
return jsonify({"error": "Message cannot be empty."}), 400
|
|
|
|
| 1905 |
- "price_trend_query": User is asking about historical price trends, market analysis, or future price predictions. (e.g., "how are maize prices trending?", "what was the price of sorghum last month?")
|
| 1906 |
- "general_agri_info": User is asking for general agricultural advice, farming techniques, business tips, or information not tied to current platform data or specific historical trends. (e.g., "how to grow tomatoes?", "best fertilizer for sandy soils", "exporting crops in SADC")
|
| 1907 |
- "other": If the query doesn't fit well or is a simple greeting/chit-chat.
|
|
|
|
| 1908 |
User Query: "{user_message}"
|
|
|
|
| 1909 |
Return ONLY the category string (e.g., "platform_data_query").
|
| 1910 |
"""
|
| 1911 |
+
|
| 1912 |
response_obj_gemini = gemini_client.generate_content( # Corrected: use generate_content directly
|
| 1913 |
model='gemini-2.0-flash',
|
| 1914 |
contents=[{'parts': [{'text': classify_prompt}]}] # Pass contents as a list
|
| 1915 |
)
|
| 1916 |
+
|
| 1917 |
intent = response_obj_gemini.text.strip().replace('"', '') if response_obj_gemini.text else "general_agri_info"
|
| 1918 |
+
|
| 1919 |
valid_intents = ["platform_data_query", "price_trend_query", "general_agri_info", "other"]
|
| 1920 |
if intent not in valid_intents:
|
| 1921 |
logger.warning(f"AI Chat: Unexpected intent: '{intent}' for query '{user_message}'. Defaulting to general_agri_info.")
|
| 1922 |
intent = "general_agri_info"
|
| 1923 |
+
|
| 1924 |
context_for_gemini = ""
|
| 1925 |
platform_data_summary = ""
|
| 1926 |
trend_analysis_summary = ""
|
|
|
|
| 1929 |
platform_data_summary, _ = _fetch_platform_data_for_chat(user_message)
|
| 1930 |
if platform_data_summary:
|
| 1931 |
context_for_gemini += f"Current Platform Data Context (summarized for you):\n{platform_data_summary}\n\n"
|
| 1932 |
+
|
| 1933 |
elif intent == "price_trend_query":
|
| 1934 |
crop_match = re.search(r"(?:trend for|prices of|price of|trend of)\s+([\w\s]+?)(?:\s+in\s+([\w\s]+?))?(?:\s|$)", user_message.lower())
|
| 1935 |
trend_crop, trend_location = (None, None)
|
|
|
|
| 1937 |
trend_crop = crop_match.group(1).strip()
|
| 1938 |
if crop_match.group(2):
|
| 1939 |
trend_location = crop_match.group(2).strip()
|
| 1940 |
+
|
| 1941 |
trend_analysis_summary, _ = _get_price_trend_analysis_for_chat(crop_type=trend_crop, location=trend_location)
|
| 1942 |
if trend_analysis_summary:
|
| 1943 |
context_for_gemini += f"Price Trend Analysis Context (generated for you):\n{trend_analysis_summary}\n\n"
|
| 1944 |
|
| 1945 |
main_prompt = f"""
|
| 1946 |
+
You are Tunasonga Agri Assistant, an AI for an agricultural marketplace in Zimbabwe and SADC.
|
| 1947 |
+
Your goal is to provide helpful, concise, and accurate information. Your persona is professional, friendly, and supportive of farmers and agri-businesses.
|
| 1948 |
+
The user's original query intent was classified as: {intent}
|
| 1949 |
+
{context_for_gemini}
|
| 1950 |
+
Based on the user's query and any provided context above, please formulate your answer to the user.
|
| 1951 |
+
User Query: "{user_message}"
|
| 1952 |
+
Specific Instructions based on intent:
|
| 1953 |
+
- If the intent was 'platform_data_query': Use the "Current Platform Data Context" to answer. If the context says no items were found, relay that and suggest they browse the marketplace or refine their search. Do not invent listings.
|
| 1954 |
+
- If the intent was 'price_trend_query': Use the "Price Trend Analysis Context". If the context says trends couldn't be generated, relay that. Do not invent trends.
|
| 1955 |
+
- For 'general_agri_info': Use your broad agricultural knowledge. Focus on practices relevant to the SADC region, smallholder farmers, climate-smart agriculture, market access, and agri-business development. Provide actionable advice if possible.
|
| 1956 |
+
- If the query is unclear, classified as "other", or if the context is insufficient for a specific query: Provide a polite general response, ask for clarification, or gently guide the user on how you can help (e.g., "I can help with finding produce, getting price trends, or general farming advice. What would you like to know?").
|
| 1957 |
+
Keep your answers clear and easy to understand. Avoid overly technical jargon unless necessary and explain it.
|
| 1958 |
+
Answer:
|
| 1959 |
+
"""
|
| 1960 |
+
|
|
|
|
|
|
|
|
|
|
| 1961 |
response_obj_gemini = gemini_client.generate_content( # Corrected
|
| 1962 |
model='gemini-2.0-flash',
|
| 1963 |
contents=[{'parts': [{'text': main_prompt}]}]
|
| 1964 |
)
|
| 1965 |
+
|
| 1966 |
ai_response_text = response_obj_gemini.text.strip() if response_obj_gemini.text else "I'm having trouble generating a response right now. Please try again."
|
| 1967 |
+
|
| 1968 |
try:
|
| 1969 |
db.reference(f'ai_chat_history/{uid}/{str(uuid.uuid4())}', app=db_app).set({
|
| 1970 |
'user_message': user_message,
|
|
|
|
| 1974 |
})
|
| 1975 |
except Exception as chat_history_error:
|
| 1976 |
logger.error(f"Failed to store chat history for UID {uid}: {chat_history_error}")
|
| 1977 |
+
|
| 1978 |
return jsonify({"response": ai_response_text, "intent": intent})
|
| 1979 |
|
| 1980 |
+
except AttributeError as ae:
|
| 1981 |
logger.error(f"Gemini Response Attribute Error in ai_chat (UID: {uid}): {ae}. Response object: {response_obj_gemini}")
|
| 1982 |
ai_response_text = "I'm having a little trouble understanding that. Could you try rephrasing?"
|
| 1983 |
return jsonify({"response": ai_response_text, "intent": intent, "error_detail": "AI_RESPONSE_FORMAT_ISSUE"}), 200
|
| 1984 |
+
except Exception as e:
|
| 1985 |
return handle_route_errors(e, uid_context=uid)
|
| 1986 |
|
| 1987 |
@app.route('/api/user/ai-chat-history', methods=['GET'])
|