ssyok commited on
Commit
01ec4b3
1 Parent(s): 5d5edb1

first commit

Browse files
Files changed (2) hide show
  1. app.py +224 -0
  2. requirements.txt +0 -0
app.py ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from jamaibase import JamAI, protocol as p
3
+ import time
4
+ import os
5
+
6
+ # Initialize session state variables
7
+ def initialize_session_state():
8
+ if "unique_time" not in st.session_state:
9
+ st.session_state.unique_time = time.time()
10
+ if "knowledge_base_exist" not in st.session_state:
11
+ st.session_state.knowledge_base_exist = False
12
+ if "chat_history" not in st.session_state:
13
+ st.session_state.chat_history = []
14
+ if "api_key" not in st.session_state:
15
+ st.session_state.api_key = None
16
+ if "project_id" not in st.session_state:
17
+ st.session_state.project_id = None
18
+ if "model" not in st.session_state:
19
+ st.session_state.model = "ellm/Qwen/Qwen2-7B-Instruct"
20
+ if "k" not in st.session_state:
21
+ st.session_state.k = 2
22
+ if "temperature" not in st.session_state:
23
+ st.session_state.temperature = 0.01
24
+ if "top_p" not in st.session_state:
25
+ st.session_state.top_p = 0.01
26
+ if "max_tokens" not in st.session_state:
27
+ st.session_state.max_tokens = 496
28
+
29
+ # Function to check if any input is None
30
+ def check_all_fields_filled(file_upload, api_key, proj_id):
31
+ return file_upload is not None and api_key and proj_id
32
+
33
+ def clear_credentials():
34
+ st.session_state.api_key = ""
35
+ st.session_state.project_id = ""
36
+ st.session_state.unique_time = time.time() # reset the unique time
37
+
38
+ # Function to create knowledge base
39
+ def create_knowledge_base(jamai, file_upload):
40
+ try:
41
+ with st.spinner("Creating Knowledge Base..."):
42
+ knowledge_simple = f"knowledge-simple-{st.session_state.unique_time}"
43
+ knowledge_table = jamai.create_knowledge_table(
44
+ p.KnowledgeTableSchemaCreate(
45
+ id=knowledge_simple,
46
+ cols=[],
47
+ embedding_model="ellm/BAAI/bge-m3",
48
+ )
49
+ )
50
+ st.success("Successfully created Knowledge Base")
51
+
52
+ # Save PDF to local directory
53
+ current_dir = os.path.dirname(os.path.abspath(__file__))
54
+ file_path = os.path.join(current_dir, file_upload.name)
55
+ with open(file_path, "wb") as f:
56
+ f.write(file_upload.read())
57
+
58
+ # Upload file to knowledge base
59
+ with st.spinner("Uploading PDF to Knowledge Base..."):
60
+ response = jamai.upload_file(
61
+ p.FileUploadRequest(
62
+ file_path=file_path,
63
+ table_id=knowledge_simple,
64
+ )
65
+ )
66
+ assert response.ok
67
+ st.success("Successfully uploaded PDF to Knowledge Base!")
68
+ st.session_state.knowledge_base_exist = True
69
+
70
+ # remove after upload successfully
71
+ os.remove(file_path)
72
+
73
+ return knowledge_simple
74
+ except Exception as e:
75
+ clear_credentials()
76
+ # st.error(f"An error occurred: {str(e)}")
77
+ st.warning("An error occurred. Please check your credentials and try again.")
78
+ return None
79
+
80
+ # Function to create chat table
81
+ def create_chat_table(jamai, knowledge_simple):
82
+ try:
83
+ with st.spinner("Creating Chat Table..."):
84
+ table = jamai.create_chat_table(
85
+ p.ChatTableSchemaCreate(
86
+ id=f"chat-rag-{st.session_state.unique_time}",
87
+ cols=[
88
+ p.ColumnSchemaCreate(id="User", dtype=p.DtypeCreateEnum.str_),
89
+ p.ColumnSchemaCreate(
90
+ id="AI",
91
+ dtype=p.DtypeCreateEnum.str_,
92
+ gen_config=p.ChatRequest(
93
+ model=st.session_state.model,
94
+ messages=[p.ChatEntry.system("You are a concise assistant.")],
95
+ rag_params=p.RAGParams(
96
+ table_id=knowledge_simple,
97
+ k=st.session_state.k,
98
+ ),
99
+ temperature=st.session_state.temperature,
100
+ top_p=st.session_state.top_p,
101
+ max_tokens=st.session_state.max_tokens,
102
+ ).model_dump(),
103
+ ),
104
+ ],
105
+ )
106
+ )
107
+ st.success("Successfully created Chat Table")
108
+ except Exception as e:
109
+ clear_credentials()
110
+ # st.error(f"An error occurred while creating the chat table: {str(e)}")
111
+ st.warning("An error occurred. Please check your credentials and try again.")
112
+
113
+ # Function to ask a question with improved streaming output
114
+ def ask_question(question):
115
+ jamai = JamAI(api_key=st.session_state.api_key, project_id=st.session_state.project_id)
116
+ completion = jamai.add_table_rows(
117
+ "chat",
118
+ p.RowAddRequest(
119
+ table_id=f"chat-rag-{st.session_state.unique_time}",
120
+ data=[dict(User=question)],
121
+ stream=True,
122
+ ),
123
+ )
124
+
125
+ full_response = ""
126
+
127
+ for chunk in completion:
128
+ if chunk.output_column_name != "AI":
129
+ continue
130
+ if isinstance(chunk, p.GenTableStreamReferences):
131
+ pass
132
+ else:
133
+ full_response += chunk.text
134
+ yield full_response
135
+
136
+ # Main app function
137
+ def main():
138
+ st.title("Chat With PDF")
139
+
140
+ initialize_session_state()
141
+
142
+ # Sidebar for configuration
143
+ with st.sidebar:
144
+ st.logo("resource/Jamai-Long-Black-Main.icuEAbYB.svg")
145
+ login_button = """
146
+ <a href="https://cloud.jamaibase.com/" style="
147
+ display: inline-block;
148
+ padding: 10px 30px;
149
+ font-size: 1.2rem;
150
+ font-weight: 600;
151
+ text-align: center;
152
+ text-decoration: none;
153
+ transition: 0.25s;
154
+ color: #ffffff;
155
+ background-color: #007bff;
156
+ border: 1px solid transparent;
157
+ border-radius: 0.25rem;
158
+ ">
159
+ Login to your Jamai Base
160
+ </a>
161
+ """
162
+
163
+ st.markdown(login_button, unsafe_allow_html=True)
164
+
165
+ st.header("Configuration")
166
+ file_upload = st.file_uploader("Upload your PDF", type=["pdf"], disabled=st.session_state.knowledge_base_exist)
167
+ api_key = st.text_input('JAMAI API KEY', value=st.session_state.get('api_key', ''), type='password', disabled=st.session_state.knowledge_base_exist)
168
+ project_id = st.text_input('Project ID', value=st.session_state.get('project_id', ''), disabled=st.session_state.knowledge_base_exist)
169
+
170
+ with st.expander("Advanced Settings"):
171
+ model_options = [
172
+ 'ellm/Qwen/Qwen2-7B-Instruct', 'ellm/Qwen/Qwen2-72B-Instruct',
173
+ 'ellm/meta-llama/Llama-3-8B-Instruct', 'ellm/meta-llama/Llama-3-70B-Instruct',
174
+ 'ellm/meta-llama/Llama-3.1-8B-Instruct', 'ellm/meta-llama/Llama-3.1-70B-Instruct',
175
+ 'ellm/microsoft/Phi-3-mini-128k-Instruct-Int4'
176
+ 'ellm/microsoft/Phi-3-medium-128k-Instruct-Int4',
177
+ ]
178
+ st.session_state.model = st.selectbox("Model", options=model_options, index=0, disabled=st.session_state.knowledge_base_exist)
179
+ st.session_state.k = st.slider("k", value=2, min_value=1, max_value=30, step=1, disabled=st.session_state.knowledge_base_exist)
180
+ st.session_state.max_tokens = st.slider("max tokens", value=496, min_value=96, max_value=960, step=8, disabled=st.session_state.knowledge_base_exist)
181
+ temperature_options = [str(i/10) for i in range(1,11)]
182
+ st.session_state.temperature = st.selectbox("temperature", options=temperature_options, format_func=lambda x: float(x), disabled=st.session_state.knowledge_base_exist)
183
+ top_p_options = [str(i/10) for i in range(1,11)]
184
+ st.session_state.top_p = st.selectbox("top p", options=top_p_options, format_func=lambda x: float(x), disabled=st.session_state.knowledge_base_exist)
185
+
186
+ if st.button("Create Knowledge Base", disabled=st.session_state.knowledge_base_exist):
187
+ if not check_all_fields_filled(file_upload, api_key, project_id):
188
+ st.warning("Please provide all required information: PDF file, JAMAI API KEY, and Project ID.")
189
+ else:
190
+ st.session_state.api_key = api_key
191
+ st.session_state.project_id = project_id
192
+ jamai = JamAI(api_key=api_key, project_id=project_id)
193
+ knowledge_simple = create_knowledge_base(jamai, file_upload)
194
+ if knowledge_simple:
195
+ create_chat_table(jamai, knowledge_simple)
196
+
197
+ # Main chat interface
198
+ st.header("Jamai Base")
199
+
200
+ # Display chat history
201
+ for message in st.session_state.chat_history:
202
+ with st.chat_message(message["role"]):
203
+ st.markdown(message["content"])
204
+
205
+ # Chat input
206
+ if question := st.chat_input("Ask a question about your PDF"):
207
+ if st.session_state.knowledge_base_exist:
208
+ st.session_state.chat_history.append({"role": "user", "content": question})
209
+ with st.chat_message("user"):
210
+ st.markdown(question)
211
+
212
+ with st.chat_message("assistant"):
213
+ message_placeholder = st.empty()
214
+ full_response = ""
215
+ for response in ask_question(question):
216
+ message_placeholder.markdown(response + "▌")
217
+ full_response = response
218
+ message_placeholder.markdown(full_response)
219
+ st.session_state.chat_history.append({"role": "assistant", "content": full_response})
220
+ else:
221
+ st.warning("Please upload a PDF and create a Knowledge Base first.")
222
+
223
+ if __name__ == "__main__":
224
+ main()
requirements.txt ADDED
Binary file (2.12 kB). View file