File size: 5,462 Bytes
f374654
 
 
 
 
 
 
 
8c56999
f374654
 
 
 
 
 
 
8c56999
f374654
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c56999
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# flask_app.py

from flask import Flask, request, jsonify, render_template
from app import EasyFarmsAssistant
from conversation_manager import ConversationManager # Make sure this import is present
import logging
import uuid
import os
from flask_cors import CORS

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Initialize the Flask application
app = Flask(__name__)
CORS(app)

# --- Initialize Core Services ---
# This setup assumes your .env file is correctly configured with Supabase credentials.
try:
    conv_manager = ConversationManager()
    assistant = EasyFarmsAssistant(manager=conv_manager)
    logger.info("EasyFarmsAssistant and ConversationManager initialized successfully.")
except Exception as e:
    logger.error(f"FATAL: Could not initialize services. Error: {e}")
    assistant = None
    conv_manager = None

# --- Frontend Serving Route ---
@app.route('/')
def index():
    """Serves the main chat application page (index.html)."""
    return render_template('index.html')

# --- API Endpoints ---

@app.route('/config', methods=['GET'])
def get_config():
    """Provides public configuration keys to the frontend."""
    return jsonify({
        'imgbb_api_key': os.getenv('IMGBB_API_KEY')
    })

@app.route('/chat', methods=['POST'])
def chat():
    """Handles incoming user messages and returns the assistant's response."""
    if not assistant:
        return jsonify({"error": "Assistant is not available due to an initialization error."}), 503

    # The request is multipart/form-data to handle potential image uploads
    data = request.form
    user_message = data.get('message')
    session_id = data.get('session_id')
    image_url = data.get('image_url') # The permanent URL from ImgBB

    # A message must contain either text or an image
    if not user_message and not image_url:
        return jsonify({"error": "Cannot process an empty message."}), 400
    
    # If no session_id is provided by the client, it's a new conversation
    if not session_id or session_id == 'null' or session_id == 'undefined':
        session_id = str(uuid.uuid4())
        logger.info(f"No session_id provided. Creating new session: {session_id}")
    
    # Call the assistant's core logic, now passing the image_url separately
    response_content = assistant.process_query(
        user_message=user_message or "",  # Ensure user_message is a string
        session_id=session_id,
        image_url=image_url
    )
    
    return jsonify({
        "response": response_content,
        "session_id": session_id
    })

@app.route('/history/sessions', methods=['GET'])
def get_sessions():
    """Fetches a list of all conversation sessions for the sidebar."""
    if not conv_manager:
        return jsonify({"error": "Conversation manager not available"}), 503
    try:
        # Fetch session_id and the full history to generate a title
        all_conversations = conv_manager.supabase.table('conversations').select('session_id, history').execute()
        
        sessions = []
        for conv in all_conversations.data:
            title = "New Chat" # Default title
            # Generate a title from the first user message in the history
            if conv.get('history') and len(conv['history']) > 0:
                first_message_content = conv['history'][0].get('content')
                if first_message_content:
                    # Truncate for display
                    title = first_message_content[:35] + '...' if len(first_message_content) > 35 else first_message_content
                else: # If the first message was only an image
                    title = "Image Query"

            sessions.append({
                "session_id": conv.get('session_id'),
                "title": title
            })
        
        return jsonify(sessions)
    except Exception as e:
        logger.error(f"Error fetching sessions from Supabase: {e}")
        return jsonify({"error": "Could not fetch conversation sessions"}), 500

@app.route('/history/messages/<session_id>', methods=['GET'])
def get_messages(session_id):
    """Fetches the full, structured message history for a given session_id."""
    if not conv_manager:
        return jsonify({"error": "Conversation manager not available"}), 503
    try:
        history = conv_manager.get_history(session_id)
        return jsonify(history)
    except Exception as e:
        logger.error(f"Error fetching messages for session {session_id}: {e}")
        return jsonify({"error": "Could not fetch message history"}), 500

@app.route('/clear', methods=['POST'])
def clear_history():
    """Deletes a conversation history from the database."""
    if not assistant:
        return jsonify({"error": "Assistant is not available."}), 503
    
    data = request.get_json()
    session_id = data.get('session_id')

    if not session_id:
        return jsonify({"error": "Missing 'session_id' in request body"}), 400

    if assistant.clear_history(session_id):
        return jsonify({"status": "success", "message": f"History for session {session_id} was cleared."})
    else:
        return jsonify({"error": "Failed to clear history."}), 500

# --- Main Execution ---
if __name__ == '__main__':
    # Set debug=False for production
    app.run(debug=False, port=7860)