cryogenic22 commited on
Commit
e25aaba
·
verified ·
1 Parent(s): 4670fef

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -186
app.py CHANGED
@@ -2,11 +2,13 @@ import streamlit as st
2
  from utils.vector_store import VectorStore
3
  from utils.document_processor import DocumentProcessor
4
  from utils.case_manager import CaseManager
 
5
  from utils.legal_notebook_interface import LegalNotebookInterface
6
  from datetime import datetime
7
  import os
8
  import nltk
9
  import spacy
 
10
 
11
  # Page configuration
12
  st.set_page_config(
@@ -73,6 +75,115 @@ def init_components():
73
  st.error(f"Error initializing components: {str(e)}")
74
  raise
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  def main():
77
  # Add custom styles
78
  st.markdown("""
@@ -102,202 +213,25 @@ def main():
102
  st.markdown("<h1 class='main-header'>SuoMoto.AI</h1>", unsafe_allow_html=True)
103
  st.markdown("<p class='main-tagline'>Empowering Legal Intelligence: Automate, Analyze, Act.</p>", unsafe_allow_html=True)
104
 
105
- # Initialize components with error handling
106
  try:
107
  case_manager, vector_store, doc_processor = init_components()
108
  except Exception as e:
109
  st.error("Failed to initialize application components. Please try again.")
110
  st.stop()
111
 
112
- # Sidebar navigation
113
- st.sidebar.title("SuoMoto.AI ⚖️")
114
- st.sidebar.markdown("""
115
- Streamline legal workflows with advanced AI-powered tools for document
116
- analysis and management.
117
- """)
118
-
119
  tab = st.sidebar.radio(
120
  "Navigation",
121
  ["📁 Case Manager", "📄 Document Analysis", "🤖 Legal Assistant"]
122
  )
123
 
124
- # Tab 1: Case Manager
125
- if tab == "📁 Case Manager":
126
- st.title("📁 Manage Cases")
127
- st.markdown("Create and manage legal cases with linked documents.")
128
-
129
- # Case creation form
130
- with st.expander("➕ Create New Case", expanded=True):
131
- with st.form("create_case_form"):
132
- title = st.text_input("Case Title")
133
- description = st.text_area("Description", placeholder="Enter case details...")
134
- case_type = st.selectbox(
135
- "Case Type",
136
- ["Judgment", "Contract", "MOU", "Will", "Other"]
137
- )
138
- create_case = st.form_submit_button("Create Case")
139
-
140
- if create_case and title:
141
- try:
142
- case_id = case_manager.create_case(title, description, case_type)
143
- st.success(f"Case '{title}' created successfully!")
144
- except Exception as e:
145
- st.error(f"Error creating case: {str(e)}")
146
-
147
- # List all cases
148
- st.subheader("📜 All Cases")
149
- try:
150
- cases = case_manager.get_all_cases()
151
- if cases:
152
- for case in cases:
153
- with st.expander(f"Case: {case['title']}"):
154
- st.write(f"**Description**: {case['description']}")
155
- st.write(f"**Type**: {case['case_type']}")
156
- st.write(f"**Created At**: {case['created_at']}")
157
-
158
- # List documents in case
159
- documents = case_manager.list_documents(case["id"])
160
- if documents:
161
- st.markdown("### Documents")
162
- for doc in documents:
163
- st.markdown(f"- **{doc['title']}** (Added: {doc['added_at']})")
164
- else:
165
- st.info("No documents uploaded yet.")
166
-
167
- # Upload new document
168
- uploaded_file = st.file_uploader(
169
- f"Upload Document to Case: {case['title']}",
170
- key=f"upload_{case['id']}"
171
- )
172
- # In the Case Manager tab section, where documents are uploaded
173
- if uploaded_file:
174
- if uploaded_file:
175
- with st.spinner("Processing document..."):
176
- try:
177
- # Process document
178
- text, chunks, metadata = doc_processor.process_and_tag_document(uploaded_file)
179
-
180
- # Add each chunk to vector store
181
- for chunk in chunks:
182
- try:
183
- vector_store.add_document(
184
- doc_id=f"{metadata['doc_id']}_chunk_{chunk['chunk_id']}",
185
- text=chunk['text'],
186
- metadata={
187
- 'doc_id': metadata['doc_id'],
188
- 'chunk_id': chunk['chunk_id'],
189
- 'title': uploaded_file.name,
190
- 'type': metadata.get('document_type', 'unknown')
191
- }
192
- )
193
- except Exception as e:
194
- st.warning(f"Error adding chunk to vector store: {str(e)}")
195
-
196
- # Add document to case
197
- doc_data = {
198
- "id": metadata['doc_id'],
199
- "title": uploaded_file.name,
200
- "text": text,
201
- "metadata": metadata,
202
- "chunks": chunks
203
- }
204
- case_manager.add_document(case["id"], doc_data)
205
- st.success(f"Document '{uploaded_file.name}' processed and added successfully!")
206
-
207
- except Exception as e:
208
- st.error(f"Error processing document: {str(e)}")
209
- else:
210
- st.info("No cases created yet. Use the form above to create your first case.")
211
- except Exception as e:
212
- st.error(f"Error loading cases: {str(e)}")
213
-
214
- # Tab 2: Document Analysis
215
- # In the Document Analysis tab section
216
- elif tab == "📄 Document Analysis":
217
- st.title("📄 Document Analysis")
218
- try:
219
- cases = case_manager.get_all_cases()
220
- if not cases:
221
- st.info("Please create a case and add documents first.")
222
- else:
223
- notebook = LegalNotebookInterface(case_manager, vector_store, doc_processor)
224
- notebook.render()
225
- except Exception as e:
226
- st.error(f"Error initializing document analysis: {str(e)}")
227
-
228
- # Tab 3: Legal Assistant
229
- elif tab == "🤖 Legal Assistant":
230
- st.title("🤖 AI Legal Assistant")
231
- st.markdown("Chat with your AI legal assistant about cases and documents.")
232
-
233
- try:
234
- # Select case and documents
235
- cases = case_manager.get_all_cases()
236
- if not cases:
237
- st.warning("Please create a case and add documents first.")
238
- return
239
-
240
- selected_case = st.selectbox(
241
- "Select Case",
242
- cases,
243
- format_func=lambda x: x['title']
244
- )
245
-
246
- if selected_case:
247
- documents = case_manager.list_documents(selected_case['id'])
248
- if not documents:
249
- st.warning("Please add documents to the case first.")
250
- return
251
-
252
- # Initialize chat history
253
- if "messages" not in st.session_state:
254
- st.session_state.messages = []
255
-
256
- # Display chat history
257
- for message in st.session_state.messages:
258
- with st.chat_message(message["role"]):
259
- st.markdown(message["content"])
260
-
261
- # Chat input
262
- if prompt := st.chat_input("Ask about your legal documents..."):
263
- st.session_state.messages.append({"role": "user", "content": prompt})
264
- with st.chat_message("user"):
265
- st.markdown(prompt)
266
-
267
- with st.chat_message("assistant"):
268
- with st.spinner("Analyzing documents..."):
269
- try:
270
- # Get relevant document chunks
271
- chunks = vector_store.similarity_search(prompt, k=3)
272
- context = "\n".join([chunk['text'] for chunk in chunks])
273
-
274
- # Generate response
275
- response = f"Analysis based on your documents:\n\n"
276
- response += "1. Key findings...\n"
277
- response += "2. Legal implications...\n"
278
- response += "3. Recommendations...\n\n"
279
- response += f"Context length: {len(context)} characters"
280
-
281
- st.markdown(response)
282
- st.session_state.messages.append({
283
- "role": "assistant",
284
- "content": response
285
- })
286
- except Exception as e:
287
- st.error(f"Error processing query: {str(e)}")
288
-
289
- except Exception as e:
290
- st.error(f"Error in Legal Assistant: {str(e)}")
291
-
292
- # Footer
293
- st.markdown(
294
- """
295
- <div class="footer">
296
- Powered by SuoMoto.AI
297
- </div>
298
- """,
299
- unsafe_allow_html=True
300
- )
301
 
302
  if __name__ == "__main__":
303
- main()
 
2
  from utils.vector_store import VectorStore
3
  from utils.document_processor import DocumentProcessor
4
  from utils.case_manager import CaseManager
5
+ from utils.legal_prompt_generator import LegalPromptGenerator
6
  from utils.legal_notebook_interface import LegalNotebookInterface
7
  from datetime import datetime
8
  import os
9
  import nltk
10
  import spacy
11
+ import anthropic
12
 
13
  # Page configuration
14
  st.set_page_config(
 
75
  st.error(f"Error initializing components: {str(e)}")
76
  raise
77
 
78
+ class ChatInterface:
79
+ def __init__(self, case_manager, vector_store, document_processor):
80
+ self.case_manager = case_manager
81
+ self.vector_store = vector_store
82
+ self.document_processor = document_processor
83
+ self.prompt_generator = LegalPromptGenerator()
84
+
85
+ # Initialize Anthropics client
86
+ try:
87
+ api_key = os.getenv("ANTHROPIC_API_KEY")
88
+ if not api_key:
89
+ st.error("Please set the ANTHROPIC_API_KEY environment variable.")
90
+ st.stop()
91
+ self.client = anthropic.Anthropic(api_key=api_key)
92
+ except Exception as e:
93
+ st.error(f"Error initializing Anthropic client: {str(e)}")
94
+ st.stop()
95
+
96
+ # Initialize session state
97
+ if "messages" not in st.session_state:
98
+ st.session_state.messages = []
99
+ if "current_case" not in st.session_state:
100
+ st.session_state.current_case = None
101
+
102
+ def render(self):
103
+ """Render the chat interface."""
104
+ st.title("🤖 Legal Assistant")
105
+ st.sidebar.title("📁 Select Case")
106
+
107
+ # Sidebar case selection
108
+ cases = self.case_manager.get_all_cases()
109
+ if not cases:
110
+ st.sidebar.info("No cases found. Create a case first.")
111
+ return
112
+
113
+ selected_case = st.sidebar.selectbox(
114
+ "Choose a case",
115
+ cases,
116
+ format_func=lambda x: x['title']
117
+ )
118
+ st.session_state.current_case = selected_case['id']
119
+
120
+ # Chat interface
121
+ for message in st.session_state.messages:
122
+ with st.chat_message(message["role"]):
123
+ st.markdown(message["content"])
124
+
125
+ # Chat input
126
+ if prompt := st.chat_input("Ask about your legal documents..."):
127
+ self._handle_chat_input(prompt)
128
+
129
+ def _handle_chat_input(self, prompt: str):
130
+ """Handle user input and generate a response."""
131
+ st.session_state.messages.append({"role": "user", "content": prompt})
132
+
133
+ with st.spinner("Analyzing documents..."):
134
+ try:
135
+ # Get case documents
136
+ documents = self.case_manager.list_documents(st.session_state.current_case)
137
+ if not documents:
138
+ st.error("No documents available for analysis.")
139
+ return
140
+
141
+ # Search for relevant chunks
142
+ context_chunks = self.vector_store.similarity_search(
143
+ query=prompt,
144
+ k=5
145
+ )
146
+
147
+ # Generate response using the LLM
148
+ response, references = self.generate_response(prompt, context_chunks)
149
+
150
+ # Append assistant response to chat
151
+ st.session_state.messages.append({
152
+ "role": "assistant",
153
+ "content": f"{response}\n\n{references}"
154
+ })
155
+ except Exception as e:
156
+ st.error(f"Error processing input: {str(e)}")
157
+
158
+ def generate_response(self, prompt: str, context_chunks: list) -> tuple[str, str]:
159
+ """Generate a response using the LLM and `LegalPromptGenerator`."""
160
+ try:
161
+ # Generate structured messages
162
+ messages = self.prompt_generator._generate_messages(prompt, context_chunks)
163
+
164
+ # Call the LLM API
165
+ message = self.client.messages.create(
166
+ model="claude-3",
167
+ max_tokens=2000,
168
+ temperature=0.7,
169
+ messages=messages
170
+ )
171
+
172
+ # Format references
173
+ references = self._format_references(context_chunks)
174
+ return message.content[0].text, references
175
+
176
+ except Exception as e:
177
+ st.error(f"Error generating response: {str(e)}")
178
+ return "An error occurred while processing your request.", ""
179
+
180
+ def _format_references(self, chunks: list) -> str:
181
+ """Format references for the assistant response."""
182
+ references = []
183
+ for i, chunk in enumerate(chunks, 1):
184
+ references.append(f"**Reference {i}:** {chunk['metadata'].get('title', 'Untitled')}\n- Section: {chunk['text'][:200]}...")
185
+ return "\n".join(references)
186
+
187
  def main():
188
  # Add custom styles
189
  st.markdown("""
 
213
  st.markdown("<h1 class='main-header'>SuoMoto.AI</h1>", unsafe_allow_html=True)
214
  st.markdown("<p class='main-tagline'>Empowering Legal Intelligence: Automate, Analyze, Act.</p>", unsafe_allow_html=True)
215
 
216
+ # Initialize components
217
  try:
218
  case_manager, vector_store, doc_processor = init_components()
219
  except Exception as e:
220
  st.error("Failed to initialize application components. Please try again.")
221
  st.stop()
222
 
223
+ # Navigation
 
 
 
 
 
 
224
  tab = st.sidebar.radio(
225
  "Navigation",
226
  ["📁 Case Manager", "📄 Document Analysis", "🤖 Legal Assistant"]
227
  )
228
 
229
+ if tab == "🤖 Legal Assistant":
230
+ chat_interface = ChatInterface(case_manager, vector_store, doc_processor)
231
+ chat_interface.render()
232
+ else:
233
+ # Implement other tabs
234
+ st.info("Other tabs are under construction.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
  if __name__ == "__main__":
237
+ main()