akash015 commited on
Commit
ce2c30d
·
verified ·
1 Parent(s): 1f7062a

Upload 7 files

Browse files
Files changed (7) hide show
  1. .chainlit/config.toml +120 -0
  2. .chainlit/translations/en-US.json +229 -0
  3. .env +1 -0
  4. app.py +196 -0
  5. chainlit.md +1 -0
  6. public/test.css +20 -0
  7. requirements.txt +20 -0
.chainlit/config.toml ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ # Whether to enable telemetry (default: true). No personal data is collected.
3
+ enable_telemetry = true
4
+
5
+
6
+ # List of environment variables to be provided by each user to use the app.
7
+ user_env = []
8
+
9
+ # Duration (in seconds) during which the session is saved when the connection is lost
10
+ session_timeout = 3600
11
+
12
+ # Enable third parties caching (e.g LangChain cache)
13
+ cache = false
14
+
15
+ # Authorized origins
16
+ allow_origins = ["*"]
17
+
18
+ # Follow symlink for asset mount (see https://github.com/Chainlit/chainlit/issues/317)
19
+ # follow_symlink = false
20
+
21
+ [features]
22
+ # Process and display HTML in messages. This can be a security risk (see https://stackoverflow.com/questions/19603097/why-is-it-dangerous-to-render-user-generated-html-or-javascript)
23
+ unsafe_allow_html = false
24
+
25
+ # Process and display mathematical expressions. This can clash with "$" characters in messages.
26
+ latex = false
27
+
28
+ # Automatically tag threads with the current chat profile (if a chat profile is used)
29
+ auto_tag_thread = true
30
+
31
+ # Authorize users to spontaneously upload files with messages
32
+ [features.spontaneous_file_upload]
33
+ enabled = true
34
+ accept = ["*/*"]
35
+ max_files = 20
36
+ max_size_mb = 500
37
+
38
+ [features.audio]
39
+ # Threshold for audio recording
40
+ min_decibels = -45
41
+ # Delay for the user to start speaking in MS
42
+ initial_silence_timeout = 3000
43
+ # Delay for the user to continue speaking in MS. If the user stops speaking for this duration, the recording will stop.
44
+ silence_timeout = 1500
45
+ # Above this duration (MS), the recording will forcefully stop.
46
+ max_duration = 15000
47
+ # Duration of the audio chunks in MS
48
+ chunk_duration = 1000
49
+ # Sample rate of the audio
50
+ sample_rate = 44100
51
+
52
+ [UI]
53
+ name = "Shield Chat"
54
+ custom_css = "/public/test.css"
55
+
56
+
57
+ # Description of the assistant. This is used for HTML tags.
58
+ # description = ""
59
+
60
+ # Large size content are by default collapsed for a cleaner ui
61
+ default_collapse_content = true
62
+
63
+ # Hide the chain of thought details from the user in the UI.
64
+ hide_cot = false
65
+
66
+ # Link to your github repo. This will add a github button in the UI's header.
67
+ # github = ""
68
+
69
+ # Specify a CSS file that can be used to customize the user interface.
70
+ # The CSS file can be served from the public directory or via an external link.
71
+ # custom_css = "/public/test.css"
72
+
73
+ # Specify a Javascript file that can be used to customize the user interface.
74
+ # The Javascript file can be served from the public directory.
75
+ # custom_js = "/public/test.js"
76
+
77
+ # Specify a custom font url.
78
+ # custom_font = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap"
79
+
80
+ # Specify a custom meta image url.
81
+ # custom_meta_image_url = "https://chainlit-cloud.s3.eu-west-3.amazonaws.com/logo/chainlit_banner.png"
82
+
83
+ # Specify a custom build directory for the frontend.
84
+ # This can be used to customize the frontend code.
85
+ # Be careful: If this is a relative path, it should not start with a slash.
86
+ # custom_build = "./public/build"
87
+
88
+ [UI.theme]
89
+ default = "dark"
90
+ #layout = "wide"
91
+ #font_family = "Inter, sans-serif"
92
+ # Override default MUI light theme. (Check theme.ts)
93
+ [UI.theme.light]
94
+ #background = "#FAFAFA"
95
+ #paper = "#FFFFFF"
96
+
97
+ [UI.theme.light.primary]
98
+ main = "#F80061"
99
+ dark = "#980039"
100
+ light = "#FFE7EB"
101
+ [UI.theme.light.text]
102
+ primary = "#212121"
103
+ secondary = "#616161"
104
+
105
+ # Override default MUI dark theme. (Check theme.ts)
106
+ [UI.theme.dark]
107
+ #background = "#FAFAFA"
108
+ #paper = "#FFFFFF"
109
+
110
+ [UI.theme.dark.primary]
111
+ main = "#F80061"
112
+ dark = "#980039"
113
+ light = "#FFE7EB"
114
+ [UI.theme.dark.text]
115
+ primary = "#EEEEEE"
116
+ secondary = "#BDBDBD"
117
+
118
+
119
+ [meta]
120
+ generated_by = "1.1.304"
.chainlit/translations/en-US.json ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "components": {
3
+ "atoms": {
4
+ "buttons": {
5
+ "userButton": {
6
+ "menu": {
7
+ "settings": "Settings",
8
+ "settingsKey": "S",
9
+ "APIKeys": "API Keys",
10
+ "logout": "Logout"
11
+ }
12
+ }
13
+ }
14
+ },
15
+ "molecules": {
16
+ "newChatButton": {
17
+ "newChat": "New Chat"
18
+ },
19
+ "tasklist": {
20
+ "TaskList": {
21
+ "title": "\ud83d\uddd2\ufe0f Task List",
22
+ "loading": "Loading...",
23
+ "error": "An error occurred"
24
+ }
25
+ },
26
+ "attachments": {
27
+ "cancelUpload": "Cancel upload",
28
+ "removeAttachment": "Remove attachment"
29
+ },
30
+ "newChatDialog": {
31
+ "createNewChat": "Create new chat?",
32
+ "clearChat": "This will clear the current messages and start a new chat.",
33
+ "cancel": "Cancel",
34
+ "confirm": "Confirm"
35
+ },
36
+ "settingsModal": {
37
+ "settings": "Settings",
38
+ "expandMessages": "Expand Messages",
39
+ "hideChainOfThought": "Hide Chain of Thought",
40
+ "darkMode": "Dark Mode"
41
+ },
42
+ "detailsButton": {
43
+ "using": "Using",
44
+ "used": "Used"
45
+ },
46
+ "auth": {
47
+ "authLogin": {
48
+ "title": "Login to access the app.",
49
+ "form": {
50
+ "email": "Email address",
51
+ "password": "Password",
52
+ "noAccount": "Don't have an account?",
53
+ "alreadyHaveAccount": "Already have an account?",
54
+ "signup": "Sign Up",
55
+ "signin": "Sign In",
56
+ "or": "OR",
57
+ "continue": "Continue",
58
+ "forgotPassword": "Forgot password?",
59
+ "passwordMustContain": "Your password must contain:",
60
+ "emailRequired": "email is a required field",
61
+ "passwordRequired": "password is a required field"
62
+ },
63
+ "error": {
64
+ "default": "Unable to sign in.",
65
+ "signin": "Try signing in with a different account.",
66
+ "oauthsignin": "Try signing in with a different account.",
67
+ "redirect_uri_mismatch": "The redirect URI is not matching the oauth app configuration.",
68
+ "oauthcallbackerror": "Try signing in with a different account.",
69
+ "oauthcreateaccount": "Try signing in with a different account.",
70
+ "emailcreateaccount": "Try signing in with a different account.",
71
+ "callback": "Try signing in with a different account.",
72
+ "oauthaccountnotlinked": "To confirm your identity, sign in with the same account you used originally.",
73
+ "emailsignin": "The e-mail could not be sent.",
74
+ "emailverify": "Please verify your email, a new email has been sent.",
75
+ "credentialssignin": "Sign in failed. Check the details you provided are correct.",
76
+ "sessionrequired": "Please sign in to access this page."
77
+ }
78
+ },
79
+ "authVerifyEmail": {
80
+ "almostThere": "You're almost there! We've sent an email to ",
81
+ "verifyEmailLink": "Please click on the link in that email to complete your signup.",
82
+ "didNotReceive": "Can't find the email?",
83
+ "resendEmail": "Resend email",
84
+ "goBack": "Go Back",
85
+ "emailSent": "Email sent successfully.",
86
+ "verifyEmail": "Verify your email address"
87
+ },
88
+ "providerButton": {
89
+ "continue": "Continue with {{provider}}",
90
+ "signup": "Sign up with {{provider}}"
91
+ },
92
+ "authResetPassword": {
93
+ "newPasswordRequired": "New password is a required field",
94
+ "passwordsMustMatch": "Passwords must match",
95
+ "confirmPasswordRequired": "Confirm password is a required field",
96
+ "newPassword": "New password",
97
+ "confirmPassword": "Confirm password",
98
+ "resetPassword": "Reset Password"
99
+ },
100
+ "authForgotPassword": {
101
+ "email": "Email address",
102
+ "emailRequired": "email is a required field",
103
+ "emailSent": "Please check the email address {{email}} for instructions to reset your password.",
104
+ "enterEmail": "Enter your email address and we will send you instructions to reset your password.",
105
+ "resendEmail": "Resend email",
106
+ "continue": "Continue",
107
+ "goBack": "Go Back"
108
+ }
109
+ }
110
+ },
111
+ "organisms": {
112
+ "chat": {
113
+ "history": {
114
+ "index": {
115
+ "showHistory": "Show history",
116
+ "lastInputs": "Last Inputs",
117
+ "noInputs": "Such empty...",
118
+ "loading": "Loading..."
119
+ }
120
+ },
121
+ "inputBox": {
122
+ "input": {
123
+ "placeholder": "Type your message here..."
124
+ },
125
+ "speechButton": {
126
+ "start": "Start recording",
127
+ "stop": "Stop recording"
128
+ },
129
+ "SubmitButton": {
130
+ "sendMessage": "Send message",
131
+ "stopTask": "Stop Task"
132
+ },
133
+ "UploadButton": {
134
+ "attachFiles": "Attach files"
135
+ },
136
+ "waterMark": {
137
+ "text": "Built with"
138
+ }
139
+ },
140
+ "Messages": {
141
+ "index": {
142
+ "running": "Running",
143
+ "executedSuccessfully": "executed successfully",
144
+ "failed": "failed",
145
+ "feedbackUpdated": "Feedback updated",
146
+ "updating": "Updating"
147
+ }
148
+ },
149
+ "dropScreen": {
150
+ "dropYourFilesHere": "Drop your files here"
151
+ },
152
+ "index": {
153
+ "failedToUpload": "Failed to upload",
154
+ "cancelledUploadOf": "Cancelled upload of",
155
+ "couldNotReachServer": "Could not reach the server",
156
+ "continuingChat": "Continuing previous chat"
157
+ },
158
+ "settings": {
159
+ "settingsPanel": "Settings panel",
160
+ "reset": "Reset",
161
+ "cancel": "Cancel",
162
+ "confirm": "Confirm"
163
+ }
164
+ },
165
+ "threadHistory": {
166
+ "sidebar": {
167
+ "filters": {
168
+ "FeedbackSelect": {
169
+ "feedbackAll": "Feedback: All",
170
+ "feedbackPositive": "Feedback: Positive",
171
+ "feedbackNegative": "Feedback: Negative"
172
+ },
173
+ "SearchBar": {
174
+ "search": "Search"
175
+ }
176
+ },
177
+ "DeleteThreadButton": {
178
+ "confirmMessage": "This will delete the thread as well as it's messages and elements.",
179
+ "cancel": "Cancel",
180
+ "confirm": "Confirm",
181
+ "deletingChat": "Deleting chat",
182
+ "chatDeleted": "Chat deleted"
183
+ },
184
+ "index": {
185
+ "pastChats": "Past Chats"
186
+ },
187
+ "ThreadList": {
188
+ "empty": "Empty...",
189
+ "today": "Today",
190
+ "yesterday": "Yesterday",
191
+ "previous7days": "Previous 7 days",
192
+ "previous30days": "Previous 30 days"
193
+ },
194
+ "TriggerButton": {
195
+ "closeSidebar": "Close sidebar",
196
+ "openSidebar": "Open sidebar"
197
+ }
198
+ },
199
+ "Thread": {
200
+ "backToChat": "Go back to chat",
201
+ "chatCreatedOn": "This chat was created on"
202
+ }
203
+ },
204
+ "header": {
205
+ "chat": "Chat",
206
+ "readme": "Readme"
207
+ }
208
+ }
209
+ },
210
+ "hooks": {
211
+ "useLLMProviders": {
212
+ "failedToFetchProviders": "Failed to fetch providers:"
213
+ }
214
+ },
215
+ "pages": {
216
+ "Design": {},
217
+ "Env": {
218
+ "savedSuccessfully": "Saved successfully",
219
+ "requiredApiKeys": "Required API Keys",
220
+ "requiredApiKeysInfo": "To use this app, the following API keys are required. The keys are stored on your device's local storage."
221
+ },
222
+ "Page": {
223
+ "notPartOfProject": "You are not part of this project."
224
+ },
225
+ "ResumeButton": {
226
+ "resumeChat": "Resume Chat"
227
+ }
228
+ }
229
+ }
.env ADDED
@@ -0,0 +1 @@
 
 
1
+ GROQ_API_KEY=gsk_your_key
app.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import PyPDF2
3
+ from langchain_community.embeddings import OllamaEmbeddings
4
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
5
+ from langchain_community.vectorstores import Chroma
6
+ from langchain.chains import ConversationalRetrievalChain
7
+ from langchain_community.chat_models import ChatOllama
8
+ from langchain_groq import ChatGroq
9
+ from langchain.memory import ChatMessageHistory, ConversationBufferMemory
10
+ import chainlit as cl
11
+ from langchain_experimental.data_anonymizer import PresidioReversibleAnonymizer
12
+ import logging
13
+ import pypandoc
14
+ import pdfkit
15
+ from paddleocr import PaddleOCR
16
+ import fitz
17
+ import asyncio
18
+
19
+ llm_groq = ChatGroq(
20
+ model_name='llama3-70b-8192'
21
+ )
22
+
23
+ # Initialize anonymizer
24
+ anonymizer = PresidioReversibleAnonymizer(analyzed_fields=['PERSON', 'EMAIL_ADDRESS', 'PHONE_NUMBER', 'IBAN_CODE', 'CREDIT_CARD', 'CRYPTO', 'IP_ADDRESS', 'LOCATION', 'DATE_TIME', 'NRP', 'MEDICAL_LICENSE', 'URL', 'US_BANK_NUMBER', 'US_DRIVER_LICENSE', 'US_ITIN', 'US_PASSPORT', 'US_SSN'], faker_seed=18)
25
+
26
+ def extract_text_from_pdf(file_path):
27
+ pdf = PyPDF2.PdfReader(file_path)
28
+ pdf_text = ""
29
+ for page in pdf.pages:
30
+ pdf_text += page.extract_text()
31
+ return pdf_text
32
+
33
+ def has_sufficient_selectable_text(page, threshold=50):
34
+ text = page.extract_text()
35
+ if len(text.strip()) > threshold:
36
+ return True
37
+ return False
38
+
39
+ async def get_text(file_path):
40
+ text = ""
41
+ try:
42
+ logging.info("Starting OCR process for file: %s", file_path)
43
+ extension = file_path.split(".")[-1].lower()
44
+ allowed_extension = ["jpg", "jpeg", "png", "pdf", "docx"]
45
+ if extension not in allowed_extension:
46
+ error = "Not a valid File. Allowed Format are jpg, jpeg, png, pdf, docx"
47
+ logging.error(error)
48
+ return {"error": error}
49
+
50
+ if extension == "docx":
51
+ file_path = convert_docx_to_pdf(file_path)
52
+
53
+ ocr = PaddleOCR(use_angle_cls=True, lang='en')
54
+ result = ocr.ocr(file_path, cls=True)
55
+ for idx in range(len(result)):
56
+ res = result[idx]
57
+ for line in res:
58
+ text += line[1][0] + " "
59
+ logging.info("OCR process completed successfully for file: %s", file_path)
60
+ except Exception as e:
61
+ logging.error("Error occurred during OCR process for file %s: %s", file_path, e)
62
+ text = "Error occurred during OCR process."
63
+ logging.info("Extracted text: %s", text)
64
+ return text
65
+
66
+ def convert_docx_to_pdf(input_path):
67
+ html_path = input_path.replace('.docx', '.html')
68
+ output_path = ".".join(input_path.split(".")[:-1]) + ".pdf"
69
+ pypandoc.convert_file(input_path, 'html', outputfile=html_path)
70
+ pdfkit.from_file(html_path, output_path)
71
+ logging.info("DOCX Format Handled")
72
+ return output_path
73
+
74
+ async def extract_text_from_mixed_pdf(file_path):
75
+ pdf = PyPDF2.PdfReader(file_path)
76
+ ocr = PaddleOCR(use_angle_cls=True, lang='en')
77
+ pdf_text = ""
78
+ for i, page in enumerate(pdf.pages):
79
+ text = page.extract_text()
80
+ if not has_sufficient_selectable_text(page):
81
+ logging.info(f"Page {i+1} has insufficient selectable text, performing OCR.")
82
+ pdf_document = fitz.open(file_path)
83
+ pdf_page = pdf_document.load_page(i)
84
+ pix = pdf_page.get_pixmap()
85
+ image_path = f"page_{i+1}.png"
86
+ pix.save(image_path)
87
+ result = ocr.ocr(image_path, cls=True)
88
+ for idx in range(len(result)):
89
+ res = result[idx]
90
+ for line in res:
91
+ text += line[1][0] + " "
92
+ pdf_text += text
93
+ return pdf_text
94
+
95
+ @cl.on_chat_start
96
+ async def on_chat_start():
97
+
98
+ files = None # Initialize variable to store uploaded files
99
+
100
+ # Wait for the user to upload a file
101
+ while files is None:
102
+ files = await cl.AskFileMessage(
103
+ content="Please upload a pdf file to begin!",
104
+ # accept=["application/pdf"],
105
+ accept=["application/pdf", "image/jpeg", "image/png", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
106
+ max_size_mb=100,
107
+ timeout=180,
108
+ ).send()
109
+
110
+ file = files[0] # Get the first uploaded file
111
+
112
+ # Inform the user that processing has started
113
+ msg = cl.Message(content=f"Processing `{file.name}`...")
114
+ await msg.send()
115
+
116
+ # Extract text from PDF, checking for selectable and handwritten text
117
+ if file.name.endswith('.pdf'):
118
+ pdf_text = await extract_text_from_mixed_pdf(file.path)
119
+ else:
120
+ pdf_text = await get_text(file.path)
121
+
122
+ # Anonymize the text
123
+ anonymized_text = anonymizer.anonymize(
124
+ pdf_text
125
+ )
126
+
127
+ # with splitting into chunks
128
+ # {
129
+ # # Split the sanitized text into chunks
130
+ # text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
131
+ # texts = text_splitter.split_text(anonymized_text)
132
+
133
+ # # Create metadata for each chunk
134
+ # metadatas = [{"source": f"{i}-pl"} for i in range(len(texts))]
135
+
136
+ # # Create a Chroma vector store
137
+ # embeddings = OllamaEmbeddings(model="nomic-embed-text")
138
+ # docsearch = await cl.make_async(Chroma.from_texts)(
139
+ # texts, embeddings, metadatas=metadatas
140
+ # )
141
+ # }
142
+
143
+ # without splitting into chunks
144
+ # {
145
+ # Create a Chroma vector store
146
+ embeddings = OllamaEmbeddings(model="nomic-embed-text")
147
+ docsearch = await cl.make_async(Chroma.from_texts)(
148
+ [anonymized_text], embeddings, metadatas=[{"source": "0-pl"}]
149
+ )
150
+ # }
151
+
152
+ # Initialize message history for conversation
153
+ message_history = ChatMessageHistory()
154
+
155
+ # Memory for conversational context
156
+ memory = ConversationBufferMemory(
157
+ memory_key="chat_history",
158
+ output_key="answer",
159
+ chat_memory=message_history,
160
+ return_messages=True,
161
+ )
162
+
163
+ # Create a chain that uses the Chroma vector store
164
+ chain = ConversationalRetrievalChain.from_llm(
165
+ llm = llm_groq,
166
+ chain_type="stuff",
167
+ retriever=docsearch.as_retriever(),
168
+ memory=memory,
169
+ return_source_documents=True,
170
+ )
171
+
172
+ # Let the user know that the system is ready
173
+ msg.content = f"Processing `{file.name}` done. You can now ask questions!"
174
+ await msg.update()
175
+ # Store the chain in user session
176
+ cl.user_session.set("chain", chain)
177
+
178
+
179
+ @cl.on_message
180
+ async def main(message: cl.Message):
181
+
182
+ # Retrieve the chain from user session
183
+ chain = cl.user_session.get("chain")
184
+ # Callbacks happen asynchronously/parallel
185
+ cb = cl.AsyncLangchainCallbackHandler()
186
+
187
+ # Call the chain with user's message content
188
+ res = await chain.ainvoke(message.content, callbacks=[cb])
189
+ answer = anonymizer.deanonymize(
190
+ "ok"+res["answer"]
191
+ )
192
+ text_elements = []
193
+
194
+ # Return results
195
+ await cl.Message(content=answer, elements=text_elements).send()
196
+
chainlit.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Developed by "Akash Bhavsar"
public/test.css ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .MuiButtonBase-root.MuiIconButton-root.MuiIconButton-sizeMedium.css-1egpgfe {
2
+ display: none;
3
+ }
4
+
5
+ .MuiStack-root.watermark.css-1705j0v {
6
+ display: none;
7
+ }
8
+
9
+ .MuiAvatar-img.css-1hy9t21 {
10
+ content: url("/public/image.png"); /* Path to your custom avatar image */
11
+ }
12
+
13
+ img[src="http://localhost:8000/logo?theme=dark"]
14
+ {
15
+ display: none;
16
+ }
17
+
18
+ #open-sidebar-button {
19
+ display: none;
20
+ }
requirements.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ chainlitchainlit==1.1.304
2
+ langchain==0.2.5
3
+ langchain-community==0.2.5
4
+ langchain-core==0.2.9
5
+ langchain-groq==0.1.5
6
+ langchain-experimental==0.0.61
7
+ PyPDF2==3.0.1
8
+ chromadb==0.5.3
9
+ groq==0.9.0
10
+ ollama==0.2.1
11
+ pypandoc==1.13
12
+ pdfkit==1.0.0
13
+ docx2pdf==0.1.8
14
+ paddlepaddle==2.6.1
15
+ paddleocr==2.7.3
16
+ presidio-analyzer==2.2.354
17
+ presidio-anonymizer==2.2.354
18
+ spacy==3.7.5
19
+ Faker==25.9.1
20
+ # python 3.10.0