d12o6aa commited on
Commit
80013b7
ยท
1 Parent(s): 2b1b043

Add application file

Browse files
.env.example ADDED
@@ -0,0 +1 @@
 
 
1
+ APP_NAME = "ITI-RAG"
Dockerfile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+
5
+ RUN apt-get update && apt-get install -y \
6
+ build-essential \
7
+ libmagic-dev \
8
+ && rm -rf /var/lib/apt/lists/*
9
+
10
+ COPY requirements.txt .
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ COPY . .
14
+
15
+ EXPOSE 8000
16
+
17
+ CMD ["python", "app/main.py"]
app/__init__.py ADDED
File without changes
app/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (127 Bytes). View file
 
app/api/endpoints.py ADDED
File without changes
app/core/config.py ADDED
File without changes
app/core/constants.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ CHUNK_SIZE = 1500
2
+ CHUNK_OVERLAP = 200
3
+ VECTOR_DB_PATH = "data/vector_db"
app/main.py ADDED
File without changes
app/services/__pycache__/ingestion.cpython-310.pyc ADDED
Binary file (722 Bytes). View file
 
app/services/ingestion.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_community.document_loaders import PyMuPDFLoader
2
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
3
+ from app.core.constants import CHUNK_SIZE, CHUNK_OVERLAP
4
+
5
+ def load_and_split_book(file_path):
6
+ loader = PyMuPDFLoader(file_path)
7
+ documents = loader.load()
8
+
9
+ text_splitter = RecursiveCharacterTextSplitter(
10
+ chunk_size=CHUNK_SIZE,
11
+ chunk_overlap=CHUNK_OVERLAP,
12
+ length_function=len
13
+ )
14
+ chunks = text_splitter.split_documents(documents)
15
+
16
+ print(f"Book splited to {len(chunks)}")
17
+ return chunks
app/services/llm_service.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from langchain_google_genai import ChatGoogleGenerativeAI
3
+ from langchain.prompts import PromptTemplate
4
+ from langchain.chains import RetrievalQA
5
+ from app.services.vector_store import load_vector_store
6
+
7
+ llm = ChatGoogleGenerativeAI(
8
+ model="gemini-1.5-flash",
9
+ google_api_key="YOUR_GEMINI_API_KEY",
10
+ temperature=0
11
+ )
12
+
13
+ def get_book_assistant_chain(mode="Explain"):
14
+ vector_db = load_vector_store()
15
+ retriever = vector_db.as_retriever(search_kwargs={"k": 5})
16
+
17
+ if mode == "Explain":
18
+ template = """You are an expert tutor. Use the provided context to explain the concept simply.
19
+ Context: {context}
20
+ Question: {question}
21
+ Explanation:"""
22
+ else:
23
+ template = """Based on the following text, generate 3 multiple-choice questions with answers.
24
+ Context: {context}
25
+ Question: {question}
26
+ Questions:"""
27
+
28
+ QA_PROMPT = PromptTemplate(template=template, input_variables=["context", "question"])
29
+
30
+ return RetrievalQA.from_chain_type(
31
+ llm=llm,
32
+ chain_type="stuff",
33
+ retriever=retriever,
34
+ return_source_documents=True,
35
+ chain_type_kwargs={"prompt": QA_PROMPT}
36
+ )
app/services/vector_store.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_community.embeddings import HuggingFaceEmbeddings
2
+ from langchain_community.vectorstores import FAISS
3
+ from app.core.constants import VECTOR_DB_PATH
4
+
5
+ # ุงุฎุชูŠุงุฑู†ุง ู„ู€ all-MiniLM-L6-v2 ู„ุฃู†ู‡ ุฎููŠู ุนู„ู‰ ุฌู‡ุงุฒูƒ Dell G12 [cite: 51]
6
+ embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
7
+
8
+ def create_vector_store(chunks):
9
+ # ุชุญูˆูŠู„ ุงู„ู†ุต ู„ุฃุฑู‚ุงู… ูˆุชุฎุฒูŠู†ู‡ [cite: 29, 30]
10
+ vector_db = FAISS.from_documents(chunks, embeddings)
11
+
12
+ # ุญูุธ ุงู„ู‚ุงุนุฏุฉ ู…ุญู„ูŠุงู‹ (Local Storage)
13
+ vector_db.save_local(VECTOR_DB_PATH)
14
+ return vector_db
15
+
16
+ def load_vector_store():
17
+ # ุชุญู…ูŠู„ ุงู„ู‚ุงุนุฏุฉ ุนู†ุฏ ุงู„ุญุงุฌุฉ [cite: 32]
18
+ return FAISS.load_local(VECTOR_DB_PATH, embeddings, allow_dangerous_deserialization=True)
docker-compose.yml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: '3.8'
2
+
3
+ services:
4
+ smart-assistant:
5
+ build: .
6
+ ports:
7
+ - "8000:8000"
8
+ environment:
9
+ - GROQ_API_KEY=${GROQ_API_KEY}
10
+ volumes:
11
+ - ./data:/app/data
12
+
main.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ import uvicorn
3
+ from ui.gradio_app import demo
4
+ import gradio as gr
5
+
6
+ app = FastAPI(title="Smart Contract/Book Assistant API")
7
+
8
+ app = gr.mount_gradio_app(app, demo, path="/")
9
+
10
+ if __name__ == "__main__":
11
+ uvicorn.run(app, host="0.0.0.0", port=8000)
requirements.txt ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Core Web Framework
2
+ fastapi==0.111.0
3
+ uvicorn[standard]==0.30.1
4
+
5
+ # AI & RAG Engine
6
+ langchain>=0.2.0
7
+ langchain-community>=0.2.0
8
+ langchain-google-genai>=1.0.0
9
+ sentence-transformers>=2.7.0
10
+ faiss-cpu>=1.8.0
11
+
12
+ # Document Processing
13
+ pypdf>=4.2.0
14
+ python-docx>=1.1.0
15
+
16
+ # UI & Local Execution
17
+ gradio>=4.36.1
18
+ transformers>=4.41.0
19
+ torch>=2.3.0
20
+
21
+ # Critical Dependencies (To fix the Numpy/Scipy error)
22
+ numpy<2.0.0
23
+ scipy>=1.13.0
ui/__pycache__/gradio_app.cpython-310.pyc ADDED
Binary file (2.13 kB). View file
 
ui/gradio_app.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from app.services.ingestion import load_and_split_book
3
+ from app.services.vector_store import create_vector_store
4
+ from app.services.llm_service import get_book_assistant_chain
5
+
6
+ def handle_upload(file):
7
+ if file is None:
8
+ return "Please upload a file first."
9
+
10
+ chunks = load_and_split_book(file.name)
11
+
12
+ create_vector_store(chunks)
13
+
14
+ return "โœ… Document processed successfully! You can now go to the Chat tab."
15
+
16
+ def handle_chat(user_question, mode):
17
+ qa_chain = get_book_assistant_chain(mode=mode)
18
+
19
+ result = qa_chain({"query": user_question})
20
+
21
+ answer = result["result"]
22
+ sources = "\n\n๐Ÿ“Œ Sources:\n" + "\n".join([doc.metadata.get('source', 'Unknown') for doc in result["source_documents"]])
23
+
24
+ return answer + sources
25
+
26
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
27
+ gr.Markdown("# ๐Ÿ“š Smart Book & Contract Assistant")
28
+
29
+ with gr.Tabs():
30
+ with gr.TabItem("โฌ†๏ธ Upload Document"):
31
+ file_input = gr.File(label="Upload PDF or DOCX", file_types=[".pdf", ".docx"])
32
+ upload_btn = gr.Button("Process Document", variant="primary")
33
+ status_output = gr.Textbox(label="Status", interactive=False)
34
+ upload_btn.click(handle_upload, inputs=file_input, outputs=status_output)
35
+
36
+ with gr.TabItem("๐Ÿ’ฌ Explanation & Q&A"):
37
+ mode_radio = gr.Radio(
38
+ choices=["Explain", "Generate Questions"],
39
+ label="Interaction Mode",
40
+ value="Explain"
41
+ )
42
+ chat_input = gr.Textbox(label="Ask a question or request a summary/questions")
43
+ chat_btn = gr.Button("Submit", variant="primary")
44
+ chat_output = gr.Textbox(label="AI Assistant Response", lines=12)
45
+
46
+ chat_btn.click(handle_chat, inputs=[chat_input, mode_radio], outputs=chat_output)
47
+
48
+ if __name__ == "__main__":
49
+ demo.launch()