File size: 5,661 Bytes
940c98a
052e52f
940c98a
 
 
 
 
96fe0c0
 
0fd9053
940c98a
 
 
 
c8af05e
1d239e0
 
f85bc8f
 
 
 
 
 
 
 
 
 
 
 
 
 
573cef7
940c98a
 
6ac9478
 
 
 
940c98a
 
 
c8af05e
940c98a
 
 
 
 
 
 
1d239e0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c36a14b
940c98a
d9a1f2d
0fd9053
 
 
 
1d239e0
d9a1f2d
0fd9053
 
 
 
 
d9a1f2d
0fd9053
940c98a
1d239e0
f85bc8f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0fd9053
940c98a
558f5d1
 
052e52f
558f5d1
 
 
940c98a
558f5d1
 
 
 
a8f0234
1d239e0
 
 
 
 
 
558f5d1
1d239e0
558f5d1
940c98a
c36a14b
 
940c98a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05b09c6
691414c
1a1cf31
c36a14b
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
from flask import Flask, request
import os
from langchain.vectorstores import Chroma
from langchain.document_loaders import PyPDFLoader
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
import requests
from twilio.rest import Client


# Flask app
app = Flask(__name__)

# ChromaDB path
CHROMA_PATH = '/code/chroma_db'
if not os.path.exists(CHROMA_PATH):
    os.makedirs(CHROMA_PATH)
def initialize_chroma():
    try:
        # Initialize Chroma
        embedding_function = HuggingFaceEmbeddings()  # Use your desired embedding function
        db = Chroma(persist_directory=CHROMA_PATH, embedding_function=embedding_function)
        
        # Perform an initial operation to ensure the database is correctly initialized
        db.similarity_search_with_score("test query", k=1)
        print("Chroma initialized successfully.")
    except Exception as e:
        print(f"Error initializing Chroma: {e}")

initialize_chroma()


# Set AI71 API key
AI71_API_KEY = os.environ.get('AI71_API_KEY')
account_sid = os.environ.get('TWILIO_ACCOUNT_SID')
auth_token = os.environ.get('TWILIO_AUTH_TOKEN')
client = Client(account_sid, auth_token)
from_whatsapp_number = 'whatsapp:+14155238886'

# Download file utility
def download_file(url, ext):
    local_filename = f'/code/uploaded_file{ext}'
    with requests.get(url, stream=True) as r:
        with open(local_filename, 'wb') as f:
            for chunk in r.iter_content(chunk_size=8192):
                f.write(chunk)
    return local_filename

# Process PDF and save to ChromaDB
def save_pdf_and_update_database(pdf_filepath):
    try:
        document_loader = PyPDFLoader(pdf_filepath)
        documents = document_loader.load()
        
        text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=800,
            chunk_overlap=80,
            length_function=len,
            is_separator_regex=False,
        )
        chunks = text_splitter.split_documents(documents)
        
        embedding_function = HuggingFaceEmbeddings()
        db = Chroma(persist_directory=CHROMA_PATH, embedding_function=embedding_function)
        
        db.add_documents(chunks)
        db.persist()
        print("PDF processed and data updated in Chroma.")
    except Exception as e:
        print(f"Error processing PDF: {e}")

# Generate response using Falcon model
def generate_response(query, chat_history):
    response = ''
    for chunk in AI71(AI71_API_KEY).chat.completions.create(
            model="tiiuae/falcon-180b-chat",
            messages=[
                {"role": "system", "content": "You are the best agricultural assistant. Remember to give a response in not more than 2 sentences."},
                {"role": "user", "content": f'''Answer the query based on history {chat_history}: {query}'''},
            ],
            stream=True,
    ):
        if chunk.choices[0].delta.content:
            response += chunk.choices[0].delta.content
    return response.replace("###", '').replace('\nUser:', '')

# Query the RAG system
def query_rag(query_text: str, chat_history):
    try:
        # Ensure the database is initialized
        initialize_chroma()

        embedding_function = HuggingFaceEmbeddings()
        db = Chroma(persist_directory=CHROMA_PATH, embedding_function=embedding_function)
        
        results = db.similarity_search_with_score(query_text, k=5)
        
        if not results:
            return "Sorry, I couldn't find any relevant information."
        
        context_text = "\n\n---\n\n".join([doc.page_content for doc, _score in results])
        
        prompt = f"Context:\n{context_text}\n\nQuestion:\n{query_text}"
        response = generate_response(prompt, chat_history)
        
        return response
    except Exception as e:
        print(f"Error querying RAG system: {e}")
        return "An error occurred while querying the RAG system."


# Flask route to handle WhatsApp webhook
@app.route('/whatsapp', methods=['POST'])
def whatsapp_webhook():
    incoming_msg = request.values.get('Body', '').lower()
    sender = request.values.get('From')
    num_media = int(request.values.get('NumMedia', 0))

    chat_history = []  # You need to handle chat history appropriately

    if num_media > 0:
        media_url = request.values.get('MediaUrl0')
        content_type = request.values.get('MediaContentType0')

        if content_type == 'application/pdf':
            filepath = download_file(media_url, ".pdf")
            save_pdf_and_update_database(filepath)
            response_text = "PDF has been processed. You can now ask questions related to its content."
        else:
            response_text = "Unsupported file type. Please upload a PDF document."
    else:
        response_text = query_rag(incoming_msg, chat_history)

    # Assuming you have a function to send a message back to the user
    send_message(sender, response_text)
    return '', 204
    
def send_message(to, body):
    try:
        message = client.messages.create(
            from_=from_whatsapp_number,
            body=body,
            to=to
        )
        print(f"Message sent with SID: {message.sid}")
    except Exception as e:
        print(f"Error sending message: {e}")
        
def send_initial_message(to_number):
    send_message(
        f'whatsapp:{to_number}',
        'Welcome to the Agri AI Chatbot! How can I assist you today? You can send an image with "pest" or "disease" to classify it.'
    )
if __name__ == "__main__":
    send_initial_message('919080522395')
    send_initial_message('916382792828')
    app.run(host='0.0.0.0', port=7860)